iOS 数据持久化之CoreData(二)堆栈建立和基本操作Demo

原创Blog,转载请注明出处

blog.csdn.net/hello_hwc

欢迎关注我的iOS SDK详解专栏

http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html



前言:本文会通过一个完整的工程创建,讲解

  • CoreData的堆栈创建
  • 四种基本的操作(查询,创建,删除,更新)
  • 简单的MVC设计
  • 如何使用Block传递Action,缩减代码量
  • 再CoreData使用类别扩展NSManagedObject方法


Demo下载

http://download.csdn.net/detail/hello_hwc/8692083

注意,这个Demo侧重讲解如何建立CoreData堆栈,以及常见的四种操作,为后续文章的讲解做铺垫的,所以非常简单,简单到体现不到CoreData的优点,如果你哪怕写过一个使用了CoreData的工程,那就这篇就可以直接不看了。


Demo效果

四种基本操作

点击Query All

Log输出

2015-05-13 10:26:13.534 QuiteSimpeCoreDataDemo[3029:62136] (
    "name:Lucy age:21",
    "name:Tom age:20",
    "name:jack age:21"
)

然后,添加一个新的Person,点击Create

输出

2015-05-13 10:27:03.764 QuiteSimpeCoreDataDemo[3029:62136] Create Successfully.Id is 0xd000000000100000 <x-coredata://ACB1C333-E7B3-4D6A-BF58-7061952D95AD/Person/p4>

然后更新



输出

2015-05-13 10:28:21.109 QuiteSimpeCoreDataDemo[3029:62136] Update Successfully

在查询全部,看到年龄更新成功

2015-05-13 10:30:06.557 QuiteSimpeCoreDataDemo[3029:62136] (
    "name:Lily age:24",
    "name:Lucy age:21",
    "name:Tom age:20",
    "name:jack age:21"
)

删除

输出

2015-05-13 10:31:27.312 QuiteSimpeCoreDataDemo[3029:62136] Delete successfully

再查询,发现删除成功

2015-05-13 10:31:42.711 QuiteSimpeCoreDataDemo[3029:62136] (
    "name:Lucy age:21",
    "name:Tom age:20",
    "name:jack age:21"
)

Demo的建立过程

  • 新建一个工程,注意选中使用CoreData

  • 查看AppDelegate.m,会发现很多和CoreData创建堆栈相关的代码,为了代码的解耦合,把这些代码以AppDelegate.m中的代码拷贝到一个新建类(Store)中,这个类点作用就是创建堆栈,提供NSManagedContext

    Store.h

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Store : NSObject

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

@end

再看看Store.m各个部分的内容

//获取DocumentDirectory
- (NSURL *)applicationDocumentsDirectory {
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

获取对象图模型,这里的对象图名字就是这个文件的名字

- (NSManagedObjectModel *)managedObjectModel {
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"QuiteSimpeCoreDataDemo" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

创建持久化存储协调器

 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"QuiteSimpeCoreDataDemo.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]) {
        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();//这里为了方便调试,正常的App不要这样写
    }

    return _persistentStoreCoordinator;
}

创建Managed Context

- (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] init];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

保存到磁盘

 - (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();
        }
    }
}

  • 点击QuiteSimpleCoreDataDemo.xcdatamodeld,创建一个Entity,命名为Person,添加两个属性,name和age,如图


  • Editor- CreateNSManaged Subclass - 一致勾选-创建声称两个文件,Person.h,Person.m



创建Person的类别Function+Person,在这里为NSManagedObject添加方法,不要在类中直接添加,因为下次在自动生成时候会把这之前的覆盖掉。

Function+Person.h文件

#import "Person.h"

@interface Person (Functions)
+(NSString *)entityName;
+(Person *)insertNewObjectInManagedObjectContext:(NSManagedObjectContext *) context;
@end

Function+Person.m文件

#import "Person+Functions.h"

@implementation Person (Functions)
+(NSString *)entityName{
    return @"Person";
}
+(Person *)insertNewObjectInManagedObjectContext:(NSManagedObjectContext *) context{
    return [NSEntityDescription insertNewObjectForEntityForName:[self entityName] inManagedObjectContext:context];
}
//重写Description,方便Log
-(NSString *)description{
    return [NSString stringWithFormat:@"name:%@ age:%ld",self.name,(long)self.age.integerValue];
}
@end


