I have vCards that were exported from the Contacts app of Mac OS X 10.8.2. From what I can tell, Apple exported the notes with RTF that was compressed with LZF and converted the compressed data to base 64 before exporting the vCard. I'm trying to restore an export but the current version (Sonoma 14.2.1) ignores the notes field of the vCard. (I sanitized the contact information but didn't touch the X-APPLE-OL-NOTE section.)
Here's an example vCard:
BEGIN:VCARD
VERSION:3.0
PRODID:-//Apple Inc.//Mac OS X 10.8.2//EN
N:;Jane;;;(Baker) Smith
FN:Jane (Baker) Smith
TEL;type=HOME;type=VOICE;type=pref:(123) 123-4567
TEL;type=CELL;type=VOICE:(321) 321-7654
item1.ADR;type=HOME;type=pref:;;123 Any Street;Any Town;XX;T1T 1T1;Canada
item1.X-ABADR:ca
UID:CZTL-07DB0A0E-002E-0202-FF32-00816
X-ABUID:6EB029FB-BBBB-4242-A054-C5F4392245BD:ABPerson
X-EVOLUTION-FILE-AS:Smith, Jane
X-APPLE-OL-MAPPING-INFO:1
X-APPLE-OL-NOTE;TYPE=text/rtf;X-COMPRESSION=X-OL;X-HASH=03c582c83054be62e05
e09df57aff23b;X-HASHALGORITHM=X-zMD5;ENCODING=B:fAAAAI0AAABMWkZ1YU/S1F8AAwF
AAHIB9wK3VgSQZC0AcGECgAqScASQdzEYMTA0AUAPc2g5OIYwAUAAwHJnbDEMAd0Q4nIRMgsDDN
A1DAEM0F0P4DYC0QoRAUBpAUB1VGxuAiBlAgBjAUBjAQu1IChBYnJhaGBhbXNlKQ9AFcA=
END:VCARD
The note in the above vCard is "(Abrahamse)".
I've attempted to read the Note with the following Swift code (the above vCard is stored on disk as test.vcf):
import Foundation
import Contacts
func readVCard(filePath: String) {
do {
// Read the content of the vCard file
let vCardContent = try String(contentsOfFile: filePath, encoding: .utf8)
// Parse the vCard data
if let data = vCardContent.data(using: .utf8) {
let contacts = try CNContactVCardSerialization.contacts(with: data)
// Print information for each contact
for contact in contacts {
print("Contact Identifier: \(contact.identifier)")
print("Given Name: \(contact.givenName)")
for phoneNumber in contact.phoneNumbers {
print("Phone Number: \(phoneNumber.value.stringValue)")
}
print("Notes: \(contact.note)")
}
}
} catch {
print("Error reading the vCard file: \(error.localizedDescription)")
}
}
// Example usage: replace "test.vcf" with the actual path to your vCard file
let vCardFilePath = "test.vcf"
readVCard(filePath: vCardFilePath)
The output of running the code is below -- the note information is not extracted properly:
Contact Identifier: 2035C9D6-6A76-49F4-A5ED-C2C073A517CE:ABPerson
Given Name: Jane
Phone Number: (123) 123-4567
Phone Number: (321) 321-7654
Notes:
Program ended with exit code: 0
I used the base64 command at the terminal to decode the notes from 2 vcards and the first few bytes were (from xxd):
test.vcf: 00000000: 7c00 0000 8d00 0000 4c5a 4675 614f d2d4 |.......LZFuaO..
second.vcf: 00000000: 5e1f 0000 4f4e 0000 4c5a 4675 59f1 0eeb ^...ON..LZFuY...
So the main overlap is 4c5a 4675, corresponding to LZFu. I wasn't able to match that up with the hints on the Identifying Compression Algorithms page.
How could I extract the note correctly?