MBS FileMaker Advent calendar - Door 5 - Apple Contacts
Door 5 - Apple Contacts |
Today is day 5 of our calendar and our monkey has a few calls to make on his iPhone. He just doesn't want to keep typing in the number and searching for the customer. It would be much easier if he could simply save the specific contacts in Apple Contacts with the touch of a button. That's no problem, because as a Mac user you can read and write data in Apple Contacts. We use our Contacts functions for this.
But before we can start, we first need to be able to assign phone numbers and email addresses to our contacts. Until now, this was very complicated because we had to leave the giftee layout and enter the data in the respective layouts of the tables. We would now like to change this. To do this, we go to our relationship diagram and double-click on the equal sign between our phone and giftee relationship. Then the Edit Relationship dialog opens and we can make settings. Here we can decide whether we can delete or create data records via this relationship. To do this, we can make a choice in the checkboxes at the bottom. We tick Allow creation of records in this table via this relationship and Delete related records in this table when a record is deleted in the other table for the Telphone table. This allows us to create records in our portal and if a gifte is deleted, the associated telephone numbers are also deleted. We now do the same for the mail addresses.
Now we add a button to our layout with which we export the data to Apple Contacts.
A contact is identified in the Apple phone book by an ID. We get this ID back when we create the contact for the first time. We save it in the database so that we can later change email addresses and telephone numbers in the contact. We add this ContactID as a field to the Giftee table. The field must not be on the layout so that we can read and write it, so we do not add it to the layout.
Now we come to the appropriate script. We first want to distinguish whether we are creating a new contact or whether we are updating a contact that has already been added by FileMaker. We can see whether a contact has already been created by the fact that the ContactID field is empty for a contact that does not exist yet.
If this ContactID field is empty, we create a new contact using the MBS function CNContactStore.NewContact. This function then returns the ContactID, which we store directly in our database. Now we want to enter the values for the contact. The CNContact.SetValue function is available for this purpose. Here we first enter the reference again in the parameters and then the name of the value that we want to change and the value that we want to set. In our case, for example, the names are givenName, familyName and birthday. The value for birthday is not so easy to pass because we have to pass it as JSON. A JSON is a text with a special data structure. In this text, for example, we have entries that are assigned via key-value pairs. So here we have an array that we can imagine as a list with the keys day, month and year, to each of which the appropriate values are assigned. You may find more information about JSON in another door
# Birthday Set Variable [ $day ; Value: Day ( Giftee::Birthday ) ] Set Variable [ $month ; Value: Month ( Giftee::Birthday ) ] Set Variable [ $year ; Value: Year ( Giftee::Birthday ) ] Set Variable [ $BDJSON ; Value: JSONSetElement ( "{}" ; ["day" ; $day ; JSONNumber]; ["month" ; $month ; JSONNumber]; ["year" ; $year ; JSONNumber] ) ] Set Variable [ $JSONBDAYCon ; Value: MBS("CNContact.Value"; $CNID; "birthday") ]
The address is an easier thing to do. In the Apple phone book we can have not just one address, but several, e.g. to the office or home. Since we want to know exactly where the gifts are to be delivered, we limit ourselves to the home address. To add the address there is the function CNContact.AddPostalAddress. In the parameters of this function, we first enter the reference and the label for the address. This is followed by the street, city, state, zip code and country. We could also specify ISOCountryCode, subLocality or subAdministrativeArea. But we will leave these out now.
Set Variable [ $r ; Value: MBS("CNContact.AddPostalAddress"; $CNID; "Home"; Giftee::Street; Giftee::City; Giftee::State; Giftee::Postcode; Giftee::Country) ]
All we need to do is add the telephone numbers and email addresses. We add the individual email addresses and telephone numbers in a similar way to the address, by calling certain functions. Here we use CNContact.AddPhoneNumber and CNContact.AddEmailAddress. In both functions, we first enter the ID, then the label name and finally the number or email address. We determine these values by looping through the two portals. First we go to the portal, we want to run through by specifying the object name of the portal. We gave this object the name in layout mode in the settings. In this Portal we go to the first data record and start the loop. After we have written the data to the address book, we go to the next entry in the portal within the loop. Here we see that for the telephone portal.
Go to Object [ Object Name: "Telephoneportal" ] Go to Portal Row [ Select: Off ; First ] Loop [ Flush: Always ] Set Variable [ $Number ; Value: Telephone::Number ] Set Variable [ $TypTel ; Value: Telephone::Type ] Set Variable [ $r ; Value: MBS("CNContact.AddPhoneNumber"; $CNID; $Number; $TypTel) ] Go to Portal Row [ Select: Off ; Next ; Exit after last: On ] End Loop
Now we have to transfer this new contact to the address book using CNContactStore.AddContact, specifying the reference.
Let's deal with the case in the Else part that the contact already exists, i.e. our ContactID field is not empty. In this case, we save the reference number in a variable so that we can continue working with it. Now problems can occur when retrieving the contact, as there may be an incorrect value in our database. We can counteract this by using CNContact.JSON to get the contact as JSON. If this could not be found in the address book, we get an error back and can record this with MBS(“isError”). In the event of an error, we display a dialog. But if the contact exists in the phone book, it should be updated. To do this, we compare the old values with the new ones. We get the corresponding value with CNContact.Value, enter the ID and the name of the value and compare it with the value from the database in an If. If the values are not the same, the value is set again with CNContact.SetValue. With Birthday, we also get a JSON as a response with this function. To compare this, we also build a JSON from the date of birth in the database and compare the two JSON contents with each other using the MBS function JSON.EqualContent. If they do not match, we have already assembled our JSON that we can set as a value and can pass it.
# Birthday Set Variable [ $day ; Value: Day ( Giftee::Birthday ) ] Set Variable [ $month ; Value: Month ( Giftee::Birthday ) ] Set Variable [ $year ; Value: Year ( Giftee::Birthday ) ] Set Variable [ $BDJSON ; Value: JSONSetElement ( "{}" ; ["day" ; $day ; JSONNumber]; ["month" ; $month ; JSONNumber]; ["year" ; $year ; JSONNumber] ) ] Set Variable [ $JSONBDAYCon ; Value: MBS("CNContact.Value"; $CNID; "birthday") ] If [ MBS("JSON.EqualContent"; $BDJSON; $JSONBDAYCon) ≠ 1 ] Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "birthday"; $BDJSON) ] End If
As the address, telephone numbers and email addresses are difficult to check for existence and changes, we take a radical approach here. We delete the address, all email addresses and telephone numbers from the contact and add them again as previously seen. To delete, we simply use CNContact.SetValue to pass an empty array to the corresponding value name, i.e. an open and a closed square bracket.
# Address Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "postalAddresses"; "[]") ] Set Variable [ $r ; Value: MBS("CNContact.AddPostalAddress"; $CNID; "Home"; Giftee::Street; Giftee::City; Giftee::State; Giftee::Postcode; Giftee::Country) ]
After we have made all the necessary changes, we need to apply these changes to the contacts. To do this, we use the CNContactStore.UpdateContact function, specifying the reference to save the changes.
Now we have done this and can transfer our customer data to the address book at the touch of a button.
Here is the complete script from today:
# Contacts in file Advent24 If [ Giftee::ContactID = "" ] # We need a new Contact Set Variable [ $CNID ; Value: MBS( "CNContactStore.NewContact" ) ] Set Field [ Giftee::ContactID ; $CNID ] Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "givenName"; Giftee::first_name) ] Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "familyName"; Giftee::last_name) ] Set Variable [ $day ; Value: Day ( Giftee::Birthday ) ] Set Variable [ $month ; Value: Month ( Giftee::Birthday ) ] Set Variable [ $year ; Value: Year ( Giftee::Birthday ) ] Set Variable [ $BDJSON ; Value: JSONSetElement ( "{}" ; ["day" ; $day ; JSONNumber]; ["month" ; $month ; JSONNumber]; ["year" ; $year ; JSONNumber] ) ] Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "birthday"; $BDJSON) ] Set Variable [ $r ; Value: MBS("CNContact.AddPostalAddress"; $CNID; "Home"; Giftee::Street; Giftee::City; Giftee::State; Giftee::Postcode; Giftee::Country) ] Go to Object [ Object Name: "Telephoneportal" ] Go to Portal Row [ Select: Off ; First ] Loop [ Flush: Always ] Set Variable [ $Number ; Value: Telephone::Number ] Set Variable [ $TypTel ; Value: Telephone::Type ] Set Variable [ $r ; Value: MBS("CNContact.AddPhoneNumber"; $CNID; $Number; $TypTel) ] Go to Portal Row [ Select: Off ; Next ; Exit after last: On ] End Loop # Go to Object [ Object Name: "EmaiPortal" ] Go to Portal Row [ Select: Off ; First ] Loop [ Flush: Always ] Set Variable [ $Address ; Value: Email::Emailaddress ] Set Variable [ $TypMail ; Value: Email::Typ ] Set Variable [ $r ; Value: MBS("CNContact.AddEmailAddress"; $CNID; $Address; $TypMail) ] Go to Portal Row [ Select: Off ; Next ; Exit after last: On ] End Loop Set Variable [ $r ; Value: MBS("CNContactStore.AddContact"; $CNID) ] # Else # We have an ID in the FMDatabase Set Variable [ $CNID ; Value: Giftee::ContactID ] Set Variable [ $Contact ; Value: MBS( "CNContact.JSON"; $CNID ; 1 ) ] If [ MBS("IsError") = 0 ] # Contact exists If [ MBS("CNContact.Value"; $CNID;"familyName") ≠ Giftee::last_name ] Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "familyName"; Giftee::last_name) ] End If # If [ MBS("CNContact.Value"; $CNID;"givenName") ≠ Giftee::first_name ] Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "givenName"; Giftee::first_name) ] End If # Birthday Set Variable [ $day ; Value: Day ( Giftee::Birthday ) ] Set Variable [ $month ; Value: Month ( Giftee::Birthday ) ] Set Variable [ $year ; Value: Year ( Giftee::Birthday ) ] Set Variable [ $BDJSON ; Value: JSONSetElement ( "{}" ; ["day" ; $day ; JSONNumber]; ["month" ; $month ; JSONNumber]; ["year" ; $year ; JSONNumber] ) ] Set Variable [ $JSONBDAYCon ; Value: MBS("CNContact.Value"; $CNID; "birthday") ] If [ MBS("JSON.EqualContent"; $BDJSON; $JSONBDAYCon) ≠ 1 ] Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "birthday"; $BDJSON) ] End If # # Address Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "postalAddresses"; "[]") ] Set Variable [ $r ; Value: MBS("CNContact.AddPostalAddress"; $CNID; "Home"; Giftee::Street; Giftee::City; Giftee::State; Giftee::Postcode; Giftee::Country) ] # # JSON of the FM Adress vergelichen mit Knoten JSON wenn nicht geich dann mit JSON anlegen Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "phoneNumbers"; "[]") ] Go to Object [ Object Name: "Telephoneportal" ] Go to Portal Row [ Select: Off ; First ] Loop [ Flush: Always ] Set Variable [ $Number ; Value: Telephone::Number ] Set Variable [ $TypTel ; Value: Telephone::Type ] Set Variable [ $r ; Value: MBS("CNContact.AddPhoneNumber"; $CNID; $Number; $TypTel) ] Go to Portal Row [ Select: Off ; Next ; Exit after last: On ] End Loop # Set Variable [ $r ; Value: MBS("CNContact.SetValue"; $CNID; "emailAddresses"; "[]") ] Go to Object [ Object Name: "EmaiPortal" ] Go to Portal Row [ Select: Off ; First ] Loop [ Flush: Always ] Set Variable [ $Address ; Value: Email::Emailaddress ] Set Variable [ $TypMail ; Value: Email::Typ ] Set Variable [ $r ; Value: MBS("CNContact.AddEmailAddress"; $CNID; $Address; $TypMail) ] Go to Portal Row [ Select: Off ; Next ; Exit after last: On ] End Loop # Save Set Variable [ $r ; Value: MBS("CNContactStore.UpdateContact"; $CNID) ] # Else # We have an ID but contact could not be found Show Custom Dialog [ "Error" ; "Contact could not be found" ] End If End If
I look forward to meeting you again tomorrow. Until then, have a peaceful time.
4 👈 | 5 of 24 | 👉 6 |