CoreData的简单使用

大家好~之前项目中一直用的是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就算配置好了,接下来开始使用.
  • 首先创建实体
    1. 点击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
查询方法在修改和删除里都有使用,这里就不单独列出来了~

以上就是CoreData的 增删改查的简单使用,如果有说错的地方或者不足的,欢迎大家指出~(转载请注明出处)

原文地址:https://www.cnblogs.com/Free-Thinker/p/7059462.html