In-app-aankopen in iOS met Swift 3

Wat je gaat creëren

Invoering

In-app-aankopen zijn een geweldige functie voor alle ontwikkelaars die meer inkomsten willen genereren en extra inhoud en functies willen aanbieden via hun apps. Voor games kun je bijvoorbeeld edelstenen of munten kopen en voor fotografie-apps kun je nieuwe effecten of hulpmiddelen ontgrendelen. En u kunt dit alles doen met een creditcard of andere betaalmethode, zonder de app te verlaten. 

In deze tutorial zal ik alle nodige stappen bespreken om een verbruiksartikelen en Niet eetbaar IAP-product op iTunes Connect en ik zal u de code tonen die u nodig hebt om beide artikelen te kopen. Ik heb een voorbeeld Xcode-project gemaakt met een label en twee knoppen, dus download het en volg deze tutorial om te begrijpen hoe het werkt.

Maak een Sandbox-tester in iTunes Connect

Ik neem aan dat je al een iOS-app hebt gemaakt in de Mijn apps sectie op iTunes Connect. Het eerste dat u moet doen, is het maken van een Sandbox-tester om IAP op je echte apparaat te testen (geen simulator - het ondersteunt geen in-app aankopen). 

invoeren Gebruikers en rollen, ga naar de Sandbox-tester tab en klik op de (+) teken naast tester.

Vul het formulier in om een ​​nieuwe sandbox-tester toe te voegen. Nadat u uw gegevens heeft opgeslagen, gaat u terug naar de Mijn app sectie en klik op het pictogram van uw app om de details in te voeren en IAP-producten te maken.

Maak IAP-producten in iTunes Connect

Verbruiksgoederen

Klik op de Kenmerken tab en dan de (+) teken naast In-app aankopen. Je kunt één product per keer maken, dus laten we beginnen met een verbruiksartikelen een.

EEN verbruiksartikelen IAP, zoals de naam al doet vermoeden, is een product dat u meerdere keren kunt kopen. We zullen het gebruiken om extra 'munten' te verzamelen in onze demo-app. 

Klik creëren om uw IAP-item te initialiseren. Op het volgende scherm kun je alle informatie over je product instellen:

  • Referentienaam: deze naam wordt gebruikt op iTunes Connect en in Verkoop en trends rapporten. Het wordt niet weergegeven in de App Store en u kunt elke gewenste naam typen, maar het mag niet langer zijn dan 64 tekens.
  • Product-ID: Een unieke alfanumerieke ID die door de app wordt opgehaald om uw product te herkennen. Gewoonlijk gebruiken ontwikkelaars een web-reverse syntaxis voor product-id's. In dit voorbeeld hebben we gekozen com.iaptutorial.coins. Later zullen we deze ID als een string in onze code plakken.
  • Prijs: Kies een prijsniveau in het vervolgkeuzemenu. Vergeet niet dat om een ​​in-app-aankoopproduct in de App Store te verkopen, u een aanvraag heeft ingediend voor een Betaalde toepassingsovereenkomst in de Overeenkomsten, belastingen en bankzaken sectie.
  • lokalisaties: Omwille van deze tutorial hebben we alleen Engels gekozen, maar je kunt meer talen toevoegen door op de (+) knop. Typ vervolgens een Weergavenaam en een Omschrijving. Beide zijn zichtbaar in de App Store. 
  • screenshot: Upload een screenshot voor beoordeling. Het wordt niet weergegeven in de App Store en het moet een geldige grootte hebben voor uw app-platform, dus als uw app Universal is, kunt u een iPad-screenshot uploaden.
  • Opmerkingen bekijken: Alle aanvullende informatie over uw IAP die nuttig kan zijn voor de beoordelaar.

Als je klaar bent, klik je op Opslaan en u ontvangt deze waarschuwing:

Uw eerste In-app-aankoop moet worden ingediend met een nieuwe app-versie. Selecteer het in de In-app-aankopen van de app en klik op Verzenden.

Niet-verbruiksartikelen

Klik nu op de knop Inkoop bij aankopen in de lijst aan de linkerzijde, rechtsboven de Game Center knop en voeg een nieuw IAP-product toe. Selecteer deze keer de Niet eetbaar keuze:

Klik creëren en herhaal de stappen die we hierboven vermeldden. Aangezien dit een Niet eetbaar product, kunnen gebruikers het slechts één keer kopen, en Apple vereist de mogelijkheid om dergelijke aankopen te herstellen. Dat gebeurt in het geval u de app verwijdert en opnieuw installeert of downloadt vanaf een ander apparaat met dezelfde Apple ID en uw aankopen terug moet krijgen zonder tweemaal te betalen. Dus later voegen we een toe Herstel aankoop functie in onze code.

Het product-ID dat we nu hebben is com.iaptutorial.premium, met een prijsniveau van USD $ 2,99. We hebben het genoemd Ontgrendel de Premium-versie.

Als u klaar bent, vult u alle velden in, slaat u uw product op en gaat u terug naar de In-app-aankopen-pagina. Nu zou u een lijst moeten hebben van uw twee producten, met hun Naam, Type, ID kaart en staat instellen als Klaar om in te dienen.

Ga terug naar de pagina van je app door op de. Te klikken App Winkel en Bereid je voor op inzending toetsen. Blader omlaag naar de In-app aankopen sectie, rechtsonder Algemene app-informatie, en klik op de (+) om uw IAP-producten toe te voegen. 

Selecteer ze allemaal en klik op Gedaan.

Klik ten slotte op Opslaan in de rechterbovenhoek van het scherm en je bent klaar met het configureren van In-App Purchase-producten op iTunes Connect.

Log in op Sandbox Tester op een iOS-apparaat

Voordat je aan de code begint, is er nog iets anders te doen. Ga naar instellingen > iTunes & App Store op uw iOS-apparaat. Als je al bent ingelogd met je originele Apple ID, tik je erop en kies je Afmelden. Log vervolgens in met de inloggegevens voor de sandbox-tester die u hebt gemaakt. Nadat u zich heeft aangemeld, ontvangt u mogelijk een melding als deze:

Negeer gewoon het bericht en tik op annuleren. Uw apparaat zal u opnieuw uw sandbox-inloggegevens vragen terwijl u probeert een aankoop te doen en herkent uw testaccount, zodat u geen cent op uw creditcard hoeft te betalen voor elke aankoop die u doet.

Uitgang instellingen, sluit je apparaat aan op je Mac via de USB-kabel, en laten we eindelijk beginnen met het coderen!

De code

Als je ons demo-project hebt gedownload, zul je zien dat alle benodigde code voor in-app-aankopen is geschreven, dus als je het uitvoert, krijg je zoiets als dit:

Als u de app wilt testen, moet u de Bundelidentificatie naar je eigen id. Anders staat Xcode je niet toe om de app op een echt apparaat uit te voeren en de app herkent de twee IAP-producten die je hebt gemaakt niet.


invoeren ViewController.swift en controleer de code. Allereerst hebben we een importinstructie toegevoegd voor StoreKit en de afgevaardigden die we nodig hebben om betalingsverrichtingen en productverzoeken bij te houden.

import StoreKit class ViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver 

Vervolgens hebben we een aantal weergaven verklaard die nuttig zullen zijn.

 / * Bekeken * / @IBOutlet zwakke var muntenLabel: UILabel! @IBOutlet weak var premiumLabel: UILabel! @IBOutlet weak var consumableLabel: UILabel! @IBOutlet weak var nonConsumableLabel: UILabel! 

coinsLabel en premiumLabel wordt gebruikt om de resultaten van aankopen voor beide producten te tonen. consumableLabel en nonConsumableLabel toont de beschrijving en prijs van elk IAP-product, degene die we eerder hebben gemaakt in iTunes Connect. 

Nu is het tijd om enkele variabelen toe te voegen:

/ * Variables * / laat COINS_PRODUCT_ID = "com.iaptutorial.coins" laat PREMIUM_PRODUCT_ID = "com.iaptutorial.premium" var productID = "" var productsRequest = SKProductsRequest () var iapProducts = [SKProduct] () var nonConsumablePurchaseMade = UserDefaults.standard .bool (forKey: "nonConsumablePurchaseMade") var coins = UserDefaults.standard.integer (forKey: "coins") 

