{"id":6577,"date":"2021-02-04T14:08:10","date_gmt":"2021-02-04T08:38:10","guid":{"rendered":"https:\/\/www.innovationm.com\/blog\/?p=6577"},"modified":"2021-02-04T14:08:10","modified_gmt":"2021-02-04T08:38:10","slug":"in-app-purchase","status":"publish","type":"post","link":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/","title":{"rendered":"In-App Purchase"},"content":{"rendered":"<p><b>What is In-App Purchase and what is its need?\u00a0<\/b><\/p>\n<p><span style=\"font-weight: 400;\">In-App Purchase alludes to the purchasing of some extra highlights or administrations inside an application. Designers offer these extra types of assistance as a piece of a free application to adapt it.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It&#8217;s simpler to draw in clients towards a free application and afterwards give extra highlights to their convenience. For instance,\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">You can add promotions to your application and can charge clients to allow them to have an advertisement free encounter of the equivalent application.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">You can likewise give an alternative to purchasing gems for additional utilization in a game.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Presently I&#8217;ll specify In-App Purchase as IAP in the further report.<\/span><\/p>\n<p><b>Sorts of IAP :\u00a0<\/b><\/p>\n<p><span style=\"font-weight: 400;\">There are not many kinds of IAPs, accessible which are advised beneath:<\/span><b>\u00a0<\/b><\/p>\n<ul>\n<li aria-level=\"1\"><b>Non-Consumable: <span style=\"font-weight: 400;\">An item which you purchase once and never terminates or diminishes with use are Non-Consumable Products. For instance, the skin of a character in a game.<\/span><\/b><\/li>\n<\/ul>\n<ul>\n<li aria-level=\"1\"><b>Consumable: <span style=\"font-weight: 400;\">These are the items which you purchase more than once and decline with use. For instance, an asset to overhaul certain stuff inside a game.<\/span><\/b><\/li>\n<\/ul>\n<ul>\n<li aria-level=\"1\"><b>Auto-Renewable Subscriptions: <span style=\"font-weight: 400;\">The item which you purchase once and gets overhauled consequently for a specific charge except if the clients select themself out of it. For instance, Netflix membership.<\/span><\/b><\/li>\n<\/ul>\n<ul>\n<li aria-level=\"1\"><b>Non-Renewing Subscription: <span style=\"font-weight: 400;\">Product which you purchase and exists for a specific timeframe. For instance, a pass to open additional highlights for a month.<\/span><\/b><\/li>\n<\/ul>\n<p><b>Step by step instructions to add IAP to your application?\u00a0<\/b><\/p>\n<p><span style=\"font-weight: 400;\">You don&#8217;t have to make a pristine application to add IAP, rather you can add IAP to the current application and again distribute it to the App Store. Yet, here we&#8217;ll take it from the earliest starting point for which you need to do some additional undertaking.<\/span><\/p>\n<p><b>Step 1:<\/b><span style=\"font-weight: 400;\"> Expecting you to now have an Apple account.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><strong>i.<\/strong> Make an App ID. Visit <\/span><a href=\"https:\/\/developer.apple.com\"><span style=\"font-weight: 400;\">Apple Developer<\/span><\/a><span style=\"font-weight: 400;\"> and SignIn to your record.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><strong>ii.<\/strong> Select <\/span><b style=\"font-size: 1rem;\">Certificates, IDs &amp; Profiles <\/b><span style=\"font-weight: 400;\">from the left menu.<\/span><\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"alignnone wp-image-6581 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-6.04.19-PM.png\" alt=\"\" width=\"650\" height=\"378\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-6.04.19-PM.png 650w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-6.04.19-PM-300x174.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-6.04.19-PM-624x363.png 624w\" sizes=\"(max-width: 650px) 100vw, 650px\" \/><\/p>\n<p><span style=\"font-weight: 400;\"><strong>iii.<\/strong> Select <\/span><b>App IDs<\/b><span style=\"font-weight: 400;\"> inside the <\/span><b>Identifiers<\/b><span style=\"font-weight: 400;\"> segment and snap <\/span><b>+<\/b><span style=\"font-weight: 400;\"> at the upper right corner.<\/span><\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-6582 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-6.04.41-PM.png\" alt=\"\" width=\"652\" height=\"302\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-6.04.41-PM.png 652w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-6.04.41-PM-300x139.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-6.04.41-PM-624x289.png 624w\" sizes=\"(max-width: 652px) 100vw, 652px\" \/><\/p>\n<p><strong>iv.<\/strong> <b>App ID <\/b><span style=\"font-weight: 400;\">will be chosen naturally. Snap <\/span><b>Continue<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><strong>v.<\/strong><b> The app<\/b><\/span><span style=\"font-weight: 400;\"> will be chosen naturally. Snap <\/span><b style=\"font-weight: 400;\">Continue<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\"><strong>vi.<\/strong> Round out all the subtleties and you\u2019ll see <\/span><b>Game Center<\/b><span style=\"font-weight: 400;\"> &amp; <\/span><b>In-App Purchase<\/b><span style=\"font-weight: 400;\"> will be chosen naturally. Snap <\/span><b>Continue<\/b><span style=\"font-weight: 400;\"> at that point <\/span><b>Register<\/b><span style=\"font-weight: 400;\"> and <\/span><b>Done<\/b><span style=\"font-weight: 400;\">. Your new <\/span><b>App ID<\/b><span style=\"font-weight: 400;\"> is made.<\/span><\/p>\n<p><b>Step 2:<\/b><span style=\"font-weight: 400;\"> Presently visit <\/span><a href=\"https:\/\/appstoreconnect.apple.com\"><span style=\"font-weight: 400;\">App Store Connect<\/span><\/a><span style=\"font-weight: 400;\"> &amp; make another application in <\/span><b>My Apps<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><b>Step 3:<\/b><span style=\"font-weight: 400;\"> In the wake of making another application, in the left menu see the <\/span><b>In-App Purchases <\/b><span style=\"font-weight: 400;\">segment and snap <\/span><b>Manage<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><b>Step 4:<\/b><span style=\"font-weight: 400;\"> Presently to make another IAP Product, you need to click <\/span><b>+<\/b><span style=\"font-weight: 400;\"> at the privilege of the In-App Purchases. You&#8217;ll see the accompanying screen.<\/span><\/p>\n<p><img decoding=\"async\" class=\"alignnone wp-image-6583 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/IAP_Option_Screen.png\" alt=\"\" width=\"703\" height=\"452\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/IAP_Option_Screen.png 703w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/IAP_Option_Screen-300x193.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/IAP_Option_Screen-624x401.png 624w\" sizes=\"(max-width: 703px) 100vw, 703px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Select from these choices as indicated by your need, click Create. On the following screen, round out all the necessary subtleties like <\/span><b>Reference Name<\/b><span style=\"font-weight: 400;\">, <\/span><b>Product ID<\/b><span style=\"font-weight: 400;\">, <\/span><b>Cleared for Sale<\/b><span style=\"font-weight: 400;\"> and <\/span><b>Price Tier <\/b><span style=\"font-weight: 400;\">as per your prerequisite. Arrangement for <\/span><b>Product ID <\/b><span style=\"font-weight: 400;\">ought to resemble \u201ccom.organisation_name.project_name.iap_product_display_name\u201d. Underneath the subtleties, you&#8217;ll discover the Localizations segment with <\/span><b>Localizations<\/b><span style=\"font-weight: 400;\"> section with English(U.S.) as the default locale. Add <\/span><b>Display Name<\/b><span style=\"font-weight: 400;\"> &amp; <\/span><b>Description <\/b><span style=\"font-weight: 400;\">same as the <\/span><b>Reference Name, <\/b><span style=\"font-weight: 400;\">for default localization and snap <\/span><b>Save<\/b><span style=\"font-weight: 400;\">. You can likewise add various areas here by tapping on the <\/span><b>+<\/b><span style=\"font-weight: 400;\"> button after <\/span><b>Localizations<\/b><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><b>Note:<\/b><span style=\"font-weight: 400;\"> Ensure you have added a screen capture of the IAP at the lower part of a similar page. This screen capture might be utilized by Apple to audit IAP.<\/span><\/p>\n<p><b>Step 5:<\/b><span style=\"font-weight: 400;\"> To test the IPA, you need to make another Sandbox Tester. Go to the <\/span><b>Home Screen<\/b><span style=\"font-weight: 400;\"> of the <\/span><a href=\"https:\/\/appstoreconnect.apple.com\"><span style=\"font-weight: 400;\">App Store Connect<\/span><\/a><span style=\"font-weight: 400;\"> &amp; pick <\/span><b>Users &amp; Profiles<\/b><span style=\"font-weight: 400;\">. From this screen, you can add another Sandbox Tester by clicking <\/span><b>+ <\/b><span style=\"font-weight: 400;\">after <\/span><b>Tester<\/b><span style=\"font-weight: 400;\"> label. In the event that you as of now have an analyzer account, you can skirt this progression.<\/span><\/p>\n<p><b>Note:<\/b><span style=\"font-weight: 400;\"> For testing Non-Consumable IAP Products, you need to make another analyzer account again and again as it will continue reestablishing the buy, rather than regarding it as another buy.<\/span><\/p>\n<p><b>Code to add IAP to a project:<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Before straightforwardly leaping to the code area, open your venture in Xcode, pick your project in the <\/span><b>Targets<\/b><span style=\"font-weight: 400;\"> segment and then select <\/span><b>Signing &amp; Capabilities<\/b><span style=\"font-weight: 400;\"> tab.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Look down and select <\/span><b>In-App Purchase<\/b><span style=\"font-weight: 400;\"> from the rundown of alternatives. It will add IAP ability to your task.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Add \u2018New File\u2019 to your project with a name, for instance, <\/span><b>IAPProduct.swift<\/b><span style=\"font-weight: 400;\"> and add following code to it:<\/span><\/p>\n<pre class=\"lang:default decode:true \">\/\/ replace Display_Name with the string you added to Display Name &amp; Product_ID with Product ID in App Store Account\r\n\r\nimport Foundation\r\n\r\nenum IAPProduct: String {\r\n\r\n\u00a0\u00a0\u00a0case Display_Name =\u00a0 \"Product_ID\"\r\n\r\n}\r\n\r\nAdd one more \u2018New File\u2019 with name IAPManager.swift and add the beneath code to this record:\r\n\r\nimport Foundation\r\n\r\nimport StoreKit\r\n\r\nclass IAPManager: NSObject {\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ MARK: - Custom Types\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0enum IAPManagerError: Error {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case noProductIDsFound\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case noProductsFound\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case paymentWasCancelled\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case productRequestFailed\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\u00a0 \u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ MARK: - Properties\u00a0 \u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0static let shared = IAPManager()\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0var onReceiveProductsHandler: ((Result&lt;[SKProduct], IAPManagerError&gt;) -&gt; Void)?\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0var onBuyProductHandler: ((Result&lt;Bool, Error&gt;) -&gt; Void)?\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0var totalRestoredPurchases = 0\u00a0\u00a0\r\n\r\n\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\/\/ MARK: - Init\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0private override init() {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0super.init()\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ MARK: - General Methods\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0func getProduct() -&gt; [String]? {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0productStr = IAPPruduct.Display_Name.rawValue\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let product = [productStr]\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return product\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\u00a0 \u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0func startObserving() {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SKPaymentQueue.default().add(self)\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0func stopObserving() {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SKPaymentQueue.default().remove(self)\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ MARK: - Get IAP Products\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0func getProducts(withHandler productsReceiveHandler: @escaping (_ result: Result&lt;[SKProduct], IAPManagerError&gt;) -&gt; Void) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Keep the handler (closure) that will be called when requesting for\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ products on the App Store are finished.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onReceiveProductsHandler = productsReceiveHandler\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Get the product identifiers.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0guard let productIDs = getProductIDs() else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0productsReceiveHandler(.failure(.noProductIDsFound))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Initialize a product request.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let request = SKProductsRequest(productIdentifiers: Set(productIDs))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Set self as its delegate.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0request.delegate = self\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Make the request.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0request.start()\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\/\/ MARK: - Purchase Products\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0func buy(product: SKProduct, withHandler handler: @escaping ((_ result: Result&lt;Bool, Error&gt;) -&gt; Void)) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let payment = SKPayment(product: product)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SKPaymentQueue.default().add(payment)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Keep the completion handler.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onBuyProductHandler = handler\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0func restorePurchases(withHandler handler: @escaping ((_ result: Result&lt;Bool, Error&gt;) -&gt; Void)) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onBuyProductHandler = handler\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0totalRestoredPurchases = 0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SKPaymentQueue.default().restoreCompletedTransactions()\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n}\r\n\r\n\/\/ MARK: - SKPaymentTransactionObserver\r\n\r\nextension IAPManager: SKPaymentTransactionObserver {\r\n\r\n\u00a0\u00a0\u00a0\u00a0func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0transactions.forEach { (transaction) in\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0switch transaction.transactionState {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .purchased:\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onBuyProductHandler?(.success(true))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SKPaymentQueue.default().finishTransaction(transaction)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .restored:\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0totalRestoredPurchases += 1\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SKPaymentQueue.default().finishTransaction(transaction)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .failed:\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if let error = transaction.error as? SKError {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if error.code != .paymentCancelled {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onBuyProductHandler?(.failure(error))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onBuyProductHandler?(.failure(IAPManagerError.paymentWasCancelled))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(\"IAP Error:\", error.localizedDescription)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SKPaymentQueue.default().finishTransaction(transaction)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .deferred, .purchasing: break\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0@unknown default: break\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if totalRestoredPurchases != 0 {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onBuyProductHandler?(.success(true))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(\"IAP: No purchases to restore!\")\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onBuyProductHandler?(.success(false))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\u00a0 \u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if let error = error as? SKError {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if error.code != .paymentCancelled {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0print(\"IAP Restore Error:\", error.localizedDescription)\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onBuyProductHandler?(.failure(error))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onBuyProductHandler?(.failure(IAPManagerError.paymentWasCancelled))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n}\r\n\r\n\/\/ MARK: - SKProductsRequestDelegate\r\n\r\nextension IAPManager: SKProductsRequestDelegate {\r\n\r\n\u00a0\u00a0\u00a0\u00a0func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Get the available products contained in the response.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let products = response.products\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Check if there are any products available.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if products.count &gt; 0 {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Call the following handler passing the received products.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onReceiveProductsHandler?(.success(products))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ No products were found.\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onReceiveProductsHandler?(.failure(.noProductsFound))\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\u00a0 \u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0func request(_ request: SKRequest, didFailWithError error: Error) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onReceiveProductsHandler?(.failure(.productRequestFailed))\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0\u00a0\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0func requestDidFinish(_ request: SKRequest) {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Implement this method OPTIONALLY and add any custom logic\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ you want to apply when a product request is finished.\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n}\r\n\r\n\/\/ MARK: - IAPManagerError Localized Error Descriptions\r\n\r\nextension IAPManager.IAPManagerError: LocalizedError {\r\n\r\n\u00a0\u00a0\u00a0\u00a0var errorDescription: String? {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0switch self {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .noProductIDsFound: return \"No In-App Purchase product identifiers were found.\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .noProductsFound: return \"No In-App Purchases were found.\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .productRequestFailed: return \"Unable to fetch available In-App Purchase products at the moment.\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .paymentWasCancelled: return \"In-App Purchase process was cancelled.\"\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Use the below code wherever needed in the <\/span><b>ViewController<\/b><span style=\"font-weight: 400;\"> class to request &amp; get IAP products from the App Store.<\/span><\/p>\n<pre class=\"lang:default decode:true \">func viewDidSetup() {\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0IAPManager.shared.getProducts { (result) in\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0switch result {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .success(let products): \/\/save products to a variable or to your model\u2019s property, both of [SKProduct] type\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .failure(let error): \/\/ display error here\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">After adding the above method open <\/span><i><span style=\"font-weight: 400;\">AppDelegate.swift<\/span><\/i><span style=\"font-weight: 400;\"> and call startObserving() method of IAPManager in the <\/span><b>application(_:didFinishLaunchingWithOptions:)<\/b><span style=\"font-weight: 400;\"> method like this <\/span><b>IAPManger.shared.startObserving()<\/b><span style=\"font-weight: 400;\"> before returning <\/span><b>true.<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Next add <\/span><b>IAPManager.shared.stopObserving()<\/b><span style=\"font-weight: 400;\"> in the <\/span><b>applicationWillTerminate(_:) <\/b><span style=\"font-weight: 400;\">method of the <\/span><i><span style=\"font-weight: 400;\">AppDelegate.swift<\/span><\/i><span style=\"font-weight: 400;\"> to stop observing.<\/span><\/p>\n<p><b>You\u2019ve implemented all the required methods related to IAP.<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Now, we are going to add a custom function named <\/span><b>purchase(product: SKProduct)<\/b><span style=\"font-weight: 400;\"> to purchase the available IAP product. Below is the function which we need to call in our IBAction or on the click of a cell in UITableView or UICollectionView.<\/span><\/p>\n<pre class=\"lang:default decode:true \">\/\/ pass the [SKProduct] type value as an argument to this function which we get from the above defined function viewDidSetup()\r\n\r\nfunc purchase(product: SKProduct) -&gt; Bool {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0IAPManager.shared.buy(product: product) { (result) in\u00a0\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0switch result {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .success(_): \/\/update UI or something according to your need after a successful purchase\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .failure(let error): \/\/ display error here\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Also, done! You would now be able to test the IAP through the Sandbox Tester account in your actual gadget using these steps :<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Open device settings.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Discover <\/span><b>iTunes and App Store<\/b><span style=\"font-weight: 400;\"> from the accessible choices.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Begin looking to the base and there you&#8217;ll discover the Sandbox Account area. Snap SignIn and give the analyzer account credentials.<\/span><\/li>\n<\/ul>\n<p><b>Note: <\/b><span style=\"font-weight: 400;\">You don&#8217;t have to give your genuine Apple account credentials here.<\/span><\/p>\n<p><b><i>With Xcode 12 you can test In-App Purchases with simulator utilizing the accompanying advances :<\/i><\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Make another configuration file. Open <\/span><b>File -&gt; New -&gt; File<\/b><span style=\"font-weight: 400;\"> in Xcode and pick <\/span><b>StoreKit Configuration File<\/b><span style=\"font-weight: 400;\"> in the <\/span><b>Other<\/b><span style=\"font-weight: 400;\"> area.<\/span><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6584 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.00.25-PM.png\" alt=\"\" width=\"652\" height=\"472\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.00.25-PM.png 652w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.00.25-PM-300x217.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.00.25-PM-624x452.png 624w\" sizes=\"(max-width: 652px) 100vw, 652px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Snap <\/span><b>Next<\/b><span style=\"font-weight: 400;\">. The document will show up in the project navigator window.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">At the left-bottom, you&#8217;ll discover a <\/span><b>+<\/b><span style=\"font-weight: 400;\"> button.<\/span><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6585 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.12.11-PM.png\" alt=\"\" width=\"652\" height=\"513\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.12.11-PM.png 652w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.12.11-PM-300x236.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.12.11-PM-624x491.png 624w\" sizes=\"(max-width: 652px) 100vw, 652px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">You can add three sorts of IAP items through this alternative which are :<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Auto-Renewable Subscription<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Consumable IAP<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Non-Consumable IAP<\/span><\/li>\n<\/ul>\n<p><b>Note:<\/b><span style=\"font-weight: 400;\"> You need to create separate configuration files to test diverse IAP items and ensure that just each, in turn, is chosen while testing.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Then, fill Reference Name, Product ID (same as this &#8220;com.organisation_name.project_name.iap_product_display_name&#8221; ) and Price. At that point go to the <\/span><b>Localizations<\/b><span style=\"font-weight: 400;\"> segment and enter <\/span><b>Display Name<\/b><span style=\"font-weight: 400;\"> and <\/span><b>Description<\/b><span style=\"font-weight: 400;\"> as we did in the <\/span><b>App Store Connect<\/b><span style=\"font-weight: 400;\"> record and press Cmd+S. You can likewise eliminate the IAP <\/span><b>things<\/b><span style=\"font-weight: 400;\"> from the configuration file by picking the item and choosing &#8216;<\/span><b>&#8211;<\/b><span style=\"font-weight: 400;\">&#8216; at bottom-left.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Presently go to the Xcode toolbar and pick your project scheme and select <\/span><b>Edit Scheme<\/b><span style=\"font-weight: 400;\">. There you&#8217;ll discover a choice by name <\/span><b>StoreKit Configuration<\/b><span style=\"font-weight: 400;\">, select it and pick one from the rundown of setup records shown in the dropdown, as indicated by your need.<\/span><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-6586 size-full\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.57.03-PM.png\" alt=\"\" width=\"701\" height=\"364\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.57.03-PM.png 701w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.57.03-PM-300x156.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/Screenshot-2021-01-22-at-5.57.03-PM-624x324.png 624w\" sizes=\"(max-width: 701px) 100vw, 701px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Close the scheme editor.<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Presently run your application and test your IAP usage.<\/span><\/li>\n<\/ul>\n<p><b>Restoring In-App Purchases:<\/b><\/p>\n<p><span style=\"font-weight: 400;\">On the off chance that the buy is non-consumable and the client again attempts to buy that thing, StoreKit and payment queue when discovered any data like the client has bought the thing then the new buy measure gets considered as a reestablished buy so the client won&#8217;t be charged once more. To actualize this usefulness, you need to add the underneath code to your IBAction for reestablishing buys.<\/span><\/p>\n<pre class=\"lang:default decode:true \">func restorePurchases() {\r\n\r\n\u00a0\u00a0\u00a0\u00a0IAPManager.shared.restorePurchases { (result) in\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0switch result {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .success(let success): \/\/ do something with UI or functionality\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0case .failure(let error): \/\/display error here\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0}\r\n\r\n}<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What is In-App Purchase and what is its need?\u00a0 In-App Purchase alludes to the purchasing of some extra highlights or administrations inside an application. Designers offer these extra types of assistance as a piece of a free application to adapt it.\u00a0 It&#8217;s simpler to draw in clients towards a free application and afterwards give extra [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":6578,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[575,3,7,380,576],"tags":[574,14],"class_list":["post-6577","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-in-app-purchases","category-ios","category-mobile-testing","category-swift-5","category-xcode-12","tag-in-app-purchase","tag-innovationm"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>In-App Purchase - InnovationM - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"In-App Purchase - InnovationM - Blog\" \/>\n<meta property=\"og:description\" content=\"What is In-App Purchase and what is its need?\u00a0 In-App Purchase alludes to the purchasing of some extra highlights or administrations inside an application. Designers offer these extra types of assistance as a piece of a free application to adapt it.\u00a0 It&#8217;s simpler to draw in clients towards a free application and afterwards give extra [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/\" \/>\n<meta property=\"og:site_name\" content=\"InnovationM - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-02-04T08:38:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/In-App-Purchase.png\" \/>\n\t<meta property=\"og:image:width\" content=\"960\" \/>\n\t<meta property=\"og:image:height\" content=\"540\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"InnovationM Admin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"InnovationM Admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/\"},\"author\":{\"name\":\"InnovationM Admin\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\"},\"headline\":\"In-App Purchase\",\"datePublished\":\"2021-02-04T08:38:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/\"},\"wordCount\":1223,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/In-App-Purchase.png\",\"keywords\":[\"In-App Purchase\",\"InnovationM\"],\"articleSection\":[\"In-App Purchases\",\"iOS\",\"Mobile Testing\",\"Swift 5\",\"Xcode 12\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/\",\"name\":\"In-App Purchase - InnovationM - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/In-App-Purchase.png\",\"datePublished\":\"2021-02-04T08:38:10+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/In-App-Purchase.png\",\"contentUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2021\\\/02\\\/In-App-Purchase.png\",\"width\":960,\"height\":540},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/in-app-purchase\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"In-App Purchase\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/\",\"name\":\"InnovationM - Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\",\"name\":\"InnovationM Admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"caption\":\"InnovationM Admin\"},\"sameAs\":[\"http:\\\/\\\/www.innovationm.com\\\/\"],\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/author\\\/innovationmadmin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"In-App Purchase - InnovationM - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/","og_locale":"en_US","og_type":"article","og_title":"In-App Purchase - InnovationM - Blog","og_description":"What is In-App Purchase and what is its need?\u00a0 In-App Purchase alludes to the purchasing of some extra highlights or administrations inside an application. Designers offer these extra types of assistance as a piece of a free application to adapt it.\u00a0 It&#8217;s simpler to draw in clients towards a free application and afterwards give extra [&hellip;]","og_url":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/","og_site_name":"InnovationM - Blog","article_published_time":"2021-02-04T08:38:10+00:00","og_image":[{"width":960,"height":540,"url":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/In-App-Purchase.png","type":"image\/png"}],"author":"InnovationM Admin","twitter_misc":{"Written by":"InnovationM Admin","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/#article","isPartOf":{"@id":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/"},"author":{"name":"InnovationM Admin","@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed"},"headline":"In-App Purchase","datePublished":"2021-02-04T08:38:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/"},"wordCount":1223,"commentCount":0,"image":{"@id":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/In-App-Purchase.png","keywords":["In-App Purchase","InnovationM"],"articleSection":["In-App Purchases","iOS","Mobile Testing","Swift 5","Xcode 12"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.innovationm.com\/blog\/in-app-purchase\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/","url":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/","name":"In-App Purchase - InnovationM - Blog","isPartOf":{"@id":"https:\/\/www.innovationm.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/#primaryimage"},"image":{"@id":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/#primaryimage"},"thumbnailUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/In-App-Purchase.png","datePublished":"2021-02-04T08:38:10+00:00","author":{"@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed"},"breadcrumb":{"@id":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.innovationm.com\/blog\/in-app-purchase\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/#primaryimage","url":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/In-App-Purchase.png","contentUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2021\/02\/In-App-Purchase.png","width":960,"height":540},{"@type":"BreadcrumbList","@id":"https:\/\/www.innovationm.com\/blog\/in-app-purchase\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.innovationm.com\/blog\/"},{"@type":"ListItem","position":2,"name":"In-App Purchase"}]},{"@type":"WebSite","@id":"https:\/\/www.innovationm.com\/blog\/#website","url":"https:\/\/www.innovationm.com\/blog\/","name":"InnovationM - Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.innovationm.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed","name":"InnovationM Admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","caption":"InnovationM Admin"},"sameAs":["http:\/\/www.innovationm.com\/"],"url":"https:\/\/www.innovationm.com\/blog\/author\/innovationmadmin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts\/6577","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/comments?post=6577"}],"version-history":[{"count":0,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts\/6577\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/media\/6578"}],"wp:attachment":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/media?parent=6577"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/categories?post=6577"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/tags?post=6577"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}