Plug-ins > Address Book Manipulator

Custom field behavior - On My Mac vs. iCloud


I'm developing a bi-directional sync with an iCloud Address Book, and trying to piece together how iCloud handles the data between multiple devices.  Among other things, I'm a bit confused how custom fields are handled.  Can anyone confirm or deny my assumptions so far:

The UID for an individual Contact is different depending on the device (searching for the same record will result in a different UID from different computers.  For that matter, when a user makes a change to a Contact on her phone, the UID changes, as if the original record was replaced by a new record on all devices.)  Therefore, I can't rely on the UID to maintain the link between a FM record and the AB record.  So I did some testing with storing the FM ID in a custom field (precisely because the data in a custom field cannot be tampered with by a user).  When I tested locally (contacts On My Mac), I was able to use PCAB_Search to find a record with a particular FM ID in the custom field.  However, now that I'm testing on an iCloud account, the search doesn't work.  But if I search for the contact using, say, first/last name, and open the record, I can still get the value out of the custom field using PCAB_GetCustomField... but only on the computer where the data was originally pushed to AB.  If I find/open the same AB record on another computer, not only is the UID different, the custom field is empty.  (The field exists, but there's no data in it.)

Each individual piece of the puzzle makes sense to me (disappointing as it is), but there seems to be a weird inconsistency in the overall picture.  If the plugin search function works on a custom field when the AB is local, why would it not work on the iCloud account?  Unless... it would make sense if the custom field data was simply not retained once the record was sync'd to iCloud.  However, the data is retained (on the original computer) but the search no longer works.

What this really leads to is... how do you maintain a link between the FM record and the AB record, when both UID and custom fields are not shared among devices?  I could put the FM ID in, say, a Related Person property, but then it's visible (and modifiable) by users, rendering it a bit unreliable.  Am I missing something?

Ideas/techniques would be appreciated!


Paul Dacanay:

A sample use of why you may desire to use the custom field would be to store a FileMaker ID to an Address Book contact record (see page 17 of the Address Book Manipulator Developer Guide).

However, if you wish to relate/link a specific FileMaker contact database record (for a specific logged in user) to a specific Address Book record via the UID, using a "background" (hidden) join table would be the better way to accomplish this.

Try this:

1) After successfully pushing a contact from your FileMaker database, immediately capture the UID generated by the Mac Address Book (in a variable, global field, etc.).
2) Create a unique record in a join table that is only for the specific contact record (and logged in user and specific machine) and store the UID in that record.

This will ensure that the appropriate UID is available when you need to edit/delete a specific Address Book record, since you can reference the related record (for the current contact record, logged in user and machine) and "load" that value into your edit/delete script.

Keep in mind that your relationship will need three Parent predicates (fields) in order to keep it truly unique for the current contact record, user and machine:

1) Serialized ID of the current FileMaker database contact record
2) Account Name of the current logged in user. You can make this an unstored calculation field: Get ( AccountName )
3) The unique address of the current machine. You can make this an unstored calculation field: Get ( SystemNICAddress )

Set the relationship to "allow creation", and when your push script is run, a unique record will be created in the join table when you set the UID field in the join table (after capturing the value upon successful pushing to the Address Book). For edits or deletes, simply reference the related join table record to use the appropriate UID.

Hope this helps,


Paul -

Thanks so much for your reply.  Actually, I am already using a join table as you described.  But that doesn't resolve the issue(s)...

The AB account belongs to one user, who has a laptop, a desktop, an iPad and iPhone, plus her assistant has her iCloud Contacts on her desktop--5 different devices.  If I do a PCAB_Search based on a person's name (yes, I made sure to test with a unique name - the result of the search is 1), and then do a PCAB_OpenFirstRecord, I get a different UID on the laptop than I do from the desktop, or the assistant's computer.  Not only that, I activated the iCloud account on my own computer.  When I open the same record on my computer, not only is the UID different, the creation and modification dates are set to the time that I activated the account.  Obviously, the way iCloud works is to create a local copy of all the Contacts, and when a change is committed from one device, the Contact record is instantly sync'd to all the other devices.  However iCloud doesn't maintain (or expose) a consistent UID or modification date among the copies, which makes it very difficult to keep FM in the loop.

Let's assume we only sync between FM and AB on one computer (the "sync machine"...which was not the plan).  Theoretically the UID would remain consistent on that machine, so I would have a reliable key field to match the AB record to the FM record.  However, when the user makes a change to a Contact on her iPhone, and iCloud syncs that change to the sync machine, the UID changes!  So the UID isn't even reliable as a match field on a single computer, if the iCloud account is accessible on other devices.

Therefore, I need to plant my own unique ID in the record, so that I have a reliable match key.  If I put that ID in one of the standard multi-value property (such as Related Names), it is modifiable by users, rendering it unreliable.   So I tried putting the FM ID in a custom field, where user's can't see it or touch it.  However, while I can retrieve the value (PCAB_GetCustomField) on the sync machine, the value is empty on other devices.  Even if we only sync from one computer, I can't seem to *search* on the custom field - all I can do is loop thru every Contact until I find the one that has my target ID.  PCAB_Search *did work* on the custom field when the AB was local (On My Mac), but it *doesn't work* with an iCloud account.  And... when the user makes a change to a Contact on her iPhone (or even just opens/saves a record) and iCloud syncs it, my FM ID is no longer in the custom field, even on the sync machine.  Doh!

I totally understand there's nothing I can do about the way iCloud functions.  But a) I'm curious why PCAB_Search works on custom fields locally but not in iCloud (even when PCAB_GetCustomField proves the data is in there), b) maybe someone will disprove my testing, or c) perhaps someone can point me to a viable technique for maintaining a unique id across multiple devices.


[0] Message Index

Go to full version