How To Set Up In App Purchases On Iphone
Update notation: Pietro Rea updated this tutorial for Xcode ten, Swift 4.ii and iOS xi/12. Ray Wenderlich wrote the original.
One of the great things about building iOS apps is that you have lots of choices when it comes to monetizing your app: plain vanilla paid apps, free apps supported by ads, or fifty-fifty apps that support in-app purchases.
An in-app purchase (or IAP) allows developers to accuse users for specific functionality or content while using an app. Implementing IAPs is specially compelling for several reasons:
- It'south an actress fashion to earn money, in addition to simply selling the app for a fee upfront. Some users are willing to spend a lot more on extra content or features.
- An app tin can be offered for costless, which makes it a no-brainer download for most people. Gratuitous apps volition typically get many more downloads than paid apps. If users savor the app, then they can purchase more content or functionality after.
- Yous can display advertisements to the user in a costless app with an selection to remove them by purchasing an IAP.
- Following the initial release of an app, new paid content can be added to the aforementioned app instead of having to develop a brand new app to earn more money.
In this in-app purchase tutorial, you'll leverage IAPs to unlock extra content embedded in an app. You lot'll need to exist familiar with basic Swift and iOS programming concepts. If these are unfamiliar topics, and so check out our range of Swift tutorials before getting started. You'll also demand a paid developer account, with access to both the iOS Programmer Center and App Store Connect.
Getting Started
In this in-app purchase tutorial, yous'll build a small app called "RazeFaces", which allows users to buy a "RazeFace", which is a neat illustration commonly used on this site for books and videos.
A typical "RazeFace"
Download the materials using the link at the top and open up the starter project in Xcode. Build and run to see what information technology does and so far. The reply is: Non a lot! You lot'll run into an empty tabular array view, with a single Restore button in the navigation bar, which will be hooked upwardly later to restore purchases.
Upon finishing this tutorial, there will be a list of RazeFaces listed in the table view which you'll be able to buy. If you delete and reinstall the app, the Restore button will reinstate whatsoever previously purchased RazeFaces.
Head over to Xcode to take a quick look at the code. The main view controller is in MasterViewController.swift. This course displays the table view which will incorporate a listing of bachelor IAPs. Purchases are stored as an array of SKProduct objects.
Notice that MasterViewController is using an object called RazeFaceProducts.store of type IAPHelper to do the heavy lifting. Take a wait at their respective code files, RazeFaceProducts.swift and IAPHelper.swift.
RazeFaceProducts is a uncomplicated struct that contains some data nigh the products in the app, and IAPHelper does all the important piece of work of talking to StoreKit. The methods are all stubbed out at the moment, only y'all'll fill them out in this tutorial to add together IAP functionality to the app.
Before writing any lawmaking to contain IAP, you'll first need to do some setup in the iOS Programmer Center and App Store Connect.
Creating an App ID
First, you need to create an App ID. This will link together your app to your in-app purchaseable products. Login to the Apple Programmer Center, then select Certificates, IDs & Profiles.
Adjacent, select Identifiers > App IDs, and click + in the upper right corner to create a new App ID.
Fill out the information for the new App ID. Enter RazeFace IAP Tutorial App for the Name. Choose Explicit App ID and enter a unique Package ID. A mutual practice is to employ your domain proper name in contrary (for case, com.razeware.razefaces). Make note of the Package ID every bit information technology volition be needed in the steps that follow.
Scroll down to the App Services section. Discover that In-App Purchase and GameCenter are enabled past default. Click Continue and then Annals and Washed.
Congratulations! You have a new App ID! Side by side, you'll create a matching app in App Store Connect.
Checking Your Agreements
Earlier you can add IAPs to an app in iTunes Connect, you must do ii things:
- Make sure y'all have accepted the latest Apple Development Plan License Understanding on programmer.apple.com.
- Brand sure you have accustomed the latest Paid Applications agreement in the Agreements, Tax, and Billing section in App Store Connect.
If you have not done this, usually iTunes Connect will give you a warning similar the following:
If you see something like the to a higher place, follow the steps to accept the advisable agreements.
Information technology'south also good to double cheque the Agreements, Tax, and Cyberbanking department in iTunes Connect:
If you run across a section entitled Request Contracts containing a row for Paid Applications, then click the Request push button. Fill out all the necessary data and submit it. Information technology may take some fourth dimension for your request to be canonical. Sit tight!
Otherwise, if you lot see Paid Applications listed under Contracts In Effect, so it looks similar you've already done this step! Nice chore!
Note: Apple tin take days to corroborate these IAP-related agreements after you lot submit them. During this time, you won't be able to display IAP products in your apps even if you implement everything correctly in code. This is a common source of frustration for folks implementing In-App Purchases for the first fourth dimension. Hang in there!
Creating an App in iTunes Connect
Now to create the app tape itself, clickApp Store Connect in the upper left corner of the page, and so clickMy Apps.
Adjacent, click + in the upper left corner of the page and select New App to add a new app record. Fill out the information every bit shown here:
You won't be able to use the exact same app Name that you see hither, because app names need to be unique across the App Store. Perhaps add together your own initials after the instance title shown in the screenshot above.
Notation: If you are quick in getting to this step, the Bundle ID might not be showing upwardly in the dropdown list. This sometimes takes a while to propagate through Apple's systems.
Click Create and you're washed!
Creating In-App Buy Products
When offering IAPs yous must first add an entry for each individual purchase within App Store Connect. If yous've ever listed an app for sale in the shop, information technology'south a similar process and includes things like choosing a pricing tier for the purchase. When the user makes a purchase, the App Store handles the complex procedure of charging the user and respond with data most such operation.
There are a whole bunch of different types of IAP you can add together:
- Consumable: These can be bought more than once and tin can be used upward. These are a good fit for extra lives, in-game currency, temporary power-ups, and the like.
- Non-Consumable: Something that you buy once, and expect to accept permanently such as extra levels and unlockable content. The RazeFace illustrations from this tutorial autumn into this category.
- Not-Renewing Subscription: Content that'south available for a fixed period of time.
- Car-Renewing Subscription: A repeating subscription such equally a monthly raywenderlich.com subscription.
You can only offer In-App Purchases for digital items, and not for physical goods or services. For more data about all of this, check out Apple tree's total documentation on Creating In-App Purchase Products.
Now, while viewing your app'due south entry in App Store Connect, click on the Features tab and and then select In-App Purchases. To add a new IAP product, click the + to the right of In-App Purchases.
You'll see the post-obit dialog appear:
When a user purchases a RazeFace in your app, you'll want them to always have access to it, so select Non-Consumable, and click Create.
Adjacent, fill out the details for the IAP every bit follows:
- Reference Proper noun: A nickname identifying the IAP within iTunes Connect. This proper noun does not appear anywhere in the app. The title of the RazeFace you'll be unlocking with this purchase is Swift Shopping, so enter that here.
- Product ID: This is a unique string identifying the IAP. Usually it's best to starting time with the Package ID and then suspend a unique name specific to this purchasable detail. For this tutorial, make sure you lot append swiftshopping, every bit this will exist used later within the app to look upwardly the RazeFace to unlock. For case, yous tin apply: com.theNameYouPickedEarlier.razefaces.swiftshopping.
- Cleared for Auction: Enables or disables the sale of the IAP. You want to enable information technology!
- Price Tier: The cost of the IAP. Choose Tier 1.
Now ringlet downward to the Localizations department and notation that there is a default entry for English (U.S.). Enter "Swift Shopping" for both the Display Proper noun and the Description. Click Save. Swell! You've created your starting time IAP product.
Annotation: App Store Connect may mutter that you're missing metadata for your IAP. Before you submit your app for review, yous're required to add a screenshot of the IAP at the bottom of this page. The screenshot is used merely for Apple'southward review and does not appear in your App Store listing.
At that place's one more stride required before you can delve into some lawmaking. When testing in-app purchases in a development build of an app, Apple tree provides a exam environs which allows you to "buy" your IAP products without creating financial transactions.
These special exam purchases can only exist fabricated by a special "Sandbox Tester" user business relationship in App Store Connect. You lot're well-nigh at the code, I hope!
Creating a Sandbox User
In App Shop Connect, click App Store Connect in the top left corner of the window to go back to the main menu. SelectUsers and Roles, then click the Sandbox Testers tab. Click + next to the "Tester" title.
Make full out the information and click Save when you lot're done. You can make upwardly a kickoff and last name for your test user, simply y'all must utilise a existent email address as Apple will transport a verification e-mail to the address. One time you receive that email, be sure to click the link in it to verify your address.
The email address you enter should likewise NOT already be associated with an Apple ID account. Hint: if yous have a gmail account, yous can simply employ an address alias instead of having to create a brand new business relationship.
Note: Unfortunately, testing a new purchase of a non-consumable IAP requires a new sandbox tester (and email address) each time. Repeated purchases using the same sandbox tester will be treated as restoring an already purchased item, then whatever code specific to new purchases volition non be exercised.
If multiple test runs through new purchase code are necessary and your email provider does non back up qualifiers, then consider setting up a consumable IAP merely for testing purposes. Delete the app on your device after each test and the buy of a consumable IAP will be considered a new purchase.
One strategy y'all could adopt is testing the failure cases as many times as possible earlier testing the successful case. That way you'll need to create fewer sandbox testers. In general, remember the rule that in one case a user (even a sandbox one) has bought a non-consumable IAP, he can't buy it once more, only restore it.
Great — yous at present accept a test user. Yous can finally implement IAPs in your app!
Project Configuration
For everything to work correctly, information technology's actually of import that the packet identifier and product identifiers in the app match the ones yous simply created in the Programmer Center and in App Store Connect.
Head over to the starter project in Xcode. Select the RazeFaces project in the Projection navigator, so select it again under Targets. Select the Full general tab, switch your Team to your correct team, and enter the bundle ID y'all used before.
Next select the Capabilities tab. Curlicue down to In-App Purchase and toggle the switch to ON.
Note: If IAP does non show up in the listing, make sure that, in the Accounts section of Xcode preferences, you are logged in with the Apple tree ID you lot used to create the app ID.
Open up RazeFaceProducts.swift. Notice that there is a placeholder reference to the IAP production you created: SwiftShopping. Supervene upon this with the total Product ID that you configured in App Store Connect — for example:
public static let SwiftShopping = "com.theNameYouPickedEarlier.razefaces.swiftshopping" Note: The list of product identifiers tin can be pulled from a web server so new IAPs can be added dynamically rather than requiring an app update. This tutorial keeps things uncomplicated and uses hard-coded product identifiers.
Listing In-App Purchases
The store property of RazeFaceProducts is an instance of IAPHelper. As mentioned earlier, this object interacts with the StoreKit API to list and perform purchases. Your first task is to update IAPHelper to retrieve a listing of IAPs — at that place's only one so far — from Apple'due south servers.
Open IAPHelper.swift. At the top of the class, add together the following private property:
private let productIdentifiers: Fix<ProductIdentifier> Next, add the following to init(productIds:) before the call to super.init():
productIdentifiers = productIds An IAPHelper instance is created by passing in a ready of product identifiers. This is how RazeFaceProducts creates its store instance.
Adjacent, add these other private properties just under the ane you added a moment ago:
individual var purchasedProductIdentifiers: Set<ProductIdentifier> = [] private var productsRequest: SKProductsRequest? private var productsRequestCompletionHandler: ProductsRequestCompletionHandler? purchasedProductIdentifiers tracks which items have been purchased. The other two properties are used past the SKProductsRequest consul to perform requests to Apple servers.
Next, still in IAPHelper.swift replace the implementation of requestProducts(_:) with the following:
public func requestProducts(completionHandler: @escaping ProductsRequestCompletionHandler) { productsRequest?.cancel() productsRequestCompletionHandler = completionHandler productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers) productsRequest!.consul = self productsRequest!.kickoff() } This code saves the user'southward completion handler for future execution. It and then creates and initiates a request to Apple via an SKProductsRequest object. There's one trouble: the code declares IAPHelper as the request'due south consul, but it doesn't however conform to the SKProductsRequestDelegate protocol.
To fix this, add the following extension to the very end of IAPHelper.swift, after the last curly brace:
// Marker: - SKProductsRequestDelegate extension IAPHelper: SKProductsRequestDelegate { public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { print("Loaded list of products...") let products = response.products productsRequestCompletionHandler?(true, products) clearRequestAndHandler() for p in products { print("Establish product: \(p.productIdentifier) \(p.localizedTitle) \(p.price.floatValue)") } } public func request(_ asking: SKRequest, didFailWithError fault: Fault) { print("Failed to load list of products.") impress("Fault: \(error.localizedDescription)") productsRequestCompletionHandler?(false, nil) clearRequestAndHandler() } individual func clearRequestAndHandler() { productsRequest = zippo productsRequestCompletionHandler = nil } } This extension is used to get a listing of products, their titles, descriptions and prices from Apple's servers by implementing the two methods required by the SKProductsRequestDelegate protocol.
productsRequest(_:didReceive:) is chosen when the listing is succesfully retrieved. It receives an assortment of SKProduct objects and passes them to the previously saved completion handler. The handler reloads the table with new data. If a problem occurs, request(_:didFailWithError:) is chosen. In either case, when the request finishes, both the request and completion handler are cleared with clearRequestAndHandler().
Build and run. Hooray! A list of products (only one so far) is displayed in the table view! It took some piece of work, just you got at that place in the finish.
Note: You can display IAP products on both the iOS simulator as well equally physical iOS devices, but if you want to exam ownership or restoring purchases, you tin just do this on concrete devices. More than on this in the purchasing section below.
Note: If the run was unsuccessful and y'all didn't encounter whatever products, so there are a number of things to cheque. This list is courtesy of itsme.manish and abgtan from the forums on earlier versions of this post, plus more than tips added over time.
- Does the project's Parcel ID match the App ID from the iOS Development Heart?
- Is the full product ID being used when making an
SKProductRequest? (Check theproductIdentifiersproperty ofRazeFaceProducts.) - Is the Paid Applications Contract in effect on iTunes Connect? It can have hours to days for them to go from pending to accepted from them moment you submit them.
- Have you waited several hours since adding your product to App Store Connect? Product additions may be active immediately or may take some fourth dimension.
- Bank check Apple Programmer System Condition. Alternatively, try this link. If it doesn't respond with a condition value, so the iTunes sandbox may be down. The condition codes are explained in Apple's Validating Receipts With the App Store documentation.
- Take IAPs been enabled for the App ID? (Did you select Cleared for Sale earlier?)
- Have y'all tried deleting the app from your device and reinstalling information technology?
Notwithstanding stuck? Every bit you lot can see, there'southward a lot of setting upwards to exercise for IAP. Attempt this tutorial's comments for a word with other readers.
Purchased Items
You want to be able to make up one's mind which items are already purchased. To do this, yous'll employ thepurchasedProductIdentifiers belongings added earlier. If a product identifier is contained in this set, the user has purchased the item. The method for checking this is straightforward.
In IAPHelper.swift, replace the render argument inisProductPurchased(_:) with the following:
return purchasedProductIdentifiers.contains(productIdentifier) Saving purchase status locally alleviates the need to request such data to Apple tree's servers every time the app starts. purchasedProductIdentifiers are saved using UserDefaults.
Yet in IAPHelper.swift, supersede init(productIds:) with the following:
public init(productIds: Prepare<ProductIdentifier>) { productIdentifiers = productIds for productIdentifier in productIds { let purchased = UserDefaults.standard.bool(forKey: productIdentifier) if purchased { purchasedProductIdentifiers.insert(productIdentifier) impress("Previously purchased: \(productIdentifier)") } else { impress("Not purchased: \(productIdentifier)") } } super.init() } For each product identifier, you check whether the value is stored in UserDefaults. If information technology is, then the identifier is inserted into the purchasedProductIdentifiers set up. Later on, you'll add together an identifier to the set following a purchase.
Note: User defaults may not be the best place to shop information about purchased products in a real application. An owner of a jailbroken device could easily access your app's UserDefaults plist, and modify it to 'unlock' purchases. If this sort of affair concerns you, then it's worth checking out Apple'south documentation on Validating App Shop Receipts — this allows you to verify that a user has made a particular purchase.
Making Purchases (Show Me The Coin!)
Knowing what a user has purchased is great, but you lot still need to be able to brand the purchases in the showtime place! Implementing purchase capability is the logical next pace.
Even so in IAPHelper.swift, replace buyProduct(_:) with the post-obit:
public func buyProduct(_ product: SKProduct) { print("Ownership \(product.productIdentifier)...") permit payment = SKPayment(product: product) SKPaymentQueue.default().add together(payment) } This creates a payment object using an SKProduct (retrieved from the Apple server) to add to a payment queue. The code utilizes a singleton SKPaymentQueue object called default(). Boom! Money in the bank. Or is it? How practice yous know if the payment went through?
Payment verification is achieved past having the IAPHelper detect transactions happening on the SKPaymentQueue. Before setting upwards IAPHelper as an SKPaymentQueue transactions observer, the class must conform to the SKPaymentTransactionObserver protocol.
Become to the very bottom (later the terminal curly brace) of IAPHelper.swift and add the following extension:
// MARK: - SKPaymentTransactionObserver extension IAPHelper: SKPaymentTransactionObserver { public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { switch transaction.transactionState { case .purchased: complete(transaction: transaction) break example .failed: fail(transaction: transaction) suspension case .restored: restore(transaction: transaction) break case .deferred: interruption case .purchasing: interruption } } } individual func consummate(transaction: SKPaymentTransaction) { print("complete...") deliverPurchaseNotificationFor(identifier: transaction.payment.productIdentifier) SKPaymentQueue.default().finishTransaction(transaction) } private func restore(transaction: SKPaymentTransaction) { guard let productIdentifier = transaction.original?.payment.productIdentifier else { return } print("restore... \(productIdentifier)") deliverPurchaseNotificationFor(identifier: productIdentifier) SKPaymentQueue.default().finishTransaction(transaction) } private func fail(transaction: SKPaymentTransaction) { impress("fail...") if allow transactionError = transaction.error as NSError?, let localizedDescription = transaction.error?.localizedDescription, transactionError.code != SKError.paymentCancelled.rawValue { impress("Transaction Fault: \(localizedDescription)") } SKPaymentQueue.default().finishTransaction(transaction) } individual func deliverPurchaseNotificationFor(identifier: String?) { guard permit identifier = identifier else { render } purchasedProductIdentifiers.insert(identifier) UserDefaults.standard.fix(true, forKey: identifier) NotificationCenter.default.post(proper noun: .IAPHelperPurchaseNotification, object: identifier) } } That's a lot of code! A detailed review is in order. Fortunately, each method is quite curt.
paymentQueue(_:updatedTransactions:) is the only method actually required by the protocol. It gets called when one or more transaction states change. This method evaluates the state of each transaction in an array of updated transactions and calls the relevant helper method: complete(transaction:), restore(transaction:) or neglect(transaction:).
If the transaction was completed or restored, it adds to the ready of purchases and saves the identifier in UserDefaults. It besides posts a notification with that transaction then that whatsoever interested object in the app tin can heed for it to do things similar update the user interface. Finally, in both the case of success or failure, it marks the transaction as finished.
All that'due south left is to hook up IAPHelper as a payment transaction observer. All the same in IAPHelper.swift, go dorsum to init(productIds:) and add together the following line right after super.init().
SKPaymentQueue.default().add(self) Making a Sandbox Buy
Build and run the app — only to test out purchases, y'all'll have to run it on a device. The sandbox tester created before can be used to perform the purchase without getting charged. If simply I could accept a sandbox tester to do my grocery shopping :] Hither'southward how to utilise the tester business relationship:
Go to your iPhone and brand certain yous're logged out of your normal App Store account. To do this, become to the Settings app and tap iTunes & App Store.
Tap your iCloud business relationship name and and so tap Sign Out. At this bespeak don't really sign in with the sandbox user. Yous will be prompted to do this once you attempt to buy the IAP dorsum in the sample app.
Connect your device, build and run! You'll see your product listed in the app. To begin the purchase process, tap the Purchase button.
An alert will appear prompting you lot to log in. Tap Use Existing Apple ID, and enter the login details for the sandbox tester business relationship that you lot created earlier.
Confirm the purchase by tapping Buy. The alert view shows that the buy is being made in the sandbox as a reminder that you won't be charged for it.
Finally, an alarm view will appear confirming the purchase was successful. Once the purchase process has been completed, a checkmark appears next to the purchased item. Tap on the purchased particular to enjoy your new RazeFace.
Finally you get to see this "Swift Shopping" RazeFace that you've been hearing so much well-nigh!
Restoring Purchases
If the user deletes and re-installs the app or installs it on another device, then they demand the ability to admission previously purchased items. In fact, Apple may reject an app if it cannot restore non-consumable purchases.
As a purchase transaction observer, IAPHelper is already being notified when purchases take been restored. The adjacent step is to react to this notification by restoring the purchases.
Open IAPHelper.swift and scroll to the bottom of the file. In the StoreKit API extension, replace restorePurchases() with the following:
public func restorePurchases() { SKPaymentQueue.default().restoreCompletedTransactions() } That was most likewise easy! You lot've already set up the transaction observer and implemented the method to handle restoring transactions in the previous stride.
To test this out, after you've fabricated a purchase in the previous step, delete the app from your device. Build and run again, then tap Restore on the top right. You should encounter a checkmark announced next to the previously purchased product.
Payment Permissions
Some devices and accounts may non permit an in-app purchase. This can happen, for case, if parental controls are prepare to disallow it. Apple requires this situation to be handled gracefully. Not doing so will likely effect in an app rejection.
Open up IAPHelper.swift once again. In the StoreKit API extension, replace the return statement in canMakePayments() with this line:
return SKPaymentQueue.canMakePayments() Product cells should behave differently depending on the value returned by canMakePayments(). For example, if canMakePayments() returns false, so the Purchase button should not be shown and the toll should exist replaced by "Not Bachelor".
To accomplish this, open up ProductCell.swift and supercede the entire implementation of the production property's didSet handler with the following:
didSet { guard let product = product else { return } textLabel?.text = product.localizedTitle if RazeFaceProducts.store.isProductPurchased(production.productIdentifier) { accessoryType = .checkmark accessoryView = naught detailTextLabel?.text = "" } else if IAPHelper.canMakePayments() { ProductCell.priceFormatter.locale = production.priceLocale detailTextLabel?.text = ProductCell.priceFormatter.cord(from: product.toll) accessoryType = .none accessoryView = self.newBuyButton() } else { detailTextLabel?.text = "Not available" } } This implementation will brandish more advisable data when payments cannot be made with the device. And there you take it — an app with in-app purchase!
Where To Go From Here?
You tin can download the completed version of the project using the Download Materials button at the top or lesser of this tutorial. Experience free to re-utilise the IAP helper form in your own projects!
The In-App Purchase Video Tutorial Serial by Sam Davies covers all of the topics introduced hither, but goes to the next level in Part 3 where he talks near validating receipts.
One shortcoming of the sample app is that information technology doesn't indicate to the user when it is communicating with Apple. A possible improvement would exist to brandish a spinner or HUD control at appropriate times. This UI enhancement, however, is beyond the telescopic of this tutorial. For more information on HUD controls, cheque out Department 3 of The iOS Apprentice.
Apple has a cracking landing folio for in-app purchase: In-App Buy for Developers. It collects together links to all the relevant documentation and WWDC videos.
IAPs can be an important role of your business model. Use them wisely and exist sure to follow the guidelines about restoring purchases and declining gracefully, and yous'll be well on your style to success!
If you lot have any questions or comments nearly this in-app purchase tutorial, and then please join the forum discussion below!
How To Set Up In App Purchases On Iphone,
Source: https://www.raywenderlich.com/5456-in-app-purchase-tutorial-getting-started
Posted by: harttruire1981.blogspot.com

0 Response to "How To Set Up In App Purchases On Iphone"
Post a Comment