首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用CNContactVCardSerialization dataWithContacts:方法获取联系人图片的VCF数据?

如何使用CNContactVCardSerialization dataWithContacts:方法获取联系人图片的VCF数据?
EN

Stack Overflow用户
提问于 2016-09-22 19:46:33
回答 3查看 2.8K关注 0票数 7

我正在使用CNContacts和CNContactUI框架,并通过此选择联系人

代码语言:javascript
复制
CNContactPickerViewController *contactPicker = [CNContactPickerViewController new];
              contactPicker.delegate = self;
 [self presentViewController:contactPicker animated:YES completion:nil];

代码语言:javascript
复制
-(void)contactPicker:(CNContactPickerViewController *)picker didSelectContact:(CNContact *)contact
{
    NSArray *array = [[NSArray alloc] initWithObjects:contact, nil];
    NSError *error;
    NSData *data = [CNContactVCardSerialization dataWithContacts:array error:&error];
    NSLog(@"ERROR_IF_ANY :: %@",error.description);
}

contact对象具有contact.imageData和来电日志。但当我试图交叉检查这些数据时

代码语言:javascript
复制
NSArray *contactList = [NSArray arrayWithArray:[CNContactVCardSerialization contactsWithData:data error:nil]];
CNContact *contactObject = [contactList objectAtIndex:0];

这是获取null:

代码语言:javascript
复制
//contactObject.imageData  

为什么我在签入联系人时得到此null,并且此联系人有图像?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-05 20:17:06

作为一种变通方法,您可以在VCard中创建照片字段。

代码语言:javascript
复制
NSError* error = nil;
NSData* vCardData = [CNContactVCardSerialization dataWithContacts:@[contact] error:&error];
NSString* vcString = [[NSString alloc] initWithData:vCardData encoding:NSUTF8StringEncoding];
NSString* base64Image = contact.imageData.base64Encoding;
NSString* vcardImageString = [[@"PHOTO;TYPE=JPEG;ENCODING=BASE64:" stringByAppendingString:base64Image] stringByAppendingString:@"\n"];
vcString = [vcString stringByReplacingOccurrencesOfString:@"END:VCARD" withString:[vcardImageString stringByAppendingString:@"END:VCARD"]];
vCardData = [vcString dataUsingEncoding:NSUTF8StringEncoding];

出于某些原因,CNContactVCardSerialization没有使用任何联系人的照片。序列化后的VCard如下所示:

代码语言:javascript
复制
BEGIN:VCARD
VERSION:3.0
PRODID:-//Apple Inc.//iPhone OS 9.3.2//EN
N:Contact;Test;;;
FN: Test  Contact 
END:VCARD

在VCard中插入照片字段后,您将看到

代码语言:javascript
复制
BEGIN:VCARD
VERSION:3.0
PRODID:-//Apple Inc.//iPhone OS 9.3.2//EN
N:Contact;Test;;;
FN: Test  Contact 
PHOTO;TYPE=JPEG;ENCODING=BASE64:<photo base64 string>
END:VCARD

插入此内容后,联系人在CNContactViewController中看起来没有问题

票数 11
EN

Stack Overflow用户

发布于 2017-07-23 06:12:27

我想对Swift 3的kudinovdenis的优秀答案进行改进和现代化。

只需将以下扩展放入您的项目中

代码语言:javascript
复制
import Foundation
import Contacts

extension CNContactVCardSerialization {
    internal class func vcardDataAppendingPhoto(vcard: Data, photoAsBase64String photo: String) -> Data? {
        let vcardAsString = String(data: vcard, encoding: .utf8)
        let vcardPhoto = "PHOTO;TYPE=JPEG;ENCODING=BASE64:".appending(photo)
        let vcardPhotoThenEnd = vcardPhoto.appending("\nEND:VCARD")
        if let vcardPhotoAppended = vcardAsString?.replacingOccurrences(of: "END:VCARD", with: vcardPhotoThenEnd) {
            return vcardPhotoAppended.data(using: .utf8)
        }
        return nil

    }
    class func data(jpegPhotoContacts: [CNContact]) throws -> Data {
        var overallData = Data()
        for contact in jpegPhotoContacts {
            let data = try CNContactVCardSerialization.data(with: [contact])
            if contact.imageDataAvailable {
                if let base64imageString = contact.imageData?.base64EncodedString(),
                    let updatedData = vcardDataAppendingPhoto(vcard: data, photoAsBase64String: base64imageString) {
                    overallData.append(updatedData)
                }
            } else {
                overallData.append(data)
            }
        }
        return overallData
    }
}

然后,您可以类似于现有的序列化方法来使用它:

代码语言:javascript
复制
CNContactVCardSerialization.data(jpegPhotoContacts: [contact1, contact2])

请注意,这会处理序列化,如果您还在导入,则需要编写一个类似的方法来进行反序列化。

票数 10
EN

Stack Overflow用户

发布于 2017-06-15 20:37:48

对于N个联系人,您可以使用下面的简单方法将图片数据添加到VCF中。

代码语言:javascript
复制
-(NSData*)getVCFDataWithImagesFromContacts:(NSArray*)arrContacts
{
//---- Convert contacts array into VCF data.
    NSError *error;
    NSData *vcfData = [CNContactVCardSerialization dataWithContacts:arrContacts error:&error];


    //--- Convert VCF data into string.
    NSString *strVCF = [[NSString alloc] initWithData:vcfData encoding:NSUTF8StringEncoding];

    //--- Split contacts from VCF.
    NSMutableArray *arrSplit = (NSMutableArray*)[strVCF componentsSeparatedByString:@"END:VCARD"];
    [arrSplit removeLastObject];//-- if object is "\r\n" otherwise comment this line.

    //--- Validate array count
    if (arrSplit.count == arrContacts.count)
    {
        for (int index=0;index<arrContacts.count;index++)
        {
            //--- Get current contact and VCF contact string.
            CNContact *contact = arrContacts[index];
            NSString *strContact = arrSplit[index];

            //--- Get base64 string of image.
            NSString* base64Image = [UIImagePNGRepresentation([ViewController imageWithImage:[UIImage imageWithData:contact.imageData] scaledToSize:CGSizeMake(50,50)]) base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn];

            //--- Append image tag into contact string.
            NSString* vcardImageString = [[@"PHOTO;ENCODING=BASE64;JPEG:" stringByAppendingString:base64Image] stringByAppendingString:@"\r\n"];
        strContact = [strContact stringByAppendingString:[NSString stringWithFormat:@"%@%@",vcardImageString,@"END:VCARD\r\n"]];

            //--- Update contact string from array.
            [arrSplit replaceObjectAtIndex:index withObject:strContact];
            NSLog(@"strContact :%@",strContact);
        }
    }

    //--- Combine all contacts together in VCF.
    vcfData =  [[arrSplit componentsJoinedByString:@""] dataUsingEncoding:NSUTF8StringEncoding];
    strVCF = [[NSString alloc] initWithData:vcfData encoding:NSUTF8StringEncoding];//--- VCF Data

    NSLog(@"Contact VCF error :%@",error.localizedDescription);

    return vcfData;
}


+(UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize
{
   UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
   [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
   UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();
   return newImage;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39638149

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档