首先固然是把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,見下圖:
這就是結果,在看看我是在哪兒找到蘋果的官方文檔裏面的那段代碼的出處: