使用单例 封装:
第一步:我们需要获取通讯录权限
在info.plist
文件中,添加 key : Privacy - Contacts Usage Description
,value:“App Name”想访问您的通讯录(用于xxxx时直接获取通讯录中联系人的信息)
,如下图:
![](https://img.haomeiwen.com/i15646807/e63e2fa81bd3cd57.png)
直接使用时:
// 在需要使用到的地方,引入单例:
#import "GW_PhoneContactManager.h"
#pragma mark -- 点击按钮,调用手机通讯录
- (void)clickAddressBookAction {
[[GW_PhoneContactManager shareInstance] presentAddressBookReadFinishWithPhoneNumber:^(NSString * _Nonnull contactNumber) {
// NSLog(@"选取的手机号码为:%@", contactNumber);
dispatch_async(dispatch_get_main_queue(), ^{
NSString *phoneNumber = @"";
if ([contactNumber hasPrefix:@"+86"]) {
phoneNumber = [contactNumber stringByReplacingOccurrencesOfString:@"+86" withString:@""];
} else {
phoneNumber = contactNumber;
}
phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
phoneNumber = [phoneNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
if ([self isVAlidPhoneNumber:phoneNumber]) { // 正则判断是否是手机号
self.textField.text = phoneNumber;
} else {
self.textField.text = phoneNumber;
}
});
}];
}
相关链接:
【iOS获取手机通讯录方式方法(最新)】、
【iOS-封装系统通讯录调用】
// 引入
#import <ContactsUI/ContactsUI.h>
// 遵守代理:
<CNContactPickerDelegate>
直接上代码:
GW_PhoneContactManager.h
@interface GW_PhoneContactManager : NSObject
/** 判断 是否授权访问通讯录:YES 已授权,NO 未授权 */
typedef void(^AddressBookAuthorizationBlock)(BOOL isAuthorization);
//@property (nonatomic, copy) void (^judgeAuthorizationBlock)(BOOL isAuthorization);
/** 获取通讯录 选择的联系人 联系方式(手机号码):contactNumber */
typedef void(^AddressBookPhoneNumberBlock)(NSString *contactNumber);
//@property (nonatomic, copy) void (^gainContactsNumberBlock)(NSString *contactNumber);
@property (nonatomic, copy) AddressBookPhoneNumberBlock phoneNumberBlock;
+ (instancetype)shareInstance;
/** 判断:是否拥有读取通讯录权限 */
- (void)getCheckAddressBookAuthorization:(AddressBookAuthorizationBlock)addressBookAuthorizationBlock;
/** 读取:通讯录(调起通讯录列表页) */
- (void)presentAddressBookReadFinishWithPhoneNumber:(AddressBookPhoneNumberBlock)addressBookPhoneNumberBlock;
// 打开通讯录
//- (void)presentAddressBookCNContactPickerViewControllerWithNumber:(AddressBookPhoneNumberBlock)addressBookPhoneNumberBlock
@end
GW_PhoneContactManager.m
#import "GW_PhoneContactManager.h"
#import <ContactsUI/ContactsUI.h> // I框架:提供了联系人列表界面、联系人详情界面、添加联系人界面等,一般用于选择联系人。
@interface GW_PhoneContactManager () <CNContactPickerDelegate>
@end
@implementation GW_PhoneContactManager
+ (instancetype)shareInstance {
static GW_PhoneContactManager *phoneContactManager;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
phoneContactManager = [[self alloc]init];
});
return phoneContactManager;
}
/** 1、判断:是否拥有读取通讯录权限 */
- (void)getCheckAddressBookAuthorization:(AddressBookAuthorizationBlock)addressBookAuthorizationBlock {
CNAuthorizationStatus status = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
/*! 用户尚未就应用程序是否可以访问联系人数据做出选择。 */
if (status == CNAuthorizationStatusNotDetermined) { // 未授权,待授权
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
// 第一次获取权限判断,点击 “不允许”,则 granted = NO, 点击 “好”,则 granted = YES
if (granted) {
addressBookAuthorizationBlock(granted);
} else {
return; // 第一次访问时,如果点击“不允许”,则不做任何操作。
}
if (error) {
} else {
}
}];
} else if (status == CNAuthorizationStatusRestricted) { //
/*! 该应用程序没有权限访问联系人数据。
*用户无法更改此应用程序的状态,可能是由于主动限制(如父母控制到位)。 */
addressBookAuthorizationBlock(NO);
} else if (status == CNAuthorizationStatusDenied) { // 已拒绝授权
/*! 用户明确拒绝对应用程序的联系人数据的访问。 */
addressBookAuthorizationBlock(NO);
} else if (status == CNAuthorizationStatusAuthorized) { // 已授权
/*! 该应用程序被授权访问联系人数据。 */
addressBookAuthorizationBlock(YES);
}
}
/** 2、读取:通讯录(调起通讯录列表页) */
- (void)presentAddressBookReadFinishWithPhoneNumber:(AddressBookPhoneNumberBlock)addressBookPhoneNumberBlock {
[self getCheckAddressBookAuthorization:^(BOOL isAuthorization) {
if (isAuthorization) {
// 已授权
[[GW_PhoneContactManager shareInstance] presentAddressBookCNContactPickerViewControllerWithNumber:addressBookPhoneNumberBlock];
} else {
// 未授权
[[GW_PhoneContactManager shareInstance] alertMessage];
}
}];
}
// 弹出通讯录
- (void)presentAddressBookCNContactPickerViewControllerWithNumber:(AddressBookPhoneNumberBlock)addressBookPhoneNumberBlock {
[GW_PhoneContactManager shareInstance].phoneNumberBlock = addressBookPhoneNumberBlock;
dispatch_async(dispatch_get_main_queue(), ^{
// CNContactPickerViewController 只能在主线程中使用:
CNContactPickerViewController *pickerVC = [[CNContactPickerViewController alloc] init];
pickerVC.delegate = self;
pickerVC.displayedPropertyKeys = @[CNContactPhoneNumbersKey]; // 只显示手机号
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:pickerVC animated:YES completion:nil];
});
}
#pragma mark -- <CNContactPickerDelegate> 代理方法回调
- (void)contactPickerDidCancel:(CNContactPickerViewController *)picker {
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty {
// 注意:这里和displayedPropertyKeys属性设置相对应;只有 CNPhoneNumber 类型,如果添加别的类型,需要加类型判断,否则可能crash;例如:通讯录中的日期、邮箱...
CNPhoneNumber *phoneNumber = contactProperty.value;
NSString *phoneStr = phoneNumber.stringValue;
//回调block,把号码带回去
if (self.phoneNumberBlock) {
self.phoneNumberBlock(phoneStr);
}
}
// 弹出提示信息
-(void)alertMessage {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"请授权通讯录权限" message:@"请在\"设置-隐私-通讯录\"选项中,允许云间高尔夫访问您的通讯录" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"拒绝" style:UIAlertActionStyleDefault handler:nil];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"允许" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString] options:@{} completionHandler:^(BOOL success) {
}];
}];
[alertVC addAction:cancelAction];
[alertVC addAction:action];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertVC animated:YES completion:nil];
}
@end
网友评论