Condividi tramite


Contatti e contattiUI in Xamarin.iOS

Questo articolo illustra l'uso dei nuovi framework dell'interfaccia utente Contatti e Contatti in un'app Xamarin.iOS. Questi framework sostituiscono l'interfaccia utente della Rubrica e della Rubrica esistente usata nelle versioni precedenti di iOS.

Con l'introduzione di iOS 9, Apple ha rilasciato due nuovi framework, Contacts e ContactsUI, che sostituiscono i framework esistenti dell'interfaccia utente rubrica e rubrica usati da iOS 8 e versioni precedenti.

I due nuovi framework contengono le funzionalità seguenti:

  • Contatti : consente di accedere ai dati dell'elenco contatti dell'utente. Poiché la maggior parte delle app richiede solo l'accesso in sola lettura, questo framework è stato ottimizzato per l'accesso thread-safe e di sola lettura.

  • ContactsUI : fornisce elementi dell'interfaccia utente Xamarin.iOS per visualizzare, modificare, selezionare e creare contatti nei dispositivi iOS.

Foglio contatto di esempio in un dispositivo iOS

Importante

I framework e AddressBookUI esistenti AddressBook usati da iOS 8 (e versioni precedenti) sono stati deprecati in iOS 9 e devono essere sostituiti con i nuovi Contacts framework e ContactsUI appena possibile per qualsiasi app Xamarin.iOS esistente. Le nuove app devono essere scritte nei nuovi framework.

Nelle sezioni seguenti verranno esaminati questi nuovi framework e come implementarli in un'app Xamarin.iOS.

Framework contatti

Contacts Framework fornisce a Xamarin.iOS l'accesso alle informazioni di contatto dell'utente. Poiché la maggior parte delle app richiede solo l'accesso in sola lettura, questo framework è stato ottimizzato per l'accesso thread-safe e di sola lettura.

Oggetti contatto

La CNContact classe fornisce accesso thread-safe e di sola lettura alle proprietà di un contatto, ad esempio Name, Address o Telefono Numbers. CNContact funzioni come e NSDictionary contiene più raccolte di proprietà di sola lettura , ad esempio indirizzi o numeri di telefono:

Panoramica dell'oggetto contact

Per qualsiasi proprietà che può avere più valori, ad esempio l'indirizzo di posta elettronica o i numeri di telefono, verranno rappresentati come una matrice di NSLabeledValue oggetti. NSLabeledValue è una tupla thread-safe costituita da un set di etichette e valori di sola lettura in cui l'etichetta definisce il valore per l'utente (ad esempio, indirizzo di posta elettronica home o aziendale). Il framework Contatti offre una selezione di etichette predefinite (tramite le CNLabelKey classi statiche e CNLabelPhoneNumberKey ) che è possibile usare nell'app oppure è possibile definire etichette personalizzate per le proprie esigenze.

Per qualsiasi app Xamarin.iOS che deve modificare i valori di un contatto esistente (o crearne di nuovi), usare la NSMutableContact versione della classe e le relative classi secondarie ( ad esempio CNMutablePostalAddress).

Ad esempio, il codice seguente creerà un nuovo contatto e lo aggiungerà alla raccolta di contatti dell'utente:

// Create a new Mutable Contact (read/write)
var contact = new CNMutableContact();

// Set standard properties
contact.GivenName = "John";
contact.FamilyName = "Appleseed";

// Add email addresses
var homeEmail = new CNLabeledValue<NSString>(CNLabelKey.Home, new NSString("john.appleseed@mac.com"));
var workEmail = new CNLabeledValue<NSString>(CNLabelKey.Work, new NSString("john.appleseed@apple.com"));
contact.EmailAddresses = new CNLabeledValue<NSString>[] { homeEmail, workEmail };

// Add phone numbers
var cellPhone = new CNLabeledValue<CNPhoneNumber>(CNLabelPhoneNumberKey.iPhone, new CNPhoneNumber("713-555-1212"));
var workPhone = new CNLabeledValue<CNPhoneNumber>("Work", new CNPhoneNumber("408-555-1212"));
contact.PhoneNumbers = new CNLabeledValue<CNPhoneNumber>[] { cellPhone, workPhone };

// Add work address
var workAddress = new CNMutablePostalAddress()
{
    Street = "1 Infinite Loop",
    City = "Cupertino",
    State = "CA",
    PostalCode = "95014"
};
contact.PostalAddresses = new CNLabeledValue<CNPostalAddress>[] { new CNLabeledValue<CNPostalAddress>(CNLabelKey.Work, workAddress) };

// Add birthday
var birthday = new NSDateComponents()
{
    Day = 1,
    Month = 4,
    Year = 1984
};
contact.Birthday = birthday;

// Save new contact
var store = new CNContactStore();
var saveRequest = new CNSaveRequest();
saveRequest.AddContact(contact, store.DefaultContainerIdentifier);

// Attempt to save changes
NSError error;
if (store.ExecuteSaveRequest(saveRequest, out error))
{
    Console.WriteLine("New contact saved");
}
else
{
    Console.WriteLine("Save error: {0}", error);
}

Se questo codice viene eseguito in un dispositivo iOS 9, alla raccolta dell'utente verrà aggiunto un nuovo contatto. Ad esempio:

Nuovo contatto aggiunto alla raccolta dell'utente

Formattazione e localizzazione dei contatti

Il framework Contacts contiene diversi oggetti e metodi che consentono di formattare e localizzare il contenuto per la visualizzazione all'utente. Ad esempio, il codice seguente formatta correttamente un nome di contatti e un indirizzo postale per la visualizzazione:

Console.WriteLine(CNContactFormatter.GetStringFrom(contact, CNContactFormatterStyle.FullName));
Console.WriteLine(CNPostalAddressFormatter.GetStringFrom(workAddress, CNPostalAddressFormatterStyle.MailingAddress));

Per le etichette delle proprietà che verranno visualizzate nell'interfaccia utente dell'app, il framework contact include anche metodi per localizzare tali stringhe. Anche in questo caso, si basa sulle impostazioni locali correnti del dispositivo iOS in cui viene eseguita l'app. Ad esempio:

// Localized properties
Console.WriteLine(CNContact.LocalizeProperty(CNContactOptions.Nickname));
Console.WriteLine(CNLabeledValue<NSString>.LocalizeLabel(CNLabelKey.Home));

Recupero di contatti esistenti

Usando un'istanza della CNContactStore classe , è possibile recuperare le informazioni di contatto dal database contatti dell'utente. CNContactStore Contiene tutti i metodi necessari per il recupero o l'aggiornamento di contatti e gruppi dal database. Poiché questi metodi sono sincroni, è consigliabile eseguirli in un thread in background per evitare di bloccare l'interfaccia utente.

Usando predicati (compilati dalla CNContact classe ), è possibile filtrare i risultati restituiti durante il recupero dei contatti dal database. Per recuperare solo i contatti che contengono la stringa Appleseed, usare il codice seguente:

// Create predicate to locate requested contact
var predicate = CNContact.GetPredicateForContacts("Appleseed");

Importante

I predicati generici e composti non sono supportati dal framework Contatti.

Ad esempio, per limitare il recupero solo alle proprietà GivenName e FamilyName del contatto, usare il codice seguente:

// Define fields to be searched
var fetchKeys = new NSString[] {CNContactKey.GivenName, CNContactKey.FamilyName};

Infine, per eseguire una ricerca nel database e restituire i risultati, usare il codice seguente:

// Grab matching contacts
var store = new CNContactStore();
NSError error;
var contacts = store.GetUnifiedContacts(predicate, fetchKeys, out error);

Se questo codice è stato eseguito dopo l'esempio creato nella sezione Oggetto Contatti precedente, restituirà il contatto "John Appleseed" appena creato.

Privacy dell'accesso ai contatti

Poiché gli utenti finali possono concedere o negare l'accesso alle informazioni di contatto in base all'applicazione, la prima volta che si effettua una chiamata a , verrà visualizzata una finestra di dialogo che chiede di consentire l'accesso per l'app CNContactStore.

La richiesta di autorizzazione verrà presentata una sola volta, la prima volta che l'app viene eseguita e le successive esecuzioni o chiamate a CNContactStore useranno l'autorizzazione selezionata dall'utente in quel momento.

È consigliabile progettare l'app in modo che gestisca normalmente l'utente negando l'accesso al database dei contatti.

Recupero di contatti parziali

Un contatto parziale è un contatto per cui sono state recuperate solo alcune delle proprietà disponibili dall'archivio contatti. Se si tenta di accedere a una proprietà non recuperata in precedenza, verrà generata un'eccezione.

È possibile verificare facilmente se un determinato contatto ha la proprietà desiderata usando i IsKeyAvailable metodi o AreKeysAvailable dell'istanza CNContact . Ad esempio:

// Does the contact contain the requested key?
if (!contact.IsKeyAvailable(CNContactOption.PostalAddresses)) {
    // No, re-request to pull required info
    var fetchKeys = new NSString[] {CNContactKey.GivenName, CNContactKey.FamilyName, CNContactKey.PostalAddresses};
    var store = new CNContactStore();
    NSError error;
    contact = store.GetUnifiedContact(contact.Identifier, fetchKeys, out error);
}

Importante

I GetUnifiedContact metodi e GetUnifiedContacts della CNContactStore classe restituiscono solo un contatto parziale limitato alle proprietà richieste dalle chiavi di recupero fornite.

Contatti unificati

Un utente potrebbe avere diverse origini di informazioni di contatto per una singola persona nel database dei contatti (ad esempio iCloud, Facebook o Google Mail). Nelle app iOS e OS X queste informazioni di contatto verranno automaticamente collegate e visualizzate all'utente come singolo contatto unificato:

Panoramica dei contatti unificati

Questo contatto unificato è una visualizzazione temporanea in memoria delle informazioni di contatto di collegamento a cui verrà assegnato il proprio identificatore univoco (che deve essere usato per rifare il contatto, se necessario). Per impostazione predefinita, il framework Contatti restituirà un contatto unificato ogni volta che possibile.

Creazione e aggiornamento dei contatti

Come illustrato nella sezione Oggetti contatto precedente, si usa un CNContactStore oggetto e un'istanza di per CNMutableContact creare nuovi contatti che vengono quindi scritti nel database dei contatti dell'utente usando :CNSaveRequest

// Create a new Mutable Contact (read/write)
var contact = new CNMutableContact();

// Set standard properties
contact.GivenName = "John";
contact.FamilyName = "Appleseed";

// Save new contact
var store = new CNContactStore();
var saveRequest = new CNSaveRequest();
saveRequest.AddContact(contact, store.DefaultContainerIdentifier);

NSError error;
if (store.ExecuteSaveRequest(saveRequest, out error)) {
    Console.WriteLine("New contact saved");
} else {
    Console.WriteLine("Save error: {0}", error);
}

Un CNSaveRequest oggetto può essere usato anche per memorizzare nella cache più modifiche di contatto e gruppo in un'unica operazione e raggruppare tali modifiche in CNContactStore.

Per aggiornare un contatto non modificabile ottenuto da un'operazione di recupero, è prima necessario richiedere una copia modificabile che si modifica e si salva nell'archivio contatti. Ad esempio:

// Get mutable copy of contact
var mutable = contact.MutableCopy() as CNMutableContact;
var newEmail = new CNLabeledValue<NSString>(CNLabelKey.Home, new NSString("john.appleseed@xamarin.com"));

// Append new email
var emails = new NSObject[mutable.EmailAddresses.Length+1];
mutable.EmailAddresses.CopyTo(emails,0);
emails[mutable.EmailAddresses.Length+1] = newEmail;
mutable.EmailAddresses = emails;

// Update contact
var store = new CNContactStore();
var saveRequest = new CNSaveRequest();
saveRequest.UpdateContact(mutable);

NSError error;
if (store.ExecuteSaveRequest(saveRequest, out error)) {
    Console.WriteLine("Contact updated.");
} else {
    Console.WriteLine("Update error: {0}", error);
}

Notifiche di modifica contatto

Ogni volta che un contatto viene modificato, l'archivio contatti invia un oggetto CNContactStoreDidChangeNotification al Centro notifiche predefinito. Se sono stati memorizzati nella cache o sono attualmente visualizzati contatti, sarà necessario aggiornare tali oggetti dall'Archivio contatti (CNContactStore).

Contenitori e gruppi

I contatti di un utente possono esistere localmente nel dispositivo dell'utente o come contatti sincronizzati con il dispositivo da uno o più account server (ad esempio Facebook o Google). Ogni pool di contatti ha un proprio contenitore e un determinato contatto può esistere solo in un contenitore.

Panoramica di contenitori e gruppi

Alcuni contenitori consentono di disporre i contatti in uno o più gruppi o sottogruppi. Questo comportamento dipende dall'archivio di backup per un determinato contenitore. Ad esempio, iCloud ha un solo contenitore, ma può avere molti gruppi (ma nessun sottogruppi). Microsoft Exchange, invece, non supporta i gruppi, ma può avere più contenitori (uno per ogni cartella di Exchange).

Sovrapposizione all'interno di contenitori e gruppi

The ContactsUI Framework

Per le situazioni in cui l'applicazione non deve presentare un'interfaccia utente personalizzata, è possibile usare il framework ContactsUI per presentare gli elementi dell'interfaccia utente per visualizzare, modificare e creare contatti nell'app Xamarin.iOS.

Usando i controlli predefiniti di Apple non solo si riduce la quantità di codice che è necessario creare per supportare i contatti nell'app Xamarin.iOS, ma si presenta un'interfaccia coerente agli utenti dell'app.

Controller di visualizzazione selezione contatti

Il controller di visualizzazione selezione contatti (CNContactPickerViewController) gestisce la visualizzazione standard selezione contatti che consente all'utente di selezionare un contatto o una proprietà Contact dal database contatti dell'utente. L'utente può selezionare uno o più contatti (in base all'utilizzo) e il controller di visualizzazione selezione contatto non richiede l'autorizzazione prima di visualizzare la selezione.

Prima di chiamare la CNContactPickerViewController classe, definire le proprietà che l'utente può selezionare e definire predicati per controllare la visualizzazione e la selezione di Proprietà contatto.

Usare un'istanza della classe che eredita da CNContactPickerDelegate per rispondere all'interazione dell'utente con la selezione. Ad esempio:

using System;
using System.Linq;
using UIKit;
using Foundation;
using Contacts;
using ContactsUI;

namespace iOS9Contacts
{
    public class ContactPickerDelegate: CNContactPickerDelegate
    {
        #region Constructors
        public ContactPickerDelegate ()
        {
        }

        public ContactPickerDelegate (IntPtr handle) : base (handle)
        {
        }
        #endregion

        #region Override Methods
        public override void ContactPickerDidCancel (CNContactPickerViewController picker)
        {
            Console.WriteLine ("User canceled picker");

        }

        public override void DidSelectContact (CNContactPickerViewController picker, CNContact contact)
        {
            Console.WriteLine ("Selected: {0}", contact);
        }

        public override void DidSelectContactProperty (CNContactPickerViewController picker, CNContactProperty contactProperty)
        {
            Console.WriteLine ("Selected Property: {0}", contactProperty);
        }
        #endregion
    }
}

Per consentire all'utente di selezionare un indirizzo di posta elettronica dai contatti nel database, è possibile usare il codice seguente:

// Create a new picker
var picker = new CNContactPickerViewController();

// Select property to pick
picker.DisplayedPropertyKeys = new NSString[] {CNContactKey.EmailAddresses};
picker.PredicateForEnablingContact = NSPredicate.FromFormat("emailAddresses.@count > 0");
picker.PredicateForSelectionOfContact = NSPredicate.FromFormat("emailAddresses.@count == 1");

// Respond to selection
picker.Delegate = new ContactPickerDelegate();

// Display picker
PresentViewController(picker,true,null);

Controller di visualizzazione contatto

La classe Contact View Controller (CNContactViewController) fornisce un controller per presentare una visualizzazione contatto standard all'utente finale. La visualizzazione Contatto può visualizzare nuovi contatti Nuovi, Sconosciuti o Esistenti e il tipo deve essere specificato prima che la visualizzazione venga visualizzata chiamando il costruttore statico corretto (FromNewContact, FromUnknownContact, FromContact). Ad esempio:

// Create a new contact view
var view = CNContactViewController.FromContact(contact);

// Display the view
PresentViewController(view, true, null);

Riepilogo

Questo articolo ha esaminato in dettaglio l'uso dei framework contatto e contatto dell'interfaccia utente in un'applicazione Xamarin.iOS. In primo luogo, sono stati illustrati i diversi tipi di oggetti forniti dal framework contact e come usarli per creare contatti nuovi o accedere a contatti esistenti. Ha anche esaminato il framework dell'interfaccia utente contatto per selezionare i contatti esistenti e visualizzare le informazioni di contatto.