大家好~之前项目中一直用的是fmdb进行本地数据持久化,最近在项目中用到了CoreData,,所以这次就简单发个文章,方便新人来更好的使用CoreData,本篇文章简单实现了利用CoreData实现对数据的增删改查。话不多说,直接进入正题~
-
创建工程,创建的时候,记得勾选上Use Core Data,如下图
创建工程.png -
Xcode会自动在AppDelegate.h中生成如下代码
app.h文件.png
-
AppDelegate.m中生成如下代码
#pragma mark - Core Data stack @synthesize persistentContainer = _persistentContainer; - (NSPersistentContainer *)persistentContainer { // The persistent container for the application. This implementation creates and returns a container, having loaded the store for the application to it. @synchronized (self) { if (_persistentContainer == nil) { _persistentContainer = [[NSPersistentContainer alloc] initWithName:@"coredata"]; [_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error) { if (error != nil) { // 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. /* Typical reasons for an error here include: * The parent directory does not exist, cannot be created, or disallows writing. * The persistent store is not accessible, due to permissions or data protection when the device is locked. * The device is out of space. * The store could not be migrated to the current model version. Check the error message to determine what the actual problem was. */ NSLog(@"Unresolved error %@, %@", error, error.userInfo); abort(); } }]; } } return _persistentContainer; } #pragma mark - Core Data Saving support - (void)saveContext { NSManagedObjectContext *context = self.persistentContainer.viewContext; NSError *error = nil; if ([context hasChanges] && ![context 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(); } }
-
工程的左边目录会生成下面的一个文件
Snip20170120_6.png
如果工程已经创建,当时并没有勾选上Use Core Data,就需要手动创建Data Model,Command+N, 选择Core Data下的 Data Model,如下图,再将上述AppDelegate.h和AppDelegate.m中自动生成的代码手动添加到AppDelegate.h和AppDelegate.m中 就好了
Snip20170121_35.png
- 这样CoreData就算配置好了,接下来开始使用.
- 首先创建实体
- 点击coredata.xcdatamodeld文件,再点击Add entity,如下图
Snip20170120_7.png
2.我们将创建的实体起一个名字,我这里叫Person,注意首字母必须大写哦~要不会报错的,然后点击+号,来给Person 添加属性,如下图
Snip20170120_12.png
3.我这里就添加3个属性 uid ,name,url 都是String类型,如下图
Snip20170120_13.png
4.接下来创建NSManagedObject Subclass,
在Xcode菜单栏上选择Editor > Create NSManagedObject Subclass... 如下图
Snip20170120_15.png
5.之后系统自动匹配你刚才创建的Person,一直下一步就可以,最后create~ 如下面2图
Snip20170120_16.png
Snip20170120_17.png
6.创建好了之后,最侧工程目录会生成4个文件,如下图
Snip20170121_18.png
7.这个时候编译一下工程,如果报错(如下图),不要慌张,继续往下看~
Snip20170121_21.png
这是因为Xcode 8会默认生成Subclass,我们刚才手动创建Subclass导致文件重复,所以编译会报错 ,这里有两种解决方法:
- 方法1:删除步骤6生成的四个文件,选中Person,点击右侧Tools Version ,将Minimum 改成Xcode 7.3.(如下图)然后clean工程,然后重复上述步骤4,5,6,
Snip20170121_26.png
- 方法2:删除步骤6生成的四个文件,选中Person,点击右侧Codegen选项,将它改成Manual/None(如下图)然后clean工程,然后重复上述步骤4,5,6,
Snip20170121_29.png
8.然后在首页创建四个按钮, 分别是增删改查,如下图
Snip20170121_19.png
8.接下来切换到ViewController.m文件中,
添加头文件:#import "Person+CoreDataClass.h"
下面贴上我的代码
#import "ViewController.h"
#import "Chat+CoreDataClass.h"
@interface ViewController ()
{
NSManagedObjectContext *context;//coredata上下文
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:model];
NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSURL *url = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"Person.sqlite"]];//设置数据库的路径和文件名称和类型
// 添加持久化存储库,这里使用SQLite作为存储库
NSError *error = nil;
NSPersistentStore *store = [psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];
if (store == nil) { // 直接抛异常
[NSException raise:@"添加数据库错误" format:@"%@", [error localizedDescription]];
}
// 初始化上下文,设置persistentStoreCoordinator属性
context = [[NSManagedObjectContext alloc] init];
context.persistentStoreCoordinator = psc;
NSLog(@"%@",NSHomeDirectory());//数据库会存在沙盒目录的Documents文件夹下
}
9.接下来写增删改查的部分,
插入数据按钮的方法里面:
NSManagedObject *s1 = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:context];
[s1 setValue:@"小明" forKey:@"name"];
[s1 setValue:@"001" forKey:@"uid"];
[s1 setValue:@"www.test.com" forKey:@"url"];
NSError *error = nil;
BOOL success = [context save:&error];
if (!success) {
[NSException raise:@"访问数据库错误" format:@"%@", [error localizedDescription]];
}else
{
NSLog(@"插入成功");
}
点击插入数据按钮后,这时候我们进入沙盒目录下Documents,会看到三个文件,如下图,可以使用数据库可视化工具打开Person.sqlite文件(我这里用的是SQLiteStudio)
Snip20170121_30.png
打开后,就能够看到我们插入的数据了,如下图
Snip20170121_31.png
删除数据按钮的方法里面
//删除之前首先需要用到查询
NSFetchRequest *request = [[NSFetchRequest alloc] init]; //创建请求
request.entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];//找到我们的Person
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"uid = %@", @"001"];//创建谓词语句,条件是uid等于001
request.predicate = predicate; //赋值给请求的谓词语句
NSError *error = nil;
NSArray *objs = [context executeFetchRequest:request error:&error];//执行我们的请求
if (error) {
[NSException raise:@"查询错误" format:@"%@", [error localizedDescription]];//抛出异常
}
// 遍历数据
for (NSManagedObject *obj in objs) {
NSLog(@"name = %@ uid = %@ url = %@", [obj valueForKey:@"name"],[obj valueForKey:@"uid"],[obj valueForKey:@"url"]); //打印符合条件的数据
[context deleteObject:obj];//删除数据
}
BOOL success = [context save:&error];
if (!success) {
[NSException raise:@"访问数据库错误" format:@"%@", [error localizedDescription]];
}else
{
NSLog(@"删除成功,sqlite");
}
点击插入数据按钮后,刷新数据库,就可以看到我们刚才插入的数据就被删除了,如下图
Snip20170121_33.png
插入数据按钮的方法里面:
//修改数据,肯定也是要先查询,再修改
NSFetchRequest *request = [[NSFetchRequest alloc] init];//创建请求
request.entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];//找到我们的Person
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*小明*"];//查询条件:name等于小明
request.predicate = predicate;
NSError *error = nil;
NSArray *objs = [context executeFetchRequest:request error:&error];//执行请求
if (error) {
[NSException raise:@"查询错误" format:@"%@", [error localizedDescription]];
}
// 遍历数据
for (NSManagedObject *obj in objs) {
[obj setValue:@"小红" forKey:@"name"];//查到数据后,将它的name修改成小红
}
BOOL success = [context save:&error];
if (!success) {
[NSException raise:@"访问数据库错误" format:@"%@", [error localizedDescription]];
}else
{
NSLog(@"修改成功");
}
首先再插入一条数据,再点击修改按钮,刷新数据库就会看到name的值由小明改成了小红,如下图
Snip20170121_34.png