Nylas API Contacts CRUD Now Supports iCloud - Nylas

Nylas API Contacts CRUD Now Supports iCloud

6 min read

    Previously, we wrote about our development process for shipping the very beginnings of our Contacts v2.0 upgrade which allows developers to sync contact profiles from address books (like Gmail contacts) into SaaS applications with full CRUD features. The initial release allowed developers to sync contacts from Gmail, Microsoft Exchange, Outlook.com, and Office 365 accounts.

    We’re continuing to build these features to service more types of accounts, and we recently released bi-directional sync and CRUD for iCloud contacts. Now with support for iCloud contacts, developers can interface with more CRUD-supported, information-dense contacts:

    Before

    null

    After

    null

    While integrating Contacts v2.0 for iCloud, we ran into a few challenges around multipart formatting, type mapping, and the management of codebase complexity with one-off adaptations for both multipart formatting and type mapping:

    Multipart Formatting

    One substantial hurdle we faced during this build out process was translating between the different contact providers and our contact models. Each contact provider has its own system and format for collecting contact data. Google has a straightforward interface for its contacts API called gdata, Exchange Active Sync uses tokenized XML through “devices,” and iCloud follows the IETF standard of vCard.

    The vCard format that iCloud implements looks like:

    BEGIN:VCARD
    VERSION:3.0
    UID:123456789
    N:Appleseed;John;;;
    FN:John Appleseed
    NOTE:Good notes
    PHOTO;VALUE=uri;X-ABCROP-RECTANGLE=ABClipRect_1&0&205&1115&1115&hP6x6elkonMVk3k9ibig1g==:https://p41-contacts.icloud.com:000/1234567/wbs/abc123
    item1.ADR;TYPE=WORK;TYPE=pref:;;695 Minna St;San Francisco;CA;;United States
    item1.X-ABADR:us
    TEL;TYPE=CELL;TYPE=pref;TYPE=VOICE:(415) 604-9500
    item2.URL;TYPE=pref:https://www.nylas.com
    item2.X-ABLABEL:_$!!$_
    X-AIM;TYPE=HOME;TYPE=pref:aimaddress
    IMPP;X-SERVICE-TYPE=aim;TYPE=HOME;TYPE=pref:aim:aimaddress
    EMAIL;TYPE=WORK;TYPE=pref;TYPE=INTERNET:[email protected]
    REV:2018-01-01T00:00:00Z
    END:VCARD

    In addition, the parts within a single vCard are different in formatting in small, nuanced ways. Take ADR for example: It follows the format of “{Post Office Address};{Extended Address};{Street};{Locality};{Region};{Postal Code};{Country},” but when iCloud interfaces with the vCard format, the first two parts, Post Office Address and Extended Address, are overall ignored. 

    item1.ADR;TYPE=WORK;TYPE=pref:;;695 Minna St;San Francisco;CA;;United States

    There were many other tiny details regarding multipart formatting that significantly slowed down the development process when interfacing directly with the vCard format. We learned that interface documentation (like the vCard format, for example) can only take you so far because implementations (like iCloud) follow details that other providers don’t and remedying this requires testing as many types of contact information as possible. Through the testing process, we also discovered that any name or address that included a semicolon within each contact was always incorrect.

    Type Mapping

    As another added complexity to the translation, we learned that on top of weird formatting nuances, iCloud fields also have type mappings that are somewhat unintuitive.

    Remember that IMAP example from before?

    IMPP;X-SERVICE-TYPE=aim;TYPE=HOME;TYPE=pref:aim:aimaddress

    You’ll notice that the URI value aim:aimaddress also prepends a protocol and colon; in this case, it’s aim.  Instead of a one-to-one mapping from IMAP service to protocol, the mapping is sometimes many-to-one: both AIM and ICQ use the OSCAR protocol, and iCloud labels this protocol aim. Similarly, QQ and Gadu-Gadu are both labelled with the x-apple protocol.

    Although vCard fields like TEL label types with TYPE, IM addresses are different in that they have more “types.” The most important of all is provider, and it’s labeled with X-SERVICE-TYPE.

    IMPP;X-SERVICE-TYPE=aim;TYPE=HOME;TYPE=pref:aim:aimaddress

    Another example is phone type mappings: A phone labelled as “Home fax” on an iCloud contact is represented as TYPE=HOME;TYPE=FAX instead of TYPE=HOME FAX. The same is true for a phone labelled as “Work fax”: It’s labelled as TYPE=WORK;TYPE=FAX instead of TYPE=WORK FAX.

    Determining these complicated mappings required testing with a single contact that had multiple different types of phone numbers and IM addresses. This made it easier to work around these hurdles.

    Managing Codebase Complexity

    The growth of our codebase with one-off adaptions for different fields and types was a second order effect of the disconnect between interface and implementation. It made our code reviews harder because the iCloud contacts sync was intermingled with the translation between the vCard and contact, so there was no clear delegation of tasks.

    About 2/3 of iCloud v2.0 upgrade’s development was simply this translation. The first half was the pulling of contacts from iCloud, and this complexity was doubled when translating the other way around with CRUD functionality. We realized that we needed a separate adaptor to service the needs of the two-way translation.

    Separating the sync and translation functionalities by creating an adaptor solely for iCloud translation reduced our sync logic code by 60% and made our system even more modular. It also made our code reviews a lot easier, which we love!

    But reducing all of this complexity for our customers also means that using the Nylas API removes the nightmare of interfacing with implementation-specific details of large protocols and substitutes it with a simple and pleasant experience.

    We’d love for you to try it out: head over to our API docs or one of our SDKs to get started.

    Related resources

    Nylas’ 2024 predictions: Navigating AI, connectivity, and the future of work

    Explore the transformative impact of AI, the evolution of global connectivity, and the reshaping of workplace culture in the digital era in Nylas’ 2024 predictions.

    Grouping email threads with Ruby and Nylas

    Use the Nylas Email API and Ruby to group email threads into a single view, and easily access complete conversations within your app.

    How to handle timezones with JavaScript

    Learn how to work with different timezones in JavaScript.