Kontakty a ContactsUI v Xamarin. iOSContacts and ContactsUI in Xamarin.iOS

Tento článek popisuje práci s novými architekturami uživatelského rozhraní kontaktů a kontaktů v aplikaci Xamarin. iOS. Tyto architektury nahradí stávající adresář a uživatelské rozhraní adresáře používané v předchozích verzích iOS.This article covers working with the new Contacts and Contacts UI frameworks in a Xamarin.iOS app. These frameworks replace the existing Address Book and Address Book UI used in previous versions of iOS.

Po zavedení iOS 9 vydala společnost Apple dvě nové architektury, Contacts ContactsUI které nahradí stávající adresář a rozhraní uživatelského rozhraní adresáře používané systémem iOS 8 a starším.With the introduction of iOS 9, Apple has released two new frameworks, Contacts and ContactsUI, that replace the existing Address Book and Address Book UI frameworks used by iOS 8 and earlier.

Dvě nová rozhraní obsahují následující funkce:The two new frameworks contain the following functionality:

  • Kontakty – poskytuje přístup k datům seznamu kontaktů uživatele.Contacts - Provides access to the user's contact list data. Vzhledem k tomu, že většina aplikací vyžaduje jenom přístup jen pro čtení, toto rozhraní je optimalizované pro bezpečný přístup z více vláken, přístup jen pro čtení.Because most apps only require read-only access, this framework has been optimized for thread safe, read-only access.

  • ContactsUI – poskytuje prvky uživatelského rozhraní Xamarin. iOS pro zobrazení, úpravy, výběr a vytváření kontaktů na zařízeních s iOS.ContactsUI - Provides Xamarin.iOS UI elements to display, edit, select and create contacts on iOS devices.

Příklad listu s kontaktními osobami na zařízení s iOSAn example Contact Sheet on an iOS device

Důležité

Stávající AddressBook rozhraní a AddressBookUI architektury používané systémem iOS 8 (a starším) se už v iOS 9 nepoužívají a měly by být nové a nové architektury nahrazené novým Contacts rozhraním, které je ContactsUI možné použít pro všechny stávající aplikace Xamarin. iOS.The existing AddressBook and AddressBookUI frameworks use by iOS 8 (and prior) have been deprecated in iOS 9 and should be replaced with the new Contacts and ContactsUI frameworks as soon as possible for any existing Xamarin.iOS app. Nové aplikace by se měly zapisovat na nové architektury.New apps should be written against the new frameworks.

V následujících částech se podíváme na tyto nové architektury a postup jejich implementace v aplikaci Xamarin. iOS.In the following sections, we'll take a look at these new frameworks and how to implement them in a Xamarin.iOS app.

Rozhraní kontaktůThe Contacts Framework

Rozhraní kontakty nabízí přístup Xamarin. iOS k kontaktním informacím uživatele.The Contacts Framework provides Xamarin.iOS access to the user's contact information. Vzhledem k tomu, že většina aplikací vyžaduje jenom přístup jen pro čtení, toto rozhraní je optimalizované pro bezpečný přístup z více vláken, přístup jen pro čtení.Because most apps only require read-only access, this framework has been optimized for thread safe, read-only access.

Objekty kontaktuContact Objects

CNContactTřída poskytuje bezpečný přístup z více vláken, přístup jen pro čtení k vlastnostem kontaktu, jako je jméno, adresa nebo telefonní číslo.The CNContact class provides thread safe, read-only access to a contact's properties such as Name, Address or Phone Numbers. CNContact funguje jako NSDictionary a obsahuje více kolekcí vlastností jen pro čtení (například adresy nebo telefonní čísla):CNContact functions like a NSDictionary and contains multiple, read-only collections of properties (such as addresses or phone numbers):

Přehled objektu kontaktuContact Object overview

U všech vlastností, které mohou mít více hodnot (například e-mailové adresy nebo telefonní čísla), budou reprezentovány jako pole NSLabeledValue objektů.For any property that can have multiple values (such as email address or phone numbers), they will be represented as an array of NSLabeledValue objects. NSLabeledValue je podřazená kolekce členů s vláknem, která se skládá z množiny popisků a hodnot jen pro čtení, kde popisek definuje hodnotu uživateli (například domů nebo pracovní e-mail).NSLabeledValue is a thread safe tuple consisting of a read-only set of labels and values where the label defines the value to the user (for example Home or Work email). Rozhraní kontakty nabízí výběr předdefinovaných popisků (prostřednictvím CNLabelKey CNLabelPhoneNumberKey statických tříd a), které můžete použít v aplikaci, nebo máte možnost definovat vlastní štítky podle svých potřeb.The Contacts framework provides a selection of predefined labels (via the CNLabelKey and CNLabelPhoneNumberKey static classes) that you can use in your app or you have the option of defining custom labels for your needs.

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ích podtříd (například CNMutablePostalAddress ).For any Xamarin.iOS app that needs to adjust the values of an existing contact (or create new ones), use the NSMutableContact version of the class and its sub classes (such as CNMutablePostalAddress).

Například následující kód vytvoří nový kontakt a přidá ho do kolekce kontaktů uživatele:For example, the follow code will create a new contact and add it to the user's collection of contacts:

// 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 je tento kód spuštěný na zařízení s iOS 9, přidá se do kolekce uživatele nový kontakt.If this code is run on an iOS 9 device, a new contact will be added to the user's collection. Příklad:For example:

Do kolekce uživatele se přidal nový kontakt.A new contact added to the user's collection

Formátování a lokalizace kontaktuContact Formatting and Localization

Rozhraní kontaktů obsahuje několik objektů a metod, které vám pomůžou při formátování a lokalizaci obsahu pro zobrazení uživateli.The Contacts framework contains several objects and methods that can help you format and localize content for display to the user. Například následující kód bude správně formátovat název kontaktů a poštovní adresu pro zobrazení:For example, the following code would correctly format a contacts name and mailing address for display:

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

Pro popisky vlastností, které se zobrazí v uživatelském rozhraní vaší aplikace, má kontaktní rozhraní metody pro lokalizaci těchto řetězců také.For property labels that you will be displaying in your app's UI, the Contact framework has methods for localizing those strings as well. Tento postup je založený na aktuálním národním prostředí zařízení s iOS, ve kterém se aplikace spouští.Again, this is based on the current locale of the iOS device the app is being run on. Příklad:For example:

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

Načítají se existující kontakty.Fetching Existing Contacts

Pomocí instance CNContactStore třídy můžete načíst kontaktní informace z databáze kontaktů uživatele.By using an instance of the CNContactStore class, you can fetch contact information from the user's contacts database. CNContactStoreObsahuje všechny metody potřebné k načtení nebo aktualizaci kontaktů a skupin z databáze.The CNContactStore contains all of the methods required for fetching or updating contacts and groups from the database. Vzhledem k tomu, že tyto metody jsou synchronní, je doporučeno je spustit ve vlákně na pozadí, aby bylo možné blokování uživatelského rozhraní zabránit.Because these methods are synchronous, it is suggested that you run them on a background thread to keep from blocking the UI.

Pomocí predikátů (sestavených z CNContact třídy) můžete filtrovat výsledky vracené při načítání kontaktů z databáze.By using predicates (built from the CNContact class), you can filter the results returned when fetching contacts from the database. Chcete-li načíst pouze kontakty, které obsahují řetězec Appleseed , použijte následující kód:To fetch only contacts that contain the string Appleseed, use the following code:

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

Důležité

Rozhraní kontaktů nepodporuje obecné a složené predikáty.Generic and compound predicates are not supported by the Contacts framework.

Chcete-li například omezit načtení pouze na vlastnosti daného kontaktu na jméno a rodinu , použijte následující kód:For example, to limit the fetch to only the GivenName and FamilyName properties of the contact, use the following code:

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

Nakonec, pokud chcete vyhledat databázi a vrátit výsledky, použijte následující kód:Finally, to search the database and return the results, use the following code:

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

Pokud byl tento kód spuštěn po ukázce, kterou jsme vytvořili v části Object Contacts výše, vrátí "Jan Appleseed", který jsme právě vytvořili.If this code was run after the sample that we created in the Contacts Object section above, it would return the "John Appleseed" contact that we just created.

Kontaktní údaje k ochraně osobních údajůContact Access Privacy

Vzhledem k tomu, že koncoví uživatelé můžou udělit nebo odepřít přístup ke svým kontaktním údajům na základě jednotlivých aplikací, při prvním volání do se CNContactStore zobrazí dialogové okno s výzvou, aby povolil přístup k vaší aplikaci.Because end users can grant or deny access to their contact information on a per-application basis, the first time you make a call to the CNContactStore, a dialog will be presented asking them to allow access for your app.

Žádost o oprávnění bude prezentována pouze jednou, při prvním spuštění aplikace a následném spuštění nebo volání do nástroje CNContactStore bude používat oprávnění, které uživatel v daném čase vybral.The permission request will only be presented once, the first time the app is run, and subsequent runs or calls to the CNContactStore will use the permission that the user selected at that time.

Měli byste navrhnout aplikaci tak, aby řádně vyplynula přístup uživatelů k své kontaktní databázi.You should design your app so that it gracefully handles the user denying access to their contact database.

Načítají se částečné kontakty.Fetching Partial Contacts

Částečný kontakt je kontaktní osoba, že z obchodu kontaktů pro se načetly jenom některé z dostupných vlastností.A Partial Contact is a contact that only some of the available properties have been fetched from the contact store for. Pokud se pokusíte o přístup k vlastnosti, která nebyla dříve načtena, výsledkem bude výjimka.If you try to access a property that was not previously fetched, it will result in an exception.

Můžete snadno zjistit, jestli daný kontakt má požadovanou vlastnost pomocí IsKeyAvailable AreKeysAvailable metody nebo CNContact instance.You can easily check to see if a given contact has the desired property by using either the IsKeyAvailable or AreKeysAvailable methods of the CNContact instance. Příklad:For example:

// 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é

GetUnifiedContactMetody a GetUnifiedContacts CNContactStore třídy vracejí pouze částečný kontakt omezený na vlastnosti požadované z poskytnutých klíčů načtení.The GetUnifiedContact and GetUnifiedContacts methods of the CNContactStore class only return a Partial Contact limited to the properties requested from the fetch keys provided.

Sjednocené kontaktyUnified Contacts

Uživatel může mít v kontaktní databázi různé zdroje kontaktní informace pro jednoho uživatele (například iCloud, Facebook nebo Google mail).A user might have different sources of contact information for a single person in their contact database (like iCloud, Facebook or Google Mail). V aplikacích pro iOS a OS X se tyto kontaktní údaje automaticky spojí a zobrazí se uživateli jako jediný sjednocený kontakt:In iOS and OS X apps, this contact information will automatically be linked together and displayed to the user as a single, Unified Contact:

Přehled sjednocených kontaktůUnified Contacts overview

Tento Unified Contact je dočasným zobrazením v paměti kontaktních informací, které se budou předávat podle vlastního jedinečného identifikátoru (který by se měl v případě potřeby použít k opětovnému načtení kontaktu).This Unified Contact is a temporary, in-memory view of the link contact information that will be given its own unique identifier (which should be used to refetch the contact if required). Ve výchozím nastavení vrátí architektura kontaktů sjednocený kontakt, kdykoli je to možné.By default, the Contacts framework will return a Unified Contact whenever possible.

Vytváření a aktualizace kontaktůCreating and Updating Contacts

Jak jsme viděli v části objekty kontaktů výše, pomocí CNContactStore a instance a CNMutableContact vytvoříte nové kontakty, které se pak zapíší do databáze kontaktů uživatele pomocí CNSaveRequest :As we saw in the Contact Objects section above, you use a CNContactStore and an instance of a CNMutableContact to create new contacts that are then written to the user's contact database using a 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);
}

CNSaveRequestLze také použít k ukládání více kontaktů a skupin změn do jediné operace a dávkování těchto změn v CNContactStore .A CNSaveRequest can also be used to cache multiple contact and group changes into a single operation and batch those modifications to the CNContactStore.

Pokud chcete aktualizovat neproměnlivý kontakt získaný z operace načtení, musíte nejdřív vyžádat proměnlivou kopii, kterou pak upravíte a pak ji uložíte zpátky do obchodu kontaktů.To update a non-mutable contact obtained from a fetch operation, you must first request a mutable copy that you then modify and save back to the contact store. Příklad:For example:

// 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ůContact Change Notifications

Pokaždé, když se kontakt změní, odešle kontakt do CNContactStoreDidChangeNotification výchozího centra oznámení.Whenever a contact is modified, the Contact Store posts a CNContactStoreDidChangeNotification to the Default Notification Center. Pokud máte v mezipaměti nebo aktuálně zobrazujete nějaké kontakty, budete je muset aktualizovat z obchodu kontaktů ( CNContactStore ).If you have cached or are currently displaying any contacts, you'll need to refresh those objects from the Contact Store (CNContactStore).

Kontejnery a skupinyContainers and Groups

Kontakty uživatele můžou existovat místně na zařízení uživatele nebo jako kontakty synchronizované se zařízením z jednoho nebo několika účtů na serveru (jako je Facebook nebo Google).A user's contacts can exist either locally on the user's device or as contacts synced to the device from one or more server accounts (like Facebook or Google). Každý fond kontaktů má svůj vlastní kontejner a daný kontakt může existovat pouze v jednom kontejneru.Each pool of contacts has its own Container and a given Contact can only exist in one container.

Přehled kontejnerů a skupinContainers and Groups overview

