Understanding the Issue with Accessing Contacts on iOS 7
As a developer, have you ever encountered an issue where your app can access contacts only on iOS 6 but not on iOS 7? In this article, we will delve into the world of Core Address Book (CAB) and explore why this discrepancy exists. We will also discuss possible solutions to enable contact access on both iOS 6 and iOS 7.
What is Core Address Book (CAB)?
Core Address Book is a framework provided by Apple that allows developers to interact with address book data on iPhone, iPad, and iPod touch devices. CAB provides an interface for creating, editing, and deleting address book entries, as well as requesting access to the user’s contact list.
Understanding ABAddressBookRef
ABAddressBookRef
is a Core Address Book object that represents a single address book entry. This object is created using the ABAddressBookCreateWithOptions()
function, which initializes a new address book with the specified options.
Requesting Access to Contacts on iOS 7
To access contacts on iOS 7, we need to request permission from the user. We use the ABAddressBookRequestAccessWithCompletion()
function to do this. This function takes two parameters: an ABAddressBookRef
object and a completion handler block.
The completion handler block is called when the request for access has been completed. If the user grants access, the block receives two parameters: a boolean value indicating whether access was granted (granted
) and a CFErrorRef
object representing any errors that occurred during the request (if any).
Analyzing the Code Snippet
Let’s take a closer look at the provided code snippet:
CFErrorRef error;
__block BOOL accessGranted;
ABAddressBookRef myAddressBook = ABAddressBookCreateWithOptions(NULL,&error);
ABAddressBookRequestAccessWithCompletion(myAddressBook, ^(bool granted, CFErrorRef error)
{
if (!accessGranted && !granted)
{
// Show an alert with a "Deny" button to handle the case where access is denied
alertViewDeny = [[UIAlertView alloc]initWithTitle:@"Deny Access" message:@"Deny" delegate:self cancelButtonTitle:nil otherButtonTitles:@"cancel", nil];
[alertViewDeny show];
[alertViewDeny release];
}
else
{
// If access was granted, copy the address book entries and log them to the console
NSArray *allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(myAddressBook);
DLog(@"allPeople %@",allPeople);
}
});
The Issue with iOS 7
As mentioned earlier, this code snippet works on iOS 6 but not on iOS 7. The reason for this discrepancy lies in the way Apple designed the Core Address Book framework to handle requests for access to the user’s contact list.
On iOS 5 and later versions of iOS, including iOS 7, Apple introduced a new feature called “Privacy” settings. This feature allows users to control which apps can access their contacts. To request access to contacts on these versions of iOS, we need to use a different approach than on older versions of iOS.
Using ABAddressBookRequestAccessWithAccountType
To request access to contacts on iOS 7 and later versions of iOS, we need to use the ABAddressBookRequestAccessWithAccountType()
function instead of ABAddressBookRequestAccessWithCompletion()
. The main difference between these two functions is that ABAddressBookRequestAccessWithAccountType()
allows us to specify a specific account type (kABPersonAccountType
) when requesting access.
Here’s an updated code snippet that uses the new approach:
CFErrorRef error;
__block BOOL accessGranted;
ABAddressBookRef myAddressBook = ABAddressBookCreateWithOptions(NULL,&error);
ABAddressBookRequestAccessWithAccountType(myAddressBook, kABPersonAccountType, ^(bool granted, CFErrorRef error)
{
if (!accessGranted && !granted)
{
// Show an alert with a "Deny" button to handle the case where access is denied
alertViewDeny = [[UIAlertView alloc]initWithTitle:@"Deny Access" message:@"Deny" delegate:self cancelButtonTitle:nil otherButtonTitles:@"cancel", nil];
[alertViewDeny show];
[alertViewDeny release];
}
else
{
// If access was granted, copy the address book entries and log them to the console
NSArray *allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(myAddressBook);
DLog(@"allPeople %@",allPeople);
}
});
Enabling Contact Access on Both iOS 6 and iOS 7
To enable contact access on both iOS 6 and iOS 7, we need to modify our code snippet slightly. We can use the ABAddressBookRequestAccessWithCompletion()
function for iOS 6 and ABAddressBookRequestAccessWithAccountType()
for iOS 7.
Here’s an updated code snippet that handles this difference:
CFErrorRef error;
__block BOOL accessGranted;
ABAddressBookRef myAddressBook = ABAddressBookCreateWithOptions(NULL,&error);
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)
{
// Use the new approach for iOS 7 and later versions
ABAddressBookRequestAccessWithAccountType(myAddressBook, kABPersonAccountType, ^(bool granted, CFErrorRef error)
{
if (!accessGranted && !granted)
{
// Show an alert with a "Deny" button to handle the case where access is denied
alertViewDeny = [[UIAlertView alloc]initWithTitle:@"Deny Access" message:@"Deny" delegate:self cancelButtonTitle:nil otherButtonTitles:@"cancel", nil];
[alertViewDeny show];
[alertViewDeny release];
}
else
{
// If access was granted, copy the address book entries and log them to the console
NSArray *allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(myAddressBook);
DLog(@"allPeople %@",allPeople);
}
});
}
else
{
// Use the old approach for iOS 6
ABAddressBookRequestAccessWithCompletion(myAddressBook, ^(bool granted, CFErrorRef error)
{
if (!accessGranted && !granted)
{
// Show an alert with a "Deny" button to handle the case where access is denied
alertViewDeny = [[UIAlertView alloc]initWithTitle:@"Deny Access" message:@"Deny" delegate:self cancelButtonTitle:nil otherButtonTitles:@"cancel", nil];
[alertViewDeny show];
[alertViewDeny release];
}
else
{
// If access was granted, copy the address book entries and log them to the console
NSArray *allPeople = (NSArray *)ABAddressBookCopyArrayOfAllPeople(myAddressBook);
DLog(@"allPeople %@",allPeople);
}
});
}
Conclusion
In this article, we explored the issue of accessing contacts on iOS 7. We discussed the differences between Core Address Book functions for older and newer versions of iOS. We also provided an updated code snippet that handles these differences.
By using the correct function depending on the version of iOS, we can ensure that our app has access to the user’s contact list on both iOS 6 and iOS 7.
Last modified on 2024-02-24