omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    Contacts API - Group Modification

    Pythonista
    5
    31
    9477
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • hendrikstier
      hendrikstier last edited by

      Hello!

      I'm currently trying to implement a small script to explicitly set/change a single contact's group. I'm not sure how to use the API.

      Reading through http://omz-software.com/pythonista/docs/ios/contacts.html, I find ways to get all groups or those specific to a user, but I do not find information on how to set or change a user's group.

      Did anyone already successfully implement this functionality?

      Kind regards,

      Hendrik

      1 Reply Last reply Reply Quote 0
      • ccc
        ccc last edited by

        Python introspection to the rescue...

        import contacts
        print(dir(contacts.get_all_groups()[-1]))  # dir(the last Group in Contacts)
        

        Group has three methods add_member(), get_members(), and remove_member().

        1 Reply Last reply Reply Quote 0
        • hendrikstier
          hendrikstier last edited by

          Thank you, this is exactly the pointer I need..

          1 Reply Last reply Reply Quote 0
          • hendrikstier
            hendrikstier last edited by

            A quick follow-up question on groups: I try to move a locally created contact to a group that is supposed to reside on a CardDAV-server.

            Is there any way to distinguish between the individual accounts the groups belong to? I ask, because I can iterate over my iCloud-stored groups, but the CardDAV-stored group seems to be missing.

            I will try and find my way in reverse (find a user, that is stored in the CardDAV-group and inspect the attributes), but maybe there is already some advice on how to speed up my learning here...

            1 Reply Last reply Reply Quote 0
            • osamu
              osamu last edited by ccc

              My Pythonista 3 does not have these methods😥

              >>> import contacts
              >>> p = contacts.find('foo')[0]
              >>> g = contacts.Group()
              >>> g.name = 'foobar '
              >>> g = contacts.add_group(g)
              >>> contacts.add_member(p,g)
              Traceback (most recent call last):
                File "<string>", line 1, in <module>
              AttributeError: module 'contacts' has no attribute 'add_member'
              >>> print(dir(contacts.get_all_groups())[-1])
              

              sort

              Where have they gone?

              cvp 1 Reply Last reply Reply Quote 0
              • cvp
                cvp @osamu last edited by cvp

                @osamu small errors

                import contacts
                p = contacts.find('foo')[0]
                g = contacts.Group()
                g.name = 'foobar '
                contacts.add_group(g)
                g.add_member(p)
                contacts.save()
                

                If after multiple tests, you get multiple groups named "foobar", you can remove them via

                import contacts
                for g in contacts.get_all_groups():
                	print(g.name)
                	if 'foobar' in g.name:
                		contacts.remove_group(g)
                contacts.save()
                
                osamu 1 Reply Last reply Reply Quote 0
                • osamu
                  osamu last edited by

                  I got the point. add_member() is a method of object Group().
                  Thanks!

                  1 Reply Last reply Reply Quote 0
                  • osamu
                    osamu @cvp last edited by

                    @cvp one more question.
                    What is the attribute of People() that stores 'date' field?

                    cvp 1 Reply Last reply Reply Quote 0
                    • cvp
                      cvp @osamu last edited by

                      @osamu you need to use ObjectiveC to get dates infos, like

                      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():
                                print(date)					# CNLabeledValue
                                d = date.value()
                                print(d)						# NSDateComponents
                                print(date.label(),':',d.year(),d.month(),d.day())
                      
                      osamu 1 Reply Last reply Reply Quote 0
                      • osamu
                        osamu @cvp last edited by

                        @cvp Thanks! You know everything!
                        Oh, that's very challenging...

                        cvp 1 Reply Last reply Reply Quote 0
                        • cvp
                          cvp @osamu last edited by

                          @osamu said:

                          You know everything!

                          Sincerely, not at all but I'm retired thus I have a lot of time to spend by searching, trying, bugging 😂

                          osamu 1 Reply Last reply Reply Quote 0
                          • osamu
                            osamu @cvp last edited by

                            @cvp Could you give me an example to assign values?

                            cvp 2 Replies Last reply Reply Quote 0
                            • cvp
                              cvp @osamu last edited by

                              @osamu said:

                              Could you give me an example to assign values?

                              Sorry, I don't understand: assign values to what?

                              osamu 1 Reply Last reply Reply Quote 0
                              • ccc
                                ccc last edited by ccc

                                Like setting a person's first name, last name, email address, mobile phone number, country, etc?
                                Reading a value vs. writing a value.

                                1 Reply Last reply Reply Quote 0
                                • cvp
                                  cvp @osamu last edited by cvp

                                  @osamu thanks @ccc for his help

                                  Here, a sample to create a contact with his photo

                                  # https://forum.omz-software.com/topic/2734/contacts-module-access-profile-picture/4
                                  from objc_util import *
                                  import photos
                                  	
                                  # Load classes we need from Contacts.framework:
                                  NSBundle.bundleWithPath_('/System/Library/Frameworks/Contacts.framework').load()
                                  
                                  def main():
                                  	CNContactStore = ObjCClass('CNContactStore').alloc().init().autorelease()
                                  	
                                  	Containers = CNContactStore.containersMatchingPredicate_error_(None,None)
                                  	for Container in Containers:
                                  		containerId = Container.identifier()
                                  		break						# get first container
                                  		
                                  	all_assets =photos.get_assets()
                                  	asset = photos.pick_asset(assets=all_assets)
                                  	img_data_bytes = asset.get_image_data().getvalue()
                                  	
                                  	CNMutableContact = ObjCClass('CNMutableContact').alloc().init()
                                  	CNMutableContact.firstName = 'aaTest'	# just to be the first
                                  	CNMutableContact.imageData = img_data_bytes
                                  	#CNMutableContact.phoneNumbers = ['123','456']
                                  	print(dir(CNMutableContact))
                                  	#return
                                  	
                                  	CNSaveRequest = ObjCClass('CNSaveRequest').new().autorelease()
                                  	CNSaveRequest.addContact_toContainerWithIdentifier_(CNMutableContact, containerId)
                                  	CNContactStore.executeSaveRequest_error_(CNSaveRequest, None)
                                  
                                  if __name__ == '__main__':
                                  	main()
                                  

                                  1 Reply Last reply Reply Quote 0
                                  • osamu
                                    osamu @cvp last edited by

                                    @cvp Sorry, I’d like to know how to assign values to ‘date’ field of contact person.

                                    1 Reply Last reply Reply Quote 0
                                    • JonB
                                      JonB last edited by

                                      You should take a look at the CNMutableContact created here, and you may be able to figure it out.

                                      There should be an attributes dates, which according to the objc docs is an array of CNLabeledValue objects, where the value is an NSDate.

                                      You can create NSDate using

                                      dateobj=ObjCClass('NSDate').dateWithTimeIntervalSince1970_(time.mktime(time.strptime('2017-06-18', '%Y-%m-%d')))
                                      
                                      CNLabeledValue=ObjCClass('CNLabeledValue')
                                      value=CNLabeledValue.alloc().init()
                                      value.label='birthday'
                                      value.value=dateobj
                                      
                                      Then you ought to be able to use
                                      
                                      CNMutableContact.dates=[value]
                                      
                                      
                                      cvp 1 Reply Last reply Reply Quote 0
                                      • cvp
                                        cvp last edited by

                                        As I didn't know which field you want to set, I let a print(dir(CNMutableContact)) in my script, so you could find your-self the name of the field..
                                        But now, as @JonB did the job, all is good so

                                        1 Reply Last reply Reply Quote 0
                                        • cvp
                                          cvp @JonB last edited by cvp

                                          @JonB CNLabeledValue has to be initialized differently

                                          	CNLabeledValue=ObjCClass('CNLabeledValue')
                                          	value=CNLabeledValue.alloc()
                                          	value.initWithLabel_value_('birthday',dateobj)
                                          

                                          But date has to be a NSDateComponents

                                          The app was terminated due to an Objective-C exception. Details below:
                                          
                                          2021-02-02 23:04:50.219269
                                          Labeled value <CNLabeledValue: 0x283090580: identifier=87E927A0-ED12-4AC9-89A8-EE6CCC75441D, label=birthday, value=2017-06-17 22:00:00 +0000, iOSLegacyIdentifier=-1> value 2017-06-17 22:00:00 +0000 has incorrect type __NSTaggedDate. It should be NSDateComponents.
                                          
                                          1 Reply Last reply Reply Quote 1
                                          • cvp
                                            cvp last edited by

                                            That works

                                            	dateComponents = ObjCClass('NSDateComponents').alloc().init()
                                            	dateComponents.day = 4
                                            	dateComponents.month = 5
                                            	dateComponents.year = 2017
                                            
                                            	CNLabeledValue=ObjCClass('CNLabeledValue')
                                            	value=CNLabeledValue.alloc()
                                            	value.initWithLabel_value_('birthday',dateComponents)
                                            	print(dir(CNLabeledValue))
                                            	CNMutableContact.dates=[value]
                                            
                                            osamu 1 Reply Last reply Reply Quote 1
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors