Cu iOS 9, OS X El Capitan și watchOS 2, Apple a introdus un nou cadru, Contacte. Acest cadru oferă o abordare orientată pe obiecte pentru a lucra cu informațiile de contact ale utilizatorului și înlocuiește funcția Carte de adrese cadru.
În acest tutorial, vom reimplementa funcționalitatea de bază a aplicației Contacts pe iOS, astfel încât să puteți afla cum funcționează aceste noi interfețe API.
Acest tutorial cere să executați Xcode 7+ pe OS X Yosemite sau mai târziu. De asemenea, va trebui să descărcați proiectul Starter de la GitHub.
Vom utiliza în primul rând cadrul de contacte pentru a accesa contactele utilizatorului și pentru a le afișa într-o vizualizare de tabel. Deschideți proiectul de pornire și mergeți la MasterViewController.swift.
Dacă derulați în partea de sus a fișierului, puteți vedea că am adăugat deja o declarație de import pentru cadrul de contact. Acest lucru ne oferă acces la clasele, protocoalele și constantele definite în cadrul.
importă contacte
În MasterViewController
clasa, înlocuiți punerea în aplicare goală a getContacts ()
cu următoarele metode. Asigurați-vă că adăugați și retrieveContactsWithStore (_ :)
metoda prezentată mai jos.
functieContacts, completeHandler: (autorizat: Bool, eroare: NSError?) -> Void in if authorized self.retrieveContactsWithStore (store)) altfel dacă CNContactStore.authorizationStatusForEntityType (.Contacts) == .Autorizat self.retrieveContactsWithStore (store)
funcția retrieveContactsWithStore (magazin: CNContactStore) do let groups = încercați store.groupsMatchingPredicate (nil) let predicate = CNContact.predicateForContactsInGroupWithIdentifier (grupuri [0] .identifier) [CNNetContactFormatter.descriptorForRequiredKeysForStyle (.FullName), CNContactEmailAddressesKey] contacte = încercați store.unifiedContactsMatchingPredicate (predicate, keysToFetch: keysToFetch) self.objects = contacte dispatch_async (dispatch_get_main_queue (), () -> Void in self.tableView.reloadData captura print (eroare)
Să trecem prin acest pas pas cu pas. Creăm a CNContactStore
și acest obiect este utilizat pentru a comunica direct cu sistemul de contacte din iOS. Apoi verificăm starea de autorizare a CNContactStore
. Dacă este nedeterminat, solicităm autorizarea și preluăm contactele dacă reușim. Dacă aplicația este deja autorizată, preluăm imediat contactele utilizatorului.
În retrieveContactsWithStore (_ :)
metodă, ne împachetăm codul într-un do-catch
deoarece două dintre metodele pe care le folosim sunt metodele de aruncare. Puteți citi mai multe despre metodele de aruncare și tratarea erorilor pe Envato Tuts+.
În do
clauza, vom prelua grupurile de contacte de pe dispozitiv. Utilizarea CNContact
clasa, noi creăm un NSPredicate
obiect care corespunde tuturor contactelor din cadrul primului grup pe care tocmai l-am recuperat.
Apoi creăm o matrice care conține un număr de taste constante. Aceste chei se referă direct la informațiile pe care le are și accesul la aplicație. Pentru orice taste pe care nu le specificați (de exemplu, numărul de telefon), aplicația dvs. nu va putea accesa aceste informații. Când lucrați cu cadrul de contacte, acesta este denumit a contact parțial deoarece nu aveți acces la toate informațiile despre un contact.
Utilizarea magazin
obiect, vom prelua contactele care se potrivesc cu predicatul pe care l-am creat mai devreme și cu tastele specificate. Atribuiți rezultatul la controlerul de vizualizare obiecte
array să fie afișat în vizualizarea tabelului. Aplicăm vizualizarea tabelului pentru a reîncărca firul principal. Acest lucru este important deoarece preluarea contactelor este efectuată pe un fir de fundal.
Există câteva aspecte cheie care trebuie luate în considerare:
descriptorForRequiredKeysForStyle (_ :)
clasa folosită pe CNContactFormatter
este o modalitate convenabilă de a adăuga cu ușurință toate cheile necesare pentru a vizualiza numele unui contact.lasa predicat = CNContact.predicateForContactsMatchingName ("John")
unifiedContactsMatchingPredicate (_: keysToFetch :)
metodă. Ce înseamnă "unificat" în acest context? Dacă un utilizator are mai multe persoane de contact care se referă la aceeași persoană, acestea pot să le conecteze împreună în aplicația Persoane de contact. Când aplicația dvs. încearcă să acceseze mai întâi contactele acestui utilizator, decât să returneze mai multe CNContact
instanțe, cadrul de contacte unifică acestea împreună într-un singur obiect, astfel încât aplicația dvs. să poată afișa corect informațiile și să le interpreteze cu ușurință.Apoi, trebuie să afișăm informațiile despre persoana de contact în ecranul de masă. În MasterViewController
clasa, înlocuiască punerea în aplicare a tableView (_: cellForRowAtIndexPath :)
cu urmatoarele:
suprascrie func tableView (tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell lasa celula = tableView.dequeueReusableCellWithIdentifier ("Cell", pentruIndexPath: indexPath) let contact = self.objects [indexPath.row] let formatter = CNContactFormatter .textLabel? .text = formatter.stringFromContact (contact) cell.detailTextLabel? .text = contact.emailAddresses.first ?.value ca? String retur cell
Folosim CNContactFormatter
clasa pentru a prelua cu ușurință o Şir
valoarea numelui contactului. De asemenea, primim prima adresă de e-mail pentru contact (reprezentată de CNLabeledValue
obiect) și obțineți valoarea sa. A CNLabeledValue
obiect reprezintă orice informație de contact în care poate fi necesară o informație contextuală. Aceste obiecte conțin doar o etichetă și o valoare. În exemplul următor, cuvintele din îndrăzneţ reprezintă eticheta unui articol și cuvintele din cursiv reprezintă valoarea lor.
Construiți și rulați aplicația în simulator. Când executați aplicația pentru prima dată, ar trebui să vedeți următoarea alertă.
După ce faceți clic O.K, vizualizarea tabelului ar trebui să afișeze un element după cum se arată mai jos.
Acum este momentul să completați vizualizarea detaliată când este selectat un contact din vizualizarea tabelului. La preluarea contactelor, am reținut doar suficiente chei pentru a accesa numele și adresele de e-mail ale unui contact. Pentru vizualizarea detaliată a aplicației noastre, dorim și să afișăm adresa, precum și o imagine de profil. Pentru a face acest lucru, am putea adăuga cheile suplimentare în MasterViewController
clasă la preluarea contactelor. Cu toate acestea, vom relua același contact din nou cu cheile de care avem nevoie utilizând identificatorul contactului.
Deschis DetailViewController.swift și să înlocuiască punerea în aplicare a configureView ()
cu următoarele.
func configureView () // Actualizați interfața cu utilizatorul pentru elementul de detaliu. dacă permiteți oldContact = auto.contactItem let store = CNContactStore () nu let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle (.FullName), CNContactEmailAddressesKey, CNContactPostalAddressesKey, CNContactImageDataKey, CNContactImageDataAvailableKey] let contact = try store.unifiedContactWithIdentifier (oldContact.identifier, keysToFetch: (date) auto.fullName.text = CNContactFormatter (date_date_date_main_queue (), () -> Void in if contact.imageDataAvailable ) .stringFromContact (contact) self.email.text = contact.emailAddresses.first? .value ca? String dacă contact.isKeyAvailable (CNContactPostalAddressesKey) dacă permiteți adresa postalAddress = contact.postalAddresses.first? .value ca? CNPostalAddress auto.address .text = CNPostalAddressFormatter () stringFromPostalAddress (postalAddress) altceva self.address.text = "Nici o adresă") captura print (error)
Să lăsăm implementarea în jos. Obținem o referință dezbrăcată la elementul de contact primit de la MasterViewController
și noi creăm un altul CNContactStore
instanță.
În a do-catch
declarație, noi creăm un altul keysToFetch
array, de data aceasta cu tastele pentru adrese poștale, date imagine și date de imagine disponibile. Apoi folosim magazinul de contact pentru a prelua un nou CNContact
instanță cu informațiile de care avem nevoie prin utilizarea unifiedContactWithIdentifier (_: keysToFetch :)
metodă.
Din nou, rețineți că actualizăm interfața de utilizator pe firul principal. Verificăm să vedem dacă sau nu contactul are date de imagine disponibile pentru încărcare și transformă acest lucru într-un UIImage
dacă este posibil. Populam Numele complet
și e-mail
etichete cu informațiile corecte.
Deși nu este strict necesar în acest exemplu, deoarece știm care sunt cheile disponibile, verificăm dacă aplicația noastră poate accesa sau nu informațiile despre adresele poștale ale contactului. Rețineți că acest pas este doar un exemplu, dar ar trebui să se facă întotdeauna cu persoanele de contact dacă nu sunteți sigur despre informațiile pe care le puteți accesa.
Descoperim prima adresă poștală a contactului (reprezentată de CNPostalAddress
clasă) și să formateze acest lucru într - un șir folosind un CNPostalAddressFormatter
instanță. CNPostalAddress
clasa functioneaza similar cu CNContact
dar are proprietăți diferite, cum ar fi strada, provincia și țara.
Construiți și rulați aplicația în simulator și selectați un contact din listă. Vizualizarea detaliată care apare ar trebui să arate cam așa:
Pe lângă recuperarea contactelor, puteți crea și actualiza contacte existente utilizând CNMutableContact
și CNSaveRequest
clase. Deschis AddContactViewController.swift și înlocuiți a lua legatura
proprietate cu următoarea implementare:
var contact: CNContact a se obține let store = CNContactStore () permite contactToAdd = CNMutableContact () contactToAdd.givenName = self.firstName.text ?? "" contactToAdd.familyName = auto.lastName.text ?? "" lasa mobileNumber = CNPhoneNumber (stringValue: (auto.mobileNumber.text ?? "")) lasa mobileValue = CNLabeledValue (eticheta: CNLabelPhoneNumberMobile, value: mobileNumber) contactToAdd.phoneNumbers = [mobileValue] valoare: (auto.homeEmail.text ?? "")) contactToAdd.emailAddresses = [email] dacă permiteți image = self.contactImage.image contactToAdd.imageData = UIImagePNGRpresentation (image) let saveRequest = CNSaveRequest () saveRequest.addContact contactToAdd, toContainerWithIdentifier: nil) nu try store.executeSaveRequest (saveRequest) captura print (error) return contactToAdd
Creăm a CNMutableContact
obiect și a atribui a nume dat
și nume de familie
la el. Rețineți că folosim ??
sau un operator de colastare nul. În cazul în care valoarea din stânga lui ??
operatorul este zero
, în schimb, este atribuită valoarea din dreapta.
Creăm a CNPhoneNumber
obiect pentru a reprezenta numărul mobil introdus în câmpul de text. Apoi am pus acest număr în a CNLabeledValue
obiect cu constanta CNLabelPhoneNumberMobile
eticheta. Utilizarea CNPhoneNumber
clasa este necesară deoarece numerele de telefon pot fi formate în mai multe moduri diferite într-o varietate de regiuni. Această clasă are un șir și creează o valoare a numărului de telefon pe care o poate lucra restul cadrului de contacte. mobileValue
este apoi pus într-o matrice și atribuită contactului mutabil numere de telefon
proprietate.
Noi creăm un lucru similar CNLabeledValue
pentru e-mail, oferindu-i CNLabelHome
eticheta. Această valoare este apoi atribuită contactului adrese de email
proprietate. Verificăm să vedem dacă o imagine a fost atribuită persoanei de contact și, dacă este așa, să îi atribuie datele brute contactului imageData
proprietate.
Pentru a salva contactul, creăm un CNSaveRequest
obiect și numiți-l addContact (_: toContainerWithIdentifier :)
metodă de a spune cadrului de contacte că dorim să creăm un contact nou. Trecând zero
ca identificator, noul contact va fi salvat în grupul implicit de contacte.
In alt do-catch
, spuneți magazinului de contact să execute cererea de salvare. În cele din urmă, returnează contactul nou creat pentru utilizare în restul aplicației.
Construiți și rulați aplicația dvs. și faceți clic pe butonul plus din colțul din dreapta sus pentru a adăuga un contact nou. Completați formularul, adăugați o fotografie și faceți clic pe Terminat. Noul contact trebuie apoi adăugat în vizualizarea de masă a controlerului de vizualizare master așa cum se arată mai jos.
Actualizarea unui contact existent este foarte asemănătoare cu crearea unui nou contact. Deși nu vom implementa acest lucru în aplicație, codul pentru actualizarea unui contact existent ar fi similar cu următorul:
(contactToUpdate = existingContact.mutableCopy () contactToUpdate.emailAddresses.append (CNLabelledValue (etichetă: CNLabelWork, valoare: emailToAdd)) saveRequest = CNSaveRequest () saveRequest.updateContact (contactToUpdate) try store.executeSaveRequest (saveRequest)
După cum am menționat în prima parte a acestui tutorial, cadrul de contacte nu are un API pentru accesarea directă a fiecărui contact de pe dispozitivul utilizatorului. Aceasta este pentru a proteja confidențialitatea utilizatorului, astfel încât aplicațiile să nu poată citi toate contactele și să colecteze informații.
Din fericire, cadrul oferă o UIViewController
subclasă, CNContactPickerViewController
, care oferă utilizatorului acces la toate contactele stocate pe dispozitiv.
Revedeți MasterViewController.swift și adăugați o declarație de import în partea de sus pentru ContactUI.
importați ContactsUI
Apoi, faceți MasterViewController
clasa este conformă cu CNContactPickerDelegate
protocol.
clasa MasterViewController: UITableViewController, CNContactPickerDelegate
Înlocuiți punerea în aplicare a addExistingContact ()
metodă a MasterViewController
clasă cu următoarele:
func addExistingContact () permite contactPicker = CNContactPickerViewController () contactPicker.delegate = auto-auto.presentViewController (contactPicker, animat: true, completare: nil)
În cele din urmă, adăugați următoarea metodă a CNContactPickerDelegate
protocol la MasterViewController
clasă:
(contact: CNContact) NSNotificationCenter.defaultCenter () postNotificationName ("addNewContact", obiect: null, userInfo: ["contactToAdd": contact]
Construiți și rulați aplicația ultima oară și dați clic pe Adăugați existente în colțul din stânga sus. Ar trebui să apară un controler de vizualizare similar cu următorul:
Dacă este selectat un contact din controlerul de vizualizare a contactelor, controlerul de vizualizare respinge și contactul selectat este adăugat la vizualizarea de masă a controlerului de vizualizare master.
Controlerul de vizualizare a contactelor de selectare acceptă, de asemenea, mai multe selecții, în funcție de metodele pe care delegatul le implementează. De asemenea, poate fi personalizat pentru a accesa anumite proprietăți, precum și pentru a filtra contactele pe care le afișează pe baza predicatelor. Pentru mai multe informații, vă recomand să citiți CNContactPickerViewController
clasa de referință și CNContactPickerDelegate
referința protocolului.
După cum puteți vedea, noul cadru de contacte din iOS 9, OS X El Capitan și watchOS 2 este o colecție de API foarte bine concepută și ușor de utilizat. Acum ar trebui să fiți confortabil să accesați, să creați și să actualizați contactele pe dispozitivul unui utilizator. Ca întotdeauna, asigurați-vă că părăsiți comentariile și comentariile dvs. în comentariile de mai jos.