Core Data - result0924/iosLearning GitHub Wiki

Some note

  • The NSPersistentContainer class is the starting point for any modern Core Data stack.
  • Why in a persistent container the main queue is called viewContext.
It's the context that you'll use in your views.
  • Core Data is not an SQLite wrapper, nor a database in itself.
Core Data is a framework that manages an object graph
For example, when you’re rendering a list of movies and 
you want to show the directors’ names alongside each movie. 
If directors are stored as a Director entity, 
and Movie has a directors property that establishes a to-many relationship with Director, 
it makes sense to configure your fetch request to always preload the directors relationship as a performance enhancement. 

You can do this using a fetch request’s relationshipKeyPathsForPrefetching property. 
This property takes an array of keypaths that represent relationships on the object that you created a fetch request for.

For example, to prefetch the directors relationship you could use the following code:
myFetchRequest.relationshipKeyPathsForPrefetching = ["directors"]
CONTAINS[cd]: 匹配包含指定字符串的結果,不區分大小寫和重音符號。

ENDSWITH[cd]: 匹配以指定字符串結尾的結果,不區分大小寫和重音符號。

LIKE[cd]: 用於模式匹配,支持使用通配符(*表示零個或多個字符,?表示一個字符)。

IN: 用於匹配給定集合中的值。

ANY: 用於在關係中查找滿足條件的任意元素,比如查找數組中包含特定值的元素。

ALL: 用於在關係中查找所有元素是否都滿足條件。

NOT: 用於取反操作,否定一個條件。

BETWEEN: 用於指定一個範圍,判斷一個值是否在該範圍內。

MATCHES: 用於正則表達式匹配。

Core data migration

  1. 判斷要不要migration

    * 完全不要migration? 直接清掉資料庫重建?
    * 版本不一樣才migration? 從那一版開始migration
    
  2. 先check WAL是否已經備份完成

    Since iOS 7, Core Data has used the [Write-Ahead Logging (WAL)](https://www.sqlite.org/wal.html) option on SQLite stores 
    to provide the ability to recover from crashes by allowing changes to be rolled back until the database is stable. 
    If you have ever had to perform a rollback before, the WAL approach may work a little differently from what you are expecting. 
    Rather than directly writing changes to the sqlite file and having a pre-write copy of the changes to rollback to, 
    in WAL mode the changes are first written to the sqlite-wal file and at some future date those changes are transferred to the sqlite file. 
    The sqlite-wal file is in effect an up-to-date copy of some of the data stored in the main sqlite file.
    
    The sqlite-wal and sqlite files store their data using the same structure to allow data to be transferred easily between them. 
    However, this shared structure causes issues during migration as Core Data only migrates the data stored in the sqlite file 
    to the new structure, leaving the data in the sqlite-wal file in the old structure. 
    The resulting mismatch in structure will lead to a crash when Core Data attempts to update/use data stored in the sqlite-wal file 😞 . 
    To avoid this crash, we need to force any data in the sqlite-wal file into the sqlite file 
    before we perform a migration - a process known as checkpointing:
    
  3. 從mom或metadata的identifier去取得目前的app version

    • What is mom
    When Xcode compiles your app into its app bundle, 
    it will also compile your data models. 
    The app bundle will have at its root a .momd folder that contains .mom files. 
    MOM or Managed Object Model files are the compiled versions of .xcdatamodel files. 
    You'll have a .mom for each data model version. 
    
    • How to find persistent store model version?
    These properties will allow you to access the current store URL and model. 
    As it turns out, there is no method in the CoreData API to ask a store for its model version.
    Instead, the easiest solution is brute force. 
    Since you've already created helper methods to check if a store is compatible with a particular model, 
    you'll simply need to iterate through all the available models until you find one that works with the store.
    
    lazy var currentModel: NSManagedObjectModel =  {   
      // Let core data tell us which model is the current model   
      let modelURL = NSBundle.mainBundle().URLForResource(self.modelName, withExtension:"momd")   
      let model = NSManagedObjectModel(contentsOfURL: modelURL!)   
      return model 
    }()
    
    • How to find current model version
    // 可以用NSManagedObjectModel的isConfiguration來比較差異
    /* 
    Compares the version information in the store metadata with the entity version of a given configuration. 
    Returns NO if there are differences between the version information.  
    (For information on specific differences, developers should utilize the entityVersionHashesByName method, and perform a comparison.)
    */
    @available(iOS 3.0, *)
    open func isConfiguration(withName configuration: String?, compatibleWithStoreMetadata metadata: [String : Any]) -> Bool
    
    
  4. Debug

    A useful launch argument when testing migrations is -com.apple.CoreData.MigrationDebug. When set to 1, 
    you will receive information in the console about exceptional cases as it migrates data.
    If you’re used to SQL but new to Core Data, set -com.apple.CoreData.SQLDebug to 1 to see actual SQL commands.
    
  5. Some note

    Both Lightweight and Standard migration techniques can be achieved automatically or manually. 
    By default with NSPersistentContainer Core Data will attempt to perform Standard 
    and then fall back to Lightweight if it can't find the needed mapping model. 
    

Core data

The Core Data stack 處理與外部數據存儲的所有交互,以便您的應用程序可以專注於其業務邏輯

The stack consists of four primary objects:

The managed object context (NSManagedObjectContext) is the object that your application will interact with the most, and therefore it is the one that is exposed to the rest of your application. 
The NSPersistentStoreCoordinator sits in the middle of the Core Data stack.
The coordinator is responsible for realizing instances of entities that are defined inside of the model. 
The NSManagedObjectModel instance describes the data that is going to be accessed by the Core Data stack.
handles the creation of the Core Data stack and offers access to the NSManagedObjectContext as well as a number of convenience methods

Refer

Core Data Batch Insert

Background task

Debug

encrypt core data

找了很多總方法最後靠
- brew install coreutils

手動建立NSManageObject Subclass error

core-data-codegen