IOS開發中使用CNContact\CNMutableContact 對通信錄增刪改查

IOS開發中使用CNContact\CNMutableContact 對通信錄增刪改查

首先固然是把CNcontact包含在工程中:swift

1 @import Contacts;

 

 

一、下面是增長聯繫人的程序段:app

 1 CNMutableContact * contact = [[CNMutableContact alloc]init];
 2     contact.imageData = UIImagePNGRepresentation([UIImage imageNamed:@"22"]);
 3     //設置名字
 4     contact.givenName = @"三強";
 5     //設置姓氏
 6     contact.familyName = @"";
 7     CNLabeledValue *homeEmail = [CNLabeledValue labeledValueWithLabel:CNLabelHome value:@"316045346@qq.com"];
 8     CNLabeledValue *workEmail =[CNLabeledValue labeledValueWithLabel:CNLabelWork value:@"316045346@qq.com"];
 9     contact.emailAddresses = @[homeEmail,workEmail];
10     //家庭
11     CONTACTS_EXTERN NSString * const CNLabelHome                             NS_AVAILABLE(10_11, 9_0);
12     //工做
13     CONTACTS_EXTERN NSString * const CNLabelWork                             NS_AVAILABLE(10_11, 9_0);
14     //其餘
15     CONTACTS_EXTERN NSString * const CNLabelOther                            NS_AVAILABLE(10_11, 9_0);
16     
17     // 郵箱地址
18     CONTACTS_EXTERN NSString * const CNLabelEmailiCloud                      NS_AVAILABLE(10_11, 9_0);
19     
20     // url地址
21     CONTACTS_EXTERN NSString * const CNLabelURLAddressHomePage               NS_AVAILABLE(10_11, 9_0);
22     
23     // 日期
24     CONTACTS_EXTERN NSString * const CNLabelDateAnniversary                  NS_AVAILABLE(10_11, 9_0);
25     contact.phoneNumbers = @[[CNLabeledValue labeledValueWithLabel:CNLabelPhoneNumberiPhone value:[CNPhoneNumber phoneNumberWithStringValue:@"12344312321"]]];
26     CNMutablePostalAddress * homeAdress = [[CNMutablePostalAddress alloc]init];
27     homeAdress.street = @"貝克街";
28     homeAdress.city = @"倫敦";
29     homeAdress.state = @"英國";
30     homeAdress.postalCode = @"221B";
31     contact.postalAddresses = @[[CNLabeledValue labeledValueWithLabel:CNLabelHome value:homeAdress]];
32     NSDateComponents * birthday = [[NSDateComponents  alloc]init];
33     birthday.day=7;
34     birthday.month=5;
35     birthday.year=1992;
36     contact.birthday=birthday;
37     
38     
39     
40     
41     //    //初始化方法
42     CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
43     //    添加聯繫人(能夠)
44     [saveRequest addContact:contact toContainerWithIdentifier:nil];
45     //    寫入
46     CNContactStore * store = [[CNContactStore alloc]init];
47     [store executeSaveRequest:saveRequest error:nil];

 

 

二、下面是刪除聯繫人的程序段,在蘋果的開發文檔中是這麼描述的:post

其中的contact參數是要被刪除的聯繫人,也就覺得這這個也就意味着這個聯繫人以前在通信錄存在,也就是說它不是咱們新建的一個聯繫人對象,而是從通信錄中查出來的一個聯繫人對象,因此咱們先要去查找聯繫人,這樣的話先建立一個謂詞,而後去查找,找到以後再執行刪除,如下是程序段:url

 1 //    CNContactStore * store = [[CNContactStore alloc]init];
 2 //    //檢索條件,檢索全部名字中GivenName是W的聯繫人
 3 //    NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@"W"];
 4 //    //提取數據
 5 //    NSArray * contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];
 6 //    CNMutableContact *contact1 = [contacts objectAtIndex:0];
 7 //    
 8 //    
 9 ////    //初始化方法
10 //    CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
11 //
12 //    //刪除聯繫人(不行)
13 //    [saveRequest deleteContact:contact1];

 

 

三、關於更新聯繫人,在這裏糾結了很久如下是整個過程,但願你們少走彎路:spa

1)、看到蘋果的官方文檔裏,對這個updateContact方法輕描淡寫,我也就沒有注意,想一想只要先把須要的聯繫人讀出來,而後修改屬性,並使用updateContact方法更新就行,而後我編寫了如下程序(有問題的程序,灰色底色標註):3d

 1 CNContactStore * store = [[CNContactStore alloc]init];  2     //檢索條件,檢索全部名字中有zhang的聯繫人
 3     NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@""];  4     //提取數據
 5     NSArray * contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];  6     CNMutableContact *contact1 = [contacts objectAtIndex:0];  7 // 修改聯繫人的屬性
 8     contact1.givenName = @"heh";  9 // 實例化一個CNSaveRequest
