所以我一直在尝试在我的应用程序中设置应用程序购买,但遇到了一个我不知道如何解决的问题。我与 xamarin 合作,我按照他们的应用内购买指南了解如何购买耗材产品。
一切都很顺利,直到我试图拿到苹果退回的交易收据。每次我从 SKPaymentTransaction 对象(在我的项目中的任何位置)访问此属性时,我都会收到此错误,根据某些人的说法是内存泄漏。每当我访问此属性 (SKPaymentTransaction.TransactionReceipt) 时,就会发生这种情况。
错误:
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
我的代码看起来很像我之前告诉您的指南中的代码。首先,我创建了一个应用内购买管理器,它负责向苹果发出请求以获取产品信息(这很好用),并在交易成功或失败时更新我的 UI:
public class InAppPurchaseManager : SKProductsRequestDelegate
{
IMobileServiceTable receiptTable = AppDelegate.MobileService.GetTable("Receipt");
public InAppPurchaseManager ()
{
SKPaymentQueue.DefaultQueue.AddTransactionObserver (new TransactionObserver(this));
}
public void RequestProductData (List<NSString> productIds)
{
var array = new NSString[productIds.Count];
for (var i = 0; i < productIds.Count; i++) {
array[i] = productIds[i];
}
NSSet productIdentifiers = NSSet.MakeNSObjectSet<NSString>(array);
var productsRequest = new SKProductsRequest(productIdentifiers);
productsRequest.Delegate = this; // for SKProductsRequestDelegate.ReceivedResponse
productsRequest.Start();
}
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);
}
public override void RequestFailed (SKRequest request, NSError error)
{
Console.WriteLine (" ** InAppPurchaseManager RequestFailed() " + error.LocalizedDescription);
}
public void PuchaseProduct (SKProduct product)
{
SKPayment payment = SKPayment.PaymentWithProduct (product);
SKPaymentQueue.DefaultQueue.AddPayment (payment);
}
public void CompleteTransaction (SKPaymentTransaction transaction)
{
var productId = transaction.Payment.ProductIdentifier;
// Register the purchase, so it is remembered for next time
FinishTransaction(transaction, true);
}
public void FinishTransaction(SKPaymentTransaction transaction, bool wasSuccessful)
{
// remove the transaction from the payment queue.
SKPaymentQueue.DefaultQueue.FinishTransaction(transaction);
using (var pool = new NSAutoreleasePool()) {
NSDictionary userInfo = NSDictionary.FromObjectsAndKeys(new NSObject[] {transaction},new NSObject[] {new NSString("transaction")});
if (wasSuccessful) { NSNotificationCenter.DefaultCenter.PostNotificationName (new NSString("InAppPurchaseManagerTransactionSuccedeedNotification"), this, userInfo);
} else {
// send out a notification for the failed transaction
NSNotificationCenter.DefaultCenter.PostNotificationName (new NSString("InAppPurchaseManagerTransacionFailedNotification"), this, userInfo);
}
}
}
public void FailedTransaction (SKPaymentTransaction transaction)
{
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);
}
}}
在 FinishTransaction 方法上,如果交易成功,我想在我的服务器中插入返回的收据(在插入之前,当然要针对苹果服务器进行验证)。所以此时我需要访问 SKPaymentTransaction.TransactionReceipt,将此收据编码为 base64,并将其发送到我的服务器。这只是行不通,我不知道为什么。
我的交易观察者:
public class TransactionObserver : SKPaymentTransactionObserver
{
private InAppPurchaseManager iap;
public TransactionObserver (InAppPurchaseManager manager) : base()
{
iap = manager;
}
public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions)
{
foreach (SKPaymentTransaction transaction in transactions)
{
switch (transaction.TransactionState)
{
case SKPaymentTransactionState.Purchased:
iap.CompleteTransaction (transaction);
break;
case SKPaymentTransactionState.Failed:
iap.FailedTransaction(transaction);
break;
default:
break;
}
}
}
}
所以,我可以给你的另一个信息是我的项目编译,当它试图将应用程序部署到我的设备时,它崩溃了。
另外,我在 xamarin beta 频道上,因为我已经在使用 async 和 await。
因此,如果您发现任何问题,请告诉我。
更新
每次我清理项目时它都可以工作,并停止给出该错误!!!我不知道为什么会这样!