适用于iOS9.0以后的通讯录开发

需求中不少会出现选择联系人信息的情况,有些需要自定义UI,有些不需要。直接调用系统的不需要授权,自定义UI只获取数据的需要用户授权。

#import   //有UI效果
#import   //无UI效果,只拿到数据,UI可以自定义
  //遵循协议
import Contacts
import ContactsUI
CNContactPickerDelegate
ContactsUI (有UI效果,无需自定义)
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    CNContactPickerViewController *cncpVC = [[CNContactPickerViewController alloc]init];
    cncpVC.delegate = self;
    [self presentViewController:cncpVC animated:YES completion:nil];
}
override func touchesBegan(_ touches: Set, with event: UIEvent?) {
        let cpvc = CNContactPickerViewController()
        cpvc.delegate = self
        self.present(cpvc, animated: true, completion: nil)
    }

代理方法根据需求二选一实现

#pragma mark - CNContactPickerDelegate
/**
 选择单个联系人

 @param picker 通讯录列表
 @param contact 联系人对象
 */
-(void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact
{
    NSLog(@"%@ %@",contact.givenName,contact.familyName);
    
    for (CNLabeledValue *labelValue in contact.phoneNumbers) {
        //contact.phoneNumbers联系人下的所有电话号码
        NSString *phoneLabel = labelValue.label;
        CNPhoneNumber *phoneNumer = labelValue.value;
        NSString *phoneValue = phoneNumer.stringValue;
        
        NSLog(@"%@ %@", phoneLabel, phoneValue);
    }
}

/**
 选中某一联系人的某一属性

 @param picker 通讯录列表
 @param contactProperty 联系人属性
 */
-(void)contactPicker:(CNContactPickerViewController *)picker didSelectContactProperty:(CNContactProperty *)contactProperty
{
    NSLog(@"contact == %@\nkey == %@\nvalue == %@\nidentifier == %@\nlabel == %@",contactProperty.contact,contactProperty.key,contactProperty.value,contactProperty.identifier,contactProperty.label);
    if ([contactProperty.key isEqualToString:@"phoneNumbers"]) {
        for (CNLabeledValue *labelValue in contactProperty.contact.phoneNumbers) {
            if ([labelValue.identifier isEqualToString:contactProperty.identifier]) {
                CNPhoneNumber *phoneNumber = labelValue.value;
                NSString *phoneStr = phoneNumber.stringValue;
                NSLog(@"%@",phoneStr);
                break;
            }
        }
    }
}

/**
 点击取消

 @param picker 通讯录列表
 */
-(void)contactPickerDidCancel:(CNContactPickerViewController *)picker
{
    NSLog(@"click cancel");
}
func contactPicker(_ picker: CNContactPickerViewController, didSelect contactProperty: CNContactProperty) {
        print(contactProperty.contact.familyName + contactProperty.contact.givenName)
        if contactProperty.key == "phoneNumbers" {
            for labelVale in contactProperty.contact.phoneNumbers {
                if contactProperty.identifier == labelVale.identifier {
                    let phoneStr = labelVale.value.stringValue
                    print(phoneStr)
                }
            }
        }
    }

点选属性时打印结果

contact == !$_, value=>",
    "!$_, value=>"
), emailAddresses=(
    "!$_, [[email protected]](mailto:[email protected])>"
), postalAddresses=(
    "!$_, value=>",
    "!$_, value=>"
)>
key == phoneNumbers
value == 
identifier == 7D2CD244-2CB3-4778-AC37-967B5837BC84
label == _$!!$_
适用于iOS9.0以后的通讯录开发_第1张图片
屏幕快照 2017-08-22 下午5.22.55.png
Contacts(无UI效果,需自定义)
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    [self initData];
    [self createCustomUI];
}

-(void)initData
{
    self.dataArray = [[NSMutableArray alloc]init];
    [self registAuthorize];
}

-(void)createCustomUI
{
    self.tableView = [[UITableView alloc]initWithFrame:self.view.bounds];
    self.tableView.delegate = self;
    self.tableView.dataSource = self;
    [self.view addSubview:_tableView];
}

#pragma mark - 请求授权
-(void)registAuthorize
{
    CNAuthorizationStatus authorizationStatus = [CNContactStore authorizationStatusForEntityType:CNEntityTypeContacts];
    
    if (authorizationStatus == CNAuthorizationStatusNotDetermined) {
        //用户还没有决定是否授权
        CNContactStore *contactStore = [[CNContactStore alloc] init];
        [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                NSLog(@"授权成功!");
                [self createCustomContact];
            } else {
                NSLog(@"授权失败, error=%@", error);
            }
        }];
    }else if (authorizationStatus == CNAuthorizationStatusAuthorized){
        //用户明确同意
        [self createCustomContact];
    }else{
        //用户明确拒绝或者程序中阻止了通讯录,可跳转通讯录手动打开
    }
}

#pragma mark - 获取数据
-(void)createCustomContact
{
    CNContactStore *contactStore = [[CNContactStore alloc]init];
    NSArray *keys = @[CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey];
    CNContactFetchRequest *request = [[CNContactFetchRequest alloc]initWithKeysToFetch:keys];
    __block int index = 1;
    [contactStore enumerateContactsWithFetchRequest:request error:nil usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) {
        
        [self.dataArray addObject:contact];
        
        NSLog(@"%@ %@",contact.givenName,contact.familyName);
        
        for (CNLabeledValue *labelValue in contact.phoneNumbers) {
            
            NSString *phoneLabel = labelValue.label;
            CNPhoneNumber *phoneNumer = labelValue.value;
            NSString *phoneValue = phoneNumer.stringValue;
            
            NSLog(@"%@ %@", phoneLabel, phoneValue);
        }
        
        NSLog(@"---------------------------------%d",index);
        index += 1;
        
        //回到主线程刷新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            [_tableView reloadData];
        });
        
    }];
}

#pragma tableViewDelegate
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _dataArray.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];
    if (!cell) {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"cellID"];
    }
    if (_dataArray.count > 0) {
        CNContact *contact = _dataArray[indexPath.row];
        cell.textLabel.text = [NSString stringWithFormat:@"%@%@",contact.familyName,contact.givenName];
        CNLabeledValue *labelValue = [contact.phoneNumbers firstObject];
        CNPhoneNumber *phoneNum = labelValue.value;
        cell.detailTextLabel.text = [NSString stringWithFormat:@"%@",phoneNum.stringValue];
    }
    return cell;
}
override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        initData()
        createLayout()
    }

    func initData() -> Void {
        registAuthorize()
    }
    
    func registAuthorize() -> Void {
        let authorizeState = CNContactStore.authorizationStatus(for: .contacts)
        if authorizeState == .notDetermined {
            //用户还未决定授权
            let contactStore = CNContactStore.init()
            contactStore.requestAccess(for: .contacts, completionHandler: { (granted: Bool, error: Error?) in
                if granted {
                    print("授权成功")
                    self.createCustomContactData()
                }else{
                    print("授权失败")
                }
            })
            
        }else if authorizeState == .authorized {
            //用户确认授权
            createCustomContactData()
        }else{
            //用户拒绝或者有程序阻止了通讯录调起
        }
    }
    
    func createCustomContactData() -> Void {
        let contactStore = CNContactStore.init()
        let keys = [CNContactFamilyNameKey, CNContactGivenNameKey, CNContactPhoneNumbersKey]
        let request = CNContactFetchRequest.init(keysToFetch: keys as [CNKeyDescriptor])
        do {
            try contactStore.enumerateContacts(with: request, usingBlock: {(contact : CNContact, stop : UnsafeMutablePointer) -> Void in
                
                self.dataArray.append(contact)
                
                //1.获取姓名
                let lastName = contact.familyName
                let firstName = contact.givenName
                print("姓名 : \(lastName)\(firstName)")
                
                //2.获取电话号码
                let phoneNumbers = contact.phoneNumbers
                for phoneNumber in phoneNumbers {
                    print(phoneNumber.label ?? "")
                    print(phoneNumber.value.stringValue)
                }
                
                //3.回到主线程刷新UI
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
                
            })
        } catch  {
            print(error)
        }
        
    }
    
    func createLayout() -> Void {
        tableView = UITableView.init(frame: self.view.bounds)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.tableFooterView = UIView()
        self.view.addSubview(tableView)
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: UITableViewCellStyle.subtitle
            , reuseIdentifier: "contactCell");
        if dataArray.isEmpty == false {
            print(self.dataArray)
            
            let contact = dataArray[indexPath.row]
            let labelValue = (contact as AnyObject).phoneNumbers.first
            cell.textLabel?.text = labelValue?.value.stringValue
            cell.detailTextLabel?.text = (contact as AnyObject).familyName + (contact as AnyObject).givenName
        }
        return cell
    }

打印结果

John Appleseed
_$!!$_ 888-555-5512
_$!!$_ 888-555-1212
---------------------------------1
Kate Bell
_$!!$_ (555) 564-8583
_$!
!$_ (415) 555-3695 ---------------------------------2 Anna Haro _$!!$_ 555-522-8243 ---------------------------------3 Daniel Higgins _$!!$_ 555-478-7672 _$!!$_ (408) 555-5270 _$!!$_ (408) 555-3514 ---------------------------------4 David Taylor _$!!$_ 555-610-6679 ---------------------------------5 Hank Zakroff _$!!$_ (555) 766-4823 _$!!$_ (707) 555-1854 ---------------------------------6
适用于iOS9.0以后的通讯录开发_第2张图片
屏幕快照 2017-08-22 下午5.21.58.png
适用于iOS9.0以后的通讯录开发_第3张图片
屏幕快照 2017-08-22 下午5.22.04.png

你可能感兴趣的:(适用于iOS9.0以后的通讯录开发)