Address Book 聯絡資訊是內建在 iOS 中的一個重要的應用程式,它記錄了所有人員聯絡資訊的相關資料,包含姓名、電話、住址、網站、公司的職稱與部門、生日或是紀念日等等資訊,下面就是要示範如何取得這些已經存在於裝置中的聯絡資訊。
若要取得聯絡資訊中的資料必須透過 iOS SDK 所提供的 AddressBook Framework 來完成,所以首先我們必須先以手動的方式替專案新增 AddressBook.framework,並且引用對應的標頭檔。
手動替專案新增 AddressBook.framework |
#import < AddressBook/Addressbook.h>
對於新增 Framework 有問題的讀者們,請參考 Xcode 4 新增 Framework 的方法一文。
取得聯絡資訊的所有內容
請參考以下程式碼從聯絡資訊中取得聯絡人資料,以每一筆為單位,在成功取得每一筆資料後才去分析其中的聯絡資訊。
//建立與判斷是否成功建立聯絡資訊的資料
ABAddressBookRef myAddressBook = ABAddressBookCreate();
if (myAddressBook) {
//取得聯絡資訊裡的每筆資料並計算總數
CFArrayRef arrayOfEntries = ABAddressBookCopyArrayOfAllPeople(myAddressBook);
CFIndex countOfEntries = CFArrayGetCount(arrayOfEntries);
//取得聯絡資訊中的每筆資料
for (int i=0; i!=countOfEntries; i++) {
ABRecordRef currentRecord = CFArrayGetValueAtIndex(arrayOfEntries, i);
//
//分析currentRecord以取得詳細的聯絡資訊
//
}
NSLog(@"共有 %ld 筆資料", countOfEntries);
CFRelease(arrayOfEntries);
}
CFRelease(myAddressBook);
在成功取得每一筆資料後,下面我們將利用每筆資料中的 ABPropertyID 來取得所需要的資料的內容,完整的 ABPropertyID 使用說明,請參考官方 iOS Developer Library 的 ABPerson Reference。
取得單一類型的資訊
單一類型的資訊,這裡指的是像姓名或是匿稱這類的單一類型的資訊,這類的資訊在同一筆資料中必須是唯一的,電話號碼就不適用在此範圍內(iOS 允許在同一筆資料中輸入不同類型的電話號碼)。
//姓名與綽號
NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(currentRecord, kABPersonLastNameProperty);
NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(currentRecord, kABPersonFirstNameProperty);
NSString *nickName = (__bridge_transfer NSString *)ABRecordCopyValue(currentRecord, kABPersonNicknameProperty);
NSLog(@"姓名:%@ %@", lastName, firstName);
NSLog(@"綽號:%@", nickName);
在上述的程式碼中,我們使用 ABRecordCopyValue 配合 ABPropertyID,來取得每筆資料中我們所感興趣的單一類型資訊。
取得單一類型資訊的結果 |
取得複合類型的資訊
複合類型的資訊,像是電話、電子郵件這類,在同一筆資料中很能存在好幾種相同的種類,例如電話號碼就可以分成行動電話、iPhone 或主要聯絡電話等。
ABMultiValueRef phone = ABRecordCopyValue(currentRecord, kABPersonPhoneProperty);
ABMultiValueRef mail = ABRecordCopyValue(currentRecord, kABPersonEmailProperty);
//電話
for(CFIndex x=0; x!=ABMultiValueGetCount(phone); x++) {
NSString *phoneLabel = (__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(phone, x);
if ([phoneLabel isEqualToString:(__bridge_transfer NSString *)kABPersonPhoneMobileLabel]) {
NSLog(@"行動電話:%@", (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phone, x));
}
if ([phoneLabel isEqualToString:(__bridge_transfer NSString *)kABPersonPhoneIPhoneLabel]) {
NSLog(@"iPhone:%@", (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phone, x));
}
if ([phoneLabel isEqualToString:(__bridge_transfer NSString *)kABPersonPhoneMainLabel]) {
NSLog(@"主要電話:%@", (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phone, x));
}
}
//電子郵件
for(CFIndex x=0; x!=ABMultiValueGetCount(mail); x++) {
NSLog(@"E-Mail:%@", (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(mail, x));
}
在上述的程式碼中,我們使用 ABMultiValueRef 來取得這些複合類型的資訊,並且使用 Index 配合該資料特有的 Label,來取得每筆複合資料中對應的資訊。
取得複合類型資訊的結果 |
取得其他複合類型的資訊
其他複合類型的資訊,比起上述的複合類型還要在複雜一些,像是聯絡人的地址這類的資訊,地址可以被分拆成好幾部分,例如街道、地區、城市或是國家等等,而這些部分又會依照住家、公司或是其他分類有所不同。
ABMultiValueRef address = ABRecordCopyValue(currentRecord, kABPersonAddressProperty);
//住址
for(CFIndex x=0; x!=ABMultiValueGetCount(address); x++) {
//判斷不同類型的住址
NSString* addressLabel = (__bridge_transfer NSString *)ABMultiValueCopyLabelAtIndex(address, x);
BOOL home = [addressLabel isEqualToString:(__bridge_transfer NSString *)kABHomeLabel];
BOOL work = [addressLabel isEqualToString:(__bridge_transfer NSString *)kABWorkLabel];
BOOL other = [addressLabel isEqualToString:(__bridge_transfer NSString *)kABOtherLabel];
//取得住址的每一部分資訊
NSDictionary* personAddress =(__bridge_transfer NSDictionary *)ABMultiValueCopyValueAtIndex(address, x);
NSLog(@"國家名稱:%@", [personAddress valueForKey:(__bridge_transfer NSString *)kABPersonAddressCountryKey]);
NSLog(@"區域編號:%@", [personAddress valueForKey:(__bridge_transfer NSString *)kABPersonAddressZIPKey]);
NSLog(@"城市名稱:%@", [personAddress valueForKey:(__bridge_transfer NSString *)kABPersonAddressCityKey]);
NSLog(@"鄉鎮市區:%@", [personAddress valueForKey:(__bridge_transfer NSString *)kABPersonAddressStateKey]);
NSLog(@"街道名稱:%@", [personAddress valueForKey:(__bridge_transfer NSString *)kABPersonAddressStreetKey]);
NSLog(@"國家代碼:%@", [personAddress valueForKey:(__bridge_transfer NSString *)kABPersonAddressCountryCodeKey]);
}
在上述的程式碼中,我們同樣使用 ABMultiValueRef 來取得這些複合類型的資訊,並且使用 Index 配合該資料特有的 Label,來取得住址的分類,這點和上述的「取得複合類型的資訊」小節一樣,但是在住址中又可以在細分成好幾部分,這時就必須使用 NSDictionary 搭配 Key Value 來取得想要的部份了。(上述程式碼中只有使用 kABHomeLabel、kABWorkLabel 和 kABOtherLabel 來做住家、公司或是其他住址的判斷,但是在傾印時並未限制是何種類型的住址)
取得其他複合類型資訊的結果 |
ps:程式碼中的 __bridge_transfer 為強制轉型。
你好 !
回覆刪除想問 Address book 的Person view controller的內容有辦法修改嗎?
因為本人發現所顯示的英文地址並不合乎標準的英文地址格式。
本人想更改person view controller 中的地址顯示次序,謝謝你。
匿名者 你好:
刪除好像沒有版法修改耶,除非你在做一個出來,自己去調整順序。
如果是地址格式的問題,有可能是裝置語系的問題!
您好
回覆刪除我想請問一下
iPhone中有個電話欄位是“公司”
但是我卻找不到屬於公司的kABperson的label讓我可以取出資料
是本來就這樣嗎?
范凱傑 您好:
刪除的確使用上述的方式他沒有定義可以讓你使用比較 work 的電話,
但是您可以試著在每個迴圈中列印出 phoneLabel 字串,如果公司那一欄是有甜電話資料,那麼你應該會得到一個回傳字串 _$!!$_
你可以將此字串自行定義於 ABperson.h 中,或者直接使用該字串做判斷:
if ([phoneLabel isEqualToString:@"_$!!$_"]) {
NSLog(@"公司電話:%@", (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phone, x));
}
希望這樣有幫到您!
您好,
回覆刪除兩個問題想請教,
(1)可不可以把通訊錄裡面的某一個聯絡人變成"我的最愛“聯絡人。
(2)第一點如果不行,我想要把通訊錄裡面某個聯絡人的kABPersonInstantMessageProperty加一個Label=SIP,
當成“我的最愛”的特殊Label,但是一直無法修改現有聯絡人的資料加上一個Label... 可否提供範例或是教學指導。
我在載入我的最愛清單的時候,
或掃出有該Label的人,並顯示。
if(CFDictionaryContainsKey(lDict, kABPersonInstantMessageServiceKey)) {
CFStringRef serviceKey = CFDictionaryGetValue(lDict, kABPersonInstantMessageServiceKey);
if(CFStringCompare((CFStringRef)@"SIP", serviceKey, kCFCompareCaseInsensitive) == 0) {
add = true;
}
else {
add=false;
}
}
謝囉。
您好:
刪除本篇文章只有提及如何重聯訓運中取得聯絡人的相關資料,關於您的問題像是修改或是增加聯絡人欄位等等,可以參考網路上其他人的寫法,例如:
http://iphonedevsdk.com/forum/iphone-sdk-development/12496-add-contact-to-address-book.html
希望對你有幫助,另外我不確定能不能使用自定欄位來做設定。
版主你好,此教學對我有很大的幫助
回覆刪除最近也在寫有關通訊錄的App
想請教你如何取到值後想用xml或ajax將值存到mysql作為之後的運用,不知你的看法如何?謝謝
您好:
刪除這些問題都比較偏向web端的技術了,不過你可以在devive中就直接使用SQL語法對資料庫寫入資料,
在這之前建議妳可以先把資料從通訊簿中撈出來存放在類似NSDictionary的結構裡,
之後再對此結構操作寫進DB。
如果再實作上一定要透過網頁,那就開一個Web Service API,device用http post的方式把數值打到此API上,由WEB端做寫入DB的動作
版主你好!謝謝你的協助
刪除目前我們Web端已建置好了
這幾天有詳細研究你的建議方式,不過還是遇到一些問題
請問版主不知能否提供這方面的教學?
謝謝
這邊好像沒有提供這類的教學,
刪除如果你是手機端要打post的話可以參考這個
http://wangshifuola.blogspot.tw/2012/01/iospostservernsurlconnection.html
如果你是網頁端要測試自己的api是否準備好可以使用 postman 這套軟體(chrome有網頁版插件可以用)