CoreData的基本使用

通讯录示例1(coreData简单用法):
主页面:
1 #import "TableViewController.h" 2 #import "AppDelegate.h" 3 #import "Person.h" 4 5 @interface TableViewController () 6 @property (nonatomic,strong) NSMutableArray * arr; 7 @end 8 9 @implementation TableViewController 10 /** 11 * 懒加载 12 */ 13 - (NSMutableArray *)arr{ 14 if (!_arr) { 15 _arr = [NSMutableArray array]; 16 } 17 return _arr; 18 } 19 /** 20 * 在当前工程中只被调用一次 21 */ 22 - (void)viewDidLoad { 23 [super viewDidLoad]; 24 } 25 26 /** 27 * 当前页面即将显示时被调用(多次被调用) 28 */ 29 - (void)viewWillAppear:(BOOL)animated{ 30 /** 31 * 清空当前页面数据源数组 32 */ 33 [self.arr removeAllObjects]; 34 35 AppDelegate * app = [UIApplication sharedApplication].delegate; 36 /** 37 * 初始化数据抓取请求 38 */ 39 NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"Person"]; 40 /** 41 * 托管上下文执行数据抓取请求,返回抓取的数据 42 */ 43 self.arr = [NSMutableArray arrayWithArray:[app.managedObjectContext executeFetchRequest:request error:nil]]; 44 /** 45 * 刷新表视图数据 46 */ 47 [self.tableView reloadData]; 48 } 49 50 51 #pragma mark - 表视图数据源代理方法 52 53 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 54 return 1; 55 } 56 57 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 58 return self.arr.count; 59 } 60 61 62 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 63 static NSString * identifier = @"cell"; 64 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; 65 if (!cell) { 66 cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier]; 67 } 68 Person * p = self.arr[indexPath.row]; 69 cell.textLabel.text = p.name; 70 cell.detailTextLabel.text = p.phone; 71 return cell; 72 } 73 74 - (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{ 75 return @"删除"; 76 } 77 78 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ 79 Person * p = self.arr[indexPath.row]; 80 AppDelegate * app = [UIApplication sharedApplication].delegate; 81 /** 82 * 利用上下文对象删除数据 83 */ 84 [app.managedObjectContext deleteObject:p]; 85 /** 86 * 利用上下文对象,将数据同步到持久化存储库 87 */ 88 [app.managedObjectContext save:nil]; 89 [self.arr removeObject:p]; 90 [self.tableView reloadData]; 91 } 92 93 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 94 Person * p = self.arr[indexPath.row]; 95 UIStoryboard * story = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; 96 UIViewController * vc = [story instantiateViewControllerWithIdentifier:@"123"]; 97 /** 98 * 点击Cell进入修改页面的同时,将当前Cell的数据传输到修改页面,以便显示 99 */ 100 [vc setValue:p forKey:@"model"]; 101 [self.navigationController pushViewController:vc animated:YES]; 102 } 103 104 105 @end
编辑页面:
1 #import "ViewController.h" 2 #import "AppDelegate.h" 3 #import "Person.h" 4 5 @interface ViewController () 6 @property (strong, nonatomic) IBOutlet UIBarButtonItem *saveBtn; 7 @property (strong, nonatomic) IBOutlet UITextField *textName; 8 @property (strong, nonatomic) IBOutlet UITextField *textPhone; 9 @property (strong, nonatomic) Person * model; 10 @end 11 12 @implementation ViewController 13 14 - (void)viewDidLoad { 15 [super viewDidLoad]; 16 /** 17 * 判断是否有数据从表视图页面传过来:如果有则说明是通过点击Cell跳转过来的,目的是修改数据 18 1.将传过来的数据显示到当前视图上 19 2.设置保存按钮title为“修改” 20 */ 21 if (self.model) { 22 [self showMessageWithModel:self.model]; 23 self.saveBtn.title = @"修改"; 24 } 25 } 26 - (IBAction)saveOrEdit:(UIBarButtonItem *)sender { 27 /** 28 * 判断输入框是否存在数据,若无则不进行任何操作 29 */ 30 if (self.textPhone.text.length||self.textName.text.length) { 31 AppDelegate * app = [UIApplication sharedApplication].delegate; 32 /** 33 * 判断当前页面是添加信息,还是修改信息 34 */ 35 if ([self.saveBtn.title isEqualToString:@"保存"]) { 36 Person * p = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:app.managedObjectContext]; 37 [self setValueForModel:p]; 38 }else{ 39 [self setValueForModel:self.model]; 40 } 41 /** 42 * 保存数据 43 */ 44 [app.managedObjectContext save:nil]; 45 /** 46 * 当前控制器出栈(跳出当前页面) 47 */ 48 [self.navigationController popViewControllerAnimated:YES]; 49 } 50 51 } 52 53 /** 54 * 将传输过来的数据显示在当前页面--方法 55 */ 56 - (void)showMessageWithModel:(Person *)model{ 57 self.textName.text = model.name; 58 self.textPhone.text = model.phone; 59 } 60 61 /** 62 * 为数据类设值--方法 63 */ 64 - (void)setValueForModel:(Person *)model{ 65 model.name = self.textName.text; 66 model.phone = self.textPhone.text; 67 } 68 @end
通讯录示例2(coreData高级用法之FRC):
主页面:
1 #import "TableViewController.h" 2 #import "AppDelegate.h" 3 #import "AddressBook.h" 4 5 @interface TableViewController () <NSFetchedResultsControllerDelegate> 6 @property (nonatomic,strong) NSFetchedResultsController * fetchedResultsController; 7 @end 8 9 @implementation TableViewController 10 11 /** 12 * 在当前工程中只被调用一次 13 */ 14 - (void)viewDidLoad { 15 [super viewDidLoad]; 16 17 18 } 19 20 /** 21 * 当前页面即将显示时被调用(多次被调用) 22 */ 23 - (void)viewWillAppear:(BOOL)animated{ 24 AppDelegate * app = [UIApplication sharedApplication].delegate; 25 /** 26 * 创建数据抓取请求 27 */ 28 NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"AddressBook"]; 29 /** 30 * 创建排序规则 31 */ 32 NSSortDescriptor * sort = [NSSortDescriptor sortDescriptorWithKey:@"firstN" ascending:YES]; 33 NSSortDescriptor * sort1 = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]; 34 /** 35 * 为数据请求添加排序规则 36 */ 37 request.sortDescriptors = @[sort,sort1]; 38 /** 39 * 参数1:数据请求 40 参数2:托管上下文 41 参数3:section分区名称 42 参数4:缓存数据 43 44 */ 45 self.fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:app.managedObjectContext sectionNameKeyPath:@"firstN" cacheName:nil]; 46 /** 47 * fetchedResultsController只不过是一个控制器而已,他没有能力去coredata里面拿取数据.tableview还找fetchedResultsController找数据.这个时候就要用到fetchedResultsControllerDlegaet 48 */ 49 self.fetchedResultsController.delegate = self; 50 /** 51 * 执行抓取 52 */ 53 [self.fetchedResultsController performFetch:nil]; 54 55 } 56 57 #pragma mark - Table view data source 58 59 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 60 NSArray * sections = [self.fetchedResultsController sections]; 61 return sections.count; 62 } 63 64 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 65 NSArray * sections = [self.fetchedResultsController sections]; 66 id<NSFetchedResultsSectionInfo>sectionInfo = sections[section]; 67 return [sectionInfo numberOfObjects]; 68 } 69 70 71 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 72 static NSString * identifier = @"cell"; 73 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; 74 if (!cell) { 75 cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier]; 76 } 77 AddressBook * model = [self.fetchedResultsController objectAtIndexPath:indexPath]; 78 cell.imageView.image = [[UIImage alloc]initWithData:model.image]; 79 cell.textLabel.text = model.name; 80 cell.detailTextLabel.text = model.phone; 81 return cell; 82 } 83 84 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ 85 NSArray * sections = [self.fetchedResultsController sections]; 86 id <NSFetchedResultsSectionInfo> sectionInfo = sections[section]; 87 if ([[sectionInfo name] isEqualToString:@"a"]) { 88 return @"#"; 89 }else{ 90 return [sectionInfo name]; 91 } 92 } 93 94 - (NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView{ 95 NSArray * sections = [self.fetchedResultsController sections]; 96 NSMutableArray * arr = [NSMutableArray array]; 97 BOOL b = false; 98 for (id<NSFetchedResultsSectionInfo> sectionInfo in sections) { 99 if ([[sectionInfo name]isEqualToString:@"a"]) { 100 b = YES; 101 } 102 [arr addObject:[sectionInfo name]]; 103 } 104 if (b) { 105 [arr addObject:@"#"]; 106 } 107 return arr; 108 } 109 110 - (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{ 111 return @"删除"; 112 } 113 114 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{ 115 AddressBook * model = [self.fetchedResultsController objectAtIndexPath:indexPath]; 116 AppDelegate * app = [UIApplication sharedApplication].delegate; 117 [app.managedObjectContext deleteObject:model]; 118 [app.managedObjectContext save:nil]; 119 } 120 121 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 122 AddressBook * model = [self.fetchedResultsController objectAtIndexPath:indexPath]; 123 UIStoryboard * story = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; 124 UIViewController * vc = [story instantiateViewControllerWithIdentifier:@"123"]; 125 [vc setValue:model forKey:@"model"]; 126 [self.navigationController pushViewController:vc animated:YES]; 127 } 128 129 130 131 #pragma mark - 以下代码直接Ctr + C 132 133 //当CoreData的数据将要发生改变时,FRC产生的回调 134 - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 135 [self.tableView beginUpdates]; 136 } 137 138 //分区改变状况 139 - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo 140 atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { 141 142 switch(type) { 143 case NSFetchedResultsChangeInsert: 144 [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] 145 withRowAnimation:UITableViewRowAnimationFade]; 146 break; 147 148 case NSFetchedResultsChangeDelete: 149 [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] 150 withRowAnimation:UITableViewRowAnimationFade]; 151 break; 152 default: 153 break; 154 155 156 } 157 } 158 159 //数据改变状况,这里如果从官方文档中复制过来的,要求改一个地方 160 - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject 161 atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type 162 newIndexPath:(NSIndexPath *)newIndexPath { 163 164 UITableView *tableView = self.tableView; 165 166 switch(type) { 167 168 case NSFetchedResultsChangeInsert: 169 //让tableView在newIndexPath位置插入一个cell 170 [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 171 withRowAnimation:UITableViewRowAnimationFade]; 172 break; 173 174 case NSFetchedResultsChangeDelete: 175 [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 176 withRowAnimation:UITableViewRowAnimationFade]; 177 break; 178 179 case NSFetchedResultsChangeUpdate: 180 //让tableView刷新indexPath位置上的cell 181 [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 182 // [self.searchDisplayController.searchResultsTableView reloadData]; 183 // [self.searchDisplayController.searchResultsTableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 184 break; 185 186 case NSFetchedResultsChangeMove: 187 [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 188 withRowAnimation:UITableViewRowAnimationFade]; 189 [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 190 withRowAnimation:UITableViewRowAnimationFade]; 191 break; 192 } 193 } 194 195 //整个数据完成了,结束更新 196 - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 197 [self.tableView endUpdates]; 198 // [self.searchDisplayController.searchResultsTableView endUpdates]; 199 } 200 @end
编辑页面:
1 #import "ViewController.h" 2 #import "AddressBook.h" 3 #import "AppDelegate.h" 4 #import "Pinyin.h" 5 6 static NSInteger sum; 7 8 @interface ViewController () <UIImagePickerControllerDelegate,UINavigationControllerDelegate,UITextFieldDelegate> 9 @property (strong, nonatomic) IBOutlet UIBarButtonItem *saveBtn; 10 @property (strong, nonatomic) IBOutlet UIButton *imageBtn; 11 @property (strong, nonatomic) IBOutlet UITextField *textName; 12 @property (strong, nonatomic) IBOutlet UITextField *textPhone; 13 @property (strong, nonatomic) NSData * imageData; 14 @property (strong, nonatomic) AddressBook * model; 15 @property (nonatomic,strong) UIImagePickerController * imagePickerController; 16 17 @end 18 19 @implementation ViewController 20 21 - (void)viewDidLoad { 22 [super viewDidLoad]; 23 24 /** 25 * 判断是否有数据从表视图页面传过来:如果有则说明是通过点击Cell跳转过来的,目的是修改数据 26 1.将传过来的数据显示到当前视图上 27 2.设置保存按钮title为“修改” 28 */ 29 if (self.model) { 30 [self showMessageWithModel:self.model]; 31 self.saveBtn.title = @"修改"; 32 } 33 /** 34 * 将添加图片按钮切割为圆形 35 */ 36 [self circleView:self.imageBtn withRadius:60]; 37 /** 38 * 图片选择控制器相关设置 39 */ 40 self.imagePickerController = [[UIImagePickerController alloc]init]; 41 self.imagePickerController.allowsEditing = YES; 42 self.imagePickerController.delegate = self; 43 44 self.textName.delegate = self; 45 self.textPhone.delegate = self; 46 47 self.textName.clearButtonMode = UITextFieldViewModeWhileEditing; 48 self.textPhone.clearButtonMode = UITextFieldViewModeWhileEditing; 49 self.saveBtn.enabled = NO; 50 } 51 52 #pragma mark - 保存或修改方法 53 - (IBAction)saveOrEdit:(UIBarButtonItem *)sender { 54 if (self.textName.text.length||self.textPhone.text.length) { 55 AppDelegate * app = [UIApplication sharedApplication].delegate; 56 /** 57 * 判断当前页面是添加信息,还是修改信息 58 */ 59 if ([self.saveBtn.title isEqualToString:@"保存"]) { 60 AddressBook * ab = [NSEntityDescription insertNewObjectForEntityForName:@"AddressBook" inManagedObjectContext:app.managedObjectContext]; 61 [self setValuesForModel:ab]; 62 }else{ 63 [self setValuesForModel:self.model]; 64 } 65 /** 66 * 托管上下文保存数据 67 */ 68 [app.managedObjectContext save:nil]; 69 } 70 71 /** 72 * 当前控制器出栈(跳出当前页面) 73 */ 74 [self.navigationController popViewControllerAnimated:YES]; 75 } 76 77 #pragma mark - 添加头像方法 78 - (IBAction)addImage:(UIButton *)sender { 79 UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"请选择" message:nil preferredStyle:0]; 80 81 UIAlertAction *actionA = [UIAlertAction actionWithTitle:@"相机" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 82 /** 83 * 判断硬件是否支持照相功能 84 */ 85 if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { 86 UIAlertView * aler = [[UIAlertView alloc]initWithTitle:@"警告" message:@"未发现该硬件或硬件已损坏!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"我知道了", nil]; 87 [aler show]; 88 }else{ 89 /** 90 * 设置图片选择控制器样式为:照相机--并跳转到图片选择控制页面 91 */ 92 self.imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera; 93 [self presentViewController:self.imagePickerController animated:YES completion:nil]; 94 } 95 96 }]; 97 98 UIAlertAction *actionB = [UIAlertAction actionWithTitle:@"照片库" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { 99 /** 100 * 设置图片选择控制器样式为:照相机--并跳转到图片选择控制页面 101 */ 102 self.imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; 103 [self presentViewController:self.imagePickerController animated:YES completion:nil]; 104 }]; 105 106 UIAlertAction *actionC = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; 107 108 [alert addAction:actionA]; 109 [alert addAction:actionB]; 110 [alert addAction:actionC]; 111 112 [self presentViewController:alert animated:YES completion:nil]; 113 114 } 115 116 #pragma mark - 图片选择控制器代理方法 117 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{ 118 /** 119 * 获取选择好的图片 120 */ 121 UIImage * image = info[UIImagePickerControllerEditedImage]; 122 self.imageData = UIImagePNGRepresentation(image); 123 if (self.imageData) { 124 self.saveBtn.enabled = YES; 125 } 126 [self.imageBtn setImage:image forState:UIControlStateNormal]; 127 [self dismissViewControllerAnimated:YES completion:nil]; 128 } 129 130 /** 131 * 将传输过来的数据显示在当前页面--方法 132 */ 133 - (void)showMessageWithModel:(AddressBook *)model{ 134 self.imageData = model.image; 135 [self.imageBtn setImage:[[UIImage alloc]initWithData:model.image] forState:UIControlStateNormal]; 136 self.textName.text = model.name; 137 self.textPhone.text = model.phone; 138 } 139 140 /** 141 * 为数据类设值--方法 142 */ 143 - (void)setValuesForModel:(AddressBook *)model{ 144 char c = 97; 145 if(self.textName.text.length&&self.textPhone.text.length){ 146 c = pinyinFirstLetter([self.textName.text characterAtIndex:0]); 147 if (c >= 97&&c <= 123) { 148 c -= 32; 149 }else if(c >= 65&&c <= 91){ 150 151 }else{ 152 c = 97; 153 } 154 } 155 model.firstN = [NSString stringWithFormat:@"%c",c]; 156 model.image = self.imageData; 157 model.name = self.textName.text; 158 model.phone = self.textPhone.text; 159 } 160 161 /** 162 * 将视图切割为圆--方法 163 */ 164 - (void)circleView:(UIView *)view withRadius:(CGFloat)radius{ 165 view.layer.cornerRadius = radius; 166 view.layer.masksToBounds = radius; 167 } 168 169 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ 170 if (string.length) { 171 sum--; 172 }else{ 173 sum++; 174 } 175 if (sum) { 176 self.saveBtn.enabled = YES; 177 }else{ 178 self.saveBtn.enabled = NO; 179 } 180 return YES; 181 } 182 183 - (BOOL)textFieldShouldClear:(UITextField *)textField{ 184 if ([textField isEqual:self.textName]) { 185 if (!self.textPhone.text.length) { 186 self.saveBtn.enabled = NO; 187 } 188 }else{ 189 if (!self.textName.text.length) { 190 self.saveBtn.enabled = NO; 191 } 192 } 193 return YES; 194 }
浙公网安备 33010602011771号