Swift 3 / iOS 10,正确的核心数据使用

时间:2016-12-01 20:11:08

标签: ios core-data core-data-migration

在将我的应用程序升级到Swift 3和iOS 10之前,我将CoreData用作简单对象的数据存储没有任何问题。轻量级迁移很简单,保存和获取很简单等。但是自从最近的升级以来,我只有CoreData的麻烦。

我的问题分为两部分。首先,有没有人知道有什么好的资源可以帮助我了解CoreData如何在幕后工作,这样我可以更好地调试它? Apple的文档非常有限,我阅读的所有文章都像新的CoreData一样简单。我对关系数据库有很好的经验,因此CoreData为我添加了一个令人不舒服的抽象层。

其次,以下代码有什么问题?使用此代码,轻量级迁移不像iOS 10之前那样工作。对象保存到CoreData(保存后我可以在应用程序中与它们进行交互),但在应用程序重新启动后会消失。

class Repository
{


func getContext () -> NSManagedObjectContext
{
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    return appDelegate.persistentContainer.viewContext
}


func delete<T>(_ a: some T)
{

    getContext().delete(a as! NSManagedObject)

}


// -----------   Password Repo ----------


func savePassword(name: String, hint: String, un: String) {
    let context = getContext()

    //retrieve the entity that we just created
    let entity =  NSEntityDescription.entity(forEntityName: "Password", in: context)

    let transc = NSManagedObject(entity: entity!, insertInto: context)

    //set the entity values
    transc.setValue(name, forKey: "name")
    transc.setValue(hint, forKey: "thing")
    transc.setValue(un, forKey: "newThing")


    //save the object
    do {
        try context.save()
    } catch let error as NSError  {
        print("Could not save \(error), \(error.userInfo)")
    } catch {

    }
}


func updatePassword(pas: Password) -> Password
{
    let context = getContext()
    //        sec.is_new = false

    // TODO,  add updates

    // Try updating the model in the DB
    do {
        try context.save()
    } catch {
        print(error)

    }

    return pas
}


func fetchPasswords() -> [Password]
{

    let context = getContext()
    //create a fetch request, telling it about the entity
    let fetchRequest: NSFetchRequest<Password> = Password.fetchRequest() as! NSFetchRequest<Password>
    let sortDescriptor = NSSortDescriptor(key: "name", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor]

    do {
        //go get the results
        let searchResults = try getContext().fetch(fetchRequest)
        return searchResults

    } catch {
        print("Error with request: \(error)")
    }

    return []
}




// -----------   End Password Repo ----------





// -----------   Hints Repo ----------

func saveHint (name: String, hint: String) {
    let context = getContext()

    //retrieve the entity that we just created
    let entity =  NSEntityDescription.entity(forEntityName: "Hint", in: context)

    let transc = NSManagedObject(entity: entity!, insertInto: context)

    //set the entity values
    transc.setValue(value1, forKey: "some_string")
    transc.setValue(value2, forKey: "some_thing")

    //save the object
    do {
        try context.save()
    } catch let error as NSError  {
        print("Could not save \(error), \(error.userInfo)")
    } catch {

    }
}




func fetchHints() -> [Hint]
{

    let context = getContext()
    //create a fetch request, telling it about the entity
    let fetchRequest: NSFetchRequest<Hint> = Hint.fetchRequest() as! NSFetchRequest<Hint>
    let sortDescriptor = NSSortDescriptor(key: "my_key", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor]

    do {
        //go get the results
        let searchResults = try getContext().fetch(fetchRequest)
        return searchResults

    } catch {
        print("Error with request: \(error)")
    }

    return []
}

}

我使用单独的文件来抽象​​我的对象的存储:

Repository().savePassword(name: nameText.text!, hint: hintSoFarLabel.text!, un: "Hey")

然后我像这样调用这个Repository类:

counts

Repository类正在运行,直到我重新启动应用程序......

我也尝试迁移到我的核心数据模型的新版本,它只是添加了一个非可选的String属性(默认值),这将是iOS 9 / Swift 2中的一个简单的轻量级迁移。我对swift 3轻量级迁移有什么看法?

我毫不怀疑问题是我不能很好地理解iOS 10中的CoreData。我已经做了一段时间的软件工程师,但是我只和iOS和Swift合作了几个月,所以请保持温和。并提前感谢!

1 个答案:

答案 0 :(得分:1)

嗯,我觉得自己像个白痴。我添加了一个非可选字符串,并没有给它一个默认值。我总是给非字符串类型提供默认值,但是Xcode的设置方式使它看起来只是给字符串一个默认值&#34;&#34;如果没有其他人给予。

为新属性添加默认值允许迁移在Swift3 / iOS10中运行。 Noob错了,但未来可能会帮助这里的人。