2015-12-04 83 views
0

訪問一個Singleton財產標我有一個Singleton類:斯威夫特

class Session { 
    static let sharedInstance = Session() 
    private init() {} 
    // app properties 
    var token: String! 
    var promotions: JSON! 
} 

在網絡類我有我火了使用map功能,每個網址多個異步調用:

let urls = [ "promotions": "http:..." ] 

let results = urls.map { (k, url) in 
    self.getFromApi(url, params: ["token" : token]) { response in 
    guard response as? JSON != nil else { return } 

    Session.sharedInstance[k] = response 
    // the above should compile to Session.sharedInstance["promotions"] = response. 
    } 

問題在於嘗試通過下標在sharedInstance上設置響應。我已經嘗試實現對辛格爾頓標無濟於事:

subscript(property: Any) -> Any { 
    get { 
    return Session.sharedInstance[property] 
    } 
    set(newValue) { 
    Session.sharedInstance[property] = newValue 
    } 
} 

我也試圖通過放棄符合下標來NSObject和使用KVC然而這也沒有工作&而且我失去了所有類型安全。

任何幫助或建議非常感謝。 在此先感謝。

+0

爲什麼你需要下標?我猜,因爲你有更多的屬性,如「促銷」? –

+0

也不需要做:'Session.sharedInstance [property] = newValue'只需使用:'self。[property] = newValue'然後你就可以清楚的知道你正在創建一個遞歸下標。 –

回答

1

你可以讓你的單身人士一袋類。你有一個包含你的JSON或屬性的字典。其他一切只是計算值。

class Session { 
    static let sharedInstance = Session() 
    private init() {} 
    // app properties 
    var token: String! 

    private var fetchedJSON : [String:Any] = [:] 

    var keys : [String] { 
     return Array(fetchedJSON.keys) 
    } 

    // handy to do downcasts in here 
    var promotions : JSON? { 
     get { 
      if let promotions = fetchedJSON["promotions"] as? JSON { 
       return promotions 
      } else { 
       return nil 
      } 
     } 
     set(value) { 
      fetchedJSON["prmotions"] = value 
     } 
    } 

    subscript(property: String) -> Any? { 
     get { 
      return fetchedJSON[property] 

     } 
     set(newValue) { 
      fetchedJSON[property] = newValue 
     } 
    } 
} 

或者創建一個有限的KVC(這也可以通過反射實現在由奧利弗Borchert表示對方回答說):

class Singleton { 

    var alpha : Any? 
    var beta : Any? 
    var delta : Any? 

    subscript(property: String) -> Any? { 
     get { 
      switch property { 
      case "alpha" : return self.alpha 
      case "beta" : return self.beta 
      case "delta" : return self.delta 
      default : return nil 
      } 
     } 
     set(newValue) { 
      switch property { 
      case "alpha" : self.alpha = newValue 
      case "beta" : self.beta = newValue 
      case "delta" : self.delta = newValue 
      default : return 
      } 
     } 
    } 
} 
+0

這太好了。謝謝@ r-menke! –

+0

@KyleGillen哪一個很棒? –

+0

我喜歡KVC的選擇。鑑於我有不少屬性,它似乎不太笨拙。 –

1

你可能會使用反射。我不經常使用它,所以如果你有任何進一步的問題,只是谷歌'斯威夫特反射'。但要小心:反射可能看起來不錯,但它很慢,只適用於NSObject的子類(我認爲,但隨時可以試用)。它的工作方式如下:

subscript(property: String) -> Any { 
    get { 
     for i in 0..<reflect(self).count { // loop through all properties 
      if reflect(self)[i].0 == property { // find property with specified name 
       return reflect(self)[i].1.summary // return property's value 
      } 
     } 
     fatalError("no such property found") 
    } set(newValue) { 
     for i in 0..<reflect(self).count { // loop through all properties 
      if reflect(self)[i].0 == property { // find property with specified name 
       self.setValue(newValue, forKey: property) // not possible to do otherwise in Swift 
       return 
      } 
     } 
    } 
}