Skip to main content

I have an existing app (“Cameras”) with a subscription product and lifetime product that share the same entitlement. I’m creating a new app (“Lenses”) and I want to share subscriptions between them, but not lifetime purchases. I believe I can do this without having to make a new entitlement, and just checking the allPurchasedProductIdentifiers. For example, here’s what it might look like in the Cameras app:

Purchases.shared.getCustomerInfo { (purchaserInfo, error) in

    if let allProducts = purchaserInfo?.allPurchasedProductIdentifiers {

        if allProducts.contains("com.grayhour.cameras.lifetimeaccess") {

            // lifetime access to Cameras was purchased at some point

            unlockContent = true

        } else if allProducts.contains("com.grayhour.cameras.monthlysubscription") && purchaserInfo?.entitlementsp"Full Access"]?.isActive == true {

            // subscription access to Cameras was purchased and is still active

            unlockContent = true

        } else if allProducts.contains("com.grayhour.lenses.lifetimeaccess") {

            // lifetime access to Lenses was purchased at some point. Not relevant to unlocking content in this app.

        } else if allProducts.contains("com.grayhour.lenses.monthlysubscription") && purchaserInfo?.entitlementss"Full Access"]?.isActive == true {

            // subscription access to Lenses was purchased and is still active

            unlockContent = true

        }

    }

}

 

Does this make sense?

Hey @joshdholtz , just an update after releasing my app. Your suggestion has mostly worked out, though it seems there are some users for whom creating a new alias still revokes old entitlements, even though syncPurchases was run.

Any idea what could be causing this, or what sort of data I could collect to get a better idea? Also happy to take this convo to DMs if you’d prefer.

Thanks!


Thanks again Josh!


I believe that did it! Just to confirm, the documentation says I should only be running syncPurachses once? So my login procedure should be something like:

  1. check if the user has an apple-provided userID, if not skip to step 3
  2. if they have an ID, log in with the ID and check if purchases have been synced (based on a variable stored in userDefaults). If not, syncPurchases.
  3. get customerInfo and check for entitlements 

@Zak I think that sounds right! The syncPurchases is really only needed when you call `login` on a device that already has an entitlement on an anonymous ID.

So… you _might_ be able to even call it less times by checking if that entitlement exists before login and then calling syncPurchases so it transfers properly to the new ID after “Sign In with Apple”. But your case should definitely cover that and might be a safer approach!


I believe that did it! Just to confirm, the documentation says I should only be running syncPurachses once? So my login procedure should be something like:

  1. check if the user has an apple-provided userID, if not skip to step 3
  2. if they have an ID, log in with the ID and check if purchases have been synced (based on a variable stored in userDefaults). If not, syncPurchases.
  3. get customerInfo and check for entitlements 

Hey @Zak!

Ohhh, I think I see! So, I _think_ have your `login` you might need to call `Purchases.shared.syncPurchase` in your case. `syncPurchases will post the purchases with the existing App Store account over to the currently logged in user. 

I’m going to verify with a co-worker that this is the correct usage for it but I believe that should do it for you if you have existing purchases that didn’t get transferred for whatever reason 😊 


Thanks @joshdholtz . Both apps are in the same RC project, and both look like they’re using the same ID. The issue seems to be that it didn’t merge the second app’s anonymous ID, as I can see in the RC dashboard that it’s still a distinct user. 

One thing I realized is that when I tested Sign in with Apple, I used Hide My Email on one of the devices by accident. However both produced the same ID from Apple so I don’t see how that would ultimately make a difference. 

Is there a way to unmerge the IDs so I can just try again? Or do I need a new device and a new Apple ID for that?


Hey @Zak!

A few things to make sure is that both apps are within the same project in the RevenueCat dashboard. Apps within the same projects share App User IDs so that is how the subscriptions transfer (more can be seen here in the docs https://docs.revenuecat.com/docs/user-ids#sharing-subscriptions-across-apps-and-platforms)

The next thing would be to make sure that you are calling `Purchases.shared.login` method in both apps with the id that the Sign In with Apple gives you. By doing that, it should give you the same id. To verify this, I would usually print out `Purchases.shared.appUserID` (I think v3 has a slightly different API) to make sure they are same.

Hopefully some of this helps! Let me know if not. I should be able to reply pretty quickly here today 😊 

Thanks!


Hey @joshdholtz , I tried implementing Sign In with Apple and it half worked. I was able to get a userID from Apple and use it to login on the “Lenses” app. I can see from the RC dashboard that it successfully merged the new ID with the previous $RCAnonymous ID. But I tried doing the same on the “Cameras” app and while it successfully logs in and shows the “Lenses” entitlements, it seems to have forgotten the “Cameras” entitlements that it had. The RC dashboard shows that the $RCAnonymous ID that it was using has not been merged.

Did I miss a step?

Thanks for your continued help!


@Zak My pleasure! Please let us know if there is anything else you ever need 😊 


Ok got it. Thanks for the help Josh!


Hey @Zak!

You can totally do this without your own server 😊 

The best non-server option would probably be to implement “Sign In with Apple”. You can use what that returns as your “App User ID”. Users wouldn’t need to login but you could say something like “Sign in to sync your subscriptions across all our apps” or something like that 🤷‍♂️


Thanks @joshdholtz! I think the user ID bit was the gap in my knowledge. I notice the documentation says: 

anonymous App User IDs are not able to share subscription status across apps and platforms, so you'll need to identify with a custom App User ID via your own authentication system.

Does this mean I can’t accomplish subscription sharing with RC alone, and I need to do my own server-side, the-user-creates-a-login etc?


👋 Hey , @Zak!

You’re intent totally makes sense! I think one of the best ways to do this would be to create a new (additional) entitlement for your subscriptions (but not your lifetime purchase).

Example

  • Your subscriptions have lifetime would both have the “Full Access”  (or whatever your existing entitlement want named) so your “Cameras” app would keep working as is
  • But all of your existing subscription customers would also get your new “Full Access Cross Subscription” entitlement
  • In your “Lenses” app, you could check for “Full Access Cross Subscription” and give them full access with that

This is also all dependent that you are setting an App User ID for your customers so that you can identify the same users across your app.

Hope this helps and let me know if you have any further questions!


Tried it, but allPurchasedProductIdenitifiers doesn’t show products from other apps, even if they’re part of the same offering. I also tried creating a new entitlement but that also doesn’t seem to transfer across apps. 

What is the proper way to do this?


Reply