Setting Address Book image for a contact doesn'

2020-02-09 19:18发布

I'm trying to set the contact image with the code below. I am not seeing any errors, and the image is not saved to the contact entry in the address book. Please help! I must be doing something wrong...

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
[abcontroller setDisplayedPerson:person];

UIImage *im = [UIImage imageNamed:@"image1.jpg"];
NSData *dataRef = UIImagePNGRepresentation(im);
CFErrorRef error;
ABAddressBookRef addressBook = ABAddressBookCreate(); 

NSLog(@"Error:",error);
    if (ABPersonSetImageData(person, (CFDataRef)dataRef, &error))
    {
        NSLog(@"Set contact photo %@", error);
        if (ABAddressBookHasUnsavedChanges(addressBook))
        {
            NSLog(@"Changes made to address book");
        }
        else {
            NSLog(@"No changes made to address book");
        }

        if (ABAddressBookSave(addressBook, &error))
        {
            NSLog(@"Saved");

        }
        else {
            NSLog(@"Not saved");
        }


    }
    else {
        NSLog(@"Error saving contact photo %@", error);
    }
ABAddressBookSave(addressBook, &error);

[self dismissModalViewControllerAnimated:YES];    

return NO;
}

Here is my output log:

2010-01-17 21:58:35.465 Error:
2010-01-17 21:58:35.504 Set contact photo <ABPeoplePickerNavigationController: 0x19e9b0>
2010-01-17 21:58:43.497 No changes made to address book
2010-01-17 21:58:44.724 Saved

I'm not sure why the error object is logging as an ABPeoplePickerNavigationController object?

4条回答
虎瘦雄心在
2楼-- · 2020-02-09 19:47

All these answer didn't work. You should simply change your line of code from:

ABAddressBookRef addressBook = ABAddressBookCreate(); 

to:

ABAddressBookRef addressBook = [peoplePicker addressBook];

This way you get the reference to the "address book", "person" belongs to.

查看更多
Juvenile、少年°
3楼-- · 2020-02-09 19:48

I have also try to use to set the image (Photo) of current selected person but it display massage to saved successfully but in real it dose not work!!!

after the digging out the code and the documents provided by Apple SDK, i have some up with the following solution.

Please check out the below code. its really working fine for me and hope for you also.

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    @try {
        CFErrorRef cfError = nil;

        if (ABPersonHasImageData(person)) {
            NSLog(@"%s has an image", _cmd);

            //theAlert = [[UIAlertView alloc] initWithTitle:@"Contact already has an image" message:@"Are you sure you want to overwrite it?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Overwrite"];
            //[theAlert show];
            //[theAlert release];
            //Note: We do not yet handle the answer to this question
        }

        // Just a sanity check

        if ((nil == [imageView image])
            || (nil == UIImagePNGRepresentation([imageView image]))) {
            NSLog(@"%s NIL STUFF", _cmd);
        }

        // Not sure I even need to create and save an address book
        // Cf. https://devforums.apple.com/message/27512#27512
        ABAddressBookRef libroDirec = ABAddressBookCreate();
        ABPersonSetImageData(person, (CFDataRef) (UIImageJPEGRepresentation([imageView image], 1.0f)), &cfError);
        ABAddressBookAddRecord(libroDirec, person, &cfError);
        if (ABAddressBookSave(libroDirec, nil)) {
            NSLog(@"%s saved successfuly", _cmd);
        } else {
            NSLog(@"%s something bad happen while saving", _cmd);
        }
        CFRelease(libroDirec);
    }
    @catch (NSException * e) {

    }
    @finally {

    }
    // TODO: release peoplePicker (and refactor code to not have it global)
    [self dismissModalViewControllerAnimated:YES];

    return NO;

}
查看更多
放我归山
4楼-- · 2020-02-09 19:53

I checked your code and it doesn't work as it should. So I made 2 changes.

ABAddressBookRef libroDirec = [peoplePicker addressBook];//don't create
        ABPersonSetImageData(person, (CFDataRef)UIImagePNGRepresentation(display.image), &cfError);
        ABAddressBookAddRecord(libroDirec, person, &cfError);

        if (ABAddressBookSave(libroDirec, nil)) {
            NSLog(@"\n%s saved successfuly", _cmd);
        } else {
            NSLog(@"\n%s something bad happen while saving", _cmd);
        }
        //CFRelease(libroDirec);

Now it works as it supposed to.

查看更多
beautiful°
5楼-- · 2020-02-09 20:09

Regarding I'm not sure why the error object is logging as an ABPeoplePickerNavigationController object? -- because you're not properly initialising the error here:

CFErrorRef error;

Assign nil here, or it will have a random (or more precisely, some previous memory) value, incidentally pointing to an ABPeoplePickerNavigationController object.

Regarding the merits: are you sure the reference to person you have passed to your method is valid in the context of the address book? I would try to use a function such as ABAddressBookGetPersonWithRecordID first, instead of passing ABPersonRefs around and expecting them to be valid for different address book references.

查看更多
登录 后发表回答