The following code works correctly in iOS7, but not in iOS8 (the variable recordID is set correctly):
CFErrorRef error = nil;
const ABAddressBookRef addressBook = (ABAddressBookCreateWithOptions (NULL, &error));
ABRecordRef contactRef = ABAddressBookGetPersonWithRecordID (addressBook, recordID);
ABPersonViewController *personViewController = [[ABPersonViewController alloc] init];
personViewController.addressBook = addressBook;
personViewController.displayedPerson = contactRef;
CFRelease(addressBook);
NSArray *displayedProperties = @[@(kABPersonFirstNameProperty),
@(kABPersonLastNameProperty),
@(kABPersonMiddleNameProperty),
@(kABPersonPrefixProperty),
@(kABPersonSuffixProperty),
@(kABPersonOrganizationProperty),
@(kABPersonJobTitleProperty),
@(kABPersonDepartmentProperty),
@(kABPersonEmailProperty),
@(kABPersonBirthdayProperty),
@(kABPersonKindProperty),
@(kABPersonAddressProperty),
@(kABPersonPhoneProperty),
@(kABPersonInstantMessageProperty),
@(kABPersonURLProperty),
@(kABPersonSocialProfileProperty),
@(kABPersonNoteProperty)];
personViewController.displayedProperties = displayedProperties;
personViewController.navigationItem.title = NSLocalizedString(@"CONTACT_DETAILS", nil);
personViewController.allowsActions = YES;
personViewController.allowsEditing = YES; // if NO, no back button is shown
personViewController.personViewDelegate = self;
personViewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"ADDRESSES",nil) style:UIBarButtonItemStylePlain target:self action:@selector(personviewDoneButtonPressed:)];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:personViewController];
[self presentViewController:navigationController animated:YES completion:nil];
Bugs in iOS8:
- When
allowsEditingis set toYES, the contact is shown, but only the name is displayed. The navigation bar shows left the back button (named "Addresses") and right the edit button. When the edit button is pressed, the contact is displayed with all fields empty except the name, and the edit button is displayed as a done button. If this done button is pressed without any editing before, all information about the contact is displayed. - When
allowsEditingis set toNO, no back button is shown, so that the screen can no longer be left.
Has anybody a workaround?
UPDATE:
I realized by now, that problem 1 only sometimes occurs on the simulator, although always on my device.
montuno (thanks again), who commented my first answer, got a hint from Apple technical support how to solve the 1st problem, and I understand now also the 2nd problem:
1) Only part of the contact displayed:
Apple claimed that the following code is wrong:
Here
addressBookis erroneously released, after it has been assigned to theABPersonViewController.In my original code, I did not have the
CFReleasestatement. But then the static analyzer warned of a „Potential leak of an object stored in addressBook“. After I inserted the release statement, the build succeeded without warning, so I assumed that thepersonViewControllerretained theaddressBook, which is apparently not the case, at least not with iOS8. I removed now the release statement again, got the warning back, but everything works fine.2) Missing back button:
The docs of the
ABPersonViewControllersay „IMPORTANT Person view controllers must be used with a navigation controller in order to function properly.“So what I did was the following:
I set up an
ABPersonViewController, assigned to itsnavigationItem.backBarButtonItema „Done“ button, and initialized a newUINavigationControllerwith thispersonViewController, usinginitWithRootViewController:. Then I presented the newnavigationControllermodally.The
personViewControllerwith the back button was displayed, and when pressed, the presenting view controller dismissed the modally presented navigation controller.This worked fine on iOS < 8, but in iOS8, the back button was not displayed, when
allowsEditingwas set toNO.But this is apparently not how Apple wants to display the
personViewController:I think Apple assumes that a
navigationControlleralready exists, and presents the current view, so that a newpersonViewControlleris just pushed onto the stack of thenavigationController. In this case, thepersonViewControlleris not therootViewControllerof thenavigationController, and thenavigationControllerdisplays automatically a back button (which is not done for therootViewController). If implemented this way, everything works fine also for iOS8.