无法使用 VCard 表示创建人

Posted

技术标签:

【中文标题】无法使用 VCard 表示创建人【英文标题】:unable to create a person using VCard representation 【发布时间】:2012-02-08 21:42:11 【问题描述】:

我正在使用 XCode 4.2 开发一个应用程序,我正在尝试使用 initWithVCardRepresentation 和/或 ABPersonCreatePeopleInSourceWithVCardRepresentation 创建一个 ABPerson,但我找不到一个工作示例。有人可以帮忙吗?

我得到了 NSString 格式的 VCard....

谢谢

【问题讨论】:

【参考方案1】:

这是一个完整的示例,它运行良好,它基于最新的 ios 8。

首先你应该检查授权状态,如果没有,请请求访问权限,然后保存vcard,让我们看看下面的代码:

if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
        NSLog(@"Authorized");
        [self addVcardsIntoAddressBook:vcard];
     else
        NSLog(@"Not determined");
        ABAddressBookRequestAccessWithCompletion(ABAddressBookCreateWithOptions(NULL, nil), ^(bool granted, CFErrorRef error) 
            if (!granted)
                NSLog(@"Just denied");
                return;
            
            NSLog(@"Just authorized");
            [self addVcardsIntoAddressBook:vcard];
        );
    

这是添加 vcard 的方法:

- (void)addVcardsIntoAddressBook:(NSData *)vcard 
    CFDataRef vCardData = CFDataCreate(NULL, [vcard bytes], [vcard length]);
    ABAddressBookRef book = ABAddressBookCreate();
    ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(book);
    CFArrayRef vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource, vCardData);
    for (CFIndex index = 0; index < CFArrayGetCount(vCardPeople); index++) 
        ABRecordRef person = CFArrayGetValueAtIndex(vCardPeople, index);
        ABAddressBookAddRecord(book, person, NULL);
        CFRelease(person);
    
    ABAddressBookSave(book, NULL);

【讨论】:

【参考方案2】:

这是acoustic的答案的Swift版本;

        let vCard : NSData // vcard

        let addressBook: ABAddressBook? = ABAddressBookCreateWithOptions(nil, nil)?.takeRetainedValue()   

                ABAddressBookRequestAccessWithCompletion(addressBook) 
                        granted, error in

                        if !granted 
                            return
                        

                    let vCardData = CFDataCreate(nil, UnsafePointer<UInt8>(vCard.bytes), vCard.length)
                    let defaultSource  = ABAddressBookCopyDefaultSource(addressBook)
                    let vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource.takeUnretainedValue(), vCardData).takeRetainedValue() as NSArray

                    for person in vCardPeople 

                        ABAddressBookAddRecord(addressBook, person, nil)

                    

                    let isSaved = ABAddressBookSave(addressBook, nil)
                    if isSaved
                        //succesfully saved
                    
                    else
                       //not saved
                    
        

【讨论】:

书应该是地址书吗?我还收到了一个内置错误Variable 'vCard' let vCard: NSData // vcard vCard = code Cannot 将“String”类型的值分配给“NSData”类型的值`我如何将 readableObject.stringValue 转换为 readableObject NSData?? 我需要将扫描的代码(字符串)转换为 NSData ` func foundCode(code: String) print("Scanned vCard info (code)") // start let vCard: NSData / /vcard vCard=code let addressBook:ABAddressBook? = ABAddressBookCreateWithOptions(nil, nil)?.takeRetainedValue()` 好的,对于那些寻求转换的人link我现在发布我自己的问题 你是对的,书应该是 addressBook ,我编辑了我的答案。如果它适合你,请投票给这个答案。【参考方案3】:

我正在使用我在论坛某处找到的这段代码:

// Assuming your vCard is stored in vCardString as an NSString
CFDataRef vCardData = (__bridge CFDataRef)[vCardString dataUsingEncoding:NSUTF8StringEncoding];
ABAddressBookRef book = ABAddressBookCreate();
ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(book);
CFArrayRef vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource, vCardData);
CFIndex index = 0;
ABRecordRef person = CFArrayGetValueAtIndex(vCardPeople, index);

【讨论】:

【参考方案4】:

我正在使用它,它在 Vcard 2.1 和 3.0 上运行良好

NSString *filename = [[NSBundle mainBundle] pathForResource:@"Contacts" ofType:@"vcf"]; NSLog(@"打开文件 %@", 文件名); NSData *stringData = [NSData dataWithContentsOfFile:filename]; NSString *vCardString = [[NSString alloc] initWithData:stringData encoding:NSUTF8StringEncoding];

CFDataRef vCardData = (__bridge CFDataRef)[vCardString dataUsingEncoding:NSUTF8StringEncoding];

ABAddressBookRef book = ABAddressBookCreate();
ABRecordRef defaultSource = ABAddressBookCopyDefaultSource(book);
CFArrayRef vCardPeople = ABPersonCreatePeopleInSourceWithVCardRepresentation(defaultSource, vCardData);
for (CFIndex index = 0; index < CFArrayGetCount(vCardPeople); index++) 
    ABRecordRef person = CFArrayGetValueAtIndex(vCardPeople, index);
    ABAddressBookAddRecord(book, person, NULL);


CFRelease(vCardPeople);
CFRelease(defaultSource);
ABAddressBookSave(book, NULL);
CFRelease(book);

【讨论】:

以上是关于无法使用 VCard 表示创建人的主要内容,如果未能解决你的问题,请参考以下文章

MS“VCard”法国特色字符

使用 `xmpp` 和 `smack` 从 `vcard` 获取自定义元素

对类型的非常量左值引用无法绑定错误

从服务器 SMACK Android XMPP 获取 VCard Avatar iq 数据包

无法创建相对 URI,因为 'uriString' 参数表示绝对 URI

使用 Python 的 Vcard 解析器