仅获取来自 iPhone new/modified phone 个联系人
Get only new/modified phone contacts from iPhone
我只想第一次将所有 phone 联系人导入应用程序并保存在服务器上。
第二次只想将新的、修改的和删除的联系人导入应用程序并与保存在服务器上的联系人同步,这应该根据联系人的 created/modified 日期完成。
从 iOS 9 开始,Apple 将不允许使用 Contacts Framework
获取 create/modified 日期
我怎样才能用更好的方法实现?
您应该像这样添加更改联系人列表通知的观察者:
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)
}
您可以在 SQLite 等本地存储中保存联系人标识符和导入日期。当您收到联系人更新通知时,您可以发送相应更新联系人的保存日期,并在 SQLite 中使用收到的通知时间戳(日期)更新日期。
CNContactStore
中有一个未记录的 API - enumeratorForChangeHistoryFetchRequest:error:
我尝试使用以下代码测试此方法:
-(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];
,但这没有任何改变(甚至没有失败)。
我的猜测是这个枚举没有完全实现。
我只想第一次将所有 phone 联系人导入应用程序并保存在服务器上。
第二次只想将新的、修改的和删除的联系人导入应用程序并与保存在服务器上的联系人同步,这应该根据联系人的 created/modified 日期完成。
从 iOS 9 开始,Apple 将不允许使用 Contacts Framework
获取 create/modified 日期我怎样才能用更好的方法实现?
您应该像这样添加更改联系人列表通知的观察者:
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)
}
您可以在 SQLite 等本地存储中保存联系人标识符和导入日期。当您收到联系人更新通知时,您可以发送相应更新联系人的保存日期,并在 SQLite 中使用收到的通知时间戳(日期)更新日期。
CNContactStore
中有一个未记录的 API - enumeratorForChangeHistoryFetchRequest:error:
我尝试使用以下代码测试此方法:
-(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];
,但这没有任何改变(甚至没有失败)。
我的猜测是这个枚举没有完全实现。