2016-12-01 8 views
2

Swift 3とiOS 10にアップグレードする前に、単純なオブジェクトのデータストアとしてCoreDataを使用することに問題はありませんでした。軽量移行は簡単で、保存とフェッチは簡単でした。しかし、最近のアップグレード以来、CoreDataには何の問題もありませんでした。Swift 3/iOS 10、適切なコアのデータ使用

私の質問は2つの部分に分かれています。まず、CoreDataがバックグラウンドでどのように動作するかを知る上で役立つリソースを知っている人はいませんか? Appleのドキュメントは非常に制限されており、新しいCoreDataのように私が読んだ記事はすべてとても簡単です。私はリレーショナルデータベースでまともな経験をしているので、CoreDataは私にとって不快な抽象層を追加しています。

第2に、次のコードで何が問題になっていますか?軽量マイグレーションは、このコードを使用してiOS 10以前と同じように機能しません。オブジェクトはCoreDataに保存されています(保存した後にアプリケーションでそれらとやりとりすることができます)が、アプリが再起動されると消えます。

lazy var persistentContainer: NSPersistentContainer = { 

    let description = NSPersistentStoreDescription() 

    description.shouldInferMappingModelAutomatically = true 
    description.shouldMigrateStoreAutomatically = true 

    let container = NSPersistentContainer(name: "MY_APP") 
    container.persistentStoreDescriptions = [description] 
    let description = NSPersistentStoreDescription() 

    description.shouldInferMappingModelAutomatically = true 
    description.shouldMigrateStoreAutomatically = true 

    container.persistentStoreDescriptions = [description] 
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in 
     if let error = error as NSError? { 
      fatalError("Unresolved error \(error), \(error.userInfo)") 
     } 
    }) 
    return container 
}() 

// MARK: - Core Data Saving support 

func saveContext() { 
    let context = persistentContainer.viewContext 
    if context.hasChanges { 
     do { 
      try context.save() 
     } catch { 
      let nserror = error as NSError 
      fatalError("Unresolved error \(nserror), \(nserror.userInfo)") 
     } 
    } 
} 

私は抽象的に私のオブジェクトの保存を別のファイルを使用しています:

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

リポジトリクラスが働いていますアプリを再起動するまでは...

私はCore Daの新しいバージョンに移行しようとしていますta iOS 9/Swift 2の軽量マイグレーションとなる非オプションのString属性(デフォルト値)を単純に追加するモデル。迅速な3軽量マイグレーションについては何が欠けていますか?

iOS 10のCoreDataをよく理解していないのは間違いありません。私はしばらくの間ソフトウェアエンジニアとして働いていましたが、私は数ヶ月間iOSとSwiftで作業していましたので、優しくしてください。そして、事前に感謝します!

+0

「NSPersistentContainer」は、スウィフト3ではないし、必要でもない。以前のバージョンのiOSと同じクラスを引き続き使用できます。彼らはまだ動作し、推奨されなくなりません。また、消失するオブジェクトは移行に関係しない。既存の永続ストアの移行に失敗した場合、起動時にアプリケーションがクラッシュします。 @TomHarrington。 –

+0

ありがとう、それは良い提案です、私はそれを試してみましょう。しかし、この特定のアプリは、Xcode 8、Swift 3、iOS 10のターゲットから始まりました。だから、今後のパラダイムにこだわるべきだと思う。私はこのようなアプリケーションで簡単な軽量マイグレーションを行う方法を理解したいと思います。私はこれ以前にiOS 9で別のアプリを書いていたので、iOS9の移行とiOS10の違いについて知っています。 – Griffin

+0

私はシンプルなアプリケーションと新しいCoredata(swift3)に取り組んでいます。私はShouldInferMapping ...とShouldMigrateStoreAuを設定してみんなに気づきました...説明に真実を向け、グリフィンが上で指摘したようにcontainer.persistenStoreDescriptionsに設定しました。存続しない。しかし、私はそれらの行をコメントする(2つのプロパティをtrueに設定する)と、すべてのデータが返されます(持続する)。何か案が ? – Ohmy

答えて

1

まあ、私はばかだと感じます。私は非オプションの文字列を追加し、デフォルト値を与えませんでした。私はいつも非文字列型にデフォルト値を与えましたが、Xcodeが設定される方法によって、他に何も与えられていなければ文字列にデフォルト値 ""を与えるように見えるようになりました。

新しい属性にデフォルト値を追加すると、Swift3/iOS10での移行が可能になりました。 Noobの間違いですが、将来的には誰かを助けるでしょう。

関連する問題