9 Replies
      Latest reply on Oct 21, 2015 5:00 AM by acegreen1989
      acegreen1989 Level 1 Level 1 (0 points)

        Hello,

         

        This is a follow up question to another question I asked. I have added a pro version in-app purchase to my iOS that will unlock some features on the Watch app. Currently I sent an updateContext to the Apple Watch to tell it that the pro version was purchased. I also use NSUserDefaults on both devices to save the purchase (as a bool == true)

         

        This works fine but has some limitations:

        - The Watch has to be paired when the purchase is made

        - Deleting the Watch app will require the user to restore the inapp purchase on his iOS app for the context to get resent

        - A few more scenarios but I wont go into detail

         

        So I'm thinking to check the in-app purchases on Watch app launch. I can still keep the updateContext functionality as it causes no real harm but I would like to check at launch for in-app purchases.

         

        Is the correct way of doing this pretending to restore purchases on Watch app and doing what needs to be done in the paymentQueueRestoreCompletedTransactionsFinished()

         

        So basically in my extensionDelegate I would do:

         

            func restorePurchases() {

         

                SKPaymentQueue.defaultQueue().addTransactionObserver(self)

                SKPaymentQueue.defaultQueue().restoreCompletedTransactions()

            }

         

            func paymentQueueRestoreCompletedTransactionsFinished(queue: SKPaymentQueue) {

           

                print("transactions restored")

           

                var purchasedItemsIDs = []

           

                for transaction in queue.transactions {

               

                    let tran: SKPaymentTransaction = transaction

               

                    let prodID = tran.payment.productIdentifier as String

               

                    switch prodID {

                   

                    case "xxxxx.iap.proversion":

                   

                        print("restored - pro version")

                        proVersionPurchased()

                    default:

                   

                        print("IAP not setup")

                   

                    }

                }

            }

        • Re: WatchKit - Check in app purchase
          PBK Level 7 Level 7 (3,795 points)

          There is no need to restore the purchase each time you want to check to see if the user has purchased the IAP.  In the updatedTransaction method which will be run only once in the life of the app just store some variable in a file (like NSUserDefault or the file system)  to indicate that the purchase was made.  Then the watch app just needs to check the value of that variable - just like any other setting in tghe app.  Your idea of storing "true" in NSUserDefault is almost good enough.  But it is easily hacked.  It would be more secure to store the value of the identifierForVendor in NSUserDefault if the purchase is made.  That way a hacker can't set a simple variable to "True" and can't copy the value in NSUserDefaults from one device to another.

            • Re: WatchKit - Check in app purchase
              acegreen1989 Level 1 Level 1 (0 points)

              Thanks for the reply.

               

              The pro version IAP purchase happens on the iOS app, but the functionality is for the Apple WAtch. Currently i use updateContext to send the information over to the Apple WAtch (by telling the Apple Watch to set the NSUserDefault to true. This works but dosnt account for a few scenarios.

               

              For example if the user deletes the Apple Watch app his Apple Watch NSUserDefaults get deleted with it. So when he reinstalls the app, I can imagine that he would need to restore purchase on iOS to cause the iOS app to resend the context and update the Apple Watch NSUserDefault key.

                • Re: WatchKit - Check in app purchase
                  PBK Level 7 Level 7 (3,795 points)

                  It certainly is complicated but to simplify you segment the problem.  There are two different issues: 1) how do you communicate variables between the iOS app and the Watch and 2) how does the iOS app know whether or not the IAP was purchased.  The first is something that you have to handle using one of a variety of techniques.  I am sure you have mastered that.  If not, consider it a challenge separate from the IAP question.  The second - getting the IAP status - is done when the iOS app is operating.  It has nothing to do with the watch.  If the user deletes and reinstalls the iOS App (not the Watch App) then you can either - restoreCompletedTransactions or use the Keychain to store the IAP status (it survives delete/reinstall) or use the iCloud key/value file.

                    • Re: WatchKit - Check in app purchase
                      acegreen1989 Level 1 Level 1 (0 points)

                      Regarding 1)

                      I'm already communicating upon purchase (on iOS) to the Apple Watch the pro version was purchased using updateContext and on Apple Watch I'm setting the NSUserDefault to true.

                       

                      My concern is that when the user deleted the Apple Watch app, their Apple Watch userDefaults go too. therefore the user will need to restore purchases on their iOS device to trigger the updateContext again.

                       

                      I get the status and go a full restore of the IAPs when the user clicks the restore button on their iOS app. But thats not the point. What if the user deletes just the Apple Watch app, he still needs to restore on iOS for the app to communicate with the Apple WAtch

                        • Re: WatchKit - Check in app purchase
                          PBK Level 7 Level 7 (3,795 points)

                          Then your logic is faulty.  The app should be able to set variables on the iPhone that can be detected by the watch app. The fact that the iphone app has purchased an IAP is just one, or two, of those variables.  If you delete the watch app and then reinstall it but don't delete the iphone app then the IAP is, still, one of those variables.  If you delete the iphone app and reinstall it then the iphone may be required to restore the iap - or you could, as stated above, rely on the keychain or the icloud key-value file to reset that variable.

                    • Re: WatchKit - Check in app purchase
                      acegreen1989 Level 1 Level 1 (0 points)

                      I actually never thought of jailbreaks being able to set the NSUserDefault and circumvent my check. Thanks for point that out and I'll look into another way. I have a few questions regarding identifierForVendor

                       

                      1. Is the identifierForVendor device/account specific?

                      2. If I send that to my Apple Watch, will I be able to check against it?

                      The identifierForVendor for the iOS device/app is surely different from the Apple Watch, how would I check against it.

                      3. What if the user restores from another device with a new identifierForVendor (same itunes account), how will I handle that?

                        • Re: WatchKit - Check in app purchase
                          PBK Level 7 Level 7 (3,795 points)

                          I do not think you need to Jailbreak to get access to files stored on a device.  It can be done from a Mac through the files stored by iTunes.

                           

                          The identifierForVendor is specific to the device and the app.  It changes during a delete/resinstall process.

                           

                          Your watch (WatchKit Extension) has access to the iPhone's identifierForVendor for that app (I think in WatchOS2 the Watch has access to identifierForVendor - but I am not certain)

                           

                          In updatedTransactions, in each device, you detect the IAP purchase.  At that point you add something to the NSUserDefaults, or another file, that is device specific indicating the IAP was purchased. 

                            • Re: WatchKit - Check in app purchase
                              acegreen1989 Level 1 Level 1 (0 points)

                              I'll look into the identifierForVendor topic in more detail later.

                               

                              I just found out tht my updateApplicationContext only works for iOS 9 or later

                               

                              so my question, what are the options of telling the Apple Watch the pro version was purchased. Ie what options do I have to set the NSUserDefault on Apple Watch?