Cannot see address book contacts in iPhone [duplicate] - ios

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Programmatically Request Access to Contacts in iOS 6
I'm trying to test out some functionality on my iPhone in which I pull all the address book members and display them in a table. This works fine on the simulator, and I see the mock contacts like "John Appleseed". When I run the code on my iPhone, I only see "Mobile User" which apparently is me.
How do I see all my address book contacts?

In iOS 6 the user has to give permission to apps to use the contact information.
There are a lot examples of this if you google for it. You could use something like:
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) {
// Do whatever you want here.
}
Check out this question for more information:
Programmatically Request Access to Contacts

Related

Execution is stopped with AddressBook Code in iOS during First Install of App

I want to retrieve contacts from AddressBook into my App. The code is having problem for first install, next time onwards it is working fine. For the first installation of App, if AddressBook code executes, the App hangs. After execution of dispatch_semaphore_wait line, the App hangs. I restarted the device, this time App works fine. It is happening if it is first install on new device. How can i fix this?
CFErrorRef * error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
__block BOOL isaccess = NO;
if(ABAddressBookRequestAccessWithCompletion != NULL) {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
//ask to grand or deny access
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
isaccess = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release(sema);
}

App not asking for Contact access permission on iOS 6

I am using below Code, My application don't ask permission on iOS 6 while on iOS 7 and above version it ask for Contact permission access. On iOS 6 it doesn't show app in privacy setting as well. I have read some other thread but not found any solutions.
App crashed in iOS 6 when user changes Contacts access permissions
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"6.0")) {
__block CDNDeviceContact *controller = self;
// Request authorization to Address Book
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined) {
ABAddressBookRequestAccessWithCompletion(addressBookRef,
^(bool granted, CFErrorRef error) {
if (granted)
[controller loadContacts];
else [controller doAlertForContact];
});
} else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized) {
// The user has previously given access, add the contact
[self loadContacts];
} else {
[controller doAlertForContact];
}
if (addressBookRef) CFRelease(addressBookRef);
}
If the user has previously been presented with the request to get permission, it will not show again. According to the documentation,
The user is only asked for permission the first time you request access. Later calls use the permission granted by the user.
If testing in the simulator, I recommend that you go to iOS Simulator -> Reset Content and Settings so that you are able to simulate the event.
You don't need SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO and you also don't need to create an ABAddressBookRef.
For me, this is works like a charm:
if (ABAddressBookGetAuthorizationStatus) {
switch (ABAddressBookGetAuthorizationStatus()) {
case kABAuthorizationStatusNotDetermined:{
ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error) {
self.addContactButton.enabled = granted;
if (granted) {
// granted
} else {
// User denied access
}});
} break;
case kABAuthorizationStatusDenied: break;
case kABAuthorizationStatusAuthorized: break;
default: break;
}
}

ABAddressBookRequestAccessWithCompletion iOS 7 and semaphores

this code has been posted before, and been used as well, from what i could gather. i'm in a situation where i need the code to NOT continue until i know if i have access to the contacts.
on Xcode 5.0.2 and iOS 6, this works just fine. on iOS 7, it hangs forever, and then when i kill the app the dialog box comes up asking to allow access to the contacts.
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);
}
else { // we're on iOS 5 or older
accessGranted = YES;
}
in trying to play with this, i then simply set a BOOL to be NO, and then set it to YES within the block. after the block, i put a while loop that checked for the variable being YES, then slept for 1 second. works perfectly fine on 6, on 7 i never reach the NSLog statement in the block, and i'm stuck forever in the while loop printing the log statement.
am i doing something really lame here? or is this method gone haywire on 7?
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (granted)
{
self.myAddressBook = addressBook;
}
done = YES;
NSLog(#"in block, done is %#", done ? #"YES" : #"NO");
didGrant = granted;
//dispatch_semaphore_signal(sema);
});
while (!done)
{
NSLog(#"done is %#", done ? #"YES" : #"NO");
sleep(1);
}
I had the same problem, and I realised that the Dialog box that requests access to the contacts blocks the app anyways, so maybe there's a deadlock. So I just ditched the semaphores and did something like this (tested and works on iOS 7.1.1):
ABAddressBookRef addressBook = ABAddressBookCreate();
MyController * __weak weakSelf = self;
if (ABAddressBookRequestAccessWithCompletion != NULL)
{ // we're on iOS 6
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
{
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf accessGrantedForAddressBook];
});
});
}
else
if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized); //Maybe add something here to handle kABAuthorizationStatusRestricted
[self accessGrantedForAddressBook];
}
}
else // we're on iOS 5 or older
[self accessGrantedForAddressBook];
which is quite similar to what Apple does in their documentation (search for ABAddressBookRequestAccessWithCompletion). Besides, what's the point of ABAddressBookRequestAccessWithCompletion being asynchronous and waiting for it (see here)..

