【发布时间】:2020-10-08 13:03:12
【问题描述】:
// Service.swift
let decoder = JSONDecoder()
decoder.userInfo[CodingUserInfoKey.managedObjectContext] = self.coreDataManager.managedObjectContext
do {
_ = try decoder.decode([POI].self, from: jsonData)
self.coreDataManager.saveContext()
print("Saved")
}
catch{
print(error.localizedDescription)
}
// POI+CoreDataClass.swift
@objc(POI)
public class POI: NSManagedObject, Codable {
...
required public convenience init(from decoder: Decoder) throws {
guard let context = decoder.userInfo[CodingUserInfoKey.managedObjectContext] as? NSManagedObjectContext else {
throw DecoderConfigurationError.missingManagedObjectContext
}
let entity = NSEntityDescription.entity(forEntityName: "POI", in: context)!
self.init(entity: entity, insertInto: context)
let encodedValues = try decoder.container(keyedBy: CodingKeys.self)
let idString = try encodedValues.decode(String.self, forKey: .id)
self.id = UUID.init(uuidString: idString)!
self.externalId = try encodedValues.decode(String.self, forKey: .externalId)
self.title = try encodedValues.decode([String:String].self, forKey: .title)
self.coordinates = try encodedValues.decode(Geometry.self, forKey: .coordinates)
self.author = try encodedValues.decode(String.self, forKey: .author)
self.imageUrl = try encodedValues.decode(String.self, forKey: .imageUrl)
self.type = try encodedValues.decode(String.self, forKey: .type)
let propertyValues = try encodedValues.decode([String:Any].self, forKey: .properties)
self.properties = propertyValues
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(externalId, forKey: .externalId)
try container.encode(title, forKey: .title)
try container.encode(coordinates, forKey: .coordinates)
try container.encode(author, forKey: .author)
try container.encode(imageUrl, forKey: .imageUrl)
try container.encode(type, forKey: .type)
try container.encode(properties, forKey: .properties)
}
private enum CodingKeys: String, CodingKey {
case id
case externalId
case title
case coordinates
case author
case imageUrl
case type
case properties
}
}
enum DecoderConfigurationError: Error {
case missingManagedObjectContext
}
// POI+CoreDataProperties.swift
extension POI {
@nonobjc public class func fetchRequest() -> NSFetchRequest<POI> {
return NSFetchRequest<POI>(entityName: "POI")
}
@NSManaged public var author: String
@NSManaged public var coordinates: Geometry
@NSManaged public var externalId: String
@NSManaged public var id: UUID
@NSManaged public var imageUrl: String
@NSManaged public var properties: [String:Any]
@NSManaged public var title: [String:String]
@NSManaged public var type: String
}
// CoreDataManager.swift
...
func saveContext() {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// The context couldn't be saved.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
// Example.json
..
{
"id": "0c0ef61d-9507-4400-8e5e-e7dc31a34370",
"externalId": "node/1234567890",
"title": {
"de": "Küche",
"en": "kitchen"
},
"coordinates": {
"type": "Point",
"values": [
{
"lat": 52.123456,
"lon": 13.123456
}
]
},
"author": "Authorname",
"imageUrl": "null",
"type": "Type",
"properties": {
"Website": {
"de": "https://website.com/de"
},
"wheelchair": false,
"start_date": 2020
}
}
..
我们在 swift 中使用 CoreData 来存储 json 数据并检索它们。我们想将我们的 json 数据保存在我们的数据库中,因此我们使用 Service.swift 中的 Example.json 作为 jsonData。我提供了 POI 模型,因为它是由 XCode 创建的,它使用 Codeable 和解码和编码。上下文是通过依赖注入传递的,它是一个单例。该模型使用带有“NSSecureUnarchiveFromData”的Transformable 作为Transformer。问题是:在解码时我可以在调试模式下看到所有属性,但是当应该保存上下文时,所有值都是“nil”。如何解决这个问题?其他型号类似,所以我没有包括它们。如果您需要任何其他文件或其中的一部分,请随时询问。
【问题讨论】:
-
听起来像是一个并发问题 - 您是在后台线程上下载和处理该 json 吗?
-
该json是之前下载的,如果我在添加属性的行中添加断点,我可以正确读取内容。这就是为什么我无法弄清楚 self.
是如何设置的,但在上下文中似乎为零。 -
哪些属性或属性使用可转换属性?
-
@TomHarrington 每个不是基本类型的属性,例如“标题”、“属性”、“坐标”。我使用您在模型中可以看到的类作为自定义类,例如坐标是一个几何类,它本身就是一个模型。 Title 是字典,属性也是,但它使用 any 因为可能包含另一个字典,但我们在实现 CoreData 之前设法让一切正常工作,现在它必须与它一起工作。
标签: ios swift core-data codable