从 JSON + Swift 或 ObjC 检索数据时如何处理 CoreData 中的关系
Posted
技术标签:
【中文标题】从 JSON + Swift 或 ObjC 检索数据时如何处理 CoreData 中的关系【英文标题】:How handling relationships in CoreData while retrieving data from JSON + Swift Or ObjC 【发布时间】:2014-12-09 09:52:25 【问题描述】:我实际上想在解析 Json 数据并创建子对象、保存和管理关系时处理关系。
我使用 findOrCreat 函数来验证我的对象是否已经存在,如果它存在,我会从 JSON 数据更新,如果不存在,我创建对象。当我使用 NSAsynchnonusFetchRequest 时,我不知道如何处理这些关系。另外,关系必须在父对象之前创建,所以当我在异步调用中创建父对象时,如何管理子对象和关系的创建?
在这里你可以找到我的 findOrCreat 函数:
// Asynchronous fetch
let asyncFetch = NSAsynchronousFetchRequest(fetchRequest: fetchRequest)
(result:NSAsynchronousFetchResult!)-> Void in
if result.finalResult!.count <= 0
var eventToSave:Events!;
eventToSave = NSEntityDescription.insertNewObjectForEntityForName(Entities.Event.rawValue, inManagedObjectContext: self.cdhUser.backgroundContext!) as Events;
eventToSave.setValue(eventId, forKey: "id");
eventToSave.setValue((dictionary.objectForKey("title") as NSString), forKey: "title");
eventToSave.setValue((dictionary.objectForKey("exclusive") as Bool), forKey: "isExclusive");
eventToSave.setValue(0, forKey: "latitude");
eventToSave.setValue(0, forKey: "longitude");
eventToSave.setValue("", forKey: "details");
eventToSave.setValue((dictionary.objectForKey("summary") as NSString), forKey: "summary");
eventToSave.setValue((NSDate(timeIntervalSince1970: dictionary.objectForKey("date") as Double)), forKey: "date");
eventToSave.setValue(NSDate(), forKey: "validFrom");
eventToSave.setValue(NSDate(), forKey: "validTo");
// Get url of image
var pictureUrl:NSString!;
if let pictureDictionary:NSDictionary = dictionary.objectForKey("main_media") as? NSDictionary
if let endUrlString:NSString = pictureDictionary.objectForKey("url") as? NSString
pictureUrl = endUrlString;
eventToSave.setValue((pictureUrl != nil ? pictureUrl : ""), forKey: "picture"); // Default Image Url
self.cdhUser.saveContext(self.cdhUser.backgroundContext!);
else if result.finalResult!.count > 0
var eventToUpdate = result.finalResult?.first as Events;
eventToUpdate.setValue((dictionary.objectForKey("title") as NSString), forKey: "title");
eventToUpdate.setValue((dictionary.objectForKey("exclusive") as Bool), forKey: "isExclusive");
eventToUpdate.setValue(0, forKey: "longitude");
eventToUpdate.setValue(0, forKey: "latitude");
eventToUpdate.setValue("", forKey: "details");
eventToUpdate.setValue((dictionary.objectForKey("summary") as NSString), forKey: "summary");
eventToUpdate.setValue((NSDate(timeIntervalSince1970: dictionary.objectForKey("date") as Double)), forKey: "date");
eventToUpdate.setValue((NSDate()), forKey: "validTo");
eventToUpdate.setValue((NSDate()), forKey: "validFrom");
// Get url of image
var pictureUrl:NSString!;
if let pictureDictionary:NSDictionary = dictionary.objectForKey("main_media") as? NSDictionary
if let endUrlString:NSString = pictureDictionary.objectForKey("url") as? NSString
pictureUrl = endUrlString;
eventToUpdate.picture = pictureUrl;
println(eventToUpdate);
self.cdhUser.saveContext(self.cdhUser.backgroundContext!);
NSLog("Update is done!");
self.cdhUser.backgroundContext!.performBlock
var result = self.cdhUser.backgroundContext!.executeRequest(asyncFetch, error: &error) as NSAsynchronousFetchResult;
这是我的 JSON 示例:
"id": 1,
"title": "Inauguration",
"summary": "Evenement",
"main_media":
"url": "c75b931abb131e9d091882c3638aca9fe0ecdee6.jpeg",
"name": "99.JPG",
"type": 2,
"created_at": 1415377363
,
"date": 1412174799,
"duration": 6483600,
"exclusive": true,
"geo_location": [],
"open": true,
"description": "Evenement",
"interested": true,
"medias": [
"url": "1c3f251b7bccd3bd4337852538fe7ba0accefa77.jpeg",
"name": "b90mq.jpg",
"type": 2,
"created_at": 1415375677,
"main_media": false
,
"url": "c75b931abb131e9d091882c3638aca9fe0ecdee6.jpeg",
"name": "woodstock-99.JPG",
"type": 2,
"created_at": 1415377363,
"main_media": true
]
那么,如何在创建事件对象时创建媒体对象? 我什么时候可以调用 findOrCreate 函数来创建 Medias 对象?以及如何管理关系?
非常感谢
【问题讨论】:
【参考方案1】:您应该在 xcdatamodeld 中添加从事件到媒体的一对多关系。
let manyRelation = eventToSave.valueForKeyPath("medias") as NSMutableSet
for dict : NSDictionary in dictionary.objectForKey("main_media") as? [NSDictionary]
let media : Media = Media()
media.url = dict.objectForKey("url")
media.name = dict.objectForKey("name")
....
manyRelation.addObject(media)
此代码需要在创建根对象后保存上下文前添加
【讨论】:
非常感谢。只是一件事,我想检查一下这个媒体是否已经存在!?为此,我必须为 Medias 调用 findOrCreate 函数。你怎么看? 有两种解决方案:1)您可以找到并更新创建的对象 2)您可以删除所有现有对象并重新创建它们。在您的情况下,第二种解决方案比第一种更简单。 非常感谢,我会做的。 我得到:由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'-[Media setPath:]: unrecognized selector sent to instance 0x19b676e0' 我认为这是因为没有创建对象“媒体”在 CoreData... 我们没有 setEntitiyDescription(Media...) !你有什么想法 ?!感谢您的帮助 是的,您应该使用 insertNewObjectForEntityForName。 (您可以在 Media 的 init 方法中添加它)您应该在 xcdatamodeld 中添加从事件到媒体的一对多关系。 - 这意味着您需要在 xcdatamodeld 中创建媒体实体。以上是关于从 JSON + Swift 或 ObjC 检索数据时如何处理 CoreData 中的关系的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中使用带有 UnsafeMutableRawPointer 或 UnsafeMutablePointer 参数的 ObjC 函数?