Core Data <二>使用简介
第一步,新建工程,勾选CoreData选项,点击Next
此时再工程文件 AppDelegate.h 和 AppDelegate.m 会⾃动⽣成被管理的数据上下⽂等相关代码.
代码简介
AppDelegate.h 文件中生成
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext; //保存数据到持久层(数据库)
- (NSURL *)applicationDocumentsDirectory; //应⽤程序沙箱下的Documents⺫录路径
/*
managedObjectContext,managedObjectModel,persistentStoreCoordinator的说明详解见Core Data <一>基本概念
*/@end
AppDelegate.m 文件中,各方法代码简介
// 数据保存到持久层
- (void)applicationWillTerminate:(UIApplication *)application {
[self saveContext];
}
// 当插入,删除和修改数据之后,我们需要通过该方法保存被管理对象上下文,其中[managedObjectContext save:&error]语句是保存上下文的核心语句
- (void)saveContext {
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
NSError *error = nil;
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
// 返回应用程序的沙盒Documents目录,返回NSURL类型.
- (NSURL *)applicationDocumentsDirectory {
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
// 返回被管理对象的上下文
- (NSManagedObjectContext *)managedObjectContext {
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (!coordinator) {
return nil;
}
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
return _managedObjectContext;
}
// 返回持久化存储协调器
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
// Create the coordinator and store
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CocoDataLearnOne.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];
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
// 返回被管理对象
- (NSManagedObjectModel *)managedObjectModel {
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CocoDataLearnOne" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
第二步 创建数据模型(数据模型编辑编辑器之间的操作)
2.1 创建实体
选中.xcdatamodeld 文件,
创建一个名称为"ContactInfo" Entity,3个属性,age,birthday和name.
操作步骤如下:
1. Add Entity 加入实体 ->2.编辑实体的名称 ->3.Add Attribute 加入实体属性 ->4. 编辑属性的名称 -> 5.设置属性的类型
同样的方法创建名称为"ContactDetailInfo"Entity.3个属性为address,name,telephone
2.2 建立实体间的关系
选中ContactInfo实体,Add Relationship 如下图所示:
图1-> 点击+添加关系,
图2-> 给关系添加名称 ,难题
图3-> 与ContactDetailInfo创建关系,并在Inverse 选择建立返回关系,与ContactDetailInfo 中建立关系名称Info(当建立一个目标关系,最好建立一个返回关系)
图4-> 设置两个Entity的关联模式,Delete Rule 关联模式cascade:其中一个数据被删除,另一个Entity中的数据也会跟着删除
选中另一个ContactDetailInfo 实体用上述步骤完成配置.
两个Enitiy设置完成后可点击 图5. Editor Style 可查看两个表的关系.
两个表的设置如图
可查看两个表Entity实体的关系
第三步 插入,查询,删除,修改方法
// 可以在-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// <一>插入数据
- (void)insertCoreData
{
// 1.获得当前上下文
NSManagedObjectContext *context = [self managedObjectContext];
// 2.NSManagedObject->被管理的数据记录; NSEntityDescription->抽象数据类型,相当于数据库中的表
// 通过上下文查找名字为@"ContactInfo"的Entity, 相当于查找ContactInfo的表,插入数据
NSManagedObject *contactInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ContactInfo" inManagedObjectContext:context];
// 3.根据Entity中属性,分别赋值.Entity 特性,相当于数据库表中的一列
/*
Property NSPropertyDescription Entity 特性,相当于数据库表中的一列
> Attribute NSAttributeDescription 基本数值型属性(如Int16, BOOL, Date等类型的属性)
> Relationship NSRelationshipDescription 属性之间的关系
> Fetched Property NSFetchedPropertyDescription 查询属性(相当于数据库中的查询语句)
*/
// 通过KVC给ContactInfo 内的属性赋值
[contactInfo setValue:@"香蕉" forKey:@"name"];
[contactInfo setValue:@"1920" forKey:@"birthday"];
[contactInfo setValue:@"80" forKey:@"age"];
NSManagedObject *contactDetailInfo = [NSEntityDescription insertNewObjectForEntityForName:@"ContactDetailInfo" inManagedObjectContext:context];
[contactDetailInfo setValue:@"香蕉" forKey:@"address"];
[contactDetailInfo setValue:@"苹果" forKey:@"name"];
[contactDetailInfo setValue:@"110" forKey:@"telephone"];
// 4.保存关系
[contactDetailInfo setValue:contactInfo forKey:@"info"];
[contactInfo setValue:contactDetailInfo forKey:@"detail"];
// 5.1 保存方法一
NSError *error = nil;
if ([context save:&error])
{
NSLog(@"保存,");
}else{
NSLog(@"保存失败;%@",[error localizedDescription]);
}
//5.2 保存方法二
// if (![context save:&error]) {
// NSLog(@"不能保存:%@",[error localizedDescription]);
// }
}
// <二>查找数据
/*
NSFetchRequest 常用方法
-setEntity: 设置你要查询的数据对象的类型(Entity)
-setPredicate: 设置查询条件
-setFetchLimit: 设置最大查询对象数目
-setSortDescriptors: 设置查询结果的排序方法
-setAffectedStores: 设置可以在哪些数据存储中查询
*/
// 查找所有数据
- (void)fetchRequestCoreData
{
// 1.获得当前上下文
NSManagedObjectContext *context = self.managedObjectContext;
// 2.创建查找的请求
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// 3. 通过上下文查找Entity 是@"ContactInfo"
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ContactInfo" inManagedObjectContext:context];
// 4.设置查找的Entity
[fetchRequest setEntity:entity];
// 5.通过上下文开始查找,返回数组
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *info in fetchedObjects) {
NSLog(@"name = %@",[info valueForKey:@"name"]);
NSLog(@"age = %@",[info valueForKey:@"age"]);
NSLog(@"birthday = %@",[info valueForKey:@"birthday"]);
NSManagedObject *details = [info valueForKey:@"detail"];
NSLog(@"address:%@", [details valueForKey:@"address"]);
NSLog(@"telephone:%@", [details valueForKey:@"telephone"]);
}
}
// <三>通过条件查找数据
- (void)fetchRequestCoreDataWithName:(NSString *)name
{
NSManagedObjectContext *context = [self managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ContactInfo" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
// 设置查找的条件
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@",name];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *dataArray = [context executeFetchRequest:request error:&error];
if (dataArray.count > 0) {
NSLog(@"dataArray.last = %@",dataArray.lastObject);
}
}
// <四>通过条件删除数据
- (void)deleteCoreDataWithName:(NSString *)name
{
NSManagedObjectContext *context = self.managedObjectContext;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ContactInfo" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@",name] ;
[request setPredicate:predicate];
NSError *error = nil;
NSArray *dataArray = [context executeFetchRequest:request error:&error];
if (dataArray > 0) {
// 按名字删除对象
NSManagedObject *object= [dataArray lastObject];
[self.managedObjectContext deleteObject:object];
NSError *error = nil;
if ([context save:&error]) {
NSLog(@"delete = 保存成功");
}else
{
NSLog(@"保存失败");
}
}
}
// <五>通过条件修改数据
- (void)modifyCoreDataWithName:(NSString *)name
{
NSManagedObjectContext *context = self.managedObjectContext;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ContactInfo" inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name = %@",name];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *dataArray = [context executeFetchRequest:request error:&error];
if (dataArray.count > 0) {
// 按名字修改
NSManagedObject *object = [dataArray lastObject];
[object setValue:@"小米" forKey:@"name"];
NSError *error = nil;
if([context save:&error])
{
NSLog(@"修改保存");
}else
{
NSLog(@"修改保存失败");
}
}
}
// AppDelegate.m 方法中写好的CoreData 方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self insertCoreData];
[self fetchRequestCoreDataWithName:@"苹果"];
[self modifyCoreDataWithName:@"苹果"];
[self fetchRequestCoreData];
// 沙盒Caches路径
NSLog(@"%@",NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject);
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self deleteCoreDataWithName:@"小米"];
}
可以通过路径去模拟器的沙盒路径的数据库去查看数据的变化.