robotmedia / RMStore

A lightweight iOS library for In-App Purchases
Apache License 2.0
2.43k stars 450 forks source link

iOS 11 new storekit feature : buy in-app directly from apple store #211

Open nathsociete opened 7 years ago

nathsociete commented 7 years ago

Hi,

As you may known the is a new storeKit feature in iOS11 which allow to buy in-app purchase directly from the App Store : let's see the function below :

When you return YES to this function the system will open your app with a new system in-app popup, make the transaction and RMStore will be called as usual in the transaction finished delegate.

When you have to return NO, that is to say to manage some specific workflow before proceeding to the transaction, you have to add the payment to the queue given. The big difference is that in this case we can not call the public method RMStore:addPayment:, because this function create a new payment and did not manage the one pass in parameter in the new Storekit function above.

You can have a look at this video -> https://developer.apple.com/videos/play/wwdc2017/303/

Did you plane before september to add a new function to RMStore to manage this case ?

Regards,

-> https://developer.apple.com/videos/play/wwdc2017/303/ Transcript = Then, implement a single delegate method in your app to handle the purchase info sent to you from the App Store. In most cases, this implementation can be just a single line of code, and StoreKit will handle the rest of the transaction for you. Also, if you want, you can override the order and visibility that they show up in, locally. Now, this isn't required, but it can be useful in a variety of situations. So, we've already gone into detail on how to do the iTunes Connect setup in the What's New in iTunes Connect session. That was yesterday. If you missed it, you can just catch it online. But for now, let's dive in and take a look at handling your transaction info when it's sent to you from the App Store. So, a user has clicked to purchase one of your in-app purchases in the App Store. StoreKit will automatically open your app and send information about the transaction to you via a new delegate method on the SKPaymentTransaction observer protocol. Now, you already have an object implementing this protocol, doing things like observing a transaction state, as Pete was talking about earlier. So, you can put your new code for promoting in-app purchases right next to your already existing code. It's good to know that if your app isn't already installed, the App Store will download or prompt the user to buy it. In this case, it can't be opened automatically, so instead, the user will receive a notification. And when they tap on that, then your app will open and be sent the transaction info. So, what's the code look like? Well, this is all the new code you need to get started promoting in-app purchases. StoreKit will send you the SKPayment queue, the SKPayment, and the SKProduct. Which is everything you need to handle the transaction. And the SKPayment will already be set up with the SKProduct on it. When you return true, the user will be shown that nice new in-app purchase payment sheet, so they can complete the transaction. And that's it. We're done. Time to ship it. Oh, all right. Well, what if the user is in the middle of onboarding? Or if they're creating an account? Or if they've already unlocked the item they're trying to buy? Well, in this case, you can hold onto the payment and return false. Then, when the user is done onboarding or whatever they needed to do, simply add the payment to the payment queue as you would with a normal in-app purchase. It's important that you add the SKPayment that was sent to you in this delegate method and not create a new one with the same product. If for some reason you need to cancel the transaction entirely, just return false and no other action is required. If you're going to cancel or defer a payment, you should definitely consider letting the user know, in some way. What you don't want, is for the user to tap on the in-app purchase in the App Store, be brought to your app, and then, nothing happens. They're going to think there's a bug, and that's not good. Okay. So, now you've got this all set up. You want to test it. Right. Well, your in-app purchases won't actually show up in the App Store, until you've submitted a binary that has this delegate method. So, we know you can handle the transactions. So, instead, we've created a system URL for you to use. This URL has the ITMS services protocol and three parameters. The first parameter is action, and that's always purchase intent. The next parameter is bundleID, which is of course, the bundle ID for your app. And the last one is productIdentifier, which you fill in with the product identifier of the in-app purchase you want to test. And once you've constructed this URL like so, you can simple send it to yourself in an iMessage or an email, and tap it on your device. You'll now it's working, because your app will be opened automatically. And you can test its behavior from there."

cagatayk commented 6 years ago

@nathsociete why is that a problem, returning NO for shouldAddStorePayment then call RMStore:addPayment: and skip to manage the one passed in parameter in the shouldAddStorePayment function?

nathsociete commented 6 years ago

@cagatayk

The new iOS11 method (BOOL)paymentQueue:(SKPaymentQueue *)queue shouldAddStorePayment:(SKPayment *)payment forProduct:(SKProduct *)product;

states that you must not create a new payment to add it to the queue

RMStore code

what we would like is something like that (BOOL)paymentQueue:(SKPaymentQueue )queue shouldAddStorePayment:(SKPayment )payment forProduct:(SKProduct )product { // payment, queue stored somewhere return NO; }

// Later => reuse the *payment/queue objects shouldAddStorePayment given to us sooner

WBRMAddPaymentParameters *parameters = [[WBRMAddPaymentParameters alloc] init];
parameters.successBlock = successBlock;
parameters.failureBlock = failureBlock;
NSMutableDictionary *_addPaymentParameters = [[RMStore defaultStore] valueForKey:@"_addPaymentParameters"];
_addPaymentParameters[product.productIdentifier] = parameters;

[queue addPayment:payment];
sirnacnud commented 6 years ago

I added support to my fork, you can check it out here.

orasis commented 6 years ago

+1 for supporting this.

resschneider commented 6 years ago

@sirnacnud any idea if this might be merged into the master branch soon?

sirnacnud commented 6 years ago

@resschneider I'm happy to submit a PR, but it seems this repo is no longer maintained. The last comment is from 2016.

You are more than welcome to use my fork. The master branch includes this change, and includes all the upstream commits.