16

Quickly .. I have this code to add new contact , it was working until converting my code to Swift 3 , now it accept all properties except the email I get two errors :

1-Argument type 'String?' does not conform to expected type 'NSCopying'

2-Argument type 'String?' does not conform to expected type 'NSSecureCoding'

this is my code when I try to add email to contact :

    let workEmail = CNLabeledValue(label:"Work Email", value:emp.getEmail())
    contact.emailAddresses = [workEmail]

any help ?

Zizoo
  • 1,694
  • 5
  • 20
  • 42

4 Answers4

33

In Swift 3, CNLabeledValue is declared as:

public class CNLabeledValue<ValueType : NSCopying, NSSecureCoding> : NSObject, NSCopying, NSSecureCoding {
    //...
}

You need to make Swift able to infer the ValueType, which conforms to NSCopying and NSSecureCoding.

Unfortunately, String or String? does not conform to neither of them.

And, Swift 3 removed some implicit type conversions, such as String to NSString, you need to cast it explicitly.

Please try this:

let workEmail = CNLabeledValue(label:"Work Email", value:(emp.getEmail() ?? "") as NSString)
contact.emailAddresses = [workEmail]

Or this:

if let email = emp.getEmail() {
    let workEmail = CNLabeledValue(label:"Work Email", value:email as NSString)
    contact.emailAddresses = [workEmail]
}

(Maybe the latter is the better, you should not make an empty entry.)

And one more, as suggested by Cesare, you'd better use predefined constants like CNLabel... for labels as far as possible:

if let email = emp.getEmail() {
    let workEmail = CNLabeledValue(label: CNLabelWork, value: email as NSString)
    contact.emailAddresses = [workEmail]
}
OOPer
  • 47,149
  • 6
  • 107
  • 142
8

Swift 3: Email and Phone entry

Documentation: https://developer.apple.com/reference/contacts

let workPhoneEntry : String = "(408) 555-0126"
let workEmailEntry : String = "test@apple.com"
let workEmail = CNLabeledValue(label:CNLabelWork, value:workEmailEntry as NSString)
    contact.emailAddresses = [workEmail]

    contact.phoneNumbers = [CNLabeledValue(
        label:CNLabelPhoneNumberMain,
        value:CNPhoneNumber(stringValue:workPhoneEntry))]
9BallOnTheSnap
  • 596
  • 6
  • 10
3
 let workemail = "" //Your Input goes here
 let WorkEmail = CNLabeledValue(label:CNLabelWork, value: workmail as NSString)
 contact.emailAddresses = [WorkEmail]

For Swift 3

BHAVIK
  • 890
  • 7
  • 35
-1

for Swift 3 and ios >= 9.0

You can use method CNContact mutableCopy

func saveVCardContacts (vCard : Data) {
    if #available(iOS 9.0, *) {
        let contactStore = CNContactStore()
        do {
            let saveRequest = CNSaveRequest() 
            let contacts = try CNContactVCardSerialization.contacts(with: vCard)
            var mutablePerson: CNMutableContact
            for person in contacts{
                mutablePerson = person.mutableCopy() as! CNMutableContact
                saveRequest.add(mutablePerson, toContainerWithIdentifier: nil)
            }
            try contactStore.execute(saveRequest)
        } catch  {
            print("Unable to show the new contact")
        }
    }else{
        print("CNContact not supported.")
    }
}
  • This does not answer the question. The OP's code creates a `CNLabeledValue` and he has a problem there. Your example does not address this problem in any way. – naglerrr Mar 02 '17 at 21:19