然后,回到viewController进行相关的处理

使用AlertController作为输入,创建一个公共方法,这里的CoreDataAction是我定义的一个Block,传入如何处理数据的动作。

typedef void(^CoreDataAction)(NSString * name,NSString * age);
-(void)AlertTextFieldWithTitle:(NSString *)actionTitle Action:(CoreDataAction) actionBlock {
    UIAlertController * alert = [UIAlertController alertControllerWithTitle:actionTitle message:nil preferredStyle:UIAlertControllerStyleAlert];
    [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
       textField.placeholder = @"Name";
    }];
    [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
        textField.placeholder = @"age";
    }];
    [alert addAction:[UIAlertAction actionWithTitle:actionTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        NSArray * textfields = alert.textFields;
        UITextField * nameTextfields = textfields[0];
        UITextField * ageTextFields = textfields[1];
        actionBlock(nameTextfields.text,ageTextFields.text);
    }]];
    [alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]];
    [self presentViewController:alert animated:YES completion:nil];
}


查询当前Name的Person是否存在(本工程Person的name不允许重复),存在则返回,不存在则返回nil

-(Person *)personExistWithName:(NSString *)name{
    NSFetchRequest * fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[Person entityName]];
    //This is an array
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name =  %@",name];
    NSError *error = nil;
    NSArray *fetchedObjects = [self.store.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        return nil;
    }else{
        return [fetchedObjects lastObject];
    }
}


对应的四个Button的target-action

查询

- (IBAction)queryAll:(id)sender {
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:[Person entityName] inManagedObjectContext:self.store.managedObjectContext];
    [fetchRequest setEntity:entity];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name"
                                                                   ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];

    NSError *error = nil;
    NSArray *fetchedObjects = [self.store.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"It is empty");
    }else{
        NSLog(@"%@",fetchedObjects.description);
    }
}


更新

- (IBAction)update:(id)sender {
    [self AlertTextFieldWithTitle:@"Update" Action:^(NSString *name, NSString *age) {
        Person * person = [self personExistWithName:name];
        if (person != nil) {
            person.age = @(age.integerValue);
            [self.store saveContext];
            NSLog(@"Update Successfully");
        }else{
            NSLog(@"Person does not exist,can not update");
        }
    }];
}


创建

- (IBAction)Create:(id)sender {
    [self AlertTextFieldWithTitle:@"Create" Action:^(NSString *name, NSString *age) {
        if ([self personExistWithName:name] == nil) {
            Person * person = [Person insertNewObjectInManagedObjectContext:self.store.managedObjectContext];
            person.name = name;
            person.age =  @(age.integerValue);
            [self.store saveContext];
            NSLog(@"Create Successfully.Id is %@",person.objectID.description);

        }else{
            NSLog(@"This peson  exist before,can not create");
        }
    }];
}


删除

- (IBAction)Delete:(id)sender {
    [self AlertTextFieldWithTitle:@"Delete" Action:^(NSString *name, NSString *age) {
        Person * person = [self personExistWithName:name];
        if (person != nil) {
            [self.store.managedObjectContext deleteObject:person];
            NSLog(@"Delete successfully");
        }else{
            NSLog(@"This does not exist before,can not delete");
        }
    }];
}

时间: 2024-07-30 18:42:48

iOS 数据持久化之CoreData(二)堆栈建立和基本操作Demo的相关文章

