CNGroup and Adding Contacts

Hi All


I'm currently developing an iOS app using the Contacts Framework to add contacts into a specific Group.


The code currently checks to see if the group exists, if it doesn't, it creates it and stores the Identifier into the UserDefaults store, if not it reads the identifier ready to save the contact later on.

let defaults = UserDefaults.standard
  var groupID = defaults.string(forKey: "contactsGroupID")
  let group = CNMutableGroup()
  var newGroupNeeded = Bool()
   
  if groupID?.isEmpty ?? true {
  let groupName = "my App Contact Group"
  let groupSave = CNSaveRequest()
  let newGroupNeeded = true
  group.name = groupName
  groupSave.add(group, toContainerWithIdentifier: nil)

  do {
  try store.execute(groupSave)
  defaults.set(group.identifier, forKey: "contactsGroupID")
  defaults.set(groupName, forKey: "contactsGroupName")
  print("New Identifer saved: \(group.identifier)")
  } catch let error{
  print(error)
  print()
  }
  }
  else {
  let newGroupNeeded = false
   
  let groupName = defaults.object(forKey: "contactsGroupName")
  var predicate: NSPredicate? = nil
  if let object = [
  defaults.object(forKey: "contactsGroupID")
  ] as? [String] {
  predicate = CNGroup.predicateForGroups(withIdentifiers: object)
  }
  var foundGroups = try? store.groups(matching: predicate)

  let group = foundGroups?.first! as? CNGroup
  print("FOUND GROUP: \(group?.name) & \(group?.identifier)")
  }

This code above all seems to work fine, output is "FOUND GROUP: Optional("my App Contact Group") & Optional("B03C7C3C-5BC7-4ED8-9711-E72E3091EE4E:ABGroup")"


The weird thing is that the following code will save the contact to the group correctly when it is creating the group for the first time, but when the group already exists it errors.


//Code above here sets the MutableContact, name, tele number etc etc

let request2 = CNSaveRequest()

  request2.addMember(newContact, to: group)
  request2.add(newContact, toContainerWithIdentifier: nil)
   
  do{
  try store.execute(request2)
  } catch let error{
  print(error)
  }


As i said before, it works fine before when creating a new contact but i get the following error when trying to add a contact to an existing group.



Error Domain=CNErrorDomain Code=200 "Updated Record Does Not Exist" UserInfo={CNInvalidRecords=(
"<CNMutableGroup: 0x600000d65a80: identifier=EBAF677C-7076-4B55-AC84-84BE705390FF:ABGroup, name=(null)>"
), NSLocalizedFailureReason=The save request failed because it updates a record that does not exist or has already been deleted., NSLocalizedDescription=Updated Record Does Not Exist}


There doesnt seem to be much online to do with Swift and the Contacts Framework so hoping someone in here might be able to advise?


Thanks All

Answered by WhiteT in 360321022

In case this helps anyone in the future:


request2.addMember(newContact, to:group.copy() as! CNGroup)


This little change enabled it to work - i'm still learning Swift so still not 100% sure why it made the difference!

The error message is suggesting that you should store the new Contact to a store, before you add it to some group. Have you tried?

Accepted Answer

In case this helps anyone in the future:


request2.addMember(newContact, to:group.copy() as! CNGroup)


This little change enabled it to work - i'm still learning Swift so still not 100% sure why it made the difference!

Hey WhiteT.


I have a super basic question that I'm hoping you might be able to answer. Am I able to use the Contacts Framework to have my app add my company's phone number to their iPhone contacts? I'm envisoining that after a new user installs my app, i'll walk them through a setup process and one of the steps will be to ask them if they're ok if I add my phone number to their contacts. Does the Contacts Framework have that functionality? Thanks for your adivce!

Does the Contacts Framework have that functionality?

Contacts framework does provide read/write access to the user’s contacts. The main problem with your suggestion is that this access is gated by a authorisation check, and asking for access to all the user’s contacts just so you can add a phone number is unlikely to go over well.

A better option might be to provide your company’s contact info as a vCard that the user can import.

An even better option would be to support Business Chat (-:

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Your fix makes group a CNGroup instead of a CNMutableGroup, although why that should help I am not sure
CNGroup and Adding Contacts
 
 
Q