Nákup spotřebních produktů v Xamarin.iOS
Spotřební produkty jsou nejjednodušší implementovat, protože neexistuje žádný požadavek na obnovení. Jsou užitečné pro produkty, jako je měna v hře nebo jedno použití funkce. Uživatelé si můžou znovu koupit spotřební produkty znovu a znovu.
Integrované doručování produktů
Vzorový kód, který tento dokument doprovází, ukazuje předdefinované produkty – ID produktů jsou pevně zakódovaná do aplikace, protože jsou úzce svázané s kódem, který funkci po zaplacení "odemkne". Proces nákupu lze vizualizovat takto:
Základní pracovní postup je:
Aplikace přidá do
SKPayment
fronty. V případě potřeby se uživateli zobrazí výzva k zadání Apple ID a zobrazí se výzva k potvrzení platby.StoreKit odešle požadavek na server ke zpracování.
Po dokončení transakce server odpoví účtem transakce.
Podtřída
SKPaymentTransactionObserver
obdrží potvrzení a zpracuje ji.Aplikace povolí produkt (aktualizací
NSUserDefaults
nebo jiným mechanismem) a potom zavolá StoreKitFinishTransaction
.
Existuje jiný typ pracovního postupu – Produkty doručené serverem – které jsou popsány dále v dokumentu (viz část Ověření příjmu a Produkty doručené serverem).
Příklad spotřebních produktů
Ukázka obsahuje projekt s názvem Spotřební materiál , který implementuje základní "herní měnu" (označovanou jako "opice kredity"). Ukázka ukazuje, jak implementovat dva produkty nákupu v aplikaci, aby si uživatel mohl koupit tolik "opičích kreditů", kolik si přeje – ve skutečné aplikaci by také nějaký způsob, jak je utratit!
Aplikace se zobrazí na těchto snímcích obrazovky – každý nákup přidá do zůstatku uživatele další kredity opice:
Interakce mezi vlastními třídami, StoreKitem a App Storem vypadají takto:
Metody ViewController
Kromě vlastností a metod potřebných k načtení informací o produktu vyžaduje kontroler zobrazení k naslouchání oznámením souvisejícím s nákupem další pozorovatelé oznámení. Jedná se pouze NSObjects
o to, že se zaregistrují a odeberou a ViewWillAppear
ViewWillDisappear
v uvedeném pořadí.
NSObject succeededObserver, failedObserver;
Konstruktor vytvoří také podtřídu SKProductsRequestDelegate
( InAppPurchaseManager
), která zase vytvoří a zaregistruje SKPaymentTransactionObserver
( CustomPaymentObserver
).
První částí zpracování transakce nákupu v aplikaci je zpracovat tlačítko stisknout, když si uživatel přeje něco koupit, jak je znázorněno v následujícím kódu z ukázkové aplikace:
buy5Button.TouchUpInside += (sender, e) => {
iap.PurchaseProduct (Buy5ProductId);
};
buy10Button.TouchUpInside += (sender, e) => {
iap.PurchaseProduct (Buy10ProductId);
};
Druhá část uživatelského rozhraní zpracovává oznámení, že transakce byla úspěšná, v tomto případě aktualizací zobrazeného zůstatku:
succeededObserver = NSNotificationCenter.DefaultCenter.AddObserver (InAppPurchaseManager.InAppPurchaseManagerTransactionSucceededNotification,
(notification) => {
balanceLabel.Text = CreditManager.Balance() + " monkey credits";
});
Poslední část uživatelského rozhraní zobrazuje zprávu, pokud je transakce zrušena z nějakého důvodu. V ukázkovém kódu se zpráva jednoduše zapíše do okna výstupu:
failedObserver = NSNotificationCenter.DefaultCenter.AddObserver (InAppPurchaseManager.InAppPurchaseManagerTransactionFailedNotification,
(notification) => {
Console.WriteLine ("Transaction Failed");
});
Kromě těchto metod na kontroleru zobrazení, spotřební transakce nákupu produktu také vyžaduje kód na SKProductsRequestDelegate
straně a SKPaymentTransactionObserver
.
InAppPurchaseManager – metody
Ukázkový kód implementuje řadu metod souvisejících s nákupem ve třídě InAppPurchaseManager, včetně PurchaseProduct
metody, která vytvoří SKPayment
instanci a přidá ji do fronty ke zpracování:
public void PurchaseProduct(string appStoreProductId)
{
SKPayment payment = SKPayment.PaymentWithProduct (appStoreProductId);
SKPaymentQueue.DefaultQueue.AddPayment (payment);
}
Přidání platby do fronty je asynchronní operace. Aplikace znovu získá kontrolu, zatímco StoreKit zpracuje transakci a odešle ji na servery Společnosti Apple. V tomto okamžiku se v iOSu ověří, že je uživatel přihlášený do App Storu, a v případě potřeby ji vyzve k zadání Apple ID a hesla.
Za předpokladu, že se uživatel úspěšně ověří v App Storu a souhlasí s transakcí, SKPaymentTransactionObserver
obdrží odpověď StoreKitu a zavolá následující metodu pro splnění transakce a dokončení transakce.
public void CompleteTransaction (SKPaymentTransaction transaction)
{
var productId = transaction.Payment.ProductIdentifier;
// Register the purchase, so it is remembered for next time
PhotoFilterManager.Purchase(productId);
FinishTransaction(transaction, true);
}
Posledním krokem je zajistit, abyste storeKit informovali, že jste úspěšně splnili transakci voláním FinishTransaction
:
public void FinishTransaction(SKPaymentTransaction transaction, bool wasSuccessful)
{
// remove the transaction from the payment queue.
SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); // THIS IS IMPORTANT - LET'S APPLE KNOW WE'RE DONE !!!!
using (var pool = new NSAutoreleasePool()) {
NSDictionary userInfo = NSDictionary.FromObjectsAndKeys(new NSObject[] {transaction},new NSObject[] {new NSString("transaction")});
if (wasSuccessful) {
// send out a notification that we've finished the transaction
NSNotificationCenter.DefaultCenter.PostNotificationName (InAppPurchaseManagerTransactionSucceededNotification, this, userInfo);
} else {
// send out a notification for the failed transaction
NSNotificationCenter.DefaultCenter.PostNotificationName (InAppPurchaseManagerTransactionFailedNotification, this, userInfo);
}
}
}
Jakmile se produkt doručí, musí být volán, SKPaymentQueue.DefaultQueue.FinishTransaction
aby se transakce odebrala z platební fronty.
Metody SKPaymentTransactionObserver (CustomPaymentObserver)
StoreKit volá metodu UpdatedTransactions
, když obdrží odpověď ze serverů Společnosti Apple a předá pole SKPaymentTransaction
objektů, aby váš kód zkontroloval. Metoda prochází každou transakci a provádí jinou funkci na základě stavu transakce (jak je znázorněno zde):
public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions)
{
foreach (SKPaymentTransaction transaction in transactions)
{
switch (transaction.TransactionState)
{
case SKPaymentTransactionState.Purchased:
theManager.CompleteTransaction(transaction);
break;
case SKPaymentTransactionState.Failed:
theManager.FailedTransaction(transaction);
break;
default:
break;
}
}
}
Metoda CompleteTransaction
byla popsána dříve v této části – uloží podrobnosti o nákupu do NSUserDefaults
, finalizuje transakci pomocí StoreKitu a nakonec oznámí uživatelskému rozhraní, aby se aktualizovalo.
Nákup více produktů
Pokud v aplikaci dává smysl nakupovat více produktů, použijte SKMutablePayment
třídu a nastavte pole Množství:
public void PurchaseProduct(string appStoreProductId)
{
SKMutablePayment payment = SKMutablePayment.PaymentWithProduct (appStoreProductId);
payment.Quantity = 4; // hardcoded as an example
SKPaymentQueue.DefaultQueue.AddPayment (payment);
}
Kód, který zpracovává dokončenou transakci, musí také dotazovat vlastnost Quantity, aby správně splnil nákup:
public void CompleteTransaction (SKPaymentTransaction transaction)
{
var productId = transaction.Payment.ProductIdentifier;
var qty = transaction.Payment.Quantity;
if (productId == ConsumableViewController.Buy5ProductId)
CreditManager.Add(5 * qty);
else if (productId == ConsumableViewController.Buy10ProductId)
CreditManager.Add(10 * qty);
else
Console.WriteLine ("Shouldn't happen, there are only two products");
FinishTransaction(transaction, true);
}
Když si uživatel koupí více množství, zobrazí se v potvrzovací výstraze StoreKitu množství, jednotková cena a celková cena, na kterou se budou účtovat, jak je znázorněno na následujícím snímku obrazovky:
Zpracování výpadků sítě
Nákupy v aplikaci vyžadují funkční síťové připojení pro StoreKit ke komunikaci se servery Apple. Pokud síťové připojení není dostupné, nákup v aplikaci nebude dostupný.
Žádosti o produkty
Pokud síť není při vytváření , SKProductRequest
RequestFailed
metoda SKProductsRequestDelegate
podtřídy ( InAppPurchaseManager
) bude volána, jak je znázorněno níže:
public override void RequestFailed (SKRequest request, NSError error)
{
using (var pool = new NSAutoreleasePool()) {
NSDictionary userInfo = NSDictionary.FromObjectsAndKeys(new NSObject[] {error},new NSObject[] {new NSString("error")});
// send out a notification for the failed transaction
NSNotificationCenter.DefaultCenter.PostNotificationName (InAppPurchaseManagerRequestFailedNotification, this, userInfo);
}
}
ViewController pak naslouchá oznámení a zobrazí zprávu v nákupních tlačítkách:
requestObserver = NSNotificationCenter.DefaultCenter.AddObserver (InAppPurchaseManager.InAppPurchaseManagerRequestFailedNotification,
(notification) => {
Console.WriteLine ("Request Failed");
buy5Button.SetTitle ("Network down?", UIControlState.Disabled);
buy10Button.SetTitle ("Network down?", UIControlState.Disabled);
});
Vzhledem k tomu, že síťové připojení může být na mobilních zařízeních přechodné, můžou aplikace chtít monitorovat stav sítě pomocí architektury SystemConfiguration a znovu zkusit, když je síťové připojení k dispozici. Podívejte se na apple nebo na to, co ho používá.
Nákupní transakce
Pokud je to možné, platební fronta StoreKitu bude ukládat a předávat žádosti o nákupy, takže účinek výpadku sítě se bude lišit v závislosti na tom, kdy síť během procesu nákupu selhala.
Pokud dojde k chybě během transakce, SKPaymentTransactionObserver
podtřída ( CustomPaymentObserver
) bude mít UpdatedTransactions
volána metodu a SKPaymentTransaction
třída bude ve stavu selhání.
public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions)
{
foreach (SKPaymentTransaction transaction in transactions)
{
switch (transaction.TransactionState)
{
case SKPaymentTransactionState.Purchased:
theManager.CompleteTransaction(transaction);
break;
case SKPaymentTransactionState.Failed:
theManager.FailedTransaction(transaction);
break;
default:
break;
}
}
}
Metoda FailedTransaction
zjistí, jestli byla chyba způsobená zrušením uživatele, jak je znázorněno tady:
public void FailedTransaction (SKPaymentTransaction transaction)
{
//SKErrorPaymentCancelled == 2
if (transaction.Error.Code == 2) // user cancelled
Console.WriteLine("User CANCELLED FailedTransaction Code=" + transaction.Error.Code + " " + transaction.Error.LocalizedDescription);
else // error!
Console.WriteLine("FailedTransaction Code=" + transaction.Error.Code + " " + transaction.Error.LocalizedDescription);
FinishTransaction(transaction,false);
}
I když transakce selže, FinishTransaction
musí být volána metoda pro odebrání transakce z platební fronty:
SKPaymentQueue.DefaultQueue.FinishTransaction(transaction);
Ukázkový kód pak odešle oznámení, aby ViewController mohl zobrazit zprávu. Aplikace by neměly zobrazit další zprávu, pokud uživatel zrušil transakci. Mezi další kódy chyb, ke kterým může dojít, patří:
FailedTransaction Code=0 Cannot connect to iTunes Store
FailedTransaction Code=5002 An unknown error has occurred
FailedTransaction Code=5020 Forget Your Password?
Applications may detect and respond to specific error codes, or handle them in the same way.
Omezení zpracování
Funkce Nastavení > Obecná > omezení v iOSu umožňuje uživatelům uzamknout určité funkce svého zařízení.
Pomocí této metody můžete zadat dotaz, jestli má uživatel povoleno provádět nákupy SKPaymentQueue.CanMakePayments
v aplikaci. Pokud se vrátí hodnota false, nemůže uživatel získat přístup k nákupu v aplikaci. StoreKit uživateli při pokusu o nákup automaticky zobrazí chybovou zprávu. Zaškrtnutím této hodnoty může aplikace místo toho skrýt tlačítka nákupu nebo provést nějakou jinou akci, která uživateli pomůže.
InAppPurchaseManager.cs
V souboru CanMakePayments
metoda zabalí funkci StoreKit takto:
public bool CanMakePayments()
{
return SKPaymentQueue.CanMakePayments;
}
Pokud chcete tuto metodu otestovat, pomocí funkce Omezení v iOSu zakažte nákupy v aplikaci:
Tento ukázkový kód z ConsumableViewController
reakce na CanMakePayments
vrácení nepravda zobrazením zakázaného textu AppStore na zakázaných tlačítkách.
// only if we can make payments, request the prices
if (iap.CanMakePayments()) {
// now go get prices, if we don't have them already
if (!pricesLoaded)
iap.RequestProductData(products); // async request via StoreKit -> App Store
} else {
// can't make payments (purchases turned off in Settings?)
// the buttons are disabled by default, and only enabled when prices are retrieved
buy5Button.SetTitle ("AppStore disabled", UIControlState.Disabled);
buy10Button.SetTitle ("AppStore disabled", UIControlState.Disabled);
}
Aplikace vypadá takto, když je funkce Nákupy v aplikaci omezená – tlačítka nákupu jsou zakázaná.
Informace o produktu se dají vyžádat, i když CanMakePayments
jsou nepravdivé, aby aplikace stále načítala a zobrazovala ceny. To znamená, že pokud jsme odebrali CanMakePayments
kontrolu z kódu, tlačítka nákupu by stále byla aktivní, ale při pokusu o nákup se uživateli zobrazí zpráva, že nákupy v aplikaci nejsou povolené (vygeneruje StoreKit při přístupu do platební fronty):
Aplikace z reálného světa můžou použít jiný přístup ke zpracování omezení, například úplné skrytí tlačítek a možná nabízejí podrobnější zprávu než upozornění, které StoreKit zobrazuje automaticky.