Reputation: 400
I am fetching data from URL. Data is coming in JSON form. I want to save that JSON as a string in Core Data. How can i do that ? (My JSON is a NSDictionary object and after running it is saying that
Terminating app due to uncaught exception 'NSInvalidArgumentException',reason:'Unacceptable type of value for attribute: property = "cat_list"; desired type = NSString; given type = __NSCFDictionary;
Upvotes: 2
Views: 2147
Reputation: 3074
Run the function testThis() to see it all happen. self.user.jsonTest is a Core Data varaible of type Transformable. Replace it with any Transformable CoreData variable and the storeJSON and retrieve JSON should work. I am using swiftyJSON, but it should be extremely easy to remove that if you don't use it.
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()
}
Upvotes: 0
Reputation: 106
Please note that the JSON specifications state that the order of keys is not fixed. The result is that the keys will be mingled from time to time which makes retrieving the JSON object impossible using predicates. I had this issue after using NSJsonSerialization to generate an NSString for storing/retrieving in Core Data: the order of the keys was different every time so that I could not check if that JSON message already existed.
See also https://stackoverflow.com/a/15125704/876903.
I decided to create a NSDictionary category that put all keys and values in an ordered array recursively which was then used to see if the NSDictionary object stored along with these NSStrings in the core data object was already stored.
My core data object thus contained:
I would use a predicate to see if the JSON object existed like so:
[NSPredicate predicateWithFormat:@"(keys == %@) AND (values == %@)", sortedKeys, sortedValues];
Upvotes: 0
Reputation: 3399
You can give the type of the attribute in your core data model as Transformable and then directly pass the NSDictionary object to it.
If you are creating a NSManagedObject
subclass to handle the objects, the attribute will come as type id
in your subclass(you can optionally change it to NSDictionary
to use the dictionary functions on the object directly when accessing it later).
Note: this is an alternate solution and doesn't convert the dictionary object into string.
Upvotes: 1
Reputation: 107121
You need to convert your data to string and store it to your core data.
Like this:
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
Now save jsonString
to core data.
Upvotes: 1
Reputation: 136
Use https://github.com/stig/json-framework/ , and the for you dictionary use
NSString* jsonString = [jsonDict JSONRepresentation];
as core data expects NSString
and not a NSDictionary
.
Upvotes: 1