cod*_*eqi 34 iphone cocoa-touch objective-c abaddressbook ios
我试图了解iOS 6中的方法ABAdressBookCreateWithOptions
和ABAddressBookRequestAccessWithCompletion
方法.
我能够找到的最多信息如下:"要请求访问联系人数据,请在调用该ABAddressBookRequestAccessWithCompletion
函数后调用该ABAddressBookCreateWithOptions
函数."
我相信这些方法应该提醒用户决定是否允许应用程序访问联系人,但是当我使用它们时,我看不到任何提示.
有人可以提供一些示例代码,说明如何在现实世界的例子中一起调用这些方法吗?我如何创建(CFDictionary
)选项?我使用已弃用的ABAddressBookCreate
方法使用代码,但需要更新到iOS 6以适应隐私问题.
在此先感谢任何可以解决问题的人!
Eng*_*epe 83
既然已经取消了NDA,那么我的解决方案就是你需要的地方替换一个返回一个数组的方法.(如果您在用户决定并且准备好重写某些现有代码时不想阻止,请查看下面的David的解决方案):
ABAddressBookRef addressBook = ABAddressBookCreate();
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
accessGranted = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
}
else { // we're on iOS 5 or older
accessGranted = YES;
}
if (accessGranted) {
NSArray *thePeople = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
// Do whatever you need with thePeople...
}
Run Code Online (Sandbox Code Playgroud)
希望这有助于某人......
Nik*_*Nik 23
我在这个问题上看到的大多数答案使用GCD做了疯狂复杂的事情并最终阻止了主线程.这不是必需的!
这是我一直在使用的解决方案(适用于iOS 5和iOS 6):
- (void)fetchContacts:(void (^)(NSArray *contacts))success failure:(void (^)(NSError *error))failure {
if (ABAddressBookRequestAccessWithCompletion) {
// on iOS 6
CFErrorRef err;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &err);
if (err) {
// handle error
CFRelease(err);
return;
}
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
// ABAddressBook doesn't gaurantee execution of this block on main thread, but we want our callbacks to be
dispatch_async(dispatch_get_main_queue(), ^{
if (!granted) {
failure((__bridge NSError *)error);
} else {
readAddressBookContacts(addressBook, success);
}
CFRelease(addressBook);
});
});
} else {
// on iOS < 6
ABAddressBookRef addressBook = ABAddressBookCreate();
readAddressBookContacts(addressBook, success);
CFRelease(addressBook);
}
}
static void readAddressBookContacts(ABAddressBookRef addressBook, void (^completion)(NSArray *contacts)) {
// do stuff with addressBook
NSArray *contacts = @[];
completion(contacts);
}
Run Code Online (Sandbox Code Playgroud)
Dav*_*ter 22
另一个高排名答案有问题:
这是我的MRC对它的看法:
ABAddressBookRef ab = NULL;
// ABAddressBookCreateWithOptions is iOS 6 and up.
if (&ABAddressBookCreateWithOptions) {
NSError *error = nil;
ab = ABAddressBookCreateWithOptions(NULL, (CFErrorRef *)&error);
#if DEBUG
if (error) { NSLog(@"%@", error); }
#endif
if (error) { CFRelease((CFErrorRef *) error); error = nil; }
}
if (ab == NULL) {
ab = ABAddressBookCreate();
}
if (ab) {
// ABAddressBookRequestAccessWithCompletion is iOS 6 and up.
if (&ABAddressBookRequestAccessWithCompletion) {
ABAddressBookRequestAccessWithCompletion(ab,
^(bool granted, CFErrorRef error) {
if (granted) {
// constructInThread: will CFRelease ab.
[NSThread detachNewThreadSelector:@selector(constructInThread:)
toTarget:self
withObject:ab];
} else {
CFRelease(ab);
// Ignore the error
}
// CFErrorRef should be owned by caller, so don't Release it.
});
} else {
// constructInThread: will CFRelease ab.
[NSThread detachNewThreadSelector:@selector(constructInThread:)
toTarget:self
withObject:ab];
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
31243 次 |
最近记录: |