Restoring Completed Transactions

Reading on the in-app purchase programming guide i am trying to complete the “Restoring Completed Transactions” request.

I can see in the App Storekit there is a StoreKit.SKPaymentQueue. restoreCompletedTransactions

Can anyone tell me the proper way to use this Class to restore the transaction?

I dont see any events just the transactions property.

What ive been trying is:

dim product as new StoreKit.SKProduct(productsArray.Value(0)) Dim transactions as Foundation.NSArray Dim queue as new StoreKit.SKPaymentQueue(product) queue.RestoreCompletedTransactions transactions = queue.transactions

But it crashes when queue is returned.

What about using SKReceiptRefreshRequest

If someone has purchased a product ID how do you force it to be checked again?

I know when you press the buy button again Apple indicates you already bought it and asks if you want it for free again but how do you go straight to the restoring the purchase again without buying again.

Well, I did this for my MBS Plugins to use StoreKit.
Most of those calls run asynchronously and want to call a block on another thread. That is something you can’t simply do with declares on iOS.
Your best bet is often to find a method to set the NSOperationQueue or dispatch queue to be the main thread. Or you sometimes can pass nil to have no block, but than use a timer to regularly check if things got done well. That is what I use in EventsKit for some things.

Are you saying that your MBS Plugin will do this for me in IOS or is that just for Mac?

In order to use In-app purchasing, Apple requires you to have a method to restore a previous purchase in case its download to another device, so you need to activate their purchase again. So this is not possible?
The code they specify on apple is:
request = [[SKReceiptRefreshRequest alloc] init];
request.delegate = self;
[request start];

However i have never programmed in that language before, but i can see it exists in AppStoreKit. Just dont have an example how to kick start it.

MBS Plugins do it for Mac only.
There is no plugin SDK for iOS, sorry.

Assuming you are using StoreKit from iOSKit, you need to setup a StoreKit.PaymentTransationObserver before you can request that transactions be restored. First create the observer and hook into its callbacks with AddHandler. Then create the SKPaymentQueue, then call AddTransactionObserver with your observer and queue, and finally call restoreCompletedTransactions. I recommend you read the apple documentation on In App Purchases, everything in iOSKit is a direct port of the Apple classes with some convenience helpers added so the callbacks can be properly used in Xojo.

Add some code in the UnhandledException event to figure out what is going on if you continue to experience crashes, or look at the activity log. As with many classes in iOSKit, try on a real device as well, some classes do not work in the simulator by design (this is an apple restriction, not my own).

So if im following you correctly this is what i have:

using Foundation
using storekit

Dim PTO as New PaymentTransactionObserver
Dim PQ as new SKPaymentQueue(PTO)
PQ.AddTransactionObserver(PTO)
PQ.RestoreCompletedTransactions

Just not sure about the “hook into its callbacks with AddHandler”
I tried to add handlers for the events outside of the class but that wouldnt work. Are the handlers not already created in the class?

Also it crashes within PQ.AddTransactionObserver(PTO)
Appears to have a problem with the properties of ‘self’ , (the queue)
So am i missing something?

When i use :
Dim PQ as SKPaymentQueue
PQ = pq.DefaultQueue

Build and run on an Ipad the App crashes but somehow the Receipt is restored when i rerun my app so not sure why it crashes.

Have you tried this? It can be a little more work but will almost certainly help you spot a lot of problems, especially on iOS where declares can crash your app easily.

Don’t do this. Believe it or not this will make the SKPaymentQueue object into a PaymentTransactionObserver. I know it seems weird, but thats how the pointers work behind the scenes. Operator_Convert is a blessing since you don’t have to explicitly call a Handle/ID function when passing an object into a declare, but it is also a curse because you can unintentionally copy the object into another and the compiler can’t check.

Please use the DefaultQueue shared method to access the queue:

Dim PQ as SKPaymentQueue = SKPaymentQueue.DefaultQueue() 

[quote]Just not sure about the “hook into its callbacks with AddHandler”
I tried to add handlers for the events outside of the class but that wouldnt work. Are the handlers not already created in the class?[/quote]
You have to create methods on your view or a wrapper object which will be called. The PaymentTransactionObserver exposes events which you need to implement. Look at the documentation for AddHandler for a decent explanation (feel free to ask if you have further questions).

