我目前正在解析JSON数据,并根据结果是否存在来更新或创建实体。
我正在使用SwiftyJson进行JSON解析。
我的NSManagedObject子类中有一个createInManagedObjectContext函数,它接受一堆用于创建新记录的参数:
class func createInManagedObjectContext(moc: NSManagedObjectContext, id: String, flatNumber: String, propertyName: String, propertyNumber: String, street: String, locality: String, town: String, postcode:String, createdDate: NSString) -> Work {
let newWorkItem = NSEntityDescription.insertNewObjectForEntityForName("Work", inManagedObjectContext: moc) as! Work
var mydate = createdDate
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
newWorkItem.createdDate = formatter.dateFromString(mydate as String)!
newWorkItem.id = id
newWorkItem.flatNumber = flatNumber
newWorkItem.propertyName = propertyName
newWorkItem.propertyNumber = propertyNumber
newWorkItem.street = street
newWorkItem.locality = locality
newWorkItem.town = town
newWorkItem.postcode = postcode
return newWorkItem
}
这是我目前用于解析json并创建新记录的代码:
if let moc = self.managedObjectContext {
moc.performBlockAndWait({
Work.createInManagedObjectContext(moc,
id: object["Id"].stringValue,
flatNumber: object["FlatNumber"].stringValue,
propertyName: object["PropertyName"].stringValue,
propertyNumber: object["PropertyNumber"].stringValue,
street: object["Street"].stringValue,
locality: object["Locality"].stringValue,
town: object["Town"].stringValue,
postcode: object["Postcode"].stringValue,
createdDate: object["CreatedDate"].stringValue
)
for party in object["Parties"].arrayValue {
Party.createInManagedObjectContext(moc,
id: party["Id"].stringValue,
firstName: party["FirstName"].stringValue,
lastName: party["LastName"].stringValue,
propertyName: party["PropertyName"].stringValue,
propertyNumber: party["PropertyNumber"].stringValue,
street: party["Street"].stringValue,
locality: party["Locality"].stringValue,
town: party["Town"].stringValue,
postcode: party["Postcode"].stringValue,
createdDate: party["CreatedDate"].stringValue)
}
// println(object["Parties"])
})
moc.save(nil)
}
现在我知道这不是进行此类操作的最佳方式,并且诚实地说这个模式会非常大,其他实体中会有很多依赖于这个Work实体的记录。
我认为我会从聚会开始,因为可能有很多聚会,但我不确定如何将每一方与工作实体联系起来。我确实尝试过传入workId并认为我可能需要将一个Work对象传递回Work托管对象,但我肯定有比使用这些庞大函数更好的方法吗?
所以我的问题是,在这种情况下处理创建具有多种关系的实体的最佳方法是什么?
更新
我已按以下方式更改了我的实施:
让work = NSEntityDescription.insertNewObjectForEntityForName(“Work”,inManagedObjectContext:moc)为!工作
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS"
work.id = object["Id"].stringValue
work.flatNumber = object["FlatNumber"].stringValue
work.propertyName = object["PropertyName"].stringValue
work.propertyNumber = object["PropertyNumber"].stringValue
work.street = object["Street"].stringValue
work.locality = object["Locality"].stringValue
work.town = object["Town"].stringValue
work.postcode = object["Postcode"].stringValue
work.createdDate = formatter.dateFromString(object["CreatedDate"].stringValue)!
for obj in object["Parties"].arrayValue {
let party = NSEntityDescription.insertNewObjectForEntityForName("Party", inManagedObjectContext: moc) as! Party
party.id = obj["Id"].stringValue
party.firstName = obj["FirstName"].stringValue
party.lastName = obj["LastName"].stringValue
party.propertyName = obj["PropertyName"].stringValue
party.propertyNumber = obj["PropertyNumber"].stringValue
party.street = obj["Street"].stringValue
party.locality = obj["Locality"].stringValue
party.town = obj["Town"].stringValue
party.postcode = obj["Postcode"].stringValue
party.createdDate = formatter.dateFromString(obj["CreatedDate"].stringValue)!
//doesn't work
work.parties.addlistObject(party)
}
我确实尝试过实现下面描述的NSSet解决方案,但遇到了迭代我的JSON的当前for循环正在运行的问题
修改
我已经设法通过添加
来实现它 party.work = work as Work
在for循环中,如下所示。
现在它运行良好一段时间,似乎做了正确的事情,直到它出现错误:
fatal error: unexpectedly found nil while unwrapping an Optional value
这是一个单独的或相关的问题吗?
答案 0 :(得分:2)
使用Core Data,您尝试做的事实上非常简单。你要求的是一种将两个实体相互连接起来的方法。
现在,您似乎想要一个工作实体下的多个缔约方。这意味着您正在查看工作实体与缔约方实体之间的To-Many关系。您需要做的就是在两个实体之间创建一个如下所示的关系:
首先,在“关系”标签下找到您的工作实体,然后点击“ + ”按钮。将此新关系命名为“ party ”,然后单击“输入”。将目的地作为您的缔约方实体。
第二次,转到您的各方实体并执行相同操作,命名关系“工作”并将其目标设置为您的工作实体。但这一次,请单击“反向”下的下拉菜单,然后选择您的参与方关系,以便在您的工作和参与方实体之间形成一对一的关系。现在,您的Work实体的每个实例都包含一个变量,该变量包含对方实体的实例,反之亦然。
但是,您可能希望“Party”实体的多个实例连接到一个Work实例,因此现在您希望将关系更改为To-Many关系。我们可以通过转到您的工作实体并单击“聚会”关系来完成此操作。现在,在右侧的数据模型检查器中,查找显示“类型”的菜单。单击菜单,然后从下拉列表中选择“To Many”。
您现在实体之间存在To-Many关系!
现在,要在代码中添加连接,请打开Parties.swift文件,然后在底部输入:
@NSManaged var work: Work
这提供了对该方所连接的工作对象的引用。您可以在for party in object["Parties"].arrayValue ... }
中创建Party实例时进行设置。只需使用
party.work = {Your Work instance}
但是,对于Work类,情况略有不同。您看,我们建立关系的方式,缔约方实体只能在一个工作实体下,但工作实体可以包含许多缔约方。 Core Data会将这些存储为NSSet(如果要在集合中对Parties对象进行排序,则将其存储为NSOrderedSet)。因此,将此代码添加到Work.swift的底部:
@NSManaged var parties: NSSet
这将创建一个NSSet实例,该实例将包含Work实例下的所有Party。现在,您可以通过创建新的NSSet实例并将其分配给派对变量来添加派对,如下所示:
let newSet = NSMutableSet(setWithSet: parties)
newSet.addObject({party variable})
myWork.parties = newSet.copy() as! NSSet
然后,如果您有工作ID,则可以使用myParty.work.workID == "SomeWorkID"
检查ID。如果需要,您还可以通过各方NSSet进行枚举。
希望这个答案可以帮助您完成您想要完成的任务!如果这不能完全回答你的问题,请告诉我。
如果您想进一步研究CoreData关系,可以获得一本关于Core Data的书(我通过Ray Wenderlich购买了“教程核心数据”)或查看Apple的文档here。