Core Data
在前面的範例中並沒有使用到Relationship
,如果你的資料結構是需要使用到兩個資料表時,這時可以透過Relationship
,而且操作起來…我覺得方便很多!假如有表1跟表2是有相關連了,以往我在操作MySQL的時候,會先取得表1的Key值,在拿表1的Key值到表2查詢,這樣等於我要做兩次的SQL查詢(可能有更好的作法吧,我沒有特別去研究…),所以當我用Core Data
的時候,覺得這是一個很方便又快速的作法。
接下來我們建立的資料表如下圖。
UserInfo
只用來記錄名字,UserDetail
則用來記錄該名字的電話、地址、E-mail,而下面Relationship
分別為detail
跟info
。
Step 1.編輯xcdatamodeled
檔案。
Entity
、Attribute
、Relationship
的新增就跳過了;這邊需注意的是Relationship
設定,除了Destination
還須設定Inverse
,如下圖。
Step 2.新增Model
檔案。
點選UserInfo
,在對著專案右鍵
/New File
/iOS
/Core Data
/NSManagedObject subclass
/Next
,接著自動就會產生UserInfo.h與.m的檔案;UserDetail
一樣的操作,完成後應該會有四個檔案,分別為UserInfo與UserDetail的.h與.m檔案。
Step 3.編輯MainStoryboard.storyboard
檔案。
完成如下圖,新增的時候要輸入姓名、email、電話、地址;顯示則是顯示這四個值。
Step 4.修改MasterViewController.m
。
記得要把viewDidLoad
方法內的執行內容清除,僅需保留[super viewDidLoad];
。
找到下列三段程式碼,分別修改成對應的Entity
名稱與Key
值。
MasterViewController.m1 2 3 4 5 6 7 8
| NSEntityDescription *entity = [NSEntityDescription entityForName:@"UserInfo" inManagedObjectContext:self.managedObjectContext];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
cell.textLabel.text = [[object valueForKey:@"name"] description];
|
Step 5.新增AddViewController
檔案。
新增一個UIViewController
的檔案,class名稱為AddViewController
。
指定該檔案為新增資料頁面的Class
。
Step 6.編輯AddViewController.h
。
編輯程式如下
AddViewController.h1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #import <UIKit/UIKit.h> #import "AppDelegate.h" #import "UserInfo.h" #import "UserDetail.h"
@interface AddViewController : UIViewController @property (strong, nonatomic) IBOutlet UITextField *name; @property (strong, nonatomic) IBOutlet UITextField *phone; @property (strong, nonatomic) IBOutlet UITextField *email; @property (strong, nonatomic) IBOutlet UITextField *address; - (IBAction)save:(id)sender;
@property (strong, nonatomic) AppDelegate *app; @end
|
分別定義四個UITextField
的property
,一個IBAtcion
的save:方法;AppDelegate
如同之前說的是要使用AppDelegate
內的managedObjectContext
。
Step 7.編輯AddViewController.m。
編輯程式如下
AddViewController.m1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @synthesize name, email, phone, address, app;
- (IBAction)save:(id)sender { app = [[UIApplication sharedApplication] delegate]; NSManagedObjectContext *context = [app managedObjectContext];
UserInfo *info = [NSEntityDescription insertNewObjectForEntityForName:@"UserInfo" inManagedObjectContext:context]; info.name = name.text;
UserDetail *detail = [NSEntityDescription insertNewObjectForEntityForName:@"UserDetail" inManagedObjectContext:context]; detail.address = address.text; detail.email = email.text; detail.phone = phone.text; info.detail = detail;
NSError *error; if (![context save:&error]) { NSLog(@"Save Error : %@", [error localizedDescription]); } else { [self.navigationController popViewControllerAnimated:YES]; } }
|
補上synthesize
!。這邊可以看到定義一個UserInfo
與UserDetail
的類別變數,分別將TextField的值指定給個別對應的Attribute
,這邊可以注意到的是第14行,是透過這樣方式指定兩個表格的對應關連!
Step 8.修改MasterViewController.m
。
找到prepareForSegue
方法,修改的程式如下
MasterViewController.m1 2 3 4 5 6 7 8 9 10
| - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"showDetail"]) { NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; UserInfo *object = [[self fetchedResultsController] objectAtIndexPath:indexPath]; [[segue destinationViewController] setDetailItem:object]; } }
|
Step 9.修改DetailViewController.h
。
編輯程式碼如下
DetailViewController.h1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #import <UIKit/UIKit.h> #import "UserInfo.h"
@interface DetailViewController : UIViewController
@property (strong, nonatomic) UserInfo *detailItem;
@property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel;
@property (strong, nonatomic) IBOutlet UILabel *detailEmail; @property (strong, nonatomic) IBOutlet UILabel *detailPhone; @property (strong, nonatomic) IBOutlet UILabel *detailAddress;
@end
|
Step 10.修改DetailViewController.m
。
找到configureView
方法,修改程式碼如下
DetailViewController.m1 2 3 4 5 6 7 8 9 10 11
| - (void)configureView {
if (self.detailItem) { self.detailDescriptionLabel.text = [[self.detailItem valueForKey:@"name"] description]; self.detailEmail.text = self.detailItem.detail.email; self.detailPhone.text = self.detailItem.detail.phone; self.detailAddress.text = self.detailItem.detail.address; } }
|
如果上述的程式碼有問題的話,不妨檢查一下UserInfo.h
的檔案,這邊我發現到自動產生的檔案,他產生的形態並沒有如預期的型態,detail
的形態應該是UserDeatail
,程式碼如下
UserInfo.h1 2 3 4 5 6 7 8 9 10
| #import <Foundation/Foundation.h> #import <CoreData/CoreData.h> #import "UserDetail.h"
@interface UserInfo : NSManagedObject
@property (nonatomic, retain) NSString * name; @property (nonatomic, retain) UserDetail *detail;
@end
|
Step 11.編譯專案。
最後編譯專案時,記得檢查一下IBOutlet的關聯是否都建立了,如果沒問題,就可以開始新增資料與檢視資料了。