Contacts框架
剛剛查了一下,iOS 9系統的市場份額大概占到了80%左右,所以如果你能夠說服老板放棄剩下的20%左右的用戶的話(我感覺老板不會被你忽悠),你現在就可以只使用Contacts這個新框架了,否則的話就還是乖乖的用AddressBook吧,或者通過判斷系統版本號來適配不同的手機。
好吧,現在開始進入正題,這個新框架中將要使用最多的應該就是CNContactStore這個類了,官方對其的定義是一個線程安全的,用來執行查詢和修改操作的類。此外官方還針對於這個類的使用給出了幾點小建議。
1.只去查詢那些你需要的聯系人屬性。
2.當查詢所有聯系人並緩存結果時,首先查詢所有聯系人的identifier,然後通過identifier來查詢所需要的詳細的聯系人信息。
3.想取出多個聯系人信息時,可以先收集聯系人的唯一identifier,然後通過identifier來查詢所需要的詳細的聯系人信息。
4.如果緩存了聯系人信息,那麼當接收到CNContactStoreDidChangeNotification時你需要刷新數據。
5.CNContactStore的查詢方法中執行了I/O操作,所以應該避免在主線程中執行。
在項目中,首先我們可以調用授權狀態的查詢方法來確定應用的授權狀態。
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
NotDetermined:這個狀態說明用戶暫未決定是否允許訪問聯系人數據庫。當應用第一次安裝在設備上時將處於此狀態。
Restricted:這個狀態說明應用不僅不能夠訪問聯系人數據,並且用戶也不能在設置中改變這個狀態。這個狀態是某些被激活的限制所導致的(比如說家長控制)。
Denied:這個狀態說明用戶不允許應用訪問聯系人數據。這個狀態只能夠被用戶改變。
Authorized:這個狀態是所有應用都希望擁有的,這表明應用能夠自由訪問聯系人數據庫,然後根據聯系人數據來處理某些任務。
授權狀態一共是上面的四種,我們需要分別對不同的授權狀態來做出相應的操作。首先如果是Authorized的話,那麼一切好說,接下來直接進行相應的通訊錄操作就好了,而如果是NotDetermined的話,就調用一下請求授權的方法(下面會詳細說明),至於剩下的兩個方法,則只能彈窗提示用戶去設置裡面修改權限了。
那麼接下來,我們假設調用上面的方法,得到的結果是NotDetermined,我們就需要調用下面的方法來請求授權,如果用戶不同意,那就彈窗問他,不給我通訊錄授權我怎麼服務你啊(在這點上脈脈做的比較狠:))。
CNContactStore *store = [[CNContactStore alloc] init]; [store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) { }];
如果順利的話,到這裡我們就已經拿到用戶的授權了,那麼接下來就可以讀取用戶數據了。首先,我們需要創建一個
CNContactFetchRequest對象。這裡簡單說一下
predicate和keysToFetch這兩個參數,其中的predicate謂詞參數,必須是由CNContact+Predicates生成的。至於keysToFetch參數,個人理解是由兩部分組成的,其中一部分可以去CNContact.h的最下面查,另一部分可以查詢CNContactFormatter.h。下面是我寫的一小段示例代碼:
CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[[CNContactFormatter descriptorForRequiredKeysForStyle:CNContactFormatterStyleFullName],CNContactPhoneNumbersKey]]; NSError *error = nil; self.array = [NSMutableArray array]; [store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) { [self.array addObject:contact]; }];
如果沒什麼意外情況的話,所需要的通訊錄信息都已經存在這個數組裡面了,需要注意的是這個方法的結果不是一次性返回的,這個可以通過監控stop參數來確定。(此外就是在這裡我有一個疑問,希望理解的同學幫我解釋一下。我在官方文檔中看到一種說法就是其實只要調用查詢方法,系統就會自動去請求授權。所以我對上面提到的那個請求授權的方法的調用時機不是完全的理解)。
那麼最後,當我們獲取到通訊錄信息之後,可能會將數據暫存下來,這樣就涉及到了一個數據刷新的問題,這個問題可以通過添加
CNContactStoreDidChangeNotification監聽來解決,需要注意的是這個監聽的響應次數是和通訊錄中修改信息的條數相匹配的,所以一定要做好相應的處理。
到這裡簡單的獲取通訊錄信息功能應該實現了,最後說一下iOS8之後是可以直接從應用內跳轉到設置頁面來修改通訊錄權限的,所以還是做一下系統適配的好,不然也許用戶嫌麻煩就不去自己改了。
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
最後是作者唠叨時間,感謝大家對我的支持,尤其是上一篇文章大家對我的肯定,還是老樣子,如果大家感覺對你有一定的幫助,就關注加喜歡吧,就當是小小滿足一下我的虛榮心,我們一起進步。
文/Two_Seven(簡書作者)
原文鏈接:http://www.jianshu.com/p/8de5a30cdda4