10     CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init]; 11     [saveRequest updateContact:contact1];

 

 可是以上程序段運行的時候總會提示錯誤,而且crash掉,錯誤提示是:調試

 -[CNContact setGivenName:]: unrecognized selector sent to instance 0x7fd5ba755660code

而後Add一個Expection Breakpoint,程序老是運行到修改聯繫人屬性這句卡住,見下圖:對象

而後就很糾結啊,上網查找緣由,在QQ羣裏問大神獲得的答案是對象被提早釋放了,而後我也有這個感受,我打斷點調試,發現當運行CNMutableContact *contact1 = [contacts objectAtIndex:0];這句以後,contact1就變成了CNContact類型的對象,再也不是CNMutableContact。而蘋果官方文檔要求要更新或者添加一個聯繫人到通信錄,首先要求這個對象是可變的,也就是隻有CNMutableContact類型的才能修改對象的屬性並更新通信錄,並且要求要更新的聯繫人在通信錄中必須存在。因而我去蘋果的官方手冊裏繼續查找緣由,然而並沒找到如何讀取一個聯繫人並讀成可變類型的聯繫人的方法,我就繼續翻翻,找各類可能性,後來被我看到一段代碼:blog

1 let mutableContact = contact.mutableCopy() as! CNMutableContact
2 let newEmail = CNLabeledValue(label: CNLabelHome, value: "john@example.com")
3 mutableContact.emailAddresses.append(newEmail)
4  
5 let saveRequest = CNSaveRequest()
6 saveRequest.updateContact(mutableContact)
7 try! store.executeSaveRequest(saveRequest)

 

 這段代碼是swift語言寫的,我先注意到第六行是saveRequest.updateContact,也就是說用了更新的語句,那麼它更新的對象是什麼類型呢?看看第一句就明白了,雖然我不懂swift,但看得出大概的意思是深拷貝(mutableCopy)了一個對象,那我也深拷貝一個唄,接下來我寫了如下代碼:

 1     CNContactStore * store = [[CNContactStore alloc]init];
 2     //檢索條件,檢索全部名字中有zhang的聯繫人
 3     NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@""];
 4     //提取數據
 5     NSArray * contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];
 6     CNContact*contact1 = [contacts objectAtIndex:0];
 7     CNMutableContact *contact2 = [contact1 mutableCopy];
 8 //    修改聯繫人的屬性
 9     contact2.givenName = @"asdfasdfas";
10 //    實例化一個CNSaveRequest
11     CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
12     [saveRequest updateContact:contact2];

滿懷但願的運行,發現並無修改個人聯繫人,接下來繼續找問題,修改爲如下代碼:

 1 CNContactStore * store = [[CNContactStore alloc]init];
 2     //檢索條件,檢索全部名字中有zhang的聯繫人
 3     NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@""];
 4     //提取數據
 5     NSArray * contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];
 6     CNMutableContact *contact2 = [[contacts objectAtIndex:0] mutableCopy];
 7 //    修改聯繫人的屬性
 8     contact2.givenName = @"asdfasdfas";
 9 //    實例化一個CNSaveRequest
10     CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
11     [saveRequest updateContact:contact2];

 

 仍是不行,繼續去找蘋果的茬,再讀讀上面發現的那段代碼:

1 let mutableContact = contact.mutableCopy() as! CNMutableContact
2 let newEmail = CNLabeledValue(label: CNLabelHome, value: "john@example.com")
3 mutableContact.emailAddresses.append(newEmail)
4  
5 let saveRequest = CNSaveRequest()
6 saveRequest.updateContact(mutableContact)
7 try! store.executeSaveRequest(saveRequest)

 

發現第七句,我這兒沒有用,想起使用addContact方法新增聯繫人到通信錄的時候最後要用這句,那就加上這句吧:

 1 CNContactStore * store = [[CNContactStore alloc]init];
 2     //檢索條件,檢索全部名字中有zhang的聯繫人
 3     NSPredicate * predicate = [CNContact predicateForContactsMatchingName:@""];
 4     //提取數據
 5     NSArray * contacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:@[CNContactGivenNameKey] error:nil];
 6     CNMutableContact *contact2 = [[contacts objectAtIndex:0] mutableCopy];
 7 //    修改聯繫人的屬性
 8     contact2.givenName = @"asdfasdfas";
 9 //    實例化一個CNSaveRequest
10     CNSaveRequest * saveRequest = [[CNSaveRequest alloc]init];
11     [saveRequest updateContact:contact2];
12     [store executeSaveRequest:saveRequest error:nil];

 

再次運行,並打到模擬器的通信錄,驚喜的發現姓張的聯繫人變成名字變成了asdfasdfas,見下圖:

這就是結果,在看看我是在哪兒找到蘋果的官方文檔裏面的那段代碼的出處:

相關文章
相關標籤/搜索