Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use the library in watch app? #207

Closed
mecid opened this issue Mar 19, 2020 · 33 comments
Closed

How to use the library in watch app? #207

mecid opened this issue Mar 19, 2020 · 33 comments
Assignees

Comments

@mecid
Copy link

mecid commented Mar 19, 2020

Hi, I have the error with version 4.0 when running it with the latest Xcode beta.

Showing Recent Messages
/Users/majid/Library/Developer/Xcode/DerivedData/SleepBot-fcdzzaaaglxzwpcmtdyrkdzbxapm/SourcePackages/checkouts/purchases-ios/Purchases/Public/RCPurchases.m:27:9: 'RCDeviceCache.h' file not found

@aboedo aboedo self-assigned this Mar 19, 2020
@aboedo
Copy link
Member

aboedo commented Mar 19, 2020

Hi! We're currently working on WatchOS support. You can follow the changes in #183, and see a sample watch app in #182.
As of last week's developer seed, though, purchases on watchOS weren't functional because of what seems to be a bug on watchOS.
I've been trying to check the current seed, but Apple's Sandbox environment is having issues right now, so I can't say for certain whether the bug in watchOS is fixed or not.
I'll keep you posted on it, though.

@mecid
Copy link
Author

mecid commented Mar 20, 2020

@aboedo Hi, thanks for your reply. I hope to get it asap. I am going to implement my in-app subscriptions for Apple Watch also.

@aboedo
Copy link
Member

aboedo commented Mar 20, 2020

if you want to start playing around with it and setting it up in the meantime, feel free to check out the feature/universal_purchases branch

@mecid
Copy link
Author

mecid commented Mar 20, 2020

@aboedo Awesome! thanks.

@mecid
Copy link
Author

mecid commented Mar 24, 2020

@aboedo Xcode 11.4 is already available. Are you going to merge feature/universal_purchases branch?

@aboedo
Copy link
Member

aboedo commented Mar 25, 2020

hi @mecid! the branch has been merged into master, try it out!

@aboedo
Copy link
Member

aboedo commented Mar 25, 2020

it'll also be a part of the next release, 3.2.0

@mecid
Copy link
Author

mecid commented Mar 25, 2020

@aboedo awesome! thanks. I think we can close the issue.

@mecid mecid closed this as completed Mar 25, 2020
@mecid mecid reopened this Mar 25, 2020
@mecid
Copy link
Author

mecid commented Mar 25, 2020

@aboedo ok, I've updated to the latest version of the library. I use the same API key in the watch app. I call purchaserInfo function but returns an empty set of active subscriptions. On the other hand, I have an active sandbox subscription in the iOS part of the app. Should I configure somehow universal purchases in RevenueCat dashboard?

@vegaro
Copy link
Contributor

vegaro commented Mar 26, 2020

@mecid Are you using the same app user ID for both the watch and the iOS app? If the app user IDs are different, RevenueCat will return an empty set of active subscriptions (until you restore or purchase again)

@mecid
Copy link
Author

mecid commented Apr 1, 2020

@vegaro restoring doesn't work for me. I've got these logs while restoring the purchase on my Apple Watch.
[Purchases] - INFO: Unable to load receipt, ensure you are logged in to the correct iTunes account.
[Purchases] - INFO: App running on sandbox without a receipt file. Restoring transactions won't work unless you've purchased before and there is a receipt available.

@mecid
Copy link
Author

mecid commented Apr 6, 2020

Anyone knows how to solve the issue?

@aboedo
Copy link
Member

aboedo commented Apr 6, 2020

I haven't gotten purchases to work on the watch yet either. It seems that there's an underlying error when trying to refresh receipts:
the SKReceiptRefreshRequest request fails, with error:

Error Domain=SKErrorDomain Code=0 "(null)" 
UserInfo={
    NSUnderlyingError=0x155d3b50 {
        Error Domain=ASDServerErrorDomain Code=500309 "Unhandled exception" 
        UserInfo=
        {
             NSLocalizedDescription=Unhandled exception, 
             NSLocalizedFailureReason=An unknown error occurred
        }
    }
}

I filed a radar a few weeks ago related to these issues, FB7622829. I'll update here as soon as I have more info on what's going on.

@mecid
Copy link
Author

mecid commented Apr 6, 2020

@aboedo thanks for the information.

@aboedo
Copy link
Member

aboedo commented Apr 7, 2020

to provide more clarity around this:

  • Purchasing itself does work, in that you do get to make a purchase.
  • However, as soon as a purchase is made, purchases-ios will get the receipt for validation purposes. This is the part that seems to be broken in watchOS - SKRefreshReceiptRequest fails with the error I mentioned in my previous comment. I'll continue to try out beta seeds as they come out and will update once it starts to work.

@aboedo
Copy link
Member

aboedo commented May 5, 2020

update here: on the latest beta, SKRefreshReceiptRequest doesn't actually fail, but the receipt is still empty. I'll continue to update this ticket as new betas come out.

@duycao2506
Copy link

update here: on the latest beta, SKRefreshReceiptRequest doesn't actually fail, but the receipt is still empty. I'll continue to update this tickets as new betas come out.

Actually, as what I see, SKRefreshReceiptRequest will update the receipt on your device (restoreCompletedTransactions will not do that inclusively anymore ???) but the trace to those receipts is still not revealed

@aboedo
Copy link
Member

aboedo commented May 12, 2020

thanks for the update.

I tried this again today and got an interesting finding:

In Sandbox, the receipt gets refreshed correctly, but stored in the wrong path. Instead of getting stored in [[NSBundle mainBundle] appStoreReceiptURL], (which in sandbox it gets translated to <receipts_folder>/sandboxReceipt, it gets stored in the same folder, but as <receipts_folder>/receipt. Which wouldn't be a problem if appStoreReceiptURL returned the same URL used for storing it.

To clarify, the problem is that appStoreReceiptURL (correctly) returns the url of the sandbox receipt when you’re in sandbox, but it seems like the refreshed receipt lives in the path where the production receipt would usually live.
i.e.:

file:/private/var/mobile/Containers/Data/PluginKitPlugin/6CC24F0D-402C-4AB9-9747-96116D575348/StoreKit/receipt -> contains the purchases
file:/private/var/mobile/Containers/Data/PluginKitPlugin/6CC24F0D-402C-4AB9-9747-96116D575348/StoreKit/sandboxReceipt -> MISSING, but this is the url returned by `[[NSBundle mainBundle] appStoreReceiptURL]`

I checked the receipt that was stored and it was a sandbox receipt that contained all the IAPs that I'd been testing.

It probably works fine in production, since the URL would always be the production URL, so there's no mismatch. I haven't checked, though, since I'd have to upload an app that I can't really test.

I've filed a radar for it, FB7699277. I'll update this issue if I hear back or if I have any new findings.

In the meantime, if you want to try watchOS purchases, you can get around this watchOS bug by doing the following (very hacky, don't actually do this in production) approach:

clone the RevenueCat SDK and updating RCReceiptFetcher.m's receiptData like this:

- (NSData *)receiptData
{
    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSString *receiptURLFolder = [[receiptURL absoluteString] stringByDeletingLastPathComponent];

    NSURL *productionReceiptURL = [NSURL URLWithString:[receiptURLFolder stringByAppendingPathComponent:@"receipt"]];
    NSData *data = [NSData dataWithContentsOfURL:productionReceiptURL];
    RCDebugLog(@"Loaded receipt from %@", productionReceiptURL);
    return data;
}

This effectively replaces sandboxReceipt with receipt in the URL and uses that instead. Again, I wouldn't recommend doing this on production, since it's pretty hacky.

@aboedo
Copy link
Member

aboedo commented May 20, 2020

the issue is still present in 6.2.5 from my testing

@aboedo
Copy link
Member

aboedo commented Jun 19, 2020

it looks like the bug is still present on 6.2.8, so I added a workaround for development purposes:
00e61a8.
In production, this should just work as usual.
I also added a sample watch app that just makes a purchase [as part of the same PR].
Feel free to check it out.

@alamodey
Copy link

alamodey commented Jun 28, 2020

it looks like the bug is still present on 6.2.8, so I added a workaround for development purposes:
00e61a8.
In production, this should just work as usual.
I also added a sample watch app that just makes a purchase [as part of the same PR].
Feel free to check it out.

Hi, I have an independent Watch app that I've been waiting to create a premium IAP for. I just saw your message and looked at the example you mentioned to adapt the configure, loadofferings and purchase functions for my app.

From the debug log, it looks like it's doing the right thing, and searching for the correct product IDs. but how do I test my app since you can't test it in simulator? i installed it on my watch, but i obviously can't purchase IAP either since that is not approved by the App Store until i submit.

I went ahead and submitted my app hoping the App Store would test this functionality, but it got rejected because they want to see a video demo'ing the IAP process:

Guideline 2.1 - Information Needed

We have started the review of your app, but we are not able to continue because we need access to a video that demonstrates the current version of your app in use on a physical watchOS device. Please ensure the video shows all functions and features of the new subscription process and features.

@aboedo
Copy link
Member

aboedo commented Jun 29, 2020

@alamodey the workaround hasn't been released yet, but you should be able to use it by switching to the develop branch of RevenueCat. It was merged in #263
With that workaround, you should be able to test out purchases on sandbox just fine, and it will still work in production.
Testing in-app purchases in the simulator doesn't work on Xcode <=11 so you'd need a physical device for testing. It's always a good idea to do all final testing with a physical device.

If you don't have access to an apple watch, Xcode 12 added the ability for the simulator to make purchases (See our blog post about it). So you might be able to use that to test in the simulator, but the build you submit must be built with Xcode 11 for now, since they'll reject builds done with a beta version of Xcode.

Hope that helps!

@aboedo
Copy link
Member

aboedo commented Jun 29, 2020

I just tried purchasing on the watchOS 7 simulator and it looks like it doesn't work yet, so you will have to use a physical device for testing

@alamodey
Copy link

I just tried purchasing on the watchOS 7 simulator and it looks like it doesn't work yet, so you will have to use a physical device for testing

Sorry I'm new to RevenueCat and IAP but I have a series 3 watch and i tried the following - i created a sandbox account and logged into my iPhone in the sandbox account setting (i couldn't find this setting on the watch so i assume you just log into your phone and it uses the same sandbox account on your watch?)

i have adopted the code you used in that branch you mentioned, the purchase, configure and loadofferings methods. Is that all I need to do? I installed RevenueCat via cocoapods. or if I do this, does it give me the version of RevenueCat that doesn't support watchOS?

i think i've setup everything correctly in the app store but in the simulator when i try to purchase something the console prints out:
2020-06-30 23:23:03.584849+1000 Zungzi WatchKit Extension[3120:84551] [Purchases] - INFO: Could not find SKProduct for (
"com.ditomanshum.zungzi.premiumsub",
"com.ditomanshum.zungzi.premium"

i can't tell if this is an issue with the app store (where my IAP have not been submitted for review yet), or an issue with revenuecat, or my code?

@aboedo
Copy link
Member

aboedo commented Jun 30, 2020

For cocoapods, you should be able to get the version in the branch by doing

pod 'Purchases', :git => 'https://github.com/RevenueCat/purchases-ios.git', :branch => 'develop'

What you described sounds like an issue with configuration.
What's happening there is that the backend is getting those product identifiers from the config for your app, but then the app tries to fetch them from StoreKit and they can't be found, so they can't be used yet.
Check out our guide to configuring IAPs to make sure that they're set up correctly, make sure that the ids match the config on the RevenueCat dashboard, and see if that helps.

If not, then I'd suggest checking out our support pages or contacting support to make sure you have everything set up correctly.
Additionally, you could use storekit config files to override storekit for testing and make sure that the rest of your code would work if those products are correctly set up.

@aboedo
Copy link
Member

aboedo commented Jun 30, 2020

also, note that while there is a bug in watchOS 6.2.x with how receipts are stored, you should still be able to load offerings / products correctly, since the bug only manifests after making a purchase. So the branch isn't the problem in your case.

@alamodey
Copy link

alamodey commented Jul 1, 2020

For cocoapods, you should be able to get the version in the branch by doing

pod 'Purchases', :git => 'https://github.com/RevenueCat/purchases-ios.git', :branch => 'develop'

What you described sounds like an issue with configuration.
What's happening there is that the backend is getting those product identifiers from the config for your app, but then the app tries to fetch them from StoreKit and they can't be found, so they can't be used yet.
Check out our guide to configuring IAPs to make sure that they're set up correctly, make sure that the ids match the config on the RevenueCat dashboard, and see if that helps.

If not, then I'd suggest checking out our support pages or contacting support to make sure you have everything set up correctly.
Additionally, you could use storekit config files to override storekit for testing and make sure that the rest of your code would work if those products are correctly set up.

Thanks, I checked out the 'develop' branch and still can't load offerings. So I will reach out to support for help on configuring. I think I just need some clarity on bundle and product IDs. for an independent watchOS app, i have 3 bundle IDs for the app, watchkit, and watchkit extension. and similarly for the product ID of the IAP, i would need the correct bundle ID to use as the prefix (i assume).

@alamodey
Copy link

alamodey commented Jul 5, 2020

also, note that while there is a bug in watchOS 6.2.x with how receipts are stored, you should still be able to load offerings / products correctly, since the bug only manifests after making a purchase. So the branch isn't the problem in your case.

Hi, I haven't been able to get any help from RevenueCat support so I was wondering if you could help. I've been able to implement IAP properly on my iPhone app but for my watchOS app I can't load any offerings/packages.

I think it all relates to the configuration but I can't figure out what is different between watchOS and iOS. In watchOS, I have 3 bundle IDs - and I have tried each one but still get the same debug log that can't find offerings/invalid product ID. Can you provide any guidance on this, there's no tutorials/examples available to show this working properly for an independent watch app.

@aboedo
Copy link
Member

aboedo commented Jul 7, 2020

I believe that you may have to set up the bundle ids so that the iOS app is included as a prefix for the watch app, i.e.:

iOS app: com.mycompany.myapp
iOS watch app: com.mycompany.myapp.watchkitapp
iOS watch app extension: com.mycompany.myapp.watchkitapp.watchkitextension

let me know if that works!

@jasonzurita
Copy link

it looks like the bug is still present on 6.2.8, so I added a workaround for development purposes:
00e61a8.
In production, this should just work as usual.
I also added a sample watch app that just makes a purchase [as part of the same PR].
Feel free to check it out.

👏, Switched the SDK to develop, and this unblocked my testing of sandbox subscriptions on a watchOS only app — Thanks so much!

When is the next release scheduled for?

@alamodey
Copy link

alamodey commented Jul 8, 2020

I believe that you may have to set up the bundle ids so that the iOS app is included as a prefix for the watch app, i.e.:

iOS app: com.mycompany.myapp
iOS watch app: com.mycompany.myapp.watchkitapp
iOS watch app extension: com.mycompany.myapp.watchkitapp.watchkitextension

let me know if that works!

My bundle IDs have always been setup as:
com.ditomanshum.zungzi
com.ditomanshum.zungzi.watchkit
com.ditomanshum.zungzi.watchkit.ext

In my RevenueCat configuration I have set the Bundle ID as com.ditomanshum.zungzi and that automatically loads my app icon whereas the other bundle IDs won't load my icon. Do you think there's any issue with the bundle IDs with the way they are now?

@aboedo
Copy link
Member

aboedo commented Jul 8, 2020

@alamodey the app icon is set up in a separate file, entirely separate from RevenueCat. Look for Assets.xcassets inside each project.

@jasonzurita I'm glad that worked! I need to do some testing on watchOS 7, if things remain the same I'm targeting a release this week. If there are changes to the behavior in watchOS 7 it might take a bit longer, I'll keep you posted.

@aboedo
Copy link
Member

aboedo commented Jul 9, 2020

A build including the changes here was released! You can now use version 3.5.0 for development on your favorite package manager or directly by downloading the binary.
Closing this issue now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants