CoreDataCodable
CoreDataCodable 包含了用于让 Core Data 与 Swift 的 Codable
协议配合的协议和扩展
需求
- iOS 10+
- macOS 10.12+ (Sierra)
- Swift 4+
- Xcode 10.2
安装
Cocoapods
你希望将以下代码添加到 Podfile 中,类似于以下示例:
target 'MyApp' do
pod 'CoreDataCodable', '~> 1.0'
end
然后在你的终端内运行 pod install
命令,或者从 CocoaPods.app 中运行。
或者,为了测试运行,运行以下命令:
$ pod try CoreDataCodable
Carthage
要使用 Carthage 将 CoreDataCodable 集成到 Xcode 项目中,在 Cartfile
中指定它
github "peterringset/CoreDataCodable" ~> 1.0
然后在你的终端内运行 carthage update
命令。
使用方法
为了让NSManagedObject
子类可通过Decodable
解析,您可以声明遵循DecodableManagedObject
,并实现该协议
import CoreData
import CoreDataCodable
extension Employee: DecodableManagedObject {
public enum CodingKeys: String, CodingKey {
case firstName
case lastName
case title
case telephone
case imageURL
}
public func setValues(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
firstName = try container.decode(String.self, forKey: .firstName)
lastName = try container.decode(String.self, forKey: .lastName)
title = try container.decode(String.self, forKey: .title)
telephone = try container.decode(String.self, forKey: .telephone)
imageURL = try container.decode(String.self, forKey: .imageURL)
}
}
为了与Swift的JSONDecoder
一起使用,您必须将管理对象上下文字例分配给解码器的userInfo
let decoder = JSONDecoder()
decoder.userInfo[.managedObjectContext] = persistentContainer.newBackgroundContext()
let employees = try decoder.decode(Employee.self, from: json)
这将把对象插入到提供的上下文中。注意,保存上下文仍然是您在解析完成后需要完成的。
插入或更新现有对象
如果您有一个将下载实体的应用程序,这些实体已经在本地数据库中存在,您可以使用ManagedObjectUpsert
来帮助您管理。这需要实体类遵守FetchableManagedObject
协议,这个协议告诉我们如何查询本地数据库以找到现有实例。
extension Employee {
public typealias FetchableCodingKeys = CodingKeys
public typealias Identifier = String
public static var identifierKey: Employee.CodingKeys {
return .lastName
}
}
然后,您可以修改解码调用以成为
let upsert = try decoder.decode(ManagedObjectUpsert<Employee>.self, from: json)
let employee = upsert.object
还有一个名为ManagedObjectsUpsert
的结构体,用于解码具有上揭机制的对象数组。
Core Data代码生成
CoreDataCodable
与Core Data的代码生成特性兼容,但您应该注意,如果您正在使用自定义类型(可转换类型),您将必须使用Manual/None
替代方案。您仍然可以让Xcode生成实体的源代码,但您将需要手动重新生成文件(文件),每次修改对象模型时都需要这样做。一个好的提示是添加到Entity+CoreDataClass.swift
文件中的自定义设置,这将使您在需要重新生成实体代码时更加容易。
import Foundation
import CoreData
import CoreDataCodable
@objc(Entity)
public class Entity: NSManagedObject {
}
extension Entity {
enum CodingKeys: String, CodingKey {
case name
case url
}
public func setValues(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
url = try container.decode(URL.self, forKey: .url)
}
}