[quote]Also it crashes within PQ.AddTransactionObserver(PTO)
Appears to have a problem with the properties of ‘self’ , (the queue)
So am i missing something?[/quote]
I would guess this is because of the issue I mentioned earlier. If the problem persists, try logging what is happening and use UnhandledException.

I actually found a solution. When i was looking through the InAppPurchaseHelper classs i noticed there was also a RestoreCompletedTransactions as well.

So i used:

call InAppPurchaseHelper.GetInstance InAppPurchaseHelper.GetInstance.RestoreCompletedTransactions

An voila it all worked without crashing.
All the Events from the PaymentTransactionObserver are handled.
My test app with in-app purchase and restore works as expected now.

What i did learn from all this is that since we dont have access to the users Apple ID that was used too purchase it, this allows anyone to pirate my app by a simple “Restore Purchase” using a friends apple id that already purchased. Apple cares more about the buyer than they do about us sellers.

Also on a different topic here; there is only 1 step left before i can submit my App for Mac OS and IOS.

I have my IOS app in 2 formats; 1 for Ipad and the other for Iphone. Same App but seperate builds. I have seen this on the store before but i havnt seen anywhere in Itunes Connect that i can indicate the app is for Ipad only or Iphone only…
Also im not sure if the same In-app purchase can be used by both or not, as i havnt tried. So if they make the purchase for the Ipad then it will also transfer to the Iphone version and vice versa.

Why do you have two separate builds ?
Is there such a big technical limitation in your app that it needs to be separate ?

iTunesConnect does not handle separate builds for different devices, you will need to create two apps, two inApp purchases and users will have to purchase twice if they own both iPhone and iPad.

Main reason is the screen size. My app was originally designed in the Ipad screen with no intention on Iphone. I decided later to have the Iphone version. However there are alot of objects on the screen with graphics and when shown on a smaller screen they dont fit properly. Even with Anchor layouts to position them i cant change the widths and heights to make everything fit in an Iphone screen.

Im thinking now i will have to consider all in, one yet i dont know how. When i switch from the Ipad screen to the Iphone it doesnt resize the objects on the screen

In Xojo the iPhoneScreen and iPadScreen do not need to use the same iOSView.

You can create a completely different view for iPhone and for iPad although having all in the same Xojo project.

Ok that sounds like what i want. How do i go about a different view for each device? I looked but cant find this.

In Xojo navigator click on App then set the default iPhone and iPad screens in the Inspector

Then in the Navigator set the iPhoneScreen and iPadScreen to the correct views to use on each device.

Sorry I think im misunderstanding. I was aware of how to do that but all it does is select the default startup View.
The content and layout it show is still the same. They still need to show the same Window(view) otherwise id have to duplicate all the views and code behind.

If i have View1 with all the objects and Methods then Iphone and Ipad still only have a choice of View1 as the Content

So i guess i dont understand how I arrange and resize the objects for just the Iphone and not the Ipad.

If you move most of the methods in a class, you could then have ViewiPhone with a certain layout, and ViewiPad with another layout.

Both views will share the same base methods (through the class) although displaying things differently.

So it does require duplicating the Views, their Controls, events and the code behind to acheive this?

I can easily move the Methods to App but wont this make the app larger than it should be

Yes of course it does require duplicating the views but isn’t that already what you did with your current two separate builds ?

You should consider the pros and cons but remember the following pros of one single build:

  1. One app to manage on app store
  2. Users can share downloads and inApp purchase on both iPhone and iPad
  3. User ratings and reviews will be shared between both devices
  4. Apple will only need to review your updates once

Regarding #3, one of my apps (>150k downloads) only has ~15% downloads on iPad. If you get the same, you would have poor rating count & downloads for the iPad version which leads to poor ranking on the App Store.

Yes I already have the View Layouts set for Iphone 4.7" and 5.5" in a seperate Project.
The code behind is all the same as the Ipad Project. Unfortunately this is not a smal project. Its very large.
There are 3 Windows and alot of Presized Containers.

So the proper way to do this is to have 2 of each Windows with twice the code and containers?
I cant move all the methods and code behind out of the View because most of it references the objects in the View.
Was hoping to have this ready before Christmas.

If you are curious what it is, here is my website.
My Web Site