I have implemented in-app-purchases like Mission packs or "full version" before. However, I am now looking into selling in-game credits.
What are some ways of keeping track of spent and total credits, even after removing and reinstalling the app
Is it common to sync these totals between the different iOS devices of a single user? Or should a user re-buy credits on different devices?
Should I have a user register with my server and track the credit on there?
I strongly recommend you to keep track of user's data on your server.
That way, even if the user deletes the app, the data will still be available after retrieving it from the server. Also, this will make you able to sync the same data between different platforms, not only devices.
After you retrieve the data, you might want to store it in NSUserDefaults and updated when needed.
Related
I am having trouble understanding the theory of in-app purchases and have got to the point where I read so much I have confused myself.
I have an application where I don't require the user to register however I do store data on a server and track this using the UUID. My application scrapes a hi-score system for an online game and the user has to input which players on the online game they wish to keep track of. This information is then sent to my server which scrapes the data every 24 hours by default. Here is an example of the database on my server.
Devices Table:
uuid,
scrape_interval
Players being tracked table:
uuid,
player_name
Tracking information table:
player_name,
track_data,
tracked_on
I want to include an in-app purchase which once purchased will mean that data is scraped every 12 hours instead of every 24 hours, the way I plan to do this is by updating the devices table and set the scrape_interval to 12 hours where uuid = uuid that made the purchase.
However how will this work for users that have multiple IOS devices, how do I ensure the list of players they are tracking is kept sync across devices? I have read about using an iCloud ID which is apparently a unique identifier but does this mean I will have to do a check on the launch of my app to ensure the user is logged into an iCloud account and force them to login if they aren't? This doesn't seem very user-friendly but nor does implementing a custom registration and login system.
Am I over thinking? Is there a simple solution?
In app purchases can be restored across multiple devices associated with a single itunes account. So a single purchase may actually exist on 5 devices, and you can not tell which is which.
The IAP will provide no device specific id. Your only option is to generate a unique installation id and sync all installation ids that have the paid status.
Long story short; my friend and I are developing a small game. In this game, users can purchase tokens with actual money, and use those tokens to purchase skins/characters in our game. We have no issues keeping track of their in-app purchases; however, we are having a hard time figuring out how to save the skins that they purchased and have it displayed across all devices that they are playing the game on (we currently are using iCloud to share data such as high score, number of coins, etc to their other devices).
Any advice is appreciated.
Since you are already saving data to iCloud, I would recommend having your skins stored as an array of id's in the cloud.
So if you have 10 skins available, and they buy the 5th and 8th, save an int array with 5,8 to the cloud.
The problem here is if they delete the app on all devices it will be hard for them to recover their skins, however they should be able to restore their in-app purchases and get the tokens back, and then re-buy the skins if they want to.
I want to offer my app free for a period and then charge to continue using it. I understand that the way to do this is to force the user to buy an In-App product after the free period. However, if I simply record the date that the user starts using the app in the standardUserDefaults and use this to calculate when the user must buy the upgrade the user could simply delete the app when the time arrives (I assume the sandbox is also deleted) and download the app again for another free period.
First question. Is my reasoning so far correct?
Second question. Is there any way of accessing the date that an app is first downloaded?
Assuming the answers to these questions are Yes and No I have come up with the following solution.
Upon downloading the app the user is first forced to "buy" free an In-App product which then will have the date it was added to the transaction queue. This In-App product would then be downloaded for any subsequent download and I could use the date of this product as my reference date.
As I can find no reference to this problem or solutions I really wanted confirmation that this was a sound way to proceed or if there was another more standard way of dealing with the problem.
Thank you
Silas
You are not allowed to limit you app for free for a limited period:
11.9 Apps containing content or services that expire after a limited time will be rejected, except for specific approved content (e.g.
films, television programs, music, books)
If you want to risk it, you could save the date (encrypted) in keychain to make it more persistent. Just so you know, user are able to access their keychain data if they iCloud keychain sharing and are on a Mac. So if they delete the correct key or rest there device your app will fall back to the free/trial mode.
This does not seem entirely consistent with:
Communicate the value of your products to your users. Users want to
know exactly what they’re going to buy. Combine information from the
App Store, such as product prices and descriptions, with additional
data from your server or the app bundle, such as images or demos of
your products. Let users interact with a product in a limited way
before buying it. For example, a game that gives the user the option
to buy new race cars can allow users to run a test lap with the new
car. Likewise, a drawing app that lets the user buy additional brushes
can give users the chance to draw with the new brush on a small
scratch pad and see the difference between brushes. This kind of
design provides users an opportunity to experience the product and be
convinced they want to purchase it.
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/ShowUI.html
One way of letting the user interact with a product feature in a limited way is to let them use it a few times before requiring that they pay to use the feature.
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 ;)
I'm developing an app where the user can purchase digital maps, charts and so on. I'd like to wrap these in in-app-purchases. The thing is that I don't know beforehand how many charts there will be, as I'm getting them from another source from the net. There could be hundreds.
I have a server that periodically gets the charts from that source and stores them locally; there may appear new charts in the future or disappear existing ones. All this without manual intervention.
There are three distinct types of charts.
My first solution was to create three consumable items and let the user buy these; this was working fine but unfortunately Apple rejected it, since they require charts to be "non consumable".
But I'm quite at a loss how to implement what I want with the non-consumable type. If I create these three types as non-consumable, and the user buys one, he will get all the other charts in that group for free, since a non-consumable item can only be bought once.
The only solution I can think of is to create a non-consumable item for every single chart. But that's something I want to avoid at all costs: as it is now, the charts are periodically fetched from the remote source without any manual work on my side. I'd like to keep it that way. I don't want to manually create a new non consumable purchases every time a new chart appears.
Any ideas how to make this scalable?
I can't completely spell it out for you with code but you can handle this problem two ways:
Currency.
You do not sell non-consumable items such as maps. You sell currency. With that currency you purchase maps. The maps you feed dynamically whenever the user hits your store front. That way you only need to track a few purchase options.
The other option:
The company I worked for initially set this up very simply. Our app would launch and we would reach out for a php script that handed us back the app store IDs that we had sitting in it. At that point we'd verify them and use the valid returns. This option allowed us to change our in app purchases through iTunes Connect and then in the script and everything was great.
This is an older post, but I just had the same question and found out there is now a way to dynamically provide non-consumables by hosting the product identifier list on your own server:
Every product you sell in your app has a unique product identifier.
Your app uses these product identifiers to fetch information about
products from the App Store, such as pricing, and to submit payment
requests when users purchase those products. Your app can either read
its list of product identifiers from a file in its app bundle or fetch
them from your server.
If your app has a fixed list of products, such as an in-app purchase
to remove ads or enable functionality, embed the list in the app
bundle. If the list of product identifiers can change without your app
needing to be updated, such as a game that supports additional levels
or characters, have your app fetch the list from your server.
There’s no runtime mechanism to fetch a list of all products
configured in iTunes Connect for a particular app. You’re responsible
for managing your app’s list of products and providing that
information to your app. If you need to manage a large number of
products, consider using the bulk XML upload/download feature in
iTunes Connect.
Apple Developer In-App Purchasing Guide
I think your limit on items is something massive like 10,000 or so.
Pre-create a big number of items, add some code to check your website to see what your highest chart number is and make sure the users can only buy charts that you have.
The app downloads the chart names and corresponding product id from your server and then you're just buying a product.
Apple doesn't care if the actual product is already in the app and unlocked by the purchase, downloaded from their server or provided from your website.
Whether you have these purchased directly via IAP or through some kind of in-app "currency" you could simplify the amount of work you'd need to do in the future by using a naming system which would guarantee a unique map name for each item you want to sell. For example:
NSString *myMapName = [NSString stringWithFormat:#"%#%#%#%#", app_identifier, map_type, top_left_corner_location, scale];
This way if your server passes that information for a new map, there's a programmatic way to know what the IAP identifier should be— just make it the value of the string myMapName.
In the case where you use currency (which sounds easier than the alternative option, and is what lots of big apps out there seem to be doing) you just need to make a hash with some data in your map so that people can't guess the code you're storing in their keychain/plist and magically get all your maps without paying :)
In the case where you actually have individual IAPs for each map, sadly you do have to make an IAP for every possible map once. (But you can hire some kid to do that part for minimum wage, right? It's just data entry) They can be basic shells, though, with the actual info provided via your server as described above, once it's verified that the map has actually been purchased.
Hope this helps!