iOS -数据持久化之CoreData

Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象.在此数据操作期间,我们不需要编写任何SQL语句 1.创建项目的时候勾选Use the CoreData 2.创建好之后就会在左边的文件名那里看到一个CoreData.xcdatamodeldde文件 3.点击之后在Xcode的中间可以看到它的内容,之后点击左下角的Add Entity可以添加表(表名可以修

iOS数据持久化之二——归档与设计可存储化的数据模型基类

iOS数据持久化之二--归档与设计可存储化的数据模型基类 一.引言 在上一篇博客中,我们介绍了用plist文件进行数据持久化的方法.虽然简单易用,但随着开发的深入,你会发现,这种方式还是有很大的局限性.试想,如果我们可以将用户的登录返回信息模型,游戏中角色的属性信息模型进行直接的持久化存取,那是不是非常爽的事,幸运的是,我们可以通过归档,来设计一个这样的数据模型. 二.先来精通归档吧 归档也是iOS提供给开发者的一种数据存储的方式,事实上,几乎所有的数据类型都可以通过归档来进行存取.其存储与读取

iOS数据持久化存储

本文中的代码托管在github上:https://github.com/WindyShade/DataSaveMethods 相对复杂的App仅靠内存的数据肯定无法满足,数据写磁盘作持久化存储是几乎每个客户端软件都需要做的.简单如"是否第一次打开"的BOOL值,大到游戏的进度和状态等数据,都需要进行本地持久化存储.这些数据的存储本质上就是写磁盘存文件,原始一点可以用iOS本身支持有NSFileManager这样的API,或者干脆C语言fwrite/fread,Cocoa Touch本身

iOS -数据持久化方式-以真实项目讲解

前面已经讲解了SQLite,FMDB以及CoreData的基本操作和代码讲解(CoreData也在不断学习中,上篇博客也会不断更新中).本篇我们将讲述在实际开发中,所使用的iOS数据持久化的方式以及怎么会使用到这些方式,都会以本人实际开发的场景为例,大约需要花10-15分钟,欢迎大家指正. 一.前言 和大家说一个真实故事,前年我去美图面试(当时的技术仅仅是UI和接口的实现,并不注重很多底层实现和很多概念的原理,换句话说,就是真正的码农),过了技术第一轮和第二轮(前两年的也就是问问技术点的实现),

IOS数据持久化之归档NSKeyedArchiver

IOS数据持久化的方式分为三种: 属性列表 (自定义的Property List .NSUserDefaults) 归档 (NSKeyedArchiver) 数据库 (SQLite.Core Data.第三方类库等) 下面主要来介绍一个归档NSKeyedArchiver. 归档(又名序列化),把对象转为字节码,以文件的形式存储到磁盘上:程序运行过程中或者当再次重写打开程序的时候,可以通过解归档(反序列化)还原这些对象. 归档方式: 对Foundation框架中对象进行归档 对自定义的内容进行归档

iOS数据存储之CoreData

iOS中大量数据的储存一个是SqLite,另一个就是CoreData,CoreData允许程序员以面向对象的思维方式的方法去操作面向表的数据库 做过Java开发的对这个应该很熟悉,Java中的Hibernate跟CoreData就很相似 CoreData应该怎样使用呢? 第一步,新建工程后导入CoreData框架 第二部,创建CoreData的数据模型创建步骤如下 然后给你的model起个名字,创建完成后你会看到一个这个文件(相当于数据库文件) 点击这个文件,然后看下图 点击图中1,新建实体(类

iOS数据持久化方式分析

iOS数据持久化的方式一般为:plist文件写入.对象归档.SQLite数据库.CoreData. plist文件写入.对象归档一般用于小的数据量. SQLite数据库.CoreData则用于大的数据量. SQLite是一款轻型的数据库,是一种关系型数据库管理系统,他的设计目的是嵌入式设备中使用. SQLite占用资源非常低,非常适合移动设备中使用,而且是开源免费的 SQLite的数据库操作其实和常规的数据库操作流程是一样的: 1.打开数据库 sqlite3_open() 2.准备SQL语句,采

iOS开发笔记-swift实现iOS数据持久化之归档NSKeyedArchiver

IOS数据持久化的方式分为三种: 属性列表 (plist.NSUserDefaults) 归档 (NSKeyedArchiver) 数据库 (SQLite.Core Data.第三方类库等 归档(又名序列化),把对象转为字节码,以文件的形式存储到磁盘上:程序运行过程中或者当再次重写打开程序的时候,可以通过解归档(反序列化)还原这些对象.本文主要介绍swift实现iOS数据归档. 归档Foundation框架对象 func archiveData(){ var path: AnyObject=NS

ios开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】

               在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运用: 在本节,将通过对4个文本框内容的创建.修改,退出后台,再重新回到后台,来认识这两种持久化数据的方式.效果图如下[图1]: [图1 GUI界面效果图] [本次开发环境: Xcode:7.2     iOS Simulator:iphone6S plus   By:啊左]     一.数据库SQL