CoreData 本地数据存储
在iOS开发中,我们会用到本地数据文件的存储,一般有属性列表Plist,SQLite,CoreDate以及沙盒文件等方式,现在归纳一下CoreData。
CoreData是苹果iOS 5后提供的本地文件存储框架,利用CoreData可以方便创建关系映射,进行数据CRUD(增删改查)操作。
<注意>使用CoreData处理数据务必先引入CoreData框架包:CoreData.framework:
1.创建CoreData文件的两种方式
(a).在使用CoreData时我们需要进行CoreData文件的创建:
(b).在工程中新建添加CoreDate文件
2.创建实体表Entity,并为实体添加属性字段
打开CoreData文件(xxx.xcdatamodeld):
创建实体以及属性字段:
3.设置好本地数据存储的CoreData文件之后,就需要进行代码操作,首先将实体代码化成一个数据类,选择CoreData文件以及实体创建:
创建好之后会生成四个文件:
4.CoreData的CRUD工具类,将增删改查操作封装到一个类中,直接调用接口处理数据:
***在创建的管理类中,上下文创建(contextBuilding) 和 使用fetch代码段查询数据(read) 是两个核心方法,任何数据操作都基于这两个方法
1 /* 2 * CoreData数据管理类 3 * CoreDataManager.h 4 */ 5 6 #import <Foundation/Foundation.h> 7 #import <CoreData/CoreData.h> 8 9 #define DATA_FILE @"date.date" 10 #define ENTITY_NAME @"Country" 11 #define SORT_KEY @"key" 12 #define ADD_DATA YES 13 #define CHANGE_DATA NO 14 15 @interface CoreDataManager : NSObject 16 // 数据管理模型 17 @property(nonatomic,strong)NSManagedObjectModel *model; 18 // 数据管理上下文 19 @property(nonatomic,strong)NSManagedObjectContext *context; 20 // 持久存储 21 @property(nonatomic,strong)NSPersistentStore *store; 22 // 持久化存储协调者 23 @property(nonatomic,strong)NSPersistentStoreCoordinator *psc; 24 25 // 单例 26 + (instancetype)shareInstance; 27 28 /* 29 * 搭建数据管理上下文 30 */ 31 - (void)contextBuilding; 32 33 /* 34 * 查询所有数据并返回数据数组 35 */ 36 - (NSArray*)read; 37 38 /* 39 * 添加/更新数据 40 */ 41 - (void)updataWithKey:(NSInteger)key country:(NSString*)country capital:(NSString *)capital population:(NSInteger)population area:(double)area; 42 43 /* 44 * 删除数据 45 */ 46 - (void)deleteWithKey:(NSInteger)key; 47 48 49 @end
1 // CoreDataManager.m 2 3 #import "CoreDataManager.h" 4 #import "Country.h" 5 6 CoreDataManager *manager = nil; 7 @implementation CoreDataManager 8 9 #pragma mark - 单例 10 + (instancetype)shareInstance{ 11 if(!manager){ 12 static dispatch_once_t onceToken; 13 dispatch_once(&onceToken, ^{ 14 manager = [CoreDataManager new]; 15 }); 16 } 17 return manager; 18 } 19 20 #pragma mark - 构建管理上下文 21 - (void)contextBuilding{ 22 // 从程序包中加载应用文件 23 self.model = [NSManagedObjectModel mergedModelFromBundles:nil]; 24 // 传入模型文件并初始化 25 self.psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model]; 26 // 构建数据文件路径 27 NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 28 NSURL *dataUrl = [NSURL fileURLWithPath:[docPath stringByAppendingPathComponent:DATA_FILE]]; 29 // 添加持久化数据库 30 NSError *error = nil; 31 self.store = [self.psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:dataUrl options:nil error:&error]; 32 // 判断数据库是否创建成功 33 if(!self.store){ 34 [NSException raise:@"添加数据库错误" format:@"%@", [error localizedDescription]]; 35 } 36 // 在多线程中设置上下文 37 self.context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 38 self.context.persistentStoreCoordinator = self.psc; 39 } 40 41 #pragma mark - 查询所有数据 42 - (NSArray *)read{ 43 NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 44 NSEntityDescription *entity = [NSEntityDescription entityForName:ENTITY_NAME inManagedObjectContext:self.context]; 45 [fetchRequest setEntity:entity]; 46 // Specify criteria for filtering which objects to fetch 47 // NSPredicate *predicate = [NSPredicate predicateWithFormat:@"<#format string#>", <#arguments#>]; 48 // [fetchRequest setPredicate:predicate]; 49 // Specify how the fetched objects should be sorted 50 // 设置排序关键字 51 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:SORT_KEY 52 ascending:YES]; 53 [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]]; 54 55 NSError *error = nil; 56 NSArray *fetchedObjects = [self.context executeFetchRequest:fetchRequest error:&error]; 57 if (fetchedObjects == nil) { 58 [NSException raise:@"查询数据库错误" format:@"%@", [error localizedDescription]]; 59 } 60 return fetchedObjects; 61 } 62 63 #pragma mark - 添加数据 64 - (void)updataWithKey:(NSInteger)key country:(NSString*)country capital:(NSString *)capital population:(NSInteger)population area:(double)area{ 65 // CoreData不支持主键,故在进行添加修改数据时务必做判断(手动设置主键) 66 NSError *error = nil; 67 NSArray *array = [self read]; 68 BOOL dataHandle = ADD_DATA; 69 // 判断主键是否重复,是则更新,否则添加 70 for(Country *model in array){ 71 if([[model valueForKey:SORT_KEY] isEqual:@(key)]){ 72 model.name = country; 73 model.population = @(population); 74 model.area = @(area); 75 model.capital = capital; 76 if(![self.context save:&error]){ 77 [NSException raise:@"数据更新错误" format:@"%@", [error localizedDescription]]; 78 } 79 dataHandle = CHANGE_DATA; 80 } 81 } 82 83 // 添加 84 if(dataHandle == ADD_DATA){ 85 // 创建对象 86 Country *model = [NSEntityDescription insertNewObjectForEntityForName:ENTITY_NAME inManagedObjectContext:self.context]; 87 model.key = @([((Country*)[array lastObject]).key integerValue] + 1); 88 model.name = country; 89 model.capital = capital; 90 model.population = @(population); 91 model.area = @(area); 92 if(![self.context save:&error]){ 93 [NSException raise:@"添加数据错误" format:@"%@", [error localizedDescription]]; 94 } 95 } 96 } 97 98 #pragma mark - 删除数据 99 - (void)deleteWithKey:(NSInteger)key{ 100 NSError *error = nil; 101 NSArray *array = [self read]; 102 for(Country *model in array){ 103 if([model.key isEqual:@(key)]){ 104 [self.context deleteObject:model]; 105 if(![self.context save:&error]){ 106 [NSException raise:@"删除数据错误" format:@"%@", [error localizedDescription]]; 107 } 108 } 109 } 110 } 111 112 @end
5.CoreData数据的版本迁移(轻量级):
(a).创建迁移版本:Editor -> Add Model Version
(b).更替当前版本:
(c).根据CoreData创建新的数据类
(d).在CoreData管理类中添加自动版本迁移和映射的代码,至此,轻量级的版本迁移完成
1 /* 2 * CoreData的版本迁移(轻量级) 3 * 需要创建自动版本迁移和自动版本映射的字典 4 */ 5 6 NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption:@YES,NSInferMappingModelAutomaticallyOption:@YES}; 7 8 self.store = [self.psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:dataUrl options:options error:&error];