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來儲存資料了,如果有什麼疑問,歡迎評論,也感謝大家對我的關注與支援,我將繼續努力,也希望大家如果覺得文章不錯,歡迎轉載分享。