// // Contact.swift // FriendLender // // Created by Logan Wright on 9/22/14. // Copyright (c) 2014 lowriDevs. All rights reserved. // import UIKit import AddressBook // MARK: Debugging private let ContactDebug = false // MARK: NSCoding Constants private let ContactFirstNameKey = "firstNameKey" private let ContactFirstNamePhoneticKey = "firstNamePhoneticKey" private let ContactMiddleNameKey = "middleNameKey" private let ContactMiddleNamePhoneticKey = "middleNamePhoneticKey" private let ContactLastNameKey = "lastNameKey" private let ContactLastNamePhoneticKey = "lastNamePhoneticKey" private let ContactPrefixKey = "prefixKey" private let ContactSuffixKey = "suffixKey" private let ContactNicknameKey = "nicknameKey" private let ContactBirthDateKey = "birthDateKey" private let ContactCreationDateKey = "creationDateKey" private let ContactModificationDateKey = "modificationDateKey" private let ContactOrganizationKey = "organizationKey" private let ContactJobTitleKey = "jobTitleKey" private let ContactDepartmentKey = "departmentKey" private let ContactPhoneNumbersKey = "phoneNumbersKey" private let ContactEmailsKey = "emailsKey" private let ContactNoteKey = "noteKey" // MARK: Contact Class class Contact: NSObject, NSCoding { // MARK: Names var firstName: String? var firstNamePhonetic: String? var middleName: String? var middleNamePhonetic: String? var lastName: String? var lastNamePhonetic: String? var prefix: String? // Prefix ("Sir" "Duke" "General") - kABStringPropertyType var suffix: String? // Suffix ("Jr." "Sr." "III") - kABStringPropertyType var nickname: String? var fullName: String? { get { var fullName: String = "" if let firstName = self.firstName { fullName += firstName } if let lastName = self.lastName { if countElements(fullName) > 0 { fullName += " " } fullName += lastName } return countElements(fullName) > 0 ? fullName : nil } } // MARK: Dates var birthDate: NSDate? var creationDate: NSDate? var modificationDate: NSDate? // MARK: Work var organization: String? var jobTitle: String? var department: String? // MARK: Contact Information var phoneNumbers: PhoneNumbers? var emails: Emails? // MARK: Additional Info var note: String? // MARK: Initialization init(recordRef: ABRecordRef) { super.init() self.initializeNamesWithABRecordRef(recordRef) self.initializeWorkInfoWithABRecordRef(recordRef) self.initializeCreationInfoWithABRecordRef(recordRef) self.birthDate = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonBirthdayProperty) as? NSDate self.note = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonNoteProperty) as? String if let phonesRef: Unmanaged = ABRecordCopyValue(recordRef, kABPersonPhoneProperty){ self.phoneNumbers = PhoneNumbers(phoneNumbersRef: phonesRef.takeRetainedValue() as ABMultiValueRef) } if let emailRef: Unmanaged = ABRecordCopyValue(recordRef, kABPersonEmailProperty){ self.emails = Emails(emailsRef: emailRef.takeRetainedValue() as ABMultiValueRef) } } func initializeNamesWithABRecordRef(recordRef: ABRecordRef) { self.firstName = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonFirstNameProperty) as? String self.firstNamePhonetic = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonFirstNamePhoneticProperty) as? String self.lastName = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonLastNameProperty) as? String self.lastNamePhonetic = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonLastNamePhoneticProperty) as? String self.middleName = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonMiddleNameProperty) as? String self.middleNamePhonetic = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonMiddleNamePhoneticProperty) as? String self.prefix = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonPrefixProperty) as? String self.suffix = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonSuffixProperty) as? String self.nickname = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonNicknameProperty) as? String } func initializeWorkInfoWithABRecordRef(recordRef: ABRecordRef) { self.organization = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonOrganizationProperty) as? String self.jobTitle = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonJobTitleProperty) as? String self.department = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonDepartmentProperty) as? String } func initializeCreationInfoWithABRecordRef(recordRef: ABRecordRef) { self.creationDate = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonCreationDateProperty) as? NSDate self.modificationDate = self.rawValueFromABRecordRef(recordRef, forProperty: kABPersonModificationDateProperty) as? NSDate } // MARK: Getting Properties From RecordRef func rawValueFromABRecordRef(recordRef: ABRecordRef, forProperty property: ABPropertyID) -> AnyObject? { return ABRecordCopyValue(recordRef, property).takeRetainedValue() } // MARK: NSCoding func encodeWithCoder(aCoder: NSCoder) { if firstName != nil {aCoder.encodeObject(firstName!, forKey: ContactFirstNameKey)} if firstNamePhonetic != nil {aCoder.encodeObject(firstNamePhonetic!, forKey: ContactFirstNamePhoneticKey)} if middleName != nil {aCoder.encodeObject(middleName!, forKey: ContactMiddleNameKey)} if middleNamePhonetic != nil {aCoder.encodeObject(middleNamePhonetic!, forKey: ContactMiddleNamePhoneticKey)} if lastName != nil {aCoder.encodeObject(lastName!, forKey: ContactLastNameKey)} if lastNamePhonetic != nil {aCoder.encodeObject(lastNamePhonetic!, forKey: ContactLastNamePhoneticKey)} if prefix != nil {aCoder.encodeObject(prefix!, forKey: ContactPrefixKey)} if suffix != nil {aCoder.encodeObject(suffix!, forKey: ContactSuffixKey)} if nickname != nil {aCoder.encodeObject(nickname!, forKey: ContactNicknameKey)} if birthDate != nil {aCoder.encodeObject(birthDate!, forKey: ContactBirthDateKey)} if creationDate != nil {aCoder.encodeObject(creationDate!, forKey: ContactCreationDateKey)} if modificationDate != nil {aCoder.encodeObject(modificationDate!, forKey: ContactModificationDateKey)} if organization != nil {aCoder.encodeObject(organization!, forKey: ContactOrganizationKey)} if jobTitle != nil {aCoder.encodeObject(jobTitle!, forKey: ContactJobTitleKey)} if department != nil {aCoder.encodeObject(department!, forKey: ContactDepartmentKey)} if phoneNumbers != nil {aCoder.encodeObject(phoneNumbers!, forKey: ContactPhoneNumbersKey)} if emails != nil {aCoder.encodeObject(emails!, forKey: ContactEmailsKey)} if note != nil {aCoder.encodeObject(note!, forKey: ContactNoteKey)} } required init(coder aDecoder: NSCoder) { self.firstName = aDecoder.decodeObjectForKey(ContactFirstNameKey) as? String self.firstNamePhonetic = aDecoder.decodeObjectForKey(ContactFirstNamePhoneticKey) as? String self.middleName = aDecoder.decodeObjectForKey(ContactMiddleNameKey) as? String self.middleNamePhonetic = aDecoder.decodeObjectForKey(ContactMiddleNamePhoneticKey) as? String self.lastName = aDecoder.decodeObjectForKey(ContactLastNameKey) as? String self.lastNamePhonetic = aDecoder.decodeObjectForKey(ContactLastNamePhoneticKey) as? String self.prefix = aDecoder.decodeObjectForKey(ContactPrefixKey) as? String self.suffix = aDecoder.decodeObjectForKey(ContactSuffixKey) as? String self.nickname = aDecoder.decodeObjectForKey(ContactNicknameKey) as? String self.birthDate = aDecoder.decodeObjectForKey(ContactBirthDateKey) as? NSDate self.creationDate = aDecoder.decodeObjectForKey(ContactCreationDateKey) as? NSDate self.modificationDate = aDecoder.decodeObjectForKey(ContactModificationDateKey) as? NSDate self.organization = aDecoder.decodeObjectForKey(ContactOrganizationKey) as? String self.jobTitle = aDecoder.decodeObjectForKey(ContactJobTitleKey) as? String self.department = aDecoder.decodeObjectForKey(ContactDepartmentKey) as? String self.phoneNumbers = aDecoder.decodeObjectForKey(ContactPhoneNumbersKey) as? PhoneNumbers self.emails = aDecoder.decodeObjectForKey(ContactEmailsKey) as? Emails self.note = aDecoder.decodeObjectForKey(ContactNoteKey) as? String } } // MARK: Emails Class NSCoding Constants private let EmailsHomeKey = "EmailsHomeKey" private let EmailsWorkKey = "EmailsWorkKey" private let EmailsOtherKey = "EmailsOtherKey" private let EmailsUnknownEmailsKey = "EmailsUnknownEmailsKey" // MARK: Emails class Emails: NSObject, NSCoding { // MARK: Public Properties var home: String? var work: String? var other: String? var unknownEmails: [String : String] = [:] var bestEmail: String? { get { var bestEmail: String? if let home = home { bestEmail = home } else if let work = work { bestEmail = work } else if let other = other { bestEmail = other } else if unknownEmails.count > 0 { bestEmail = unknownEmails.values.first } return bestEmail } } // MARK: Initialization init(emailsRef: ABMultiValueRef) { super.init() for i in 0.. 0 {aCoder.encodeObject(unknownEmails, forKey: EmailsUnknownEmailsKey)} } required init(coder aDecoder: NSCoder) { home = aDecoder.decodeObjectForKey(EmailsHomeKey) as? String work = aDecoder.decodeObjectForKey(EmailsWorkKey) as? String other = aDecoder.decodeObjectForKey(EmailsOtherKey) as? String if let decodedUnknownEmails = aDecoder.decodeObjectForKey(EmailsUnknownEmailsKey) as? [String : String] { unknownEmails = decodedUnknownEmails } } } // MARK: Phone Numbers Class NSCoding Constants private let PhoneNumbersMobileKey = "PhoneNumbersMobileKey" private let PhoneNumbersIPhoneKey = "PhoneNumbersIPhoneKey" private let PhoneNumbersMainKey = "PhoneNumbersMainKey" private let PhoneNumbersFaxHomeKey = "PhoneNumbersFaxHomeKey" private let PhoneNumbersFaxWorkKey = "PhoneNumbersFaxWorkKey" private let PhoneNumbersFaxOtherKey = "PhoneNumbersFaxOtherKey" private let PhoneNumbersPagerKey = "PhoneNumbersPagerKey" private let PhoneNumbersHomeKey = "PhoneNumbersHomeKey" private let PhoneNumbersUnknownNumbersKey = "PhoneNumbersUnknownNumbersKey" // MARK: PhoneNumbers class PhoneNumbers: NSObject, NSCoding { // MARK: Public Properties var mobile: String? var iPhone: String? var main: String? var home: String? var faxHome: String? var faxWork: String? var faxOther: String? var pager: String? var unknownNumbers: [String : String] = [:] var bestTextNumber: String? { get { var textNumber: String? if let iPhone = iPhone { textNumber = iPhone } else if let mobile = mobile { textNumber = mobile } else if let main = main { textNumber = main } return textNumber } } var bestPhoneNumber: String? { get { var phoneNumber: String? if let iPhone = iPhone { phoneNumber = iPhone } else if let mobile = mobile { phoneNumber = mobile } else if let main = main { phoneNumber = main } else if let home = home { phoneNumber = home } return phoneNumber } } // MARK: Initialization init(phoneNumbersRef: ABMultiValueRef) { super.init() for i in 0..!$_" { self.home = phoneNumberValue } else { if ContactDebug {println("UnknownPhoneNumberKey: \(phoneNumberKey) Val: \(phoneNumberValue)")} /* I implemented all of the available keys as well as Home, not sure if other keys exist. Just in case, I store unexpected values here. */ unknownNumbers[phoneNumberKey] = phoneNumberValue } if ContactDebug { println("PhoneNumberKey: \(phoneNumberKey)") println("PhoneNumberVal: \(phoneNumberValue)") } } } // MARK: NSCoding func encodeWithCoder(aCoder: NSCoder) { if mobile != nil {aCoder.encodeObject(mobile!, forKey: PhoneNumbersMobileKey)} if iPhone != nil {aCoder.encodeObject(iPhone!, forKey: PhoneNumbersIPhoneKey)} if main != nil {aCoder.encodeObject(main!, forKey: PhoneNumbersMainKey)} if faxHome != nil {aCoder.encodeObject(faxHome!, forKey: PhoneNumbersFaxHomeKey)} if faxWork != nil {aCoder.encodeObject(faxWork!, forKey: PhoneNumbersFaxWorkKey)} if faxOther != nil {aCoder.encodeObject(faxOther!, forKey: PhoneNumbersFaxOtherKey)} if pager != nil {aCoder.encodeObject(pager!, forKey: PhoneNumbersPagerKey)} if home != nil {aCoder.encodeObject(home!, forKey: PhoneNumbersHomeKey)} if unknownNumbers.count > 0 {aCoder.encodeObject(unknownNumbers, forKey: PhoneNumbersUnknownNumbersKey)} } required init(coder aDecoder: NSCoder) { mobile = aDecoder.decodeObjectForKey(PhoneNumbersMobileKey) as? String iPhone = aDecoder.decodeObjectForKey(PhoneNumbersIPhoneKey) as? String main = aDecoder.decodeObjectForKey(PhoneNumbersMainKey) as? String faxHome = aDecoder.decodeObjectForKey(PhoneNumbersFaxHomeKey) as? String faxWork = aDecoder.decodeObjectForKey(PhoneNumbersFaxWorkKey) as? String faxOther = aDecoder.decodeObjectForKey(PhoneNumbersFaxOtherKey) as? String pager = aDecoder.decodeObjectForKey(PhoneNumbersPagerKey) as? String home = aDecoder.decodeObjectForKey(PhoneNumbersHomeKey) as? String if let decodedUnknownNumbersDict = aDecoder.decodeObjectForKey(PhoneNumbersUnknownNumbersKey) as? [String : String] { unknownNumbers = decodedUnknownNumbersDict } } }