Přehled sady StoreKit a načtení informací o produktu v Xamarin.iOS

Uživatelské rozhraní pro nákup v aplikaci se zobrazuje na následujících snímcích obrazovky. Před provedením jakékoli transakce musí aplikace načíst cenu a popis produktu pro zobrazení. Když uživatel stiskne tlačítko Koupit, aplikace odešle žádost do StorKitu, který spravuje potvrzovací dialogové okno a přihlášení Apple ID. Za předpokladu, že transakce pak bude úspěšná, StoreKit oznámí kód aplikace, který musí uložit výsledek transakce a poskytnout uživateli přístup k jeho nákupu.

StoreKit notifies the application code, which must store the transaction result and provide the user with access to their purchase

Třídy

Implementace nákupů v aplikaci vyžaduje následující třídy z architektury StoreKit:

SKProductsRequest – Žádost o StoreKit o schválené produkty k prodeji (App Store). Dá se nakonfigurovat s řadou ID produktu.

  • SKProductsRequestDelegate – Deklaruje metody pro zpracování požadavků a odpovědí produktu.
  • SKProductsResponse – Odesláno zpět delegátovi z StoreKitu (App Store). Obsahuje skProducts, které odpovídají ID produktů odeslaným s žádostí.
  • SKProduct – Produkt načtený z StorKitu (který jste nakonfigurovali v iTunes Připojení). Obsahuje informace o produktu, jako je ID produktu, název, popis a cena.
  • SKPayment – Vytvořeno s ID produktu a přidáno do platební fronty k provedení nákupu.
  • SKPaymentQueue – žádosti o platbu ve frontě, které se mají odeslat společnosti Apple. Oznámení se aktivují v důsledku zpracování každé platby.
  • SKPaymentTransaction – představuje dokončenou transakci (požadavek na nákup, který byl zpracován App Storem a odeslán zpět do vaší aplikace přes StoreKit). Transakce může být zakoupena, obnovena nebo selhala.
  • SKPaymentTransactionObserver – vlastní podtřída, která reaguje na události generované platební frontou StoreKit.
  • Operace StoreKit jsou asynchronní – po spuštění SKProductRequest nebo přidání SKPaymentu do fronty, vrátí se do vašeho kódu ovládací prvek. StoreKit bude volat metody na vaší podtřídě SKProductsRequestDelegate nebo SKPaymentTransactionObserver, když přijímá data ze serverů Společnosti Apple.

Následující diagram znázorňuje vztahy mezi různými třídami StoreKit (abstraktní třídy musí být implementovány ve vaší aplikaci):

The relationships between the various StoreKit classes abstract classes must be implemented in the app

Tyto třídy jsou podrobněji vysvětleny dále v tomto dokumentu.

Testování

Většina operací StoreKit vyžaduje skutečné zařízení pro testování. Načítání informací o produktu (tj. cena a popis) bude fungovat v simulátoru, ale operace nákupu a obnovení vrátí chybu (například FailedTransaction Code=5002 Došlo k neznámé chybě).

Poznámka: StoreKit nefunguje v simulátoru iOS. Při spuštění aplikace v simulátoru iOS storeKit zaznamená upozornění, pokud se vaše aplikace pokusí načíst platební frontu. Testování úložiště musí být provedeno na skutečných zařízeních.

Důležité: V aplikaci Nastavení se nepřihlašujte pomocí testovacího účtu. Aplikaci Nastavení můžete použít k odhlášení z existujícího účtu Apple ID a pak musíte počkat, až se v pořadí nákupů v aplikaci zobrazí výzva k přihlášení pomocí testovacího Apple ID.

Pokud se pokusíte přihlásit k skutečnému úložišti pomocí testovacího účtu, automaticky se převede na skutečné Apple ID. Tento účet už nebude možné použít k testování.

Pokud chcete otestovat kód StoreKit, musíte se odhlásit z běžného testovacího účtu iTunes a přihlásit se pomocí speciálního testovacího účtu (vytvořeného v iTunes Připojení), který je propojený s testovacím úložištěm. Pokud se chcete odhlásit z aktuálního účtu, navštivte Nastavení > iTunes a App Store, jak je znázorněno tady:

To sign out of the current account visit Settings iTunes and App Store

pak se přihlaste pomocí testovacího účtu , když o to požádá StoreKit v rámci vaší aplikace:

Pokud chcete vytvořit testovací uživatele v iTunes Připojení klikněte na Uživatelé a role na hlavní stránce.

To create test users in iTunes Connect click on Users and Roles on the main page

Výběr testerů sandboxu

Selecting Sandbox Testers

Zobrazí se seznam existujících uživatelů. Můžete přidat nového uživatele nebo odstranit existující záznam. Portál vám (momentálně) neumožňuje zobrazit nebo upravit stávající testovací uživatele, proto doporučujeme, abyste si zachovali dobrý záznam o každém vytvořeném testovacím uživateli (zejména heslo, které přiřadíte). Po odstranění testovacího uživatele nelze e-mailovou adresu znovu použít pro jiný testovací účet.

The list of existing users is displayed

Noví testovací uživatelé mají podobné atributy jako skutečné Apple ID (například jméno, heslo, tajná otázka a odpověď). Uchovávejte záznam všech zde zadaných podrobností. Pole Vybrat iTunes Store určí, jakou měnu a jazyk budou nákupy v aplikaci používat při přihlášení jako daný uživatel.

The Select iTunes Store field will determine the user's currency and language for their in-app purchases

Načítání informací o produktu

Prvním krokem při prodeji produktu pro nákup v aplikaci je zobrazení: načtení aktuální ceny a popisu z App Storu pro zobrazení.

Bez ohledu na to, jaký typ produktů aplikace prodává (spotřební, spotřební, spotřební nebo typ předplatného), je proces načítání informací o produktu pro zobrazení stejný. Kód InAppPurchaseSample, který doprovází tento článek, obsahuje projekt s názvem Spotřební materiál , který ukazuje, jak načíst produkční informace pro zobrazení. Ukazuje, jak:

  • Vytvořte implementaci SKProductsRequestDelegate a implementujte abstraktní metodu ReceivedResponse . Příklad kódu volá tuto InAppPurchaseManager třídu.
  • V Obchodě StoreKit zkontrolujte, jestli jsou povolené platby (pomocí SKPaymentQueue.CanMakePayments ).
  • SKProductsRequest Vytvořte instanci s ID produktu, které byly definovány v Připojení iTunes. To se provádí v ukázkové InAppPurchaseManager.RequestProductData metodě.
  • Volání metody Start na .SKProductsRequest Tím se aktivuje asynchronní volání serverů App Storu. Delegát ( InAppPurchaseManager ) bude volána zpět s výsledky.
  • Metoda delegáta ( InAppPurchaseManager ) ReceivedResponse aktualizuje uživatelské rozhraní dat vrácenými z App Storu (ceny produktů a popisy nebo zprávy o neplatných produktech).

Celková interakce vypadá takto ( StoreKit je integrovaný do iOSu a App Store představuje servery Apple):

Retrieving Product Information graph

Zobrazení příkladu informací o produktu

Vzorový kód InAppPurchaseSampleSpotřební materiál ukazuje, jak lze načíst informace o produktu. Hlavní obrazovka ukázky zobrazuje informace o dvou produktech načtených z App Storu:

The main screen displays information products retrieved from the App Store

Ukázkový kód pro načtení a zobrazení informací o produktu je podrobněji vysvětlen níže.

Metody ViewController

Třída ConsumableViewController bude spravovat zobrazení cen pro dva produkty, jejichž ID produktů jsou pevně kódována ve třídě.

public static string Buy5ProductId = "com.xamarin.storekit.testing.consume5credits",
   Buy10ProductId = "com.xamarin.storekit.testing.consume10credits";
List<string> products;
InAppPurchaseManager iap;
public ConsumableViewController () : base()
{
   // two products for sale on this page
   products = new List<string>() {Buy5ProductId, Buy10ProductId};
   iap = new InAppPurchaseManager();
}

Na úrovni třídy by měl být také deklarován objekt NSObject, který se použije k nastavení pozorovatele NSNotificationCenter :

NSObject priceObserver;

V Metodě ViewWillAppear se pozorovatel vytvoří a přiřadí pomocí výchozího centra oznámení:

priceObserver = NSNotificationCenter.DefaultCenter.AddObserver (
  InAppPurchaseManager.InAppPurchaseManagerProductsFetchedNotification,
(notification) => {
   // display code goes here, to handle the response from the App Store
}

Na konci ViewWillAppear metody zavolejte metodu RequestProductData , která zahájí požadavek StoreKit. Po provedení této žádosti bude StoreKit asynchronně kontaktovat servery Společnosti Apple, aby získal informace a nasílnul je zpět do vaší aplikace. Toho dosáhne SKProductsRequestDelegate podtřída ( InAppPurchaseManager), která je vysvětlena v další části.

iap.RequestProductData(products);

Kód pro zobrazení ceny a popisu jednoduše načte informace z SKProductu a přiřadí je ovládacím prvkům UIKit (všimněte si, že zobrazujeme LocalizedTitle a LocalizedDescription – StoreKit automaticky vyřeší správný text a ceny na základě nastavení účtu uživatele). Následující kód patří do oznámení, které jsme vytvořili výše:

priceObserver = NSNotificationCenter.DefaultCenter.AddObserver (
  InAppPurchaseManager.InAppPurchaseManagerProductsFetchedNotification,
(notification) => {
   // display code goes here, to handle the response from the App Store
   var info = notification.UserInfo;
   if (info.ContainsKey(NSBuy5ProductId)) {
       var product = (SKProduct) info.ObjectForKey(NSBuy5ProductId);
       buy5Button.Enabled = true;
       buy5Title.Text = product.LocalizedTitle;
       buy5Description.Text = product.LocalizedDescription;
       buy5Button.SetTitle("Buy " + product.Price, UIControlState.Normal); // price display should be localized
   }
}

Nakonec by se měla metoda ujistit, ViewWillDisappear že pozorovatel je odebraný:

NSNotificationCenter.DefaultCenter.RemoveObserver (priceObserver);

SkProductRequestDelegate (InAppPurchaseManager) – metody

Metoda RequestProductData se volá, když aplikace chce načíst ceny produktů a další informace. Parsuje kolekci ID produktů do správného datového typu a pak vytvoří s danou SKProductsRequest informací. Volání metody Start způsobí, že se na servery Společnosti Apple provede síťový požadavek. Požadavek se spustí asynchronně a zavolá ReceivedResponse metodu delegáta po úspěšném dokončení.

public void RequestProductData (List<string> productIds)
{
   var array = new NSString[productIds.Count];
   for (var i = 0; i < productIds.Count; i++) {
       array[i] = new NSString(productIds[i]);
   }
   NSSet productIdentifiers = NSSet.MakeNSObjectSet<NSString>(array);​​​
   productsRequest = new SKProductsRequest(productIdentifiers);
   productsRequest.Delegate = this; // for SKProductsRequestDelegate.ReceivedResponse
   productsRequest.Start();
}

IOS automaticky přesměruje požadavek na "sandbox" nebo "produkční" verzi App Storu v závislosti na tom, s jakým zřizovacím profilem aplikace aplikace běží – takže když vyvíjíte nebo testujete aplikaci, bude mít žádost přístup ke všem produktům nakonfigurovaným v iTunes Připojení (i těch, které ještě nebyly odeslány nebo schváleny společností Apple). Když je vaše aplikace v produkčním prostředí, budou žádosti StoreKit vracet pouze informace o schválených produktech.

Metoda ReceivedResponse přepsání se volá, když servery Společnosti Apple odpověděly s daty. Protože je volána na pozadí, kód by měl analyzovat platná data a použít oznámení k odeslání informací o produktu do libovolného ViewControllers, které "naslouchá" pro toto oznámení. Kód pro shromažďování platných informací o produktu a odeslání oznámení je uvedený níže:

public override void ReceivedResponse (SKProductsRequest request, SKProductsResponse response)
{
   SKProduct[] products = response.Products;
   NSDictionary userInfo = null;
   if (products.Length > 0) {
       NSObject[] productIdsArray = new NSObject[response.Products.Length];
       NSObject[] productsArray = new NSObject[response.Products.Length];
       for (int i = 0; i < response.Products.Length; i++) {
           productIdsArray[i] = new NSString(response.Products[i].ProductIdentifier);
           productsArray[i] = response.Products[i];
       }
       userInfo = NSDictionary.FromObjectsAndKeys (productsArray, productIdsArray);
   }
   NSNotificationCenter.DefaultCenter.PostNotificationName (InAppPurchaseManagerProductsFetchedNotification, this, userInfo);
}

I když se tato metoda v diagramu nezobrazuje, měla by se také přepsat, RequestFailed abyste uživateli mohli poskytnout zpětnou vazbu v případě, že servery App Storu nejsou dostupné (nebo dojde k jiné chybě). Ukázkový kód pouze zapisuje do konzoly, ale skutečná aplikace se může rozhodnout dotazovat na error.Code vlastnost a implementovat vlastní chování (například upozornění na uživatele).

public override void RequestFailed (SKRequest request, NSError error)
{
   Console.WriteLine (" ** InAppPurchaseManager RequestFailed() " + error.LocalizedDescription);
}

Tento snímek obrazovky ukazuje ukázkovou aplikaci hned po načtení (pokud nejsou k dispozici žádné informace o produktu):

The sample app immediately after loading when no product information is available

Neplatné produkty

Může SKProductsRequest také vrátit seznam neplatných ID produktů. Neplatné produkty se obvykle vrací z jednoho z následujících důvodů:

ID produktu bylo nesprávně zadáno – Jsou přijata pouze platná ID produktů.

Produkt nebyl schválen – při testování by měly být vráceny všechny produkty, které jsou vymazány k prodeji , SKProductsRequestale v produkčním prostředí jsou vráceny pouze schválené produkty.

ID aplikace není explicitní – ID aplikací se zástupnými znaků (s hvězdičkou) nepovolují nákup v aplikaci.

Nesprávný zřizovací profil – Pokud provedete změny konfigurace aplikace na portálu zřizování (například povolení nákupů v aplikaci), nezapomeňte při vytváření aplikace znovu vygenerovat a použít správný profil zřizování.

Kontrakt placených aplikací pro iOS není zavedený – funkce StoreKit nebudou vůbec fungovat, pokud pro váš vývojářský účet Apple neexistuje platná smlouva.

Binární soubor je ve stavu Odmítnuto – Pokud existuje dříve odeslaný binární soubor ve stavu Odmítnuto (buď týmem App Storu, nebo vývojářem), funkce StoreKit nebudou fungovat.

Metoda ReceivedResponse v ukázkovém kódu vypíše neplatné produkty do konzoly:

public override void ReceivedResponse (SKProductsRequest request, SKProductsResponse response)
{
   // code removed for clarity
   foreach (string invalidProductId in response.InvalidProducts) {
       Console.WriteLine("Invalid product id: " + invalidProductId );
   }
}

Zobrazení lokalizovaných cen

Cenové úrovně určují konkrétní cenu pro každý produkt ve všech mezinárodních obchodech App Stores. Chcete-li zajistit, aby ceny byly zobrazeny správně pro každou měnu, použijte následující rozšiřující metodu (definovanou v SKProductExtension.cs) místo vlastnosti Price každého SKProduct:

public static class SKProductExtension {
   public static string LocalizedPrice (this SKProduct product)
   {
       var formatter = new NSNumberFormatter ();
       formatter.FormatterBehavior = NSNumberFormatterBehavior.Version_10_4;  
       formatter.NumberStyle = NSNumberFormatterStyle.Currency;
       formatter.Locale = product.PriceLocale;
       var formattedString = formatter.StringFromNumber(product.Price);
       return formattedString;
   }
}

Kód, který nastaví název tlačítka, používá metodu rozšíření takto:

string Buy = "Buy {0}"; // or a localizable string
buy5Button.SetTitle(String.Format(Buy, product.LocalizedPrice()), UIControlState.Normal);

Při použití dvou různých testovacích účtů iTunes (jeden pro americký obchod a druhý pro japonský obchod) se zobrazí následující snímky obrazovky:

Two different iTunes test accounts showing language specific results

Všimněte si, že obchod ovlivňuje jazyk, který se používá pro informace o produktu a měnu cen, zatímco nastavení jazyka zařízení ovlivňuje popisky a další lokalizovaný obsah.

Vzpomeňte si, že pokud chcete použít jiný testovací účet obchodu, musíte se odhlásit v Nastavení > iTunes a App Storu a znovu spustit aplikaci pro přihlášení pomocí jiného účtu. Pokud chcete změnit jazyk zařízení, přejděte na Nastavení > Obecný > mezinárodní > jazyk.