CoreData - 使用类别的等效w /示例 - Swift

Rya*_*yan 1 core-data nsmanagedobject ios swift

我想知道如何在下面为我的CoreData NSManagedObject客户端创建一个类别的等价物:

我知道扩展现在是Swift中类别的替代 - 但不确定它们的实现.以下是我在下面扣除的内容:

class Client: NSManagedObject {

    @NSManaged var name: String
    @NSManaged var projects: NSSet

}

extension Client {

    func addClientWithName(name:NSString, context:NSManagedObjectContext) -> Client {
        var client:Client = Client();

        // Check for name in the database already exists
        let request:NSFetchRequest = NSFetchRequest(entityName: "Client")
        let sortDescriptor:NSSortDescriptor = NSSortDescriptor(key: "name", ascending: true)
        let sortDescriptorsAry:NSArray = [sortDescriptor]
        request.sortDescriptors = sortDescriptorsAry
        request.predicate = NSPredicate(format: "name = %@", name)

        var error:NSError?
        let matches:NSArray = context.executeFetchRequest(request, error: &error)

        if matches.count == 0 {

            //Add new Client
            var newClient:NSEntityDescription = NSEntityDescription.insertNewObjectForEntityForName("Client", inManagedObjectContext: context) as NSEntityDescription
            newClient.setValue(name, forKey: "name")

            context.save(nil);

        } else {
            client = matches.lastObject as Client
        }

        return client
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,通过这种实现,这是我到目前为止所犯的错误:

CoreData: error: Failed to call designated initializer on NSManagedObject class "Ttc9AppName6Client"
Run Code Online (Sandbox Code Playgroud)

关于可能导致这种情况的任何想法?

编辑: 这是我从其他类调用该方法的方式:

@IBAction func saveBtnTapped(UIButton) {
    println("save btn tapped")
    var client:Client = Client().addClientWithName("Woofy Face", context: self.managedObjectContext)
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 6

我认为您的问题与类别/扩展无关.

 var client:Client = Client();
Run Code Online (Sandbox Code Playgroud)

没有调用指定的初始化NSManagedObject,如果读取请求没有找到匹配的对象返回该对象.

您可能想要的是在这种情况下返回新创建的对象.

另请注意

insertNewObjectForEntityForName:inManagedObjectContext:
Run Code Online (Sandbox Code Playgroud)

返回托管对象,而不是实体描述.

此外,

var client:Client = Client().addClientWithName(...)
Run Code Online (Sandbox Code Playgroud)

还可以在不使用指定初始化程序的情况下创建Client对象.您应该将方法定义为类方法.

所以你的代码应该是这样的:

 class func addClientWithName(name:NSString, context:NSManagedObjectContext) -> Client {
    var client:Client

    let request:NSFetchRequest = NSFetchRequest(entityName: "Client")
    let sortDescriptor:NSSortDescriptor = NSSortDescriptor(key: "name", ascending: true)
    let sortDescriptorsAry:NSArray = [sortDescriptor]
    request.sortDescriptors = sortDescriptorsAry
    request.predicate = NSPredicate(format: "name = %@", name)

    var error:NSError?
    let matches:NSArray = context.executeFetchRequest(request, error: &error)

    if matches.count == 0 {
        //Add new Client
        client = NSEntityDescription.insertNewObjectForEntityForName("Client", inManagedObjectContext: context) as Client
        client.name = name
        context.save(nil)
    } else {
        client = matches.lastObject as Client
    }
    return client
}
Run Code Online (Sandbox Code Playgroud)

它会被称为

let client:Client = Client.addClientWithName("Woofy Face", context: self.managedObjectContext)
Run Code Online (Sandbox Code Playgroud)