Sdílet prostřednictvím


Kontakty a contactsUI v Xamarin.iOS

Tento článek popisuje práci s novými architekturami uživatelského rozhraní Kontakty a Kontakty v aplikaci Xamarin.iOS. Tyto architektury nahrazují stávající uživatelské rozhraní adresáře a adresáře použité v předchozích verzích iOS.

S zavedením iOS 9 společnost Apple vydala dvě nové architektury a ContactsContactsUI, které nahrazují stávající architektury adresáře a uživatelského rozhraní adresáře používané iOS 8 a starší.

Dvě nové architektury obsahují následující funkce:

  • Kontakty – Poskytuje přístup k datům seznamu kontaktů uživatele. Vzhledem k tomu, že většina aplikací vyžaduje přístup jen pro čtení, je tato architektura optimalizovaná pro přístup jen pro přístup jen pro čtení.

  • ContactsUI – Poskytuje prvky uživatelského rozhraní Xamarin.iOS pro zobrazení, úpravy, výběr a vytváření kontaktů na zařízeních s iOSem.

Příklad seznamu kontaktů na zařízení s iOSem

Důležité

Stávající AddressBook a AddressBookUI architektury používané iOSem 8 (a předchozím) jsou v iOSu 9 zastaralé a měly by být nahrazeny novými Contacts a ContactsUI architekturami co nejdříve pro všechny stávající aplikace Xamarin.iOS. Nové aplikace by měly být napsané proti novým architekturám.

V následujících částech se podíváme na tyto nové architektury a na to, jak je implementovat v aplikaci Xamarin.iOS.

Rozhraní Contacts Framework

Rozhraní Contacts Framework poskytuje přístup Xamarin.iOS k kontaktním informacím uživatele. Vzhledem k tomu, že většina aplikací vyžaduje přístup jen pro čtení, je tato architektura optimalizovaná pro přístup jen pro přístup jen pro čtení.

Objekty kontaktu

Třída CNContact poskytuje bezpečný přístup z více vláken, přístup jen pro čtení k vlastnostem kontaktu, jako je jméno, adresa nebo Telefon čísla. CNContact funkce jako a NSDictionary obsahují více kolekcí vlastností jen pro čtení (například adresy nebo telefonní čísla):

Přehled objektu kontaktu

Pro libovolnou vlastnost, která může mít více hodnot (například e-mailovou NSLabeledValue adresu nebo telefonní čísla), budou reprezentovány jako pole objektů. NSLabeledValue je řazená kolekce členů bezpečná pro vlákno, která se skládá ze sady popisků a hodnot jen pro čtení, kde popisek definuje hodnotu pro uživatele (například e-mail domů nebo do práce). Architektura Kontakty poskytuje výběr předdefinovaných popisků (prostřednictvím CNLabelKey statických CNLabelPhoneNumberKey tříd), které můžete použít ve své aplikaci nebo máte možnost definovat vlastní popisky pro vaše potřeby.

Pro libovolnou aplikaci Xamarin.iOS, která potřebuje upravit hodnoty existujícího kontaktu (nebo vytvořit nové), použijte NSMutableContact verzi třídy a její podtřídy (například CNMutablePostalAddress).

Následující kód například vytvoří nový kontakt a přidá ho do kolekce kontaktů uživatele:

// 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);
}

Pokud se tento kód spustí na zařízení s iOSem 9, přidá se do kolekce uživatele nový kontakt. Příklad:

Nový kontakt přidaný do kolekce uživatele

Formátování a lokalizace kontaktů

Rozhraní Contacts obsahuje několik objektů a metod, které vám můžou pomoct formátovat a lokalizovat obsah pro zobrazení pro uživatele. Například následující kód by správně naformátoval jméno kontaktů a poštovní adresu pro zobrazení:

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

U popisků vlastností, které budete zobrazovat v uživatelském rozhraní aplikace, má rozhraní Contact metody pro lokalizaci těchto řetězců. Opět je to založené na aktuálním národním prostředí zařízení s iOSem, na které aplikace běží. Příklad:

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

Načítání existujících kontaktů

Pomocí instance CNContactStore třídy můžete načíst kontaktní informace z databáze kontaktů uživatele. Obsahuje CNContactStore všechny metody potřebné k načtení nebo aktualizaci kontaktů a skupin z databáze. Vzhledem k tomu, že tyto metody jsou synchronní, doporučujeme je spustit ve vlákně na pozadí, aby se zabránilo blokování uživatelského rozhraní.

Pomocí predikátů (sestavených z CNContact třídy) můžete filtrovat výsledky vrácené při načítání kontaktů z databáze. Chcete-li načíst pouze kontakty obsahující řetězec Appleseed, použijte následující kód:

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

Důležité

Architektura Kontakty nepodporuje obecné a složené predikáty.

Pokud chcete například omezit načtení pouze na vlastnosti GivenName a FamilyName kontaktu, použijte následující kód:

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

Nakonec vyhledejte databázi a vraťte výsledky pomocí následujícího kódu:

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

Pokud se tento kód spustil po ukázce, kterou jsme vytvořili v oddílu Contacts Object výše, vrátí kontakt "John Appleseed", který jsme právě vytvořili.

Kontaktování ochrany osobních údajů v aplikaci Access

Vzhledem k tomu, že koncoví uživatelé můžou udělit nebo odepřít přístup ke svým kontaktním informacím na základě aplikace, zobrazí se při prvním volání CNContactStoredialogové okno s žádostí o povolení přístupu k vaší aplikaci.

Žádost o oprávnění se zobrazí jenom jednou, při prvním spuštění aplikace a následné spuštění nebo volání této CNContactStore aplikace použijí oprávnění, které uživatel vybral v daném okamžiku.

Aplikaci byste měli navrhnout tak, aby řádně zpracovala uživatele, který odepře přístup ke své kontaktní databázi.

Načítání částečných kontaktů

Částečný kontakt je kontakt, pro který byly z úložiště kontaktů načteny pouze některé z dostupných vlastností. Pokud se pokusíte získat přístup k vlastnosti, která nebyla dříve načtena, dojde k výjimce.

Pomocí metod CNContact instance můžete snadno zjistit, jestli má daný kontakt požadovanou vlastnost.IsKeyAvailableAreKeysAvailable Příklad:

// 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);
}

Důležité

GetUnifiedContactsCNContactStore Metody GetUnifiedContact třídy vrací pouze částečný kontakt omezený na vlastnosti požadované ze zadaných klíčů pro načtení.

Sjednocené kontakty

Uživatel může mít různé zdroje kontaktních informací pro jednu osobu v jejich kontaktní databázi (například iCloud, Facebook nebo Google Mail). V aplikacích pro iOS a OS X se tyto kontaktní informace automaticky propojí a zobrazí se uživateli jako jediný sjednocený kontakt:

Přehled sjednocených kontaktů

Tento jednotný kontakt je dočasný pohled na kontaktní informace v paměti, které budou mít svůj vlastní jedinečný identifikátor (který by se měl použít k opětovnému načtení kontaktu v případě potřeby). Ve výchozím nastavení vrátí architektura Kontakty jednotný kontakt, kdykoli je to možné.

Vytváření a aktualizace kontaktů

Jak jsme viděli v části Objekty kontaktu výše, použijete CNContactStore instanci a instanci CNMutableContact k vytvoření nových kontaktů, které se pak zapisují do databáze kontaktů uživatele pomocí CNSaveRequestpříkazu :

// 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);
}

Lze CNSaveRequest také použít k ukládání více změn kontaktů a skupin do mezipaměti do jedné operace a dávkování těchto úprav do CNContactStore.

Chcete-li aktualizovat neměnitelný kontakt získaný z operace načítání, musíte nejprve požádat o proměnlivou kopii, kterou pak upravíte a uložíte zpět do úložiště kontaktů. Příklad:

// 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);
}

Oznámení o změnách kontaktů

Pokaždé, když se kontakt změní, publikuje CNContactStoreDidChangeNotification úložiště kontaktů do výchozího centra oznámení. Pokud jste uložili do mezipaměti nebo aktuálně zobrazují nějaké kontakty, budete muset tyto objekty aktualizovat z úložiště kontaktů (CNContactStore).

Kontejnery a skupiny

Kontakty uživatele můžou existovat buď místně na zařízení uživatele, nebo jako kontakty synchronizované se zařízením z jednoho nebo více serverových účtů (jako je Facebook nebo Google). Každý fond kontaktů má svůj vlastní kontejner a daný kontakt může existovat pouze v jednom kontejneru.

Přehled kontejnerů a skupin

Některé kontejnery umožňují uspořádání kontaktů do jedné nebo více skupin nebo dílčích skupin. Toto chování závisí na záložním úložišti pro daný kontejner. Například iCloud má pouze jeden kontejner, ale může mít mnoho skupin (ale žádné podskupy). Microsoft Exchange na druhé straně nepodporuje skupiny, ale může mít více kontejnerů (jeden pro každou složku Exchange).

Překrývat se v rámci kontejnerů a skupin

Architektura ContactsUI

V situacích, kdy aplikace nepotřebuje prezentovat vlastní uživatelské rozhraní, můžete pomocí architektury ContactsUI prezentovat prvky uživatelského rozhraní k zobrazení, úpravě, výběru a vytváření kontaktů v aplikaci Xamarin.iOS.

Díky integrovaným ovládacím prvkům Společnosti Apple nejen snížíte množství kódu, který musíte vytvořit pro podporu kontaktů v aplikaci Xamarin.iOS, ale uživatelům aplikace prezentujete konzistentní rozhraní.

Kontroler zobrazení pro výběr kontaktu

Kontroler zobrazení pro výběr kontaktů (CNContactPickerViewController) spravuje standardní zobrazení pro výběr kontaktů, které umožňuje uživateli vybrat vlastnost Kontakt nebo Kontakt z databáze kontaktů uživatele. Uživatel může vybrat jeden nebo více kontaktů (na základě jejího použití) a kontroler zobrazení pro výběr kontaktů před zobrazením výběru nezobrazí výzvu k zadání oprávnění.

Před voláním CNContactPickerViewController třídy definujete, které vlastnosti může uživatel vybrat a definovat predikáty pro řízení zobrazení a výběru vlastností kontaktu.

Použijte instanci třídy, ze které dědí CNContactPickerDelegate , aby reagovala na interakci uživatele s výběrem. Příklad:

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
    }
}

Pokud chcete uživateli povolit výběr e-mailové adresy z kontaktů v databázi, můžete použít následující kód:

// 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);

Kontroler zobrazení kontaktu

Třída Kontroler zobrazení kontaktu (CNContactViewController) poskytuje kontroler pro prezentování standardního zobrazení kontaktu koncovému uživateli. Zobrazení Kontakt může zobrazit nové nové, neznámé nebo existující kontakty a typ musí být zadán před zobrazením zobrazení voláním správného statického konstruktoru (FromNewContact, FromUnknownContact, FromContact). Příklad:

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

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

Shrnutí

V tomto článku jsme se podrobně podívali na práci s architekturami uživatelského rozhraní contact a contact v aplikaci Xamarin.iOS. Nejprve se zabýval různými typy objektů, které architektura Contact poskytuje a jak je používáte k vytvoření nových nebo přístup k existujícím kontaktům. Prozkoumala také architekturu uživatelského rozhraní kontaktu a vybrala existující kontakty a zobrazila kontaktní informace.