ABAddressBookRequestAccessWithCompletion completion block never called on the main queue by default?

On a Stackoverflow question (see "Source 1" at the bottom), I see the following pattern when working with AddressBook in which the programmer wants to block the main thread until the user has granted (or denied) access to his/her AddressBook:
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...
}
but according to the documentation (ABAddressBook Reference), the completion handler is executed on an arbitrary queue, which means it could be executed on the main queue. If the completion handler were placed on the main queue, then the above code would result in a deadlock. Is there any documentation guaranteeing that the completion handler will not be placed on the main queue?
ABAddressBook Reference: "The completion handler is called on an arbitrary queue. If your app uses an address book throughout the app, you are responsible for ensuring that all usage of that address book is dispatched to a single queue to ensure correct thread-safe operation."
Source:
First answer to: How do I correctly use ABAddressBookCreateWithOptions method in iOS 6?

iOS App gets crash in background as changed Settings->Privacy->Contacts My App ON/OFF

In my app i am getting contact information directly buy doing this ...
ABAddressBookRef m_addressbook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(m_addressbook);
CFIndex nPeople = ABAddressBookGetPersonCount(m_addressbook);
for (int i=0;i < nPeople;i++)
{
ABRecordRef ref = CFArrayGetValueAtIndex(allPeople,i);
CFStringRef company,firstName,lastName;
firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
company = ABRecordCopyValue(ref, kABPersonOrganizationProperty);
}
So, i need to check first Whether this is ON/OFF Settings --> Privacy --> Contacts ON/OFF for my app.
For this I am doing this :
__block BOOL accessGranted = NO;
float sysver = [[[UIDevice currentDevice]systemVersion]floatValue];
if(sysver>=6) {
ABAddressBookRef addressBook = ABAddressBookCreate();
if (ABAddressBookRequestAccessWithCompletion != NULL) {
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 {
accessGranted = YES;
}
} else {
accessGranted = YES;
}
if(accessGranted)
{
// doing my stuff and moving on
} else {
// please make Settings --> Privacy --> Contacts my app. ON for accessing contacts.
}
My issues is , at very first time after installing app on device , app asked me to "Don't allow"/ "Ok" alert for contact grant access. I clicked on Ok but Settings --> Privacy --> Contacts for my app was OFF so again got alert to make it ON, "Settings" "Ok" so selected Settings , and i made it ON ,, once i made it ON app get SIGKILL nothing to console.
and later whenever i changed Privacy setting to OFF to ON app getting crash at background . i get SIGKILL nothing to console.
Thanks In Advance.
There is another post with a similar issue found here.
It is intended OS functionality that each application is terminated when Privacy settings are changed. This is to ensure that each application abides by the users privacy and doesn't continue to use any cached data after the privacy settings are altered.
Also please note that your suggested code
float sysver = [[[UIDevice currentDevice]systemVersion]floatValue];
if(sysver>=6) {
is not recommended by Apple and there is a better, more official approach such as using the Foundation #define values i.e.
BOOL isiOS6OrMoreRecent = NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_6_0 ? YES : NO;
However it is very bad practice to use iOS versions in order to determine available functionality, instead check for the feature itself independently of the OS version (Address Book Code here, such as:
if (ABAddressBookRequestAccessWithCompletion) { // if in iOS 6
// Request authorization to Address Book
ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);

Resources