使用自定义类作为可转换对象的Swift和CoreData

时间:2018-01-15 02:47:25

标签: ios swift core-data nsmanagedobject transformable

我正在尝试使用swift和CoreData作为可转换对象的自定义类。我一直在浪费时间试图弄清楚但不能。我不断收到两个错误:属性无法标记为@NSManaged,因为其类型无法在Objective-C中表示,并且Property无法声明为public,因为其类型使用内部类型。 非常感谢帮助。感谢。

我有一个名为User的CoreData对象。我还有一个名为Site的对象 我不希望Site对象成为CoreData对象,因为我创建Site对象的大部分时间我都不想将它添加到CoreData上下文中。

下面您将看到“site”类型的“primarySite”和“Site”类型的数组“sites”。这两行给出了我上面列出的两个错误。

数据模型 Data Model

用户+ CoreDataClass

import Foundation
import CoreData

public class User: NSManagedObject {
}

用户+ CoreDataProperties

import Foundation
import CoreData

extension User {
    @nonobjc public class func fetchRequest() -> NSFetchRequest<User> {
        return NSFetchRequest<User>(entityName: "User");
    }

    @NSManaged public var firstName: String?
    @NSManaged public var lastName: String?
    @NSManaged public var role: String?
    @NSManaged public var primarySite: Site
    @NSManaged public var sites: [Site]
}

网站

import UIKit

class Site: NSCoding {
    let identifier: Int32
    let name: String
    let note: String

    init(with values: Dictionary<String,Any>) {
        identifier = Int32(values["identifier"] as! String)!
        name = values["name"] as! String
        note = values["note"] as! String
    }

    required convenience init(coder decoder: NSCoder) {
        var siteValues = [String:Any]()
        siteValues["identifier"] = decoder.decodeObject(forKey: "identifier") as! String
        siteValues["name"] = decoder.decodeObject(forKey: "name") as! String
        siteValues["note"] = decoder.decodeObject(forKey: "note") as!
        self.init(with: siteValues)
    }

     func encode(with coder: NSCoder) {
        coder.encode(String(self.identifier), forKey: "identifier")
        coder.encode(self.name, forKey: "name")
        coder.encode(self.note, forKey: "note")
    }
}

3 个答案:

答案 0 :(得分:2)

  

Property cannot be marked @NSManaged because its type cannot be represented in Objective-C

这是因为Site未从NSObject继承。 Swift类不必继承NSObject,但核心数据可转换。如果您添加NSObject,则该错误不会发生。

还有其他一些问题 - 例如,init(coder decoder: NSCoder)没有分配任何属性值,但这些问题应该很容易理解。

答案 1 :(得分:1)

我想出了如何解决这两个错误。

1)“无法将属性标记为@NSManaged,因为其类型无法在Objective-C中表示”
感谢@ Tom的回答我通过使Site成为NSObject的子类来解决这个错误。

class Site: NSObject, NSCoding {


2)“不能将属性声明为公共属性,因为其类型使用内部类型”
我通过在类之前添加“public”以及编码器和解码器函数来解决此错误。

public class Site: NSObject, NSCoding {
...
public func encode(with coder: NSCoder) {...}
public required convenience init(coder decoder: NSCoder) {...}

答案 2 :(得分:0)

由于Site是自定义类,因此不能将其用作NSManagedObject中的数据类型。

就我而言,我在数据模型中创建了“二进制数据”类型。 因此,使其类型NSData成为目标c中的数据类型。

在此之后,您可以取消归档数据。

例如:

if let sitesArray = NSKeyedUnarchiver.unarchiveObject(with: sites) as? [[String : Any]] {
    //enter your processing code here to convert them to site objects
}