Check if App was purchased in IAP case - ios

I'm struggling to find a way to check in the Store Kit framework a way to check if user already bought the in-app non-consumable item in order to avoid the ""You've already purchased this but it hasn't been downloaded. Tap OK to download it now. [Environment: Sandbox]""
I set my feature hardcoded in the app and save the state in sqlite file, please I'm not looking for answer about best pratice...
I already tried to get the payment callback hoping to trigger SKPaymentTransactionStateRestored buy in such case the callback is not called
any ideas? any?

AFAIK, there is not way to get that kind of information from StoreKit. If you google a bit, you will find a sort of hack described: trying to silently restore transactions in the first place, so you know which items the users has already bought. Unfortunately, this approach is not Apple-friendly and might be cause of rejection.
What I do to manage a case similar to yours is checking beforehand my local state to know whether the user has already bought the non-consumable item and then show/hide the purchase option. The information can be stored in NSUserDefaults and sync-ed through iCloud if you want to go a step further and make it available across devices and reinstalls.

Related

Using generic in-app purchase items for a dynamic range of digital products

Have any of you implemented something similar to the below scenario?
Consider an app which provides audiobooks:
The books are maintained dynamically from a web based UI by the authors.
The books become available for users of the iOS app, as in-app purchase items.
By default Apple guidelines suggests using non-consumable IAP, and adding continuously as many IAP items as many books we have. But this is not proper for us, as the authors won’t have access to iTunesConnect, so it cannot be dynamic, “self-serving”.
Therefore we are planning to create a set of generic "consumable" IAP items like “Book worth $0.99”, “Book worth $1.99”, and so on. Then in the app we’ll show the corresponding IAP item for the books as specified by the authors, when they added it to our system.
Of course we store the purchased items on the server side, so the user will always have access to the purchased items -- even if they access it later from another device.
Will Apple approve this implementation?
Does it fit with their IAP policy?
I’ve found some similar quite old topics in the forum but the answers were confusing.
Have you implemented something similar and get approval from Apple?
Apple has accepted our solution, as described in the question.
The point is, as highlighted correctly by #RomOne and #ge0rges that you need to provide the possibility to restore the items later.
As we are storing every purchase in our database, and our users are authenticated (they need to register and log in to purchase), we are able to provide them access to the purchased items forever, even when accessing the app from other device.
We are also storing the associated in-app-purchase's ProductID from iTunesConnect, plus the userID, the price, and the date, to have a detailed register of all purchases.
Important: Apple has rejected our first solution, because they didn't understand how it works, and how a purchase can be restored.
The key to success was describing in detail how the system works and providing a test user access to our web admin site. This allowed the Apple reviewers to see the whole system.
Yeah in my point of view they will accept it. As long as you allow users to retrieve their purchases later on. Your system make me think about a virtual currency I have made where I had to make generic consumable that needed to be actually saved for the user. Apple approved it (and still does) because I was saving all purchases, even if it didn't fit perfectly with IAP policy ;)
The key here is to make sure these purchases are restorable, always. So make sure to store the "IDs" or however you identify the different item in a way that is associated directly to the Apple ID (not account, but Apple ID).

Implement multiple Consumable In-App Purchases

Right first of all I have tried all kinds of tutorial but they only show how to get the purchase information and display it as a tableview then get the purchase to work, plus this is only for non-consumable or one consumable. As per the image above, I have created this in the XiB and would like to just initiate the consumable purchase when the user taps the button. I would not like to get the purchase info from iTunes Connect then display it as I am already displaying it offline.
I have created the App ID and the App in iTunes Connect and have created 5 in-app purchases. (as per the image below.) I would like the buttons to call for each of these. Does anyone have any suggestions?
I have no experiense in working with consumable purchases, but I don't think there is a large difference. I hope, you've already read Apple In-App Purchasing Programming Guide: http://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008267-CH1-SW1
So, what is your problem? If you need to show multiple products in one viewController, you need to take somewhere a list with productIdentifiers (strings, unique for each product in you app at iTunes) for each product. You can hardcode these productIdentifiers, or, better, if you are using server, request them (because, if you hardcode your productIdentifiers, and then add/remove/edit product and it's productIdentifier changes, you'll need to publish a new patch for your app).
To show actual information about each product (price, name), you need to request it. You do it by creating SKProductRequest (for each product) and adding it to your paymentQueue. You'll get price in response. If you don't - don't even show that product in your viewController, because it's something wrong with that product.
To show the products offline you can implement some cache. May be it looks nice, but does it make sense to show "Buy" button if you are offline?
Probably there will be some kind of cell for each product in your viewController. In that case, that should be not a problem to determine, which productIdentifier to use, when user taps on some of the cells.
What to do after that? IMHO it's nicely described in Apple's guide.
If you need more help or some more specific questions - please, comment my post, or edit your question.
P.S. Be aware: in iOS 7 there are some number of changes in working with in-app purchases. Anyway, you can find all information at http://developer.apple.com/library/ .
P.P.S. Check this post: https://meta.stackexchange.com/questions/182266/how-much-research-effort-is-expected-of-stack-overflow-users/182380 . I hope you know, what I mean :) You can try to find some help at #iphonedev # irc.freenode.net , for example. And search and search again. Good luck.
You need to get product information via SKProductsRequest, because you need and SKPayment instance to make a purchase, and SKPayment can be created only with existing SKProduct, not just productIdentifier string.
You can use local cache to show prices to the user even when he is offline, but Apple forces you to get product info every time user tries to purchase something.
Taking product info is not a problem, anyway.
How to store a set/array of productIdentifiers? Read my previous answer.

iOS in-app purchase free / paid persistence

I am building a game that will be free to play, and will include 100 free consumable 'hints'. I intend to offer more hints for purchase through in-app purchase. My current method is to store a file locally with the number of hints the user still has left. When the game is first downloaded the local file doesn't exist, so a new file is created with 100 hints. When an in-app purchase happens, it simply adds to the number of hints. (In the game, each hint simply removes a choice from a multiple choice question - the file simply stores a counter.)
My problem: A user could simply delete the app when they have 0 hints remaining (which will delete my local file that has a count of 0), re-download the app from the app store and they will then start again with 100 hints.
My question: How do I prevent this? Is there a different method I should use for storing hints?
use the Keychain to store your data, because the Keychain items are not deleted even if the app is Uninstalled or removed. This Api will help a lot link, have a look
or
You can refer to Apple's documentation on Keychain data
If you are going to offer some part of your hints as an in-app product, I suggest you to keep track of all your hints (both purchased and free) on a server. This way you can keep track of each user and even if they delete and re-download your app, you will still be able to keep track of your hints.
Edit: If you are implementing IAP you might find it healthy to keep track of your purchased goods anyway (ie. keeping track of your purchase statistics, watching out for fake in-app purchases, etc.)
usualy you use a server for such things, so not the device but the account is the interesting. Also a good possibility to save your progress and share to other devices ;)

iOS in-app purchases - best way to tell if user has purchased

I need to set a global variable when a user makes an in-app purchase. I could use NSUserDefaults, and just have a key called "Purchased", but that doesn't seem very secure.
What is the best way to securely store data so that I know whether or not users have made a purchase?
For example in a particular view I need to know whether or not to display a "Purchase" button. Obviously it should be hidden if they've already made the purchase.
For secure data you should use the iOS keychain. Here's the documentation:
http://developer.apple.com/library/mac/#documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html
Hope this helps.
There is no need to store that information. There is a method to restore all the user purchases. Look for restoreCompletedTransactions.
You can check all the user's purchases in your view and then show the "Purchase" button for all the items that can still be bought.
UPDATE:
Oh! I misunderstood your question. The above method will get you the purchases the user has made in case of an app reinstall for instance. Regarding your question, it is completely fine to store information relative to the purchased products in NSUserDefaults to give the user the goods, levels or whatever he has paid for.
I recommend this step by step tutorial that helped me implement in-app purchases to answer all your questions.

Update in-app purchase content for iOS app?

I can't seem to find an answer to this question anywhere, so here goes...
I've developing an iOS app that will have non-consumable in-app purchases (expansion packs). Say I sell a pack that has 10 levels in it, for example, and in a month I want to update that in-app purchase to have 15 levels. The user will NOT have to re-purchase the pack; they would just need to update it.
Three questions:
Is this even possible?
How are users notified of this (or how SHOULD they be notified of this change?)
Does Apple need to review changes like this?
Thanks in advance,
Rick
Clearly yes. It is up to you, to write the code in a way, that your app remembers which updates a user has bought and how these updates are interpreted in your app. The only thing that will stop you from changing an in-app purchase content is when you take functionality or in your case levels, away again. Apple won't allow you to upload a new paid version with less functionality.
I would probably tell the user in the info text you have on the app-store, that they will receive 5 additional levels if they already have the 10 level upgrade.
Apple reviews every change you make to the app when you upload a new version to the app-store. This is true for any feature as it is for updates to in app purchase.
I did something similar to this in my app recently. I was saving a BOOL value in NSUserDefaults that specified if the user had purchased the expansion pack. In my update I simply had the change the code that was given to the user based on whether or not that BOOL value was YES or NO. As long as you designed it correctly you shouldn't have any troubles updating
Yes it's possible. Provided you keep a track of who has bought what pack (ie. keep a bool value as an NSUserDefault), then they will still have access to it (even if you add more stuff/levels to it).
It depends what you mean by notified; they will know if they read the update comments when they install the update. Also you could just choose to alert them when the load the app after the update - your call.
If you're submitting the code Apple will review it. Just think of it like any other update to an app.
Hope this helps!

Resources