关于IOS获取本地通讯录信息(包含iOS9.0前后)
来源:互联网 发布:地球污染数据 编辑:程序博客网 时间:2024/06/11 19:41
在ios开发当中,获取用户本地的通讯录功能愈加频繁的出现,七两自己也在自己公司的项目当中遇到的获取本地的通讯录信息的功能(俗称“种子用户功能”,太可怕了)。对此七两总结了自己使用本地通讯录时的注意点,希望对大家有所帮助。
首先对于获取本地通讯录的信息,大苹果在ios9.0之后推出了另外的一个使用方式(controller),类似于之前searchcontroller与searchBar,对此七两在此分成两部分,ios9.0前与ios9.0后两部分进行总结。
一、iOS9.0前
先附上七两自己写得代码:
对于苹果对于通讯录的操作实现可以类比sqlite与sqlite3的管理实现方式,及我们在使用通讯录时需调用类似于sqlite3的管理对象,对此七两自己习惯将对通讯录的操作过程写成单例,具体如下:
.h文件
- #import <Foundation/Foundation.h>
- #import <AddressBook/AddressBook.h>
- #import <UIKit/UIKit.h>
-
- typedef void(^YFAddressBookBlock)(BOOL canRead, ABAuthorizationStatus authorStatus);
-
- @interface YFAddressBookManger : NSObject
-
- @property (nonatomic, assign) ABAddressBookRef addressBook;
-
- + (instancetype)shareManger;
-
-
- - (void)canReadAddressBookWithBlock:(YFAddressBookBlock)block;
-
- - (void)gotoSetting:(UIViewController *)vc;
-
- @end
.m文件
- #import "YFAddressBookManger.h"
-
- @implementation YFAddressBookManger
-
- + (instancetype)shareManger{
- static YFAddressBookManger *manger = nil;
-
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- if (!manger) {
- manger = [[YFAddressBookManger alloc]init];
- }
- });
- return manger;
- }
-
- - (id)init{
- self = [super init];
- if (self) {
- _addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
- }
-
- return self;
- }
-
-
- - (void)canReadAddressBookWithBlock:(YFAddressBookBlock)block{
- ABAuthorizationStatus authStatus = ABAddressBookGetAuthorizationStatus();
- if (authStatus == kABAuthorizationStatusNotDetermined) {
- ABAddressBookRequestAccessWithCompletion(_addressBook, ^(bool granted, CFErrorRef error) {
- dispatch_async(dispatch_get_main_queue(), ^{
- if (error) {
-
- block(NO,kABAuthorizationStatusDenied);
- }else{
- block(YES,0);
- }
- });
- });
- }else if (authStatus == kABAuthorizationStatusAuthorized){
- block(YES,0);
- }else{
- block(NO,authStatus);
- }
- }
-
-
- - (void)gotoSetting:(UIViewController *)vc{
- NSString *appName = [[NSBundle mainBundle].infoDictionary valueForKey:@"CFBundleDisplayName"];
- if (!appName) appName = [[NSBundle mainBundle].infoDictionary valueForKey:@"CFBundleName"];
- NSString *message = [NSString stringWithFormat:@"请在%@的\"设置-隐私-通讯录\"选项中,\r允许%@访问你的通讯录。",[UIDevice currentDevice].model,appName];
-
- UIAlertController *alertVC = [[UIAlertController alloc]init];
- [UIAlertController alertControllerWithTitle:@"提示" message:message preferredStyle:UIAlertControllerStyleAlert];
- UIAlertAction *sureAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
- }];
- UIAlertAction *cancleAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
-
- }];
- [alertVC addAction:cancleAction];
- [alertVC addAction:sureAction];
- }
- @end
后续引用通讯录中得数据至controller中的使用方式如下:
- #pragma mark - 获取本地的通讯录数据
- - (void)getDataSource{
- if (_dataSource == nil) {
- _dataSource = [NSMutableArray new];
- }
- [[YFAddressBookManger shareManger]canReadAddressBookWithBlock:^(BOOL canRead, ABAuthorizationStatus authorStatus) {
- if (canRead) {
- ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
- CFArrayRef allLinkPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
- CFIndex num = ABAddressBookGetPersonCount(addressBook);
- for (NSInteger i = 0; i < num; i++) {
- ABRecordRef people = CFArrayGetValueAtIndex(allLinkPeople, i);
- ABMultiValueRef phones = ABRecordCopyValue(people, kABPersonPhoneProperty);
-
- for (int k = 0; k<ABMultiValueGetCount(phones); k++)
- {
-
- NSString * personPhone = (__bridge NSString*)ABMultiValueCopyValueAtIndex(phones, k);
-
- NSString *newP = [personPhone stringByReplacingOccurrencesOfString:@" " withString:@""];
- newP = [newP stringByReplacingOccurrencesOfString:@"-" withString:@""];
-
-
- if ([newP containsString:@"+86"]) {
- newP = [newP stringByReplacingOccurrencesOfString:@"+86" withString:@""];
- }
-
- if ([newP containsString:@"+"]) {
- newP = [newP stringByReplacingOccurrencesOfString:@"+" withString:@""];
- }
- if (![_dataSource containsObject:newP]) {
- [_dataSource addObject:newP];
- }
- }
-
- }
-
- }else{
- [[YFAddressBookManger shareManger] gotoSetting:self];
- }
- }];
- }
如果需要其余的多余的单值属性需不同的字段,代码中的ABRecordCopyValue方法可以理解为C语言中得字典。即可根据不同的单值属性获取。
二、iOS9.0之后
苹果推荐ContactsUI使用,具体的使用方式如下:
- pragma mark - <CNContactPickerViewController代理方法>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- (void)contactPicker:(CNContactPickerViewController )picker didSelectContactProperty:(CNContactProperty )contactProperty{}
具体的细节使用如下:
-
- CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
-
- if (status != CNAuthorizationStatusAuthorized) return;
-
-
-
- CNContactStore *store = [[CNContactStore alloc] init];
-
-
-
- NSArray *fetchKeys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
- CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:fetchKeys];
-
-
- NSError *error = nil;
- [store enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOLBOOL * _Nonnull stop) {
-
-
- NSString *firstname = contact.givenName;
- NSString *lastname = contact.familyName;
- NSLog(@"%@ %@", firstname, lastname);
-
-
- NSArray *phones = contact.phoneNumbers;
-
-
- for (CNLabeledValue *labelValue in phones) {
- CNPhoneNumber *phoneNumber = labelValue.value;
- NSLog(@"%@ %@", phoneNumber.stringValue, labelValue.label);
- }
- }];