将JSON保存为核心数据中的字符串

时间:2013-02-13 05:33:11

标签: iphone ios core-data

我从URL获取数据。数据以JSON形式出现。我想将该JSON保存为Core Data中的字符串。我怎样才能做到这一点 ? (我的JSON是一个NSDictionary对象,运行后就是说

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

5 个答案:

答案 0 :(得分:1)

使用https://github.com/stig/json-framework/,并使用字典

NSString* jsonString = [jsonDict JSONRepresentation];

因为核心数据需要NSString而不是NSDictionary

答案 1 :(得分:1)

您需要将数据转换为字符串并将其存储到核心数据中。

像这样:

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

现在将jsonString保存到核心数据。

答案 2 :(得分:1)

您可以将核心数据模型中的属性类型指定为 Transformable ,然后直接将NSDictionary对象传递给它。

如果要创建NSManagedObject子类来处理对象,则属性将在子类中显示为id类型(您可以选择将其更改为NSDictionary以使用字典函数在以后访问它时直接在对象上)。

注意:这是一种替代解决方案,不会将字典对象转换为字符串。

答案 3 :(得分:0)

请注意,JSON规范声明密钥的顺序不固定。结果是密钥将不时混合,这使得使用谓词无法检索JSON对象。在使用NSJsonSerialization生成用于在Core Data中存储/检索的NSString之后我遇到了这个问题:每次键的顺序都不同,所以我无法检查JSON消息是否已经存在。

另见https://stackoverflow.com/a/15125704/876903

我决定创建一个NSDictionary类别,将所有键和值递归地放在一个有序数组中,然后用它来查看核心数据对象中存储的NSDictionary对象是否已经存储。

我的核心数据对象如此包含:

  • keys(已排序的NSString)
  • values(排序的NSString)
  • message(Transformable NSDictionary)

我会使用谓词来查看JSON对象是否存在:

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

答案 4 :(得分: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()
}