De eerste twee regels zijn bedoeld om onze product-ID's terug te roepen. Het is belangrijk dat deze tekenreeksen exact overeenkomen met de strings die zijn geregistreerd in de sectie Inkoop van de app in iTunes App.

  • Product-ID is een string die we later gaan gebruiken om te detecteren welk product we willen kopen.
  • productsRequest is een instantie van SKProductsRequest, nodig om te zoeken naar IAP-producten vanuit uw app op iTC.
  • iapProducts is een eenvoudige reeks van SKProducts. Let op: SK-voorvoegsel betekent StoreKit, het iOS-raamwerk dat we zullen gebruiken om aankopen af ​​te handelen.

De laatste twee regels laden twee variabelen van het type Boolean en Geheel getal nodig om aankopen van munten en de premiumversie, respectievelijk consumeerbare en niet-consumeerbare producten bij te houden.

De volgende code in viewDidLoad () voert een paar dingen uit zodra de app start:

 // Controleer de In-app-aankopen print ("NIET-CONSUMPERENDE AANKOOP GEMAAKT: \ (nonConsumablePurchaseMade)") print ("MUNTEN: \ (munten)") // Tekstmunten instellenLabel.text = "MUNTEN: \ (munten)" als nonConsumablePurchaseMade premiumLabel.text = "Premium-versie GEKOCHT!"  else premiumLabel.text = "Premiumversie LOCKED!" // Fetch IAP-producten beschikbaar fetchAvailableProducts ()

Eerst registreren we elke aankoop bij de Xcode-console. Vervolgens geven we het totale aantal munten weer dat we hebben gekocht met de coinsLabel. Aangezien we de demo-app voor de eerste keer gebruiken, wordt deze weergegeven MUNTEN: 0.

De als statement stelt de premiumLabel's tekst naargelang het niet-consumeerbare product is gekocht. Om te beginnen, zal het tonen Premium versie LOCKED! omdat we de premium-aankoop nog niet hebben gedaan.

De laatste coderegel roept een methode aan die we later zullen zien, die gewoon de producten ophaalt die we eerder in iTC hebben opgeslagen.

Laten we nu eens kijken wat de twee aankoopknoppen die we hebben ingesteld in onze demo-app doen:

// MARK: - KOOP 10 MUNTEN TOETS @IBAction func buy10coinsButt (_ afzender: Elke) purchaseMyProduct (product: iapProducts [0]) // MARK: - ONTGRENDEL PREMIUMKNOP @IBAction func unlockPremiumButt (_ afzender: elke) purchaseMyProduct (product: iapProducts [1])

Beide methoden bellen een functie die controleert of het apparaat aankopen kan doen, en als het kan, roept de app de StoreKit-deelnemersmethode om de aankoop te verwerken.

Zoals eerder vermeld, hebben we een derde knop nodig om onze niet-consumeerbare aankoop te herstellen. Hier is de code:

// MARK: - HERSTELLEN NIET-VERBRUIKSBARE AANKOOPKNOP @IBAction func restorePurchaseButt (_ sender: Any) SKPaymentQueue.default (). Add (self) SKPaymentQueue.default (). RestoreCompletedTransactions () func paymentQueueRestoreCompletedTransactionsFinished (_ queue: SKPaymentQueue) nonConsumablePurchaseMade = true UserDefaults.standard.set (nonConsumablePurchaseMade, forKey: "nonConsumablePurchaseMade") UIAlertView (titel: "IAP Tutorial", bericht: "U hebt uw aankoop hersteld!", delegeren: nihil, cancelButtonTitle: "OK") .laten zien()  

De IBAction functie is gekoppeld aan de Herstel aankoop knop in de storyboard en begint verbinding te maken met het In-App Purchase-systeem van Apple om de aankoop te herstellen als die al is gemaakt.

paymentQueueRestoreCompletedTransactionsFinished () is de gedelegeerde methode van het StoreKit-framework die ons zal redden nonConsumablePurchaseMade variabele naar true nadat de aankoop succesvol is hersteld.

We zijn klaar met knoppen, dus laten we eens kijken wat de fetchAvailableProducts () functie doet:

// MARK: - FETCH BESCHIKBAAR IAP PRODUCTEN func fetchAvailableProducts () // Zet hier uw IAP-producten ID's laten productIdentifiers = NSSet (objecten: COINS_PRODUCT_ID, PREMIUM_PRODUCT_ID) productsRequest = SKProductsRequest (productIdentifiers: productIdentifiers as!) productsRequest.delegate = self productsRequest.start () 

We maken eerst een instantie van NSSet, wat in feite een reeks snaren is. We slaan de twee product-ID's op die we eerder daar hebben aangegeven.

Dan beginnen we een SKProductsRequest op basis van die ID's, zodat de app de informatie over de IAP-producten (beschrijving en prijs) kan weergeven, die met deze gedelegeerde methode wordt verwerkt:

// MARK: - AANVRAGEN IAP PRODUCTEN func productsRequest (_ request: SKProductsRequest, didReceive response: SKProductsResponse) if (response.products.count> 0) iapProducts = response.products // 1st IAP Product (Verbruiksartikelen) ---- -------------------------------- laat firstProduct = response.products [0] als SKProduct // Verkrijg de prijs van iTunes Verbinden laat numberFormatter = NumberFormatter () numberFormatter.formatterBehavior = .behavior10_4 numberFormatter.numberStyle = .currency numberFormatter.locale = firstProduct.priceLocale let price1Str = numberFormatter.string (from: firstProduct.price) // Toon de beschrijving consumableLabel.text = firstProduct. localizedDescription + "\ nfor just \ (price1Str!)" // ------------------------------------ ------------ // 2e IAP-product (niet-verbruiksartikelen) ---------------------------- - laat secondProd = response.products [1] als SKProduct // Verkrijg de prijs van iTunes Connect numberFormatter.locale = secondProd.priceLocale laat price2Str = numberFormatter.string ( from: secondProd.price) // Toon de beschrijving nonConsumableLabel.text = secondProd.localizedDescription + "\ nfor just \ (price2Str!)" // ------------------- ----------------- 

In de bovenstaande functie moeten we eerst controleren of er producten zijn geregistreerd in iTunes Connect en onze instellen iapProducts array dienovereenkomstig. Dan kunnen we de twee initialiseren SKProducts en print hun beschrijving en prijs op de labels.

Voordat we naar de kern van de In-App-aankoopcode gaan, hebben we nog een paar extra functies nodig:

// MARK: - MAAK KOOP VAN EEN PRODUCT func canMakePurchases () -> Bool return SKPaymentQueue.canMakePayments () func purchaseMyProduct (product: SKProduct) if self.canMakePurchases () let payment = SKPayment (product: product) SKPaymentQueue .default (). add (self) SKPaymentQueue.default (). add (payment) print ("PRODUCT AAN AANKOOP: \ (product.productIdentifier)") productID = product.productIdentifier // IAP-aankopen dsabled op het apparaat else  UIAlertView (titel: "IAP-zelfstudie", bericht: "Aankopen zijn uitgeschakeld op uw apparaat!", Delegeren: nihil, cancelButtonTitle: "OK"). Show () 

De eerste controleert of ons apparaat aankopen kan doen. De tweede functie is die van de twee knoppen. Het start de betalingswachtrij en verandert onze Product-ID variabele in de geselecteerde productIdentifier

Nu zijn we eindelijk aangekomen bij de laatste gedelegeerde methode, degene die de betalingsresultaten verwerkt:

// MARK: - IAP-BETAALWACHTRIJ func paymentQueue (_ wachtrij: SKPaymentQueue, updatedTransactions-transacties: [SKPaymentTransaction]) voor transactie: AnyObject in transacties if let trans = transaction as? SKPaymentTransaction switch trans.transactionState case ingekocht: SKPaymentQueue.default (). FinishTransaction (transactie als! SKPaymentTransaction) // Het verbruiksmateriaal (10 munten) is gekocht -> krijg 10 extra munten! if productID == COINS_PRODUCT_ID // Voeg 10 munten toe en bewaar het totale aantal munten + = 10 UserDefaults.standard.set (coins, forKey: "coins") coinsLabel.text = "COINS: \ (coins)" UIAlertView (title: "IAP-zelfstudie", bericht: "U hebt met succes 10 extra munten gekocht!", Delegeren: nihil, cancelButtonTitle: "OK"). Show () // Het niet-verbruikbare product (Premium) is gekocht!  else if productID == PREMIUM_PRODUCT_ID // Bewaar uw aankoop lokaal (alleen nodig voor niet-verbruikte IAP) nonConsumablePurchaseMade = true UserDefaults.standard.set (nonConsumablePurchaseMade, forKey: "nonConsumablePurchaseMade") premiumLabel.text = "Premium-versie AANKOOP!" UIAlertView (titel: "IAP-zelfstudie", bericht: "U hebt de Premium-versie met succes ontgrendeld!", Delegeren: nihil, cancelButtonTitle: "OK"). Show () break case .failed: SKPaymentQueue.default (). FinishTransaction (transactie als! SKPaymentTransaction) breek zaak. gerestored: SKPaymentQueue.default (). finishTransaction (transactie als! SKPaymentTransaction) breek standaard: breuk

Deze functie heeft een schakelaar verklaring die elke staat van de betaling controleert. De eerste geval wordt gebeld als de aankoop is voltooid en de transactie is voltooid. 

Binnen dit blok moeten we controleren welk product-ID we hebben geselecteerd en de nodige acties uitvoeren om onze app bij te werken, dus als we 10 extra munten hebben gekocht, voegen we 10 toe aan onze munten variabele, bewaar de waarde met UserDefaults, toon het nieuwe aantal munten dat we hebben gewonnen en waarschuw een melding. 

Houd er rekening mee dat u deze aankoop meerdere keren onbeperkt kunt doen, omdat het een verbruiks-IAP is en er geen herstel-functie nodig is.

Evenzo, als we het niet-consumeerbare premiumproduct kochten, stelt de app ons in nonConsumablePurchaseMade variabele naar waar, slaat het op, verandert de tekst van de premiumLabel, en vuurt een waarschuwing om u te melden dat de aankoop succesvol is geweest. 

De andere TWEE gevallen omgaan met de betalingsresultaten voor mislukking en herstel. De app vuurt zelf aangepaste meldingen af ​​als uw transactie om een ​​of andere reden mislukt of als u een niet-verbruiksbare aankoop hebt hersteld.

Dat is het! Zorg er nu voor dat u bent aangemeld met uw Sandbox Tester-inloggegevens en voer de app uit om deze te testen. De eerste keer ontvangt u een waarschuwing zoals deze:

Kiezen Gebruik een bestaand Apple ID en voer de gebruikersnaam en het wachtwoord van uw Sandbox-tester opnieuw in om in te loggen. Dit gebeurt omdat de app alleen een echte gebruiker van de. kan herkennen iTunes & App Store instellingen, geen Sandbox-versie.

Nadat u bent ingelogd, kunt u beide producten kopen.

CodeCanyon-sjablonen

Als u met iOS werkt en de Swift-taal en apps verder wilt ontwikkelen, vinkt u enkele van mijn sjablonen voor iOS-apps aan op CodeCanyon. 

Er zijn ook honderden andere iOS-app-sjablonen op de Envato-markt, klaar om te worden herverdeeld en zeker om uw workflow te versnellen. Ga ze bekijken! U bespaart misschien uren werk op uw volgende app.

Conclusie

In deze zelfstudie hebben we alle stappen besproken die nodig zijn om In-App Purchase-producten te maken op iTunes Connect en hoe u de code schrijft om ze in uw app in te schakelen. Ik hoop dat je deze kennis kunt gebruiken in je volgende iOS-app!

Bedankt voor het lezen en ik zie je de volgende keer! Bekijk ook onze andere cursussen en tutorials over de ontwikkeling van iOS-apps met Swift.