0

I have a class "Contact" which manages personal information of some people. Now i want to save some of that information using the Contact Framework introduced since iOS 9.

My Contact class has a

  • Home number (huisnummer in Dutch)
  • Mobile number (mobiel in Dutch)

Because some of the contacts have no Home number and some of the contacts have no mobile number it is hard for me to create the array:

// cnContact is an object of the Contact Framework class
// contact is an object of my Contact class

if let huisnummer = contact.huisnummer  {
    if let mobiel = contact.nummer {
        cnContact.phoneNumbers = [CNLabeledValue(label: CNLabelPhoneNumberMain, value: CNPhoneNumber(stringValue: huisnummer)),CNLabeledValue(label: CNLabelPhoneNumberMobile, value: CNPhoneNumber(stringValue: mobiel))]
    } else {
        [CNLabeledValue(label: CNLabelPhoneNumberMain, value: CNPhoneNumber(stringValue: huisnummer))]
    }
} else {
    if let mobiel = contact.nummer {
        cnContact.phoneNumbers = [CNLabeledValue(label: CNLabelPhoneNumberMobile, value: CNPhoneNumber(stringValue: mobiel))]
    }
}

I have to keep checking using swifts conditionals if said number exists. But i thought since this is an inefficient way of saving those contacts that there must be a more efficient way to save this.

How can you create the cnContact's phone numbers in a more efficient way?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Emptyless
  • 2,964
  • 3
  • 20
  • 30
  • 1
    Marlo what problem do you face now? – user3182143 Mar 26 '16 at 17:52
  • 1
    Do you want to fetch contacts from iPhone using Contact framework? – user3182143 Mar 26 '16 at 17:53
  • The problem i was facing is creating (not fetching) contacts with sometimes only a Mobile number sometimes only a Main number and sometimes both. I do that using the code above but it are loops of conditionals while i feel like there must be a more efficient way of creating the contact because of the duplication of code (nested if let statements with the same executed code of creating the array). But while i was typing this I figured out the solution :-) I'll edit the original question so it becomes clear! – Emptyless Mar 27 '16 at 21:28
  • I have added the answer but cannot mark it as solved < 5 hours. I will accept it as the answer after this time period :) – Emptyless Mar 28 '16 at 11:38

2 Answers2

1

Marlo fetching contacts from iPhone using Contacts framework

lazy var contacts: [CNContact] = {
    let contactStore = CNContactStore()
    let keysToFetch = [
        CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
        CNContactEmailAddressesKey,
        CNContactPhoneNumbersKey,
        CNContactImageDataAvailableKey,
        CNContactThumbnailImageDataKey]

    // Get all the containers
    var allContainers: [CNContainer] = []
    do {
        allContainers = try contactStore.containersMatchingPredicate(nil)
    } catch {
        print("Error fetching containers")
    }

    var results: [CNContact] = []

    // Iterate all containers and append their contacts to our results array
    for container in allContainers {
        let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier)

        do {
            let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch)
            results.appendContentsOf(containerResults)
        } catch {
            print("Error fetching results for container")
        }
    }

    return results
}()

Function Permission Authorization

 func askForContactAccess()
 {
    let authorizationStatus = CNContactStore.authorizationStatusForEntityType(CNEntityType.Contacts)
    switch authorizationStatus {
    case .Denied, .NotDetermined:
      self.contactStore.requestAccessForEntityType(CNEntityType.Contacts, completionHandler: { (access, accessError) -> Void in
         if !access {
           if authorizationStatus == CNAuthorizationStatus.Denied {
             dispatch_async(dispatch_get_main_queue(), { () -> Void in
               let message = "\(accessError!.localizedDescription)\n\nPlease allow the app to access your contacts through the Settings."
               let alertController = UIAlertController(title: "Contacts", message: message, preferredStyle: UIAlertControllerStyle.Alert)
               let dismissAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default) { (action) -> Void in
              }
              alertController.addAction(dismissAction)
              self.presentViewController(alertController, animated: true, completion: nil)
           })
         }
       }
     })
   break
      default:
   break
 }
}

Contact - Authorization,Fetch,Add,Update,Search

Contacts Data

Retreive Contacts Data

AppCoda - Contacts

Community
  • 1
  • 1
user3182143
  • 9,459
  • 3
  • 32
  • 39
0

The answer had nothing to do with swift or Contacts framework but rather with programming 1o1. It must have been late that i did not figure out the solution back than but posting the solution anyway:

// Creating empty array of CNLabeledValues
var phoneNumbers : [CNLabeledValue] = []

// Add the mobile number to the array: 
if let mobiel = contact.nummer {
   phoneNumbers.append(CNLabeledValue(label: CNLabelPhoneNumberMobile, value: CNPhoneNumber(stringValue: mobiel)))
}

// Add the Main number to the array:
if let huisnummer = contact.huisnummer {
    phoneNumbers.append(CNLabeledValue(label: CNLabelPhoneNumberMain, value: CNPhoneNumber(stringValue: huisnummer)))
}

// Add the array to the Contacts Framework contact
cnContact.phoneNumbers = phoneNumbers

Thats it :-)

Emptyless
  • 2,964
  • 3
  • 20
  • 30