Některé kontejnery umožňují, aby byly kontakty uspořádány do jedné nebo více skupin nebo dílčích skupin.Some Containers allow for Contacts to be arranged into one or more Groups or Sub-Groups. Toto chování závisí na záložním úložišti pro daný kontejner.This behavior is dependent on the backing store for a given Container. Například iCloud má pouze jeden kontejner, ale může mít mnoho skupin (ale žádné podskupiny).For example, iCloud has only one Container but can have many Groups (but no Sub-Groups). Microsoft Exchange na druhé straně nepodporuje skupiny, ale může mít několik kontejnerů (jeden pro každou složku Exchange).Microsoft Exchange on the other hand, does not support groups but can have multiple Containers (one for each Exchange Folder).

Překrytí v kontejnerech a skupináchOverlap within Containers and Groups

ContactsUI FrameworkThe ContactsUI Framework

V situacích, kdy vaše aplikace nemusí prezentovat vlastní uživatelské rozhraní, můžete pomocí ContactsUI architektury prezentovat prvky uživatelského rozhraní pro zobrazení, úpravy, výběr a vytvoření kontaktů v aplikaci Xamarin. iOS.For situations where your application does not need to present a custom UI, you can use the ContactsUI framework to present UI elements to display, edit, select and create contacts in your Xamarin.iOS app.

Pomocí integrovaných ovládacích prvků společnosti Apple nesnižujete pouze množství kódu, který je třeba vytvořit pro podporu kontaktů v aplikaci Xamarin. iOS, ale pro uživatele aplikace prezentujete konzistentní rozhraní.By using Apple's built-in controls you not only reduce the amount of code that you have to create to support Contacts in your Xamarin.iOS app, but you present a consistent interface to the app's users.

Kontroler zobrazení pro výběr kontaktůThe Contact Picker View Controller

Kontroler zobrazení pro výběr kontaktů ( CNContactPickerViewController ) spravuje standardní zobrazení pro výběr kontaktů, které uživateli umožňuje vybrat kontakt nebo vlastnost Contact z databáze kontaktů uživatele.The Contact Picker View Controller (CNContactPickerViewController) manages the standard Contact Picker View that allows the user to select a Contact or a Contact property from the user's Contact Database. Uživatel může vybrat jeden nebo více kontaktů (na základě jejího využití) a kontroler zobrazení pro výběr kontaktů nezobrazí výzvu k zadání oprávnění před zobrazením ovládacího prvku pro výběr.The user can select one or more contact (based on its usage) and the Contact Picker View Controller does not prompt for permission before displaying the picker.

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.Before you call the CNContactPickerViewController class, you define which properties the user can select and define predicates to control the display and selection of Contact Properties.

K CNContactPickerDelegate reakci na interakci uživatele pomocí ovládacího prvku pro výběr použijte instanci třídy, která dědí z.Use an instance of the class that inherits from CNContactPickerDelegate to respond to the user's interaction with the picker. Příklad:For example:

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

Chcete-li uživateli dovolit vybrat e-mailovou adresu z kontaktů ve své databázi, můžete použít následující kód:To allow the user to select an email address from the contacts in their database, you could use the following code:

// 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í kontaktůThe Contact View Controller

Třída kontroleru zobrazení kontaktů ( CNContactViewController ) poskytuje kontroleru, který pro koncového uživatele nabídne standardní zobrazení kontaktu.The Contact View Controller (CNContactViewController) class provides a controller to present a standard Contact View to the end user. Zobrazení kontaktů může zobrazit nové nové, neznámé nebo existující kontakty a typ musí být zadán předtím, než se zobrazení zobrazí voláním správného statického konstruktoru ( FromNewContact , FromUnknownContact , FromContact ).The Contact view can display new New, Unknown or Existing contacts and the type must be specified before the view is displayed by calling the correct static constructor (FromNewContact, FromUnknownContact, FromContact). Příklad:For Example:

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

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

SouhrnSummary

V tomto článku se podrobně podíváme na práci s architekturami uživatelského rozhraní kontaktů a kontaktů v aplikaci Xamarin. iOS.This article has taken a detailed look at working with the Contact and Contact UI frameworks in a Xamarin.iOS application. Nejprve se potýká různých typů objektů, které poskytuje rozhraní pro kontakty, a způsob jejich použití k vytvoření nového nebo přístupu ke stávajícím kontaktům.First, it covered the different types of objects that the Contact framework provides and how you use them to create new or access existing contacts. Také se zkontrolovala architektura uživatelského rozhraní kontaktů a vybere existující kontakty a zobrazí kontaktní informace.It also examined the Contact UI framework to select existing contacts and display contact information.