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 }

 

posted on 2016-07-16 14:28  田淳  阅读(1291)  评论(0)    收藏  举报

导航