2013-07-19 4 views
3

Я разрабатываю приложение, которое меняет контактное изображение контакта, когда я выбираю любой контакт из панели выбора контактов.Добавление контактного изображения в адресную книгу iPhone

Вот код, я реализовал до сих пор,

(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 она возвращается ложной и изображение не получает установить контакт. Что может быть причиной?

Я написал этот метод в shouldContinueAfterSelectingPerson; Я проверил изображение, и оно не является нулевым, а ABPersonSetImageData возвращает TRUE.

Я обновил код, проверил уже установленное изображение, если да, то я удаляю это изображение и сохраняю сохраненную адресную книгу и передавая CFDataRef.

Но до сих пор ее не работает

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

Я написал все мой код в этом методе
- (BOOL) peoplePickerNavigationController: (ABPeoplePickerNavigationController *) peoplePicker shouldContinueAfterSelectingPerson: (ABRecordRef) человек {},
So Определенно будет человек, который уже находится в адресной книге. Но я попытался в соответствии с вышеуказанным кодом, что ABAddressBookHasUnsavedChanges возвращает false

+0

Попробуйте создать данные изображения следующим образом: 'CFDataRef cfDataRef = CFDataCreate (NULL, [dataRef bytes], [dataRef length]);' и затем передать его в 'ABPresonSetImageData'. И, конечно же, не забудьте выпустить! Также есть ли существующее изображение до этого изменения (проверьте «ABPersonHasImageData')? Если да, то сначала удалите его - 'ABPersonRemoveImageData'. –

+0

Я обновил код в соответствии с вами, но его не работает, пожалуйста, проверьте отредактированный код. – krish

+0

ABAddressBookHasUnsavedChanges возвращает false. в чем проблема ? – krish

ответ

1

Вы неправильно создаете данные - вы должны делать это так.

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

попробовать также установив точку останова где-то в начале и проверить, если что-то не ноль или не имеет неверное значение.

UPDATE

Я попробовал это на самом 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, но вы не должны использовать его (я просто хотел, чтобы увидеть изменения в неспасенный контакт).

UPDATE 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; 
} 

КПП., так как это метод делегата не освободить человека, иначе он будет разбит ужасно - просто шутит, он рухнет, потому что он пытается получить доступ к памяти, которая не существует.

+0

Я делаю все это в этом методе - (BOOL) peoplePickerNavigationController: (ABPeoplePickerNavigationController *) peoplePicker shouldContinueAfterSelectingPerson: (ABRecordRef) человек {}, поэтому определенно будет человек, который уже находится в адресной книге. Но я попытался в соответствии с вышеприведенным кодом, что ABAddressBookHasUnsavedChanges возвращает false – krish

+0

Dominik Я создал контакт с вашим кодом, его работа также может видеть изображение, но как установить изображение для контакта, которое уже находится в адресной книге, пожалуйста, предложите мне – krish

+0

Затем попробуйте получить адресную книгу из метода делегата, например, 'ABAddressBookRef addressBook = peoplePicker.addressBook;'. –

Смежные вопросы