2013-02-13 88 views
2

我正在從URL中獲取數據。數據以JSON形式出現。我想將該JSON作爲字符串保存在Core Data中。我怎樣才能做到這一點 ? (我的JSON是一個NSDictionary中的對象並運行它後說將JSON保存爲核心數據中的字符串

Terminating app due to uncaught exception 'NSInvalidArgumentException',reason:'Unacceptable type of value for attribute: property = "cat_list"; desired type = NSString; given type = __NSCFDictionary; 
+0

請張貼相關的代碼 – 2013-02-13 05:42:52

+0

'results_category_list = [NSJSONSerialization JSONObjectWithData:數據選擇:NSJSONReadingMutableLeaves誤差:&myError];' – 2013-02-13 05:47:59

+0

爲什麼不把它保存爲數據?在覈心數據模型中將類型更改爲blob,保存從URL返回的數據並在需要時將其轉換爲字典表示形式? – bennythemink 2013-02-13 05:48:57

回答

1

您需要將數據轉換爲字符串並將其存儲到您的核心數據中。

像這樣:

NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

現在將jsonString保存爲核心數據。

1

您可以將核心數據模型中的屬性類型設置爲Transformable,然後直接將NSDictionary對象傳遞給它。

如果要創建一個子類NSManagedObject處理的對象,屬性會在你的子類id類型(您可以選擇將其更改爲NSDictionary以後訪問時,直接使用對象的字典功能)。

注意:這是一個備用解決方案,不會將字典對象轉換爲字符串。

0

請注意,JSON規範規定密鑰的順序不固定。其結果是密鑰會不時混入,這使得使用謂詞來檢索JSON對象成爲不可能。在使用NSJsonSerialization生成一個用於在Core Data中存儲/檢索的NSString之後,我遇到了這個問題:每次鍵的順序都不一樣,因此我無法檢查該JSON消息是否已經存在。請參閱https://stackoverflow.com/a/15125704/876903

我決定創建一個NSDictionary類,它將所有鍵和值以遞歸方式放入有序數組中,然後用於查看NSDictionary對象是否已與這些NSStrings一起存儲在覈心數據對象中。從而

我的核心數據對象包含:

  • 鍵(排序的NSString)
  • 值(排序的NSString)
  • 消息(可變形的NSDictionary)

我會用一個謂詞看看JSON對象是否像這樣存在:

[NSPredicate predicateWithFormat:@"(keys == %@) AND (values == %@)", sortedKeys, sortedValues]; 
0

運行函數testThis()來查看這一切。 self.user.jsonTest是Transformable類型的核心數據變量。將其替換爲任何可變形的CoreData變量,storeJSON和檢索JSON應該可以工作。我使用的是swiftyJSON,但如果不使用它,刪除它應該非常容易。

func testThis() { 
    makeFakeData() { 
     self.retrieveJSON(self.user.jsonTest) { 
      json in 
      print("json: \(json)") 
     } 
    } 
} 

func storeJSON(dataToStore: [String: AnyObject], completion: (data: NSData?) -> Void) { 
    do { 
     let data = try NSJSONSerialization.dataWithJSONObject(dataToStore, options: []) 
     completion(data: data) 
    } catch let error as NSError { 
     print("NSJSONSerialization Error: \(error)") 
     completion(data: nil) 
    } 
} 

func retrieveJSON(dataToGet: NSObject?, completion: (json: JSON?) -> Void) { 
    if let data = dataToGet as? NSData { 
     do { 
      let nsJSON = try NSJSONSerialization.JSONObjectWithData(data, options: []) 
      completion(json: JSON(nsJSON)) 
     } catch let error as NSError { 
      print("NSJSONSerialization Error: \(error)") 
      completion(json: nil) 
     } 
    } 
} 

func makeFakeData(completion:() -> Void) { 
    var solarResourceDic: [String: String] = [:] 
    var srDics: [[String: String]!] = [] 

    for i in 0..<5 { 
     solarResourceDic = [:] 
     solarResourceDic["system_capacity"] = "\(i)" 
     solarResourceDic["azimuth"] = "\(i + 1)" 
     solarResourceDic["tilt"] = "\(i + 2)" 
     solarResourceDic["array_type"] = "\(i + 3)" 
     solarResourceDic["module_type"] = "\(i + 4)" 
     solarResourceDic["losses"] = "\(i + 5)" 
     srDics.append(solarResourceDic) 
    } 
    let dic = ["Solar Resource": srDics] 

    storeJSON(dic) { 
     data in 
     self.user.jsonTest = data 
     appDelegate.coreData.saveContext() 
    } 
    completion() 
}