仅从iPhone获取新的/修改过的手机通讯录

时间:2018-01-19 14:20:08

标签: ios objective-c swift import-contacts

我想首次将所有手机通讯录导入应用并保存在服务器上。

第二次想要将新的,修改过的和已删除的联系人导入到应用程序中并与保存在服务器上的联系人同步,这应该根据创建/修改的联系日期来完成。

从iOS 9开始,Apple不允许使用Contacts Framework获取创建/修改日期

如何以更好的方法实现目标?

3 个答案:

答案 0 :(得分:1)

您应该添加更改联系人列表通知的观察者,如下所示:

    NotificationCenter.default.addObserver(self,selector: #selector(self.addressBookDidChange(_:)), name: NSNotification.Name.CNContactStoreDidChange,object: nil)

然后

@objc func addressBookDidChange(_ notification: Notification){
    print(notification.object as Any, notification.userInfo as Any)
    //remove observer so far to prevent double method calling when making operations with contacts
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.CNContactStoreDidChange, object: nil)

    //processing


    //at some point return observer
    NotificationCenter.default.addObserver(self,selector: #selector(ContactsListVC.addressBookDidChange(_:)), name: NSNotification.Name.CNContactStoreDidChange,object: nil)



}

答案 1 :(得分:0)

您可以在SQLite等本地存储中保存联系人标识符和导入日期。当您收到联系人更新通知时,您可以发送相应更新联系人的保存日期,并在SQLite中更新日期并收到通知时间戳(日期)。

答案 2 :(得分:0)

CNContactStore-enumeratorForChangeHistoryFetchRequest:error:中有一个未公开的API

我尝试使用以下代码测试此方法:

-(void)testChangeHistoryRequest {
    CNContactStore *store = [[CNContactStore alloc] init];
    [self requestContactsPermissions:store completion:^(BOOL granted) {
        if (!granted)
            return;
        NSData *storeToken = [store currentHistoryToken];
        NSLog(@"testChangeHistoryRequest: store token st start - %@", storeToken);
        NSError *error;
        CNChangeHistoryFetchRequest *req = [[CNChangeHistoryFetchRequest alloc] init];
        [req setAdditionalContactKeyDescriptors:@[CNContactGivenNameKey, CNContactFamilyNameKey]];
        [req setMutableObjects:YES];
        [req setShouldUnifyResults:YES];
        [req setStartingToken:storeToken];
        CNFetchResult<NSEnumerator<CNChangeHistoryEvent*>*>* res = [store enumeratorForChangeHistoryFetchRequest:req error:&error];
        if (res && res.value) {
            NSData *token = [res currentHistoryToken];
            NSLog(@"token - %@", token);
            for (CNChangeHistoryEvent *e in res.value)
                NSLog(@"%@ - %@", [e class], e);
            NSLog(@"token at end - %@", token);
        }
    }];
}

我得到的是store.currentHistoryToken永不改变-它以nil值开始和结束。同样在迭代过程中,res.currentHistoryToken始终为nil

我还尝试使用任意数据初始化[req setStartingToken:storeToken];,但这并没有改变(甚至没有失败)。

我的猜测是该枚举没有完全实现。