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.
    • 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
                                  • osamu
                                    osamu @cvp last edited by

                                    @cvp @JonB
                                    Thank you folks.
                                    I'm just a Python beginner and I had no place to begin w/ Objective C stuff. Now I think I can begin to try.

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

                                      Now I’m trying to modify and save ‘dates’ field of an existing contact. Though the following script doesn’t spit errors but nothing happens to the contact. Could anybody help?

                                      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)
                                      	'''
                                      	print('First name: ', end='')
                                      	first_name = input()
                                      	print('Last name: ', end='')
                                      	last_name = input()
                                      	'''
                                      	first_name = 'Ludwig'
                                      	last_name = 'Beethoven'
                                      	for contact in predicate_contacts:
                                      		if first_name == str(contact.givenName()) and last_name == str(contact.familyName()):
                                      			break
                                      	CNMutableContact = contact.mutableCopy()
                                      	dateComponents = ObjCClass('NSDateComponents').alloc().init()
                                      	label = 'passing'
                                      	dateComponents.day = 26
                                      	dateComponents.month = 3
                                      	dateComponents.year = 1827
                                      	'''
                                      	print('Label: ', end='')
                                      	label = input()
                                      	print(label.capitalize()+' year: ', end='')
                                      	dateComponents.year = int(input())
                                      	print(label.capitalize()+' month: ', end='')
                                      	dateComponents.month = int(input())
                                      	print(label.capitalize()+' day: ', end='')
                                      	dateComponents.day = int(input())
                                      	'''
                                      	CNLabeledValue=ObjCClass('CNLabeledValue')
                                      	value=CNLabeledValue.alloc()
                                      	value.initWithLabel_value_(label, dateComponents)
                                      	CNMutableContact.dates=[value]
                                      
                                      	CNSaveRequest = ObjCClass('CNSaveRequest').new().autorelease()
                                      	CNSaveRequest.updateContainer_(CNMutableContact)
                                      	CNContactStore.executeSaveRequest_error_(CNSaveRequest, None) ```
                                      cvp 1 Reply Last reply Reply Quote 0
                                      • cvp
                                        cvp @osamu last edited by

                                        @osamu this works

                                        # https://forum.omz-software.com/topic/2734/contacts-module-access-profile-picture/4
                                        from objc_util import *
                                        import photos
                                        import time
                                        	
                                        # 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
                                        		
                                        	dateComponents = ObjCClass('NSDateComponents').alloc().init()
                                        	dateComponents.day = 4
                                        	dateComponents.month = 5
                                        	dateComponents.year = 2017
                                        
                                        	CNLabeledValue=ObjCClass('CNLabeledValue')
                                        	value=CNLabeledValue.alloc()
                                        	value.initWithLabel_value_('passing',dateComponents)
                                        	print(dir(CNLabeledValue))
                                        	CNMutableContact.dates=[value]
                                        	
                                        	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 1
                                        • osamu
                                          osamu last edited by

                                          Wrong: CNSaveRequest.updateContainer_(CNMutableContact)
                                          Correct: CNSaveRequest.updateContact(CNMutableContact)

                                          Console:
                                          First name: Ludwig
                                          Last name: Beethoven
                                          Label: passing
                                          Passing year: 1827
                                          Passing month: 3
                                          Passing day: 26

                                          Final code:

                                          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)
                                          	print('First name: ', end='')
                                          	first_name = input()
                                          	print('Last name: ', end='')
                                          	last_name = input()
                                          	for contact in predicate_contacts:
                                          		if first_name == str(contact.givenName()) and last_name == str(contact.familyName()):
                                          			break
                                          
                                          CNMutableContact = contact.mutableCopy()
                                          dateComponents = ObjCClass('NSDateComponents').alloc().init()
                                          print('Label: ', end='')
                                          label = input()
                                          print(label.capitalize()+' year: ', end='')
                                          dateComponents.year = int(input())
                                          print(label.capitalize()+' month: ', end='')
                                          dateComponents.month = int(input())
                                          print(label.capitalize()+' day: ', end='')
                                          dateComponents.day = int(input())
                                          CNLabeledValue=ObjCClass('CNLabeledValue')
                                          value=CNLabeledValue.alloc()
                                          value.initWithLabel_value_(label, dateComponents)
                                          CNMutableContact.dates=[value]
                                          CNSaveRequest = ObjCClass('CNSaveRequest').new().autorelease()
                                          CNSaveRequest.updateContact(CNMutableContact)
                                          CNContactStore.executeSaveRequest_error_(CNSaveRequest, None)
                                          

                                          I couldn’t attach the capture 😣

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

                                            @osamu you can also see 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 = 'aaTest'
                                            	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()
                                            
                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Powered by NodeBB Forums | Contributors