Last active
February 16, 2017 22:56
-
-
Save jonathanpeppers/be1687c289a60f589aa9c6cd701fd0fe to your computer and use it in GitHub Desktop.
ApplePurchaseService - Buy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//NOTE: should be a singleton for your entire app | |
public class ApplePurchaseService : PurchaseService | |
{ | |
private readonly ObserverDelegate _observer = new ObserverDelegate(); | |
public ApplePurchaseService() | |
{ | |
SKPaymentQueue.DefaultQueue.AddTransactionObserver(_observer); | |
} | |
protected async override Task<Receipt> BuyNative(Purchase purchase) | |
{ | |
var product = (SKProduct)purchase.NativeObject; | |
var payment = SKPayment.CreateFrom(product); | |
var source = new TaskCompletionSource<Receipt>(); | |
_observer.Sources[purchase.Id] = source; | |
SKPaymentQueue.DefaultQueue.AddPayment(payment); | |
return await source.Task; | |
} | |
private class ObserverDelegate : SKPaymentTransactionObserver | |
{ | |
public readonly Dictionary<string, TaskCompletionSource<Receipt>> Sources = new Dictionary<string, TaskCompletionSource<Receipt>>(); | |
public override void UpdatedTransactions(SKPaymentQueue queue, SKPaymentTransaction[] transactions) | |
{ | |
foreach (var transaction in transactions) | |
{ | |
//NOTE: you have to call "Finish" on every state | |
if (transaction.TransactionState != SKPaymentTransactionState.Purchasing) | |
{ | |
SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); | |
} | |
TaskCompletionSource<Receipt> source; | |
if (Sources.TryGetValue(transaction.Payment.ProductIdentifier, out source)) | |
{ | |
switch (transaction.TransactionState) | |
{ | |
case SKPaymentTransactionState.Failed: | |
source.TrySetException(new Exception(transaction.Error?.LocalizedDescription ?? "Unknown Error")); | |
break; | |
case SKPaymentTransactionState.Purchased: | |
case SKPaymentTransactionState.Restored: | |
//First make sure the receipt exists | |
var url = NSBundle.MainBundle.AppStoreReceiptUrl; | |
if (!NSFileManager.DefaultManager.FileExists(url.Path)) | |
{ | |
source.TrySetException(new Exception("No app store receipt file found!")); | |
return; | |
} | |
//If the NSData is null | |
var data = NSData.FromUrl(url); | |
if (data == null) | |
{ | |
source.TrySetException(new Exception("Could not load app store receipt!")); | |
return; | |
} | |
var receipt = new AppleReceipt | |
{ | |
BundleId = NSBundle.MainBundle.BundleIdentifier, | |
Id = transaction.Payment.ProductIdentifier, | |
TransactionId = transaction.TransactionIdentifier, | |
Data = data.ToArray(), | |
}; | |
source.TrySetResult(receipt); | |
break; | |
default: | |
break; | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment