Forum Archive

Accessing custom labels in Contacts

samaklis

Hi,

I was wondering if custom labels can be accessed through the Contacts module.

For example, I have a custom label on some of my contacts called "nameday", but I do not see a way that the Contacts module would make it accessible, so wondering if there is some undocumented feature.

Thanks

cvp

@samaklis you can have a custom label on several different fields, like phone, email, address...

Exemple if I print contact.email, I get an array of tuples (label,email) and you can see I have some custom labels like "Kindle"

[('_$!<Home>!$_', 'xxxxx@gmail.com'), ('_$!<Work>!$_', 'yyyyy@ec.europa.eu'), ('_$!<Other>!$_', 'zzzzz@hotmail.com'), ('Kindle', 'xxxxx@kindle.com'),] 
samaklis

That works fine for email as it it returns back multi string according to http://omz-software.com/pythonista/docs/ios/contacts.html but contacts in iOS also have the notion of a Date field (in contacts you can add under more fields a "Date" field, and then you can customize the label on it, but from reading the Pythonista documentation it does not seem to be exposed via the Contacts API.

cvp

@samaklis try this

from objc_util import *

# ObjectiveC contacts
CNContactStore = ObjCClass('CNContactStore').alloc().init()
CNContact = ObjCClass('CNContact')
Containers = CNContactStore.containersMatchingPredicate_error_(None,None)
for Container in Containers:
    id = Container.identifier()
    predicate = CNContact.predicateForContactsInContainerWithIdentifier_(id)
    # keys not exactly like in Apple doc
    predicate_contacts = CNContactStore.unifiedContactsMatchingPredicate_keysToFetch_error_(predicate, ['familyName', 'givenName', 'middleName', 'dates'], None)
    for contact in predicate_contacts:
        if len(contact.dates()) == 0:
          continue
        name = str(contact.givenName()) + '|' + str(contact.middleName()) + '|' + str(contact.familyName())
        print(name)
        for date in contact.dates():
          d = date.value()
          print(date.label(),':',d.year(),d.month(),d.day()) 
samaklis

@cvp Thank you. I will try and revert back, but this looks exactly what I was looking for.

Mehaffeys

The list is there, but no "iPhone" option and and no option to add custom labels. It was there recently but no longer there. Would like to have the "iPhone" option back and/or the ability to create my own labels again PrepaidGiftBalance

cvp

@Mehaffeys on my iPad, with last iOS, no problem to add my own labels

cvp

@Mehaffeys you could add by Pythonista script any custom label field, try this

# add a date field with custom label to an existing contact
#   of course extensible to all fields
from objc_util import *

def main():

    CNContactStore = ObjCClass('CNContactStore').alloc().init().autorelease()

    # get a particular contact  
    contact_name = 'a Pythonista'
    date_label   = 'my own label'
    date_ymd     = '20200201'
    CNContact = ObjCClass('CNContact')  
    predicate = CNContact.predicateForContactsMatchingName_(contact_name)
    predicate_contacts = CNContactStore.unifiedContactsMatchingPredicate_keysToFetch_error_(predicate, ['dates'], None)

    for contact in predicate_contacts:
        # Create a CNMutableContact by copy of an existing contact
        CNMutableContact = ObjCClass('CNMutableContact').alloc().init()
        CNMutableContact = contact.mutableCopy()

        # Create a date         
        NSDateComponents = ObjCClass('NSDateComponents').alloc().init()
        NSDateComponents.setDay_  (int(date_ymd[6:8]))
        NSDateComponents.setMonth_(int(date_ymd[4:6]))
        NSDateComponents.setYear_ (int(date_ymd[0:4]))

        # create a custom label
        CNLabeledValue = ObjCClass('CNLabeledValue').alloc()
        CNLabeledValue.initWithLabel_value_(date_label, NSDateComponents)

        # create a date with custom label       
        CNMutableContact.setDates_(ns([CNLabeledValue]))

        # save modified contact     
        CNSaveRequest = ObjCClass('CNSaveRequest').new().autorelease()
        CNSaveRequest.updateContact_(CNMutableContact)
        CNContactStore.executeSaveRequest_error_(CNSaveRequest, None)

if __name__ == '__main__':
    main() 

JonB

Aww, we fell for a spam trick

cvp

@JonB Do you think that about Mehaffeys ? Because samaklis answered.