0

I want to allow a user to remove elements( eg CNPhoneNumber, CNEmailAddresses) from a contact after displaying the original contact and depending on what they choose I remove from my edited contact.

Even though I have a mutable contact and use mutable array from the key in my code the returned edited contact won't delete the element.

What am I doing wrong here?

Here is my generic function(Builds and runs fine except for issue listed above)

private func removeFromEditedContact<T:NSString>(labeledValueType:T, with key:String,from contact:CNContact,to toContact:CNContact, at indexPath:IndexPath) -> CNContact {

    let mutableContact = toContact.mutableCopy() as! CNMutableContact


    //what detail are we seraching for in the contact
    if let searchingArray = contact.mutableArrayValue(forKey: key) as? [CNLabeledValue<T>] {
        let searchValue = searchingArray[indexPath.row].value
        //if detail is present in our mutable contact remove it
        var labeledValueToChange = mutableContact.mutableArrayValue(forKey: key) as? [CNLabeledValue<T>]

        if let index = labeledValueToChange?.index(where: {$0.value == searchValue})  {
            labeledValueToChange?.remove(at: index)

        }
    }
    return mutableContact
}
Kaushik Makwana
  • 1,329
  • 2
  • 14
  • 24
Prasanth
  • 646
  • 6
  • 21

1 Answers1

1

The contact is not being modified because you are only removing the value from the mutable array you have created. You have to assign this value back to the contact after removing it from labeledValueToChange like so:

contact.setValue(labeledValueToChange, forKey: key)

Also if the original contact is the one you want to modify you can just pass it to the function directly as an inout parameter. I tried your function and it works like this:

private func removeFromEditedContact<T:NSString>(labeledValueType:T, with key:String,from contact:inout CNMutableContact, at indexPath:IndexPath) -> CNMutableContact {

        //what detail are we seraching for in the contact
        if let searchingArray = contact.mutableArrayValue(forKey: key) as? [CNLabeledValue<T>] {

            let searchValue = searchingArray[indexPath.row].value
            //if detail is present in our mutable contact remove it
            var labeledValueToChange = contact.mutableArrayValue(forKey: key) as? [CNLabeledValue<T>]

            if let index = labeledValueToChange?.index(where: {$0.value == searchValue})  {
                labeledValueToChange?.remove(at: index)
            }


            contact.setValue(labeledValueToChange, forKey: key)
        }

        return contact
    }
Jarvis The Avenger
  • 2,750
  • 1
  • 19
  • 37
adri
  • 265
  • 2
  • 5
  • Thank you Adriana Elizondo. The reason I didn’t think I needed to add it back to the original cncontact is apples description of: mutableArrayValue(forKey:) Returns a mutable array proxy that provides read-write access to an ordered to-many relationship specified by a given key. I thought when it said proxy access it would directly affect the contact property value. – Prasanth Feb 13 '19 at 11:49