Note that there are some explanatory texts on larger screens.

plurals
  1. POmemory leak in xamarin in app purchase
    primarykey
    data
    text
    <p>So I have been trying to setup in app purchase within my application and encountered a problem which I don't know how to solve. Im working with xamarin, and I followed their <a href="http://docs.xamarin.com/guides/ios/application_fundamentals/in-app_purchasing/part_3_-_purchasing_consumable_products" rel="nofollow">In app purchase guide</a> on how to buy consumables products.</p> <p>Everything was going great until I tried to get the transaction receipt returned by apple. Everytime I access this property from the SKPaymentTransaction object (anywhere in my project), I get this error which according to some people is a memory leak. This just happens whenever I access this property (SKPaymentTransaction.TransactionReceipt).</p> <p>The error:</p> <pre><code>*** error: can't allocate region *** set a breakpoint in malloc_error_break to debug </code></pre> <p>My code looks a lot like the one found on the guide I previously told you about. First of all I created a in app purchase manager which is the one in charge of making requests to apple in order to obtain product information (this works great), and update my UI whenever a transaction is succeeded or failed:</p> <pre><code>public class InAppPurchaseManager : SKProductsRequestDelegate { IMobileServiceTable receiptTable = AppDelegate.MobileService.GetTable("Receipt"); public InAppPurchaseManager () { SKPaymentQueue.DefaultQueue.AddTransactionObserver (new TransactionObserver(this)); } public void RequestProductData (List&lt;NSString&gt; productIds) { var array = new NSString[productIds.Count]; for (var i = 0; i &lt; productIds.Count; i++) { array[i] = productIds[i]; } NSSet productIdentifiers = NSSet.MakeNSObjectSet&lt;NSString&gt;(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 &gt; 0) { NSObject[] productIdsArray = new NSObject[response.Products.Length]; NSObject[] productsArray = new NSObject[response.Products.Length]; for (int i = 0; i &lt; 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); } }} </code></pre> <p>On the method FinishTransaction I would like to insert the returned receipt in my server (before insert, of course verify it against apple servers) if the transaction was successful. So at this point I need to access SKPaymentTransaction.TransactionReceipt, encode this receipt to base64, and send it to my server. This just does not work and I dont know why.</p> <p>My transaction observer:</p> <pre><code>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; } } } } </code></pre> <p>So, another info I can give you is that my project compiles, and when it tries to deploy the app to my device, it crashes.</p> <p>Also, I am on the xamarin beta channel since I am already using async and await.</p> <p>So please if you see anything wrong let me know. </p> <p><strong>UPDATE</strong></p> <p>Everytime i clean the project it works, and stops giving that error!!! I dont know why this is behaving like this!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload