1. 程式人生 > >OCiOS開發:手動建立CoreData資料模型

OCiOS開發:手動建立CoreData資料模型

前言

我們知道,在專案中使用CoreData儲存資料,建立工程的時候我們需要勾選Use Core Data選項,如下所示:

這裡寫圖片描述

在教學過程中,有學生這樣問我,如果在專案過程中需要使用CoreData儲存資料,但是在建立專案的時候並沒有勾選Use Core Data選項,那又該如何操作呢?難道要重新建立專案勾選Use Core Data選項,然後再拷貝那些檔案到新建立的工程中麼?會不會太麻煩?答案是肯定的,不過不用擔心,本篇部落格,我將解決這個問題。

實現

1、首先我們需要引入CoreData FrameWork框架,具體實現方式:點選Target -> Build Phases -> Link Binary With Libraries ->點選+

號按鈕,如下所示:

這裡寫圖片描述

2、點選+號之後在彈出的框中輸入CoreData.framework並雙擊搜尋到的xiang即可新增框架(注意:搜尋不區分大小寫)。如下所示:

這裡寫項圖片描述

3、然後我們需要加入資料模型,選中工程資料夾(我這裡是CoreDataTest),滑鼠右鍵,再點選New File…,當然你也可以選中工程資料夾之後直接通過快捷鍵command + n建立檔案。在彈出的介面的左邊選擇:iOS -> CoreData -> Data Model,如下所示:

這裡寫圖片描述

4、點選Next,進入下一頁,在Save As中鍵入資料模型的名字,名字可以隨意寫,這裡我將資料模型名字與工程名一致(CoreDataTest),點選右下角的Create之後,你會發現在工程目錄中多了一個CoreDataTest.xcdatamodeld

檔案,如下所示:

這裡寫圖片描述

5、做好以上的這些工作之後,不要先急著去建立Entity。而是去Delegate中建立CoreData與Delegate的關聯。這時,點選AppDelegate.h檔案,引入標頭檔案:#import<CoreData/CoreData.h>,然後在@interface與@end之間(即類的介面部分)加入以下程式碼:

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic
) NSManagedObjectModel *managedObjectModel; @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; - (void)saveContext; - (NSURL *)applicationDocumentsDirectory;

Tips

上面的程式碼有幾個名字術語:NSManagedObjectContext、NSManagedObjectModel、NSPersistentStoreCoordinator。

1、Managed Object Model(管理資料模型):你可以將這個東西看作是資料庫的輪廓,或者結構。這裡包含了各個實體的定義資訊,一般來說,你會使用我們剛剛看過的視覺編輯器來操作這個物體,新增屬性,建立屬性之間的關係等等,當然你也可以使用程式碼。

2、Persistent Store Coordinator(永續性資料協調器): 你可以將這個東西看作是資料庫連線庫,在這裡,你將設定資料儲存的名字和位置,以及資料儲存的時機。

3、Managed Object Context (管理資料內容):你可以將這一部分看作是資料的實際內容,這也是整個資料庫中對我們而言最重要的部分(這還用說),基本上,插入資料,查詢資料,刪除資料的工作都在這裡完成。

6、之後開啟AppDelegate.m檔案,在@implementation下面寫入如下程式碼:

#pragma mark - Core Data stack

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (NSURL *)applicationDocumentsDirectory {
    // The directory the application uses to store the Core Data store file. This code uses a directory named "com.rimi.Test" in the application's documents directory.
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

- (NSManagedObjectModel *)managedObjectModel {
    // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }

    // **** 注意 ***
    // 這裡的CoreDataTest就是你剛才建立的資料模型的名字,一定要一致,否則會報錯。

    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataTest" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it.
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }

    // Create the coordinator and store

    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    // **** 注意 ***
    // 這裡的CoreDataTest.sqlite也應該與資料模型的名字保持一致,否則會報錯。

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataTest.sqlite"];
    NSError *error = nil;
    NSString *failureReason = @"There was an error creating or loading the application's saved data.";
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        // Report any error we got.
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
        dict[NSLocalizedFailureReasonErrorKey] = failureReason;
        dict[NSUnderlyingErrorKey] = error;
        error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
        // Replace this with code to handle the error appropriately.
        // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return _persistentStoreCoordinator;
}


- (NSManagedObjectContext *)managedObjectContext {
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

#pragma mark - Core Data Saving support

- (void)saveContext {
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        NSError *error = nil;
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

Tips

一定要觀察上述程式碼中的注意事項,程式碼中關聯的名字必須與資料模型的名字一致,否則會報錯。

7、ok,到這一步,手動建立CoreData資料模型就結束了,接下來你就可以正常使用CoreData來儲存資料了,如果有什麼疑問,歡迎評論,也感謝大家對我的關注與支援,我將繼續努力,也希望大家如果覺得文章不錯,歡迎轉載分享。