fb-script

2016年9月3日 星期六

CoreData with swift 2 筆記 - Xcode 自動生成程式碼

假設專案名稱叫做 CoreDataBloggerDemo,在專案創建的時候有勾選 Use Core Data 的條件下的解析
從 xcode 自動生成的 Core Data 程式碼的 // MARK: - Core Data stack 以下開始

這段程式碼是自動生成在 AppDelegate.swift 中,所以要做存取都要使用此物件來存取,獲得此物件方式為
(UIApplication.sharedApplication().delegate) as! AppDelegate

lazy var applicationDocumentsDirectory: NSURL = {
    let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    return urls[urls.count-1]
}()
  • NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) 會回傳一個 NSURL 的陣列,在這裡,陣列裡只會有一個值,此直指向 app 可以使用的 documents 資料夾,之後會把資料的實體檔案存在此。
lazy var managedObjectModel: NSManagedObjectModel = {
    let modelURL = NSBundle.mainBundle().URLForResource("CoreDataBloggerDemo", withExtension: "momd")!
    return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
  • NSBundle.mainBundle().URLForResource("CoreDataBloggerDemo", withExtension: "momd")!這裡是獲得 app 的 bundle 內 data model 存放的 資料夾,此資料夾內會存放每個版本的 data model 檔案
  • 使用NSManagedObjectModel(contentsOfURL: modelURL)!,就可以獲得和目前設定啟用的 data model
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
    var failureReason = "There was an error creating or loading the application's saved data."
    do {
        try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
    } catch {
        // Report any error we got.
        var dict = [String: AnyObject]()
        dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
        dict[NSLocalizedFailureReasonErrorKey] = failureReason

        dict[NSUnderlyingErrorKey] = error as NSError
        let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
        NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
        abort()
    }

    return coordinator
}()
  • NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)獲得 persistentStoreCoordinator
  • self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite") 獲得實際儲存的資料檔
  • addPersistentStoreWithType(NSSQLiteStoreType,configuration:nil,URL:url,options:nil) 這個動作會依照設定產生相對應的 PersistentObjectStore 物件,在這邊不會直接對此物件做操作,所以產生的程式碼並沒有擷取回傳的物件。
    StoreType
iOS 提供 SQLite/XML/Binary/InMemory 四種儲存形式,這裡使用 SQLite,所以當產生後可以在資料夾中找到 .sqlite 的檔案
    Configuration
這個 Configuration 是一個設定字串,如果輸入 nil 則使用預設,此設定在 data model 中
    URL
實體資料檔路徑,若檔案不存在則創建檔案
    Options
一個 Dictionary 設定,設定有兩種類型,一種是儲存選項 ,一種是轉換選項
  • 當 data model 和實際檔案無法成功對應時,就會產生 exception,然而無法對應也表示此 persistentStoreCoordinator 並無法真的執行永續儲存的動作,在自動產生的程式中是把錯誤 print 出來後執行 abort()直接將 app 關掉
  • 成功後回傳此 persistentStoreCoordinator 物件
lazy var managedObjectContext: NSManagedObjectContext = {
    let coordinator = self.persistentStoreCoordinator
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    managedObjectContext.persistentStoreCoordinator = coordinator
    return managedObjectContext
}()
  • NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)初始化 ManagedObjectContext 物件
    ConcurrencyType
MainQueueConcurrencyType: 可以在 main queue 中使用
NSPrivateQueueConcurrencyType: 此 ManagedObjectContext 將會在初始化後產生自己的 private queue,這種設定了話該 ManagedObjectContext 就只能在 performBlockperformBlockAndWait 方法中調用
func saveContext () {
    if managedObjectContext.hasChanges {
        do {
            try managedObjectContext.save()
        } catch {
            let nserror = error as NSError
            NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
            abort()
        }
    }
}
  • 將操作後的變動儲存到實體資料檔,當所有動作都成功後,儲存的動作是不應該失敗的,所以這邊自動產生的程式碼當錯誤發生也是直接 abort()

沒有留言:

張貼留言