Core data是苹果官方提供的一套框架,主要用来解决与对象生命周期管理,对象关系图管理和持久化的等方面的问题。
#import <UIKit/UIKit.h> #import <CoreData/CoreData.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; @end
#pragma mark - Core Data stack //返回路径 - (NSURL *)applicationDocumentsDirectory {} //描述应用程序的数据模型,这个模型包含实体(Entity),特性(Property),读取请求(Fetch Request)等。 - (NSManagedObjectModel *)managedObjectModel {} //相当于数据文件管理器,处理底层的对数据文件的读取与写入。一般我们无需与它打交道。 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {} //参与对数据对象进行各种操作的全过程,并监测数据对象的变化,以提供对 undo/redo 的支持及更新绑定到数据的 UI。 - (NSManagedObjectContext *)managedObjectContext {}
之后创建一个根视图,因为我们需要下面所有页面都要用到 UIBarButtonItem.
CommonViewController.h
#import <UIKit/UIKit.h> @interface CommonViewController : UIViewController -(void)addData2DB:(NSString *)name; -(void)deleteFromDB:(NSString *)name; -(void)updateFromDB:(NSString *)name; @end
#import "CommonViewController.h" @interface CommonViewController () @property (nonatomic, strong) UIAlertController *alertController; @end @implementation CommonViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:(UIBarButtonSystemItemAdd) target:self action:@selector(addAction:)]; [self.navigationItem setRightBarButtonItem:item]; if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) { //设置边缘是否 [self setEdgesForExtendedLayout:(UIRectEdgeNone)]; } } -(void)addAction:(id)sender{ //使用懒加载 延迟加载,当程序走到该处,才开始执行 get 方法 , 这时候才会去创建alertController [self presentViewController:self.alertController animated:YES completion:nil]; } //实现触发方法 -(UIAlertController *)alertController{ if(!_alertController){ _alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"您想要保存么?" preferredStyle:(UIAlertControllerStyleAlert)]; UIAlertAction *saveAction = [UIAlertAction actionWithTitle:@"保存" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction *action) { NSLog(@"保存成功"); [self save]; }]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"删除" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction *action) { NSLog(@"删除成功"); [self cancel]; }]; UIAlertAction *updateAction = [UIAlertAction actionWithTitle:@"更新" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction *action) { NSLog(@"更新成功"); [self update]; }]; [_alertController addAction:saveAction]; [_alertController addAction:cancelAction]; [_alertController addAction:updateAction]; [_alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) { textField.placeholder = @"请输入..."; }]; } return _alertController; } #pragma mark - 预留接口 //实现方法 2 --> To 4 --> for -(void)addData2DB:(NSString *)name{ } -(void)deleteFromDB:(NSString *)name{ } -(void)updateFromDB:(NSString *)name{ } #pragma mark - 接口方法 -(void)save{ //打印触发的方法名 NSLog(@"%@",NSStringFromSelector(_cmd)); //获取输入框中内容并放入本地 UITextField *field = [self.alertController.textFields firstObject]; NSLog(@"%@",field.text); self.alertController = nil; //将数据存入数据库中 [self addData2DB:field.text]; } -(void)cancel{ //打印触发的方法名 NSLog(@"%@",NSStringFromSelector(_cmd)); //获取输入框中内容并放入本地 UITextField *field = [self.alertController.textFields firstObject]; //删除 [self deleteFromDB:field.text]; self.alertController = nil; } -(void)update{ //打印触发的方法名 NSLog(@"%@",NSStringFromSelector(_cmd)); //获取输入框中内容并放入本地 UITextField *field = [self.alertController.textFields firstObject]; //删除 [self updateFromDB:field.text]; self.alertController = nil; } @end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds]; [self.window makeKeyAndVisible]; self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:[ProvinceViewController new]]; return YES; }
#import <Foundation/Foundation.h> @class Province; @interface DBManager : NSObject +(id)shareManager; //声明添加数据库的方法 -(void)addProvince:(NSString *)name; -(void)deleteProvince:(NSString *)name; -(void)upDataProvince:(NSString *)name; -(NSArray *)selectAllProvince; @end
#import "DBManager.h" #import "AppDelegate.h" #import "Province.h" #import "Global.h" #import "City.h" @implementation DBManager //创建一个单例 +(id)shareManager{ static DBManager *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken,^{ instance = [[[self class]alloc] init]; }); return instance; } //保存更新 -(void)save{ NSError *error = nil; if (![[appdelegate managedObjectContext]save:&error]) { NSLog(@"保存数据成功 --> %@",[error userInfo]); } else{ NSLog(@"保存数据成功"); [[NSNotificationCenter defaultCenter] postNotificationName:operateDBSuccessNotification object:nil]; } } //添加 -(void)addProvince:(NSString *)name{ // //获取代理对象 // AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication]delegate]; NSArray *array = [self selectProvinceWithName:name]; if (array.count > 0) { NSLog(@"添加数据已经存在"); return; } //创建实体描述对象 对应表名 NSEntityDescription *des = [NSEntityDescription entityForName:@"Province" inManagedObjectContext:[appdelegate managedObjectContext]]; //生成哪个表的管理对象 Province *province = [[Province alloc]initWithEntity:des insertIntoManagedObjectContext:[appdelegate managedObjectContext]]; province.name = name; [self save]; } //查询 -(NSArray *)selectProvinceWithName:(NSString *)name{ //对这个表发起查询请求 NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:@"Province"]; //查询条件 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@",name]; // [request setPredicate:predicate]; // NSError *error = nil; // NSArray *array = [[appdelegate managedObjectContext] executeFetchRequest:request error:&error]; if (error) { NSLog(@"查询失败 -> %@",[error userInfo]); } return array; } //选择 -(NSArray *)selectAllProvince{ //对这个表发起查询请求 NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:@"Province"]; // NSError *error = nil; // NSArray *array = [[appdelegate managedObjectContext] executeFetchRequest:request error:&error]; if (error) { NSLog(@"查询失败 -> %@",[error userInfo]); } return array; } //删除 -(void)deleteProvince:(NSString *)name{ //查询方法 NSArray *array = [self selectProvinceWithName:name]; if ([array count] > 0) { //想获取数据,首先遍历数组 [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { //获取到的数据,并进行强转 Province *province = (Province *)obj; //删除省份对应下的城市 [self deleteCitiesInProvince:province]; //获取上下文并删除 [[appdelegate managedObjectContext]deleteObject:province]; }]; //保存 [self save]; } else{ NSLog(@"该条数据不存在"); } } // -(void)deleteCitiesInProvince:(Province *)province{ #pragma mark - 通过对象来查找 // //查询请求 // NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:@"City"]; // //查询条件 // NSPredicate *pre = [NSPredicate predicateWithFormat:@"province = %@",province]; // // // [request setPredicate:pre]; // // // NSError *error = nil; // //上下文执行,返回结果 // NSArray *array = [[appdelegate managedObjectContext] executeFetchRequest:request error:&error]; // //遍历结果,依次删除 // if (array.count > 0) { // [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { // City *city = (City *)obj; // [self deleteCity:city.name]; // }]; // } #pragma mark - 通过关联对象查找 NSSet *set = province.city; [set enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { City *city = (City *)obj; [self deleteCity:city.name]; }]; } //更新 -(void)upDataProvince:(NSString *)name{ //1.查询数据库 NSArray *array = [self selectAllProvince]; if (array.count > 0) { //2.遍历查询的数据 [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { //3.获取每个 Province 对象 , 取得 Name Province *province = (Province *)obj; NSRange range = [province.name rangeOfString:@"省"]; //4.修改 name ,得到新的 name 并将其 重新赋值给 province 的 name 属性 if(range.location != NSNotFound){ NSString *newName = [province.name stringByReplacingCharactersInRange:range withString:name]; province.name = newName; } }]; //5.储存 [self save]; } }
#ifndef CoreDataTest_Global_h #define CoreDataTest_Global_h //appDelegate #define appdelegate (AppDelegate *)[[UIApplication sharedApplication]delegate] //operate db notification #define operateDBSuccessNotification @"operateDBSuccessNotification" #endif
#import <UIKit/UIKit.h> #import "CommonViewController.h" @interface ProvinceViewController : CommonViewController @property (nonatomic, strong) UITableView *tableView; @end
#import "ProvinceViewController.h" #import "DBManager.h" #import "Global.h" #import "CityViewController.h" @interface ProvinceViewController () <UITableViewDataSource,UITableViewDelegate> //存放数据 @property (nonatomic, strong) NSArray *provinceArray; @end @implementation ProvinceViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor colorWithRed:0.649 green:1.000 blue:0.471 alpha:1.000]; self.title = @"省 份"; //注册通知 [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(upTableData) name:operateDBSuccessNotification object:nil]; [self upTableData]; } -(void)upTableData { //使用 GCD dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //放入子线程中去进行请求 self.provinceArray = [[DBManager shareManager] selectAllProvince]; dispatch_async(dispatch_get_main_queue(), ^{ // if ([self.provinceArray count] > 0) { [self.tableView reloadData]; // } }); }); } -(UITableView *)tableView{ if (!_tableView) { _tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:(UITableViewStylePlain)]; _tableView.delegate = self; _tableView.dataSource = self; [self.view addSubview:_tableView]; } return _tableView; } #pragma mark - overriade super method (重写父类方法) //实现方法 2 --> To 4 --> for -(void)addData2DB:(NSString *)name{ [super addData2DB:name]; //调用方法 [[DBManager shareManager]addProvince:name]; } -(void)deleteFromDB:(NSString *)name{ [[DBManager shareManager]deleteProvince:name]; } -(void)updateFromDB:(NSString *)name{ [[DBManager shareManager]upDataProvince:name]; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return [self.provinceArray count]; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *identifity = @"cell"; UITableViewCell *cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:identifity]; if (!cell) { cell = [[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:identifity]; } cell.textLabel.text = [self.provinceArray[indexPath.row] name]; return cell; } #pragma mark - 实现页面跳转 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ CityViewController *cityVC = [[CityViewController alloc]init]; //将当前的省份传入下一个页面 cityVC.currentProvince = self.provinceArray[indexPath.row]; [self.navigationController pushViewController:cityVC animated:YES]; } @end
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"_6Kr.sqlite"]; NSError *error = nil; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:@{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES} error:&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. Typical reasons for an error here include: * The persistent store is not accessible; * The schema for the persistent store is incompatible with current managed object model. Check the error message to determine what the actual problem was. If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory. If you encounter schema incompatibility errors during development, you can reduce their frequency by: * Simply deleting the existing store: [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil] * Performing automatic lightweight migration by passing the following dictionary as the options parameter: @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES} Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details. */ NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return _persistentStoreCoordinator; }