将联系人图像添加到地址簿iPhone

时间:2013-07-19 08:38:19

标签: iphone ios addressbook

我正在开发应用程序,当我从联系人选择器中选择任何联系人时,它会更改联系人的联系人图片。

这是我到目前为止实施的代码,

(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    CFErrorRef error=nil;
    ABAddressBookRef addressBook = ABAddressBookCreate();
    NSString *path1 = [[NSBundle mainBundle] pathForResource:@"birthday.jpg" ofType:nil];
    UIImage *img = [UIImage imageWithContentsOfFile:path1];
    NSData *dataRef = UIImagePNGRepresentation(img);

    CFDataRef cfDataRef = CFDataCreate(NULL, [dataRef bytes], [dataRef length]);

   if(ABPersonHasImageData(person))
   {
       ABPersonRemoveImageData(person, &error);
       ABAddressBookSave(addressBook, &error);
   }
    if (ABPersonSetImageData(person,cfDataRef, &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");
        }       
    }

    CFRelease(cfDataRef);

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

    return NO;

}

但是当我调试并查看ABAddressBookHasUnsavedChanges时,它返回false并且图像未设置为联系人。可能是什么原因?

我在shouldContinueAfterSelectingPerson中写了这个方法;我检查了图片并且它不为空,ABPersonSetImageData正在返回TRUE

我已更新代码,已检查图像集,如果是,那么我将删除该图像并保存保存地址簿并重新发送CFDataRef。

但仍然无法正常工作

Update:2 
 I have edited the code , please look at the changes. 

我已经用这种方法编写了所有代码      - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {},
 所以肯定会有人已经在地址簿中。但我尝试根据上面的代码仍然ABAddressBookHasUnsavedChanges返回false

1 个答案:

答案 0 :(得分:1)

您正在创建错误的数据 - 您应该这样做。

UIImage *img = [UIImage imageWithContentsOfFile:path1];
NSData *dataRef = UIImagePNGRepresentation(img);
CFDataRef cfDataRef = CFDataCreate(NULL, [dataRef bytes], [dataRef length]);

还尝试在开头的某处设置断点,检查某些内容是否为零或没有错误值。

<强>更新

我在实际的Xcode中试过它,只是为了测试。您的代码告诉您地址簿没有未保存的更改的原因是您尚未在其中添加记录 - 否则您在尚未添加到地址簿的联系人上设置图像(不是一个问题,你可以毫无问题地做到这一点,但是在保存之前联系人本身不在地址簿中)。所以对你来说,神奇的代码可能就是这样:

ABAddressBookAddRecord(addressBook, person, &error);

这是我一直在使用的完整代码。

   CFErrorRef error = nil;
    ABAddressBookRef addressBook = ABAddressBookCreate();
    ABRecordRef person = ABPersonCreate();
    NSString *path1 = [[NSBundle mainBundle] pathForResource:@"sky_main" ofType:@"jpg"];

    UIImage *img = [UIImage imageWithContentsOfFile:path1];
    NSData *dataRef = UIImagePNGRepresentation(img);
    CFDataRef cfDataRef = CFDataCreate(NULL, [dataRef bytes], [dataRef length]);

    if (ABPersonHasImageData(person)) {
        ABPersonRemoveImageData(person, &error);
        ABAddressBookSave(addressBook, &error);
    }
    ABAddressBookAddRecord(addressBook, person, &error);

    if (ABPersonSetImageData(person, cfDataRef, &error)) {
        if (ABAddressBookHasUnsavedChanges(addressBook)) {
            NSLog(@"has unsaved changes");
        } else {
            NSLog(@"nothing to save");
        }
        if (ABAddressBookSave(addressBook, &error)) {
            NSLog(@"saved");
        } else {
            NSLog(@"not saved");
        }
    }


    ABUnknownPersonViewController *ctr = [[ABUnknownPersonViewController alloc] init];
    ctr.unknownPersonViewDelegate = nil;
    ctr.displayedPerson = person;
    ctr.allowsAddingToAddressBook = YES;
    ctr.allowsActions = YES;
    ctr.hidesBottomBarWhenPushed = YES;

    // [[[CCDirector sharedDirector] view] addSubview:ctr.view];
    CFRelease(person);
    CFRelease(addressBook);

我也在使用AddressBookUI,但您不必使用它(我只想查看未保存联系人的更改)。

更新2

好的,刚创建一个新项目只是为了尝试。看起来问题实际上是ABAddressBookRef。您必须从委托方法的peoplePicker参数中获取它。由于它是委托方法,因此您不必添加记录,因为它已经存在。这是必须工作的代码(2分钟前尝试过)。让我知道:))

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person {

    CFErrorRef error = nil;
    ABAddressBookRef addressBook = peoplePicker.addressBook;
    NSString *path1 = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"jpg"];

    UIImage *img = [UIImage imageWithContentsOfFile:path1];
    NSData *dataRef = UIImagePNGRepresentation(img);
    CFDataRef cfDataRef = CFDataCreate(NULL, [dataRef bytes], [dataRef length]);

    if (ABPersonHasImageData(person)) {
        ABPersonRemoveImageData(person, &error);
        ABAddressBookSave(addressBook, &error);
    }

    if (ABPersonSetImageData(person, cfDataRef, &error)) {
        if (ABAddressBookHasUnsavedChanges(addressBook)) {
            NSLog(@"has unsaved changes");
        } else {
            NSLog(@"nothing to save");
        }
        if (ABAddressBookSave(addressBook, &error)) {
            NSLog(@"saved");
        } else {
            NSLog(@"not saved");
        }
    }

    CFRelease(addressBook);

    return YES;
}

顺便说一句,因为它是委托方法释放该人,否则它会崩溃 - 只是开玩笑,它会崩溃,因为它试图访问不存在的内存。 / p>