CoreDataCodable 1.1.1

CoreDataCodable 1.1.1

Peter Ringset 维护。



  • 作者
  • Peter Ringset

CoreDataCodable

codecov Build Status CocoaPods Compatible Carthage Compatible Platform

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,并实现该协议

Managed object model: Employee

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)
    }

}