With iOS 6, Apple provides free hosted content for in-app purchase using StoreKit.
I would like to understand the benefits of this, especially in terms of security!
If I have a pack of images to unlock, I can choose to host the images directly in the app, or in hosted content. Is it more secure to go with hosted content? My in-app purchase already verifies the receipt from Apple.
Is there a chance that a hack can unlock the images directly in my app?
If my pack of images is like 40MB, is it a good solution for the user experience to download the hosted content? With a not so good 3G connection it can be painful...
Thanks for your answers.
Apple offers some guidance on when to use hosted content or bundled content. I'm quoting from In-App Purchase Programming Guide: Delivering Products.
Embed smaller files (up to a few megabytes) in your app, especially if you expect most users to buy that product. Content in your app bundle can be made available immediately when the user purchases it. However, to add or update content in your app bundle, you have to submit an updated version of your app.
Download larger files when needed. Separating content from your app bundle keeps your app’s initial download small. For example, a game can include the first level in its app bundle and let users download the rest of the levels when they’re purchased. Assuming your app fetches its list of product identifiers from your server, and not hard-coded in the app bundle, you don’t need to resubmit your app to add or update content that is downloaded by your app.
These are guidance, not requirements, so if you have reason to believe that someone will make an in-app purchase with a large downloadable asset while they're on cellular, you might want to bundle it. However, this is wasting space on your user's device if they do not purchase to unlock it.
As for security, they have this note in the section regarding download objects.
Note: Download all Apple-hosted content before finishing the transaction. After a transaction is complete, its download objects can no longer be used.
This implies (although, does not explicitly state) that the downloads are only available with some internal authentication of the transaction. This means that it requires Apple's approval, which is actually more secure than checking the receipt locally (which can be bypassed using jailbreaks).
Related
Building an iOS App in Swift. Quick question about IAP's I want to implement. Currently, I have my In-App Purchases fixed in my app. Meaning, I would have to push an update to the app in order to change the visible information about the IAP, etc.
Does Apple allow me to store this In-App Purchase data in my cloud(Parse), or does it have to be local? Of course, the IAP's would have to be approved in iTunes Connect, but don't have to be used if they are approved.
My goal is to alternate through different plans without having to go through an entire app update.
I feel like the answer is a big obvious yes, but I just wanted to confirm before I begin coding it all in.
Thanks!
It's up to you to decide where to store In-App Purchases.
Here is Apple documentation about storing in-app purchases data.
How to store product identifiers:
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.
How to store associated content for purchased package:
You can embed that content in your app’s bundle or you can download it
as needed — each approach has its advantages and disadvantages.
Embed smaller files (up to a few megabytes) in your app.
Download larger files when needed.
Personally I want to say that all projects I was working on used remote server for getting in-app purchases data.
You don't need care about app approval in this situation.
Yes, It is possible to store In-App Purchases on the Cloud(Parse).
The in-app purchases for iOS are done through the Apple app store. We do not take a cut or interact with the transaction in any way. We simplify the process of setting up in app purchases, take care of interacting with the Apple server, perform receipt validation to ensure your purchases are done securely, take care of delivering the purchased content through PFFiles if you choose to use this mechanism and also provide an easy to use UI component for use in your app.
if you want to know in detail visit here http://blog.parse.com/announcements/in-app-purchase/
Yes, you can do that using parse in swift(youtube)
and parse doc.
Using the links at the bottom of my post I have built a basic in app purchase for my OSX app. Basically what I do is show a UI for the user to select that they want to purchase the upgrade (which just adds more content), then I start the transaction with a call to addPayment:, I receive the transaction in paymentQueue:updatedTransactions: and if it is purchased transaction I send it along to a method that provides the content and then calls finishTransaction:.
This all works in a single use of the app but then when I fire up the up again I would have to do the purchase again to reenable those features (this makes sense because I am not storing the upgrade data anywhere), but I am wondering what is the best way to store the data about the purchase to prevent the user from being asked to buy again after they have already purchased. Is this somehow suposed to be done through receipt validation? None of the documentation I found talked much about this.
Helpful links:
In app Purchase walkthrough
Apple's in app purchase documentation
EDIT:
My app is really just trying to enable built in content through the in app purchase so it seems that using property list is the what Apple would suggest:
Apple recommends using a property list (plist) to track product identifiers for your built-in features. Content-driven applications can use this to add new content without modifying the source for your application.
But I wonder how can I edit a plist file if it is stored in the bundle (this was cause the sandboxing to think the app had been compromised). Do you store the preferences plist in the container? The link apple gives that is supposed to discuss more about changing application preferences links to an IOS page and the only thing on that page about preferences is in the settings bundle.
Implementing Application Preferences”
Is the application preferences method only to be used on IOS? Is the correct place to put the upgrade data in the settings bundle?
For purchases that enable additional content, Apple recommends using a server-based receipt validation setup as noted here:
http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/APIOverview/OverviewoftheStoreKitAPI.html#//apple_ref/doc/uid/TP40008267-CH100-SW12
"Apple recommends you retrieve product identifiers from your server, rather than including them in a property list. This gives you the flexibility to add new products without updating your application.
In the server model, your application retrieves the signed receipt associated with a transaction and sends it to your server. Your server can then validate the receipt and decode it to determine which content to deliver to your application. This process is covered in detail in “Verifying Store Receipts.”
The server model has additional security and reliability concerns. You should test the entire environment for security threats. Secure Coding Guide provides additional recommendations.
Although non-consumable products may be recovered using the built-in capabilities of Store Kit, non-renewing subscriptions must be restored by your server. You are responsible for recording information about non-renewing subscriptions and restoring them to users. Optionally, consumable products could also be tracked by your server. For example, if your consumable product is a service provided by your server, you may want the user to retrieve the results of that request on multiple devices."
You can create a UUID for the user and store it in the app's preferences. The advantage of doing this is that the uuid is then backed up when the user backs up or restores their device. It can also easily be synced across iCloud if it's a universal app. The server can then link that UUID to the purchases made and deliver the content that was purchased by that user. You may want to include additional security protocols to reduce any UUID spoofing by unscrupulous users, but unless the content is extremely valuable, that is usually more effort than it's worth IMHO.
I have an app in the iTunes store that has full functionality. I attempted to release a Free version which contains half of the functionality, and contains a link to the full version if the user tries to use the other functions.
Apple rejected the app on the basis that rather than having two apps, I ought to have the main app released for free and have the extra functions unlockable using in-app purchasing.
That's fine; I can do this. The only problem is that since I released the full version initially, some people have already paid for and downloaded the full version. When I update this app so that it is free, it will be restricted by default. Those users that have paid for the full version will have lost the functionality they've paid for.
I don't really want to release a second version of the app since I intend on continuing to update the app and managing two release streams would be unwieldy.
Is it possible to somehow offer for free the in-app purchase to those users that have already bought the full version of my app when I update the app to the new (free, in-app supported) version?
Edit: An (unpreferred) alternative would be a way of refunding the purchases to the original buyers, along with a note explaining why. Any ideas how?
What I'd do is add a already paid option within the application itself, and then allow users to enter a license code, or email address depending what you prefer, Which you can automatically issue from their contact details if you have them or ask them to contact you if you don't, which most will as they have paid.
Now as far as the licensing and the verification of these codes you could setup a cheap VPS which verify s the code and only activates with codes that you have entered on the server, meaning you won't fall victim of Keygeners.
Just my 2 cents.
If your app doesn't currently have a username/password registration, I would suggest releasing an update to the paid app that explains to your users on an initial popup view something like:
Thank you for supporting our app. Due to changes in Apple's policies, we will be converting this app into a free app with in-app upgrades. Since you already purchased the full app, you will be awarded all features! Please input an [email_address or username] so that we can provide a painless transition.
If your app has a user login mechanism already in place (username/password), then just store those details and have the user log in later in the "free" app to unlock all of the features.
Obviously, both of these suggestions require a backend for validation, but shouldn't be too difficult to create that.
This is tricky due to section 3.3.3 of the license agreement and Attachment 2. I'm not a lawyer so I'll save my interpretation but, read them.
Another option would be to make the free version a new, different app and leave the original one in the store but unavailable. Then you can still publish updates to it but new users won't see it. Apple would probably allow this considering you are still only presenting one app to new users. The downsides are (1) you have to maintain two versions and (2) you have to start over in terms of reviews etc.
I need to develop a newsstand app for a client. I've seen the tutorials on newsstand. My question is, after you make the app for newsstand how do you deliver the content of each issue?
My client wants the same UI experience that GQ magazine offers, which is a interactive magazine (videos, buttons that expand text)
Thanks in advance for any help!
For Newsstand is best to provide issues via download from your server. Don't bundle them with app, because that would require app review every time you add an issue.
For paid magazines, you have to create non-consumable in-app purchase for every issue. Then you can host your content with Apple if you don't want to use some CDN.
Still you'll need some kind of web service to:
provide list of issues for iOS app
provide issue content
send push notification when new issues are available
provide Newsstand feed to automatically update issues visible in the App Store
validate receipts from the App Store
Simplified "algorithm" for a paid magazine iOS app would look like this:
Fetch current issues from server and synchronize with local copy
Fetch issue prices from App Store (create SKProductsRequest for every issue)
Present issues to the user
When user performs purchase, validate receipt and start downloading content
If user purchased subscription, allow access to all issues for free (but keep checking if subscription is still active)
If this is too much work, you may want to use some existing solutions (disclaimer: I cofounded Issue Stand and am moderating this list).
I have two similar apps with in-app-purchase (IAP) content that could be shared between them. I'd like to reward customers who buy in one app, by letting them transfer the purchase to the other app. However, I'm worried that my apps would be rejected due to the App Store review guideline that says you can't have any non-App store content activation methods.
As far as technical feasibility, it's clear to me that the Document Interaction mechanism is a means to this end (sans web server). I can have each app register a custom file type. The app in which the user purchased the content can show a link to launch the other app, passing it appropriate metadata as the "launched file" so the second can then mark the items as purchased.
Does anybody know if this has been attempted, and if Apple is approving such an approach?
Note that I'm not concerned about purchase security with this approach, because making paying customers happy is much more important to me than preventing piracy.
This isn't so much an answer to the precise question above as it is a useful alternate technique of accomplishing the end goal. If you set things up correctly, two apps can share KeyChain access, and thus share metadata about purchased IAPs. This requires using the same Bundle Seed ID (e.g. "AXGUKHGX...") for the app ID, in combination with setting things up properly in your app's info plist. This latter technique is a much more elegant approach for propagating sharable IAPs.