VCard 格式说明

最近做一个通讯录相关的东西,需要把通讯录导出 VCF 文件。之前没有接触过 VCard 相关的东西,并不知道 VCard 的格式定义。试着导出了一个 VCF 文件看一下,iCloud 导出的 VCF 文件里面部分字段都加着下划线,明显不是本身定义的字段,看起来像是扩展字段的样子,这让我犯了难。既然这样,只能先查一下 VCF 的格式规范了,奈何中文资料并不多,大部分只是对字段进行了说明,而且不够详细,只能硬着头皮去看官方文档了。VCard 的文档在 RFC6350 这份规范上被定义。所以主要看的这个文档。

字段定义就不多言了。出门左转,百度百科。这里只记录一下使用过程中需要注意的点

1.每条记录使用[LF][CR]分割

每条记录使用换行+回车的形式进行分割,也就是\r\n
因此每一行都是一条记录(不严谨)

2.记录长度不超过75字节

每条记录长度不超过75字节。如果超过的话需要每75字节进行截取进行换行(使用[LF][CR]换行)。下一行需要以空格开头,同样不超过75字节,例如头像的 PHOTO 字段由于包含图片信息,base64编码之后通常会超长,这个字段格式化之后如下

PHOTO;ENCODING=BASE64:/9j/4AAQSkZJRgABAQAASABIAAD/4QBMRXhpZgAATU0AKgAAAAgAA
gESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAAqACAAQAAAABAAABWaADAAQAAAABAAABWQA
AAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmAC
Q96z/8ASPU/kP8ACuWn1jULkgyyKSOAQiKefcCq3226/v8A/joqlh7AoH//0v5/6KKKACiiigA
ooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKA
CiiigAooooAKKKKACiiigAooooAKKKKAP/T/n/ooooAKKKKACiiigAooooAKKKKACiiigAoooo
AKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiii
gAooooA/9T+f+iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK
KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/2Q==

除了 PHOTO 所在行之外,其它行都是以空格开头,每行长度为75字节(算空格)

3.同一记录不同属性使用分号分隔

一行是一条记录,每条记录可以有多个属性来描述,不同的属性需要使用分号来进行分隔。比如:

REV;VALUE=date:20151029T164508+0800

4.冒号之后为记录值

REV;VALUE=date:20151029T164508+0800

上面这条记录的值为20151029T164508+0800,因此没一条记录的冒号之后都需要携带值

5.时间格式

部分属性为 date 类型的值,需要使用一种规定的方式来表示,格式定义为ISO.8601.2004

对应形式可以在section-4.1.2.3找到

上面的20151029T164508+0800T前为年月日,T后为时分秒,+号后面为时区(正八区)

6.转义字符

\;,\n都需要进行转义

以上字符都需要进行反斜线转义处理。

7.ADR 记录说明

这个字段的值定义为

the post office box;
the extended address (e.g., apartment or suite number);
the street address;
the locality (e.g., city);
the region (e.g., state or province);
the postal code;
the country name (full name in the language specified in Section 5.1).

但是文档上面说从 VCard3 开始前两个字段就不再使用了,也就是说应该空置。所以 ADR 字段形式为

ADR;TYPE=Work;TYPE=PREF:;;3494 Kuhl Avenue;Atlanta;GA;30303;USA

8.值需要分号分割的,如果值为空分号仍然应该保留

比如 ADR 其中的 postal 不存在,那么分号仍然应该保留,为如下形式

ADR;TYPE=Work;TYPE=PREF:;;3494 Kuhl Avenue;Atlanta;GA;;USA

9.必须存在 FN 记录

VCard 的基本形式为

"BEGIN:VCARD" CRLF
"VERSION:3.0" CRLF
1*contentline
"END:VCARD" CRLF

其中 contentline 中必须包含 FN 这条记录

最后付一个生成之后的 VCF 文件

BEGIN:VCARD
VERSION:3.0
N:Appleseed;John;;;
FN:John Appleseed
ORG:;
BDAY;VALUE=date:19800622
NOTE:College roommate \nqwwq\;'asd\,asd\\qw asd\nad
PHOTO;ENCODING=BASE64:/9j/4AAQSkZJRgABAQAASABIAAD/4QBMRXhpZgAATU0AKgAAAAgAA
gESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAAqACAAQAAAABAAABWaADAAQAAAABAAABWQA
AAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmAC
Zjs+EJ+/8AAEQgBWQFZAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAk
KC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJ
DNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl
7Vyz6dBqWnSQM3lM2GbORtYHg8evIrwpPFfiCNVVLxwE4AwMDv0xViXxp4kmR43uhiRdrYijBI
PuFrT6lUvdMmNGS6nd6h4S1L7MksAS4Pop54P6/hVCOO4tmSG/VjMgBEmMvEvOcgjJ4rirDxTr
2mZ+x3bKCMYYK4/JgQDRL4p16eb7RNdF3xjLKpA/DGK39hPZ2NYqWzOtmvo5bhrcSEE9A3yhwf
Q96z/8ASPU/kP8ACuWn1jULkgyyKSOAQiKefcCq3226/v8A/joqlh7AoH//0v5/6KKKACiiigA
ooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKA
CiiigAooooAKKKKACiiigAooooAKKKKAP/T/n/ooooAKKKKACiiigAooooAKKKKACiiigAoooo
AKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiii
gAooooA/9T+f+iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKK
KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/2Q==
REV;VALUE=date:20151029T164508+0800
ADR;TYPE=Work;TYPE=PREF:;;3494 Kuhl Avenue;Atlanta;GA;30303;USA
ADR;TYPE=Home:;;1234 Laurel Street;Atlanta;GA;30303;USA
TEL;TYPE=mobile;TYPE=PREF:888-555-5512
TEL;TYPE=Home:888-555-1212
EMAIL;TYPE=Work;TYPE=PREF:John-Appleseed@mac.com
PRODID:-//address book sync//iOS 9.0 version 1//EN
END:VCARD

注:PHOTO 数据部分作了截取