Advertisement
  1. Code
  2. iOS SDK

Mga In-App Purchases sa iOS Gamit Ang Swift 3

Scroll to top
Read Time: 15 min

() translation by (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

Pagsisimula

Ang in-app purchase ay isang mahusay na feature para sa mga developers na gustong makakuha ng mas malaking kita at mag handog ng karagdagang content at features sa kanilang mga applications. Halimbawa, para sa games maaari kang bumili ng mga gems or mga coins, at para sa mga photography apps, maaari kang mag-unlock ng mga bagong effects o mga tools. At maaari mo itong magawa lahat ng hindi gumagamit ng credit card o kahit na anong ibang paraan sa pagbabayad ng hindi umaalis sa app.

Sa pagtuturong ito, tatalakayin ko lahat ng mga kinakailangang hakbang upang makagawa ng isan Consumable at Non-Consumable IAP na produkto sa iTunes connect, at ipapakita ko ang code na kailangang bilhin para sa parehong gamit. Gumawa ako ng sample na Xcode project na may label at dalawang pindutan, kaya naman i-download na ito at sumunod sa tutorial na ito upang maintindihan kung papaano ito gumagana.

Gumawa ng Sandbox Tester sa iTunes Connect

Pinagpapalagay kong nakagawa ka na ng isang iOS app sa My Apps na bahagi ng iTunes Connect. Ang unang bagay na kailangang gawin ay gumawa ng Sandbox Tester upang masubukan ang IAP sa iyong real device (hindi pwede ang Simulator-hindi nito suportado ang mga In-App Purchases).

Maglagay ng Users at Roles, tumungo sa Sandbox Tester tab, at pindutin ang (+) na simbolo kasunod ng Tester.

Users and roles in iTunes ConnectUsers and roles in iTunes ConnectUsers and roles in iTunes Connect

Punan ang form upang makapagdagdag ng isang bagong sandbox tester.  Kapag nai-save na ninyo ang info, bumalik sa My App section at pindutin ang icon ng iyong app upang mailagay ang mga detalye nito at gumawa ng bagong IAP products.

Gumawa ng IAP Products sa iTunes Connect

Mga Consumable na Produkto

Pindutin ang Features tab, pagkatapos ay ang simbolo na (+) katabi ng In-App Purchases. Maaari kang makagawa ng paisa-isang produkto kada pagkakataon, kaya naman simulant natin sa isang Consumable.

Select Consumable In-App PurchaseSelect Consumable In-App PurchaseSelect Consumable In-App Purchase

Ang Consumable IAP, gaya ng iminumungkahi ng pangalan, ay isang produkto na maaari mong bilhin ng maraming beses Gagamitin natin ito upang makapagkolekta ng karagdagang “coins” sa ating demo app.

Pindutin ang Create upang mag-initialize ang iyong IAP item. Sa susunod na screen, maaari mong i-setup lahat ng mga impormasyong kailangan mo para sa iyong produkto:

  • Ang Pangalan ng Reference: ang pangalang ito ang gagamitin sa iTunes connect at sa pag-uulat ng Sales and Trends. Hindi ito lalabas sa App Store kaya naman maari mong gamitin maski na anong pangalan ang gusto mo, basta’t hindi ito lalagpas ng 64 na characters.
  • Ang Product ID: Isang natatanging alpanumerikong identifier na kukunin ng app para makilala ang iyong produkto. Kadalasan, gumagamit ang mga developers ng isang web-reverse syntax para sa mga product ids. Para sa halimbawang ito, pinili natin ang com.iaptutorial.coins.  Mamaya ay ipe-paste natin ang ID na ito bilang isang string sa ating code.
  • Presyo: Pumili ng price tier mula sa dropdown menu. Tandaan na para maibenta natin ang iyong in-app purchase product sa App Store, dapat ay nakapag-apply ka na para sa isang Paid Application Agreement sa bahagi ng Agreements, Tax & Banking.
  • Mga Lokalisasyon: Para sa pagtuturong ito, pinili natin ang English lamang, ngunit maaari ka ding magdagdag ng karagdagang mga wika sa pamamagitan ng pagpindot sa (+) na pindutan. Pagkatapos ay maglagay ng Display Name at Description. Parehong lalabas ang mga ito sa App Store.
  • Screenshot: Mag-upload ng screenshot para sa pagsusuri. Hindi ito ipapakita sa App Store at dapat ay may nararapat na sukat ito para sa iyong app platform, kaya namang kung ang app mo ay Universal, pupuwede kang mag-upload ng iPad screenshot.
  • Mga Tala Ukol sa Pagsusuri: Kahit na anong karagdagang impormasyon tungkol sa iyong IAP na maaaring makatulong sa magsusuri.
Create a new IAP productCreate a new IAP productCreate a new IAP product

Kapag tapos na, pindutin ang Save at makakuha ka ng ganitong alert:

Ang una mong In-App Purchase ay dapat ipasa gamit ang bagong app version. Piliin ito mmula sa parteng In-App Purchases ng app at pindutin ang Submit.

Non-Consumable Produkto

Ngayon ay pindutin ang In-App Purchases button sa listahan sa kaliwa, sa itaas lamang ng Game Center button, at magdagdag ng bagong IAP product. Sa pagkakataong ito, piliin ang Non-Consumable na pagpipilian:

Create a Non-Consumable productCreate a Non-Consumable productCreate a Non-Consumable product

Pindutin ang Create at ulitin ang mga hakbang na nasabi na sa itaas. Dahil ito ay magiging isang Non-Consumable na produkto, isang beses lang ito mabibili ng mga users, at kakailanganin ng Apple ang kakayahang maulit ang mga pagbili na ito. Mangyayari ito kapag inuninstall ang app at ininstall ito uli, o kapag dinownload ito mula sa ibang device na may kaparehong Apple ID at kailangan mong makuha muli ang iyong nabili ng hindi nagbabayad muli. Kaya naman mamaya ay magdadagdag tayo ng Restore Purchase na function sa ating code.

Ang Product Id na ginawa natin ay nasa com.iaptutorial,premium, na may price tier na USD $ 2.99. Tinawag natin itong Unlock Premium Version.

Kapag tapos ka nang punan ang lahat ng mga fields, i-save ang produkto at bumalik sa pahina ng In-App Purchases. Ngayon dapat ay may listahan ka na ng iyong dalawang produkto, kasama ang kanilang Pangalan, Type, ID at Status na nakatakda bulang Ready to Submit.

In-app Purchases listIn-app Purchases listIn-app Purchases list

Bumalik sa pahina ng iyong app sa pamamagitan ng pagclick sa App Store at Prepare para Submission na mga pindutan. Magscroll pababa sa bahagi ng In-App Purchases, sa ibaba lang ng General App Information, at pinutin ang (+) upang maidagdag ang iyong mga IAP products.

Add In-App Purchases to your apps info pageAdd In-App Purchases to your apps info pageAdd In-App Purchases to your apps info page

Piliin ang lahat ng mga ito at pindutin ang Done.

Select your IAP productsSelect your IAP productsSelect your IAP products

Panghuli, pindutin ang Save sa pinakakanan at taas na sulok ng screen at matatapos ka na sa pag-configure ng In-App Purchase products sa iTunes Connect.

Maglog-in sa Sandbox Tester sa isang iOS device

Bago pumunta sa code, may isang bagay pang kailangan gawin. Tumungo sa Settings > iTunes & AppStore sa iyong iOS device. Kung nakalog-in ka gamit ang iyong orihinal na Apple ID, pindutin ito at piliin ang Sign Out. Pagkatapos ay magsign in lang gamit ang credentials para sa sandbox tester na nilikha mo. Pagkasign in, maaaring makakita ka ng alert na gaya nito:

Alert from the deviceAlert from the deviceAlert from the device

Huwag pansinin ang mensahe na ito at pindutin ang Cancel.  Ang iyong device ay tatanungin ka muli kung ano ang iyong sandbox login credentials habang sinusubukan mong bumili at kikilalanin ang iyong test account upang hindi ka ma-charge ng kahit singko sa iyong credit card para sa kahit na anong pagbili.

Umalis sa Settings, isaksak ang iyong device sa iyong Mac sa pamamagitan ng USB cable, at sa wakas ay simulan na nating mag-code!

Ang Code

Kapag nadownload mo na ang ating demo project, makikita mo na ang lahat ng mga kailangang code para sa In-App Purchase ay naisulat na, kaya pag ni-run mo ito ay makakakita ka ng ganito:

Demo IAP appDemo IAP appDemo IAP app

Kung gusto mong subukan ang app, kailangan mong baguhin ang Bundle Identifier sa sarili mong ID. Kung hindi, hindi ka hahayaan ng Xcode na mai-run ang iyong app sa isang real device at hindi makikilala ng device ang dalawang IAP products na ginawa mo.

Chage Bundle ID in the General tab in XCodeChage Bundle ID in the General tab in XCodeChage Bundle ID in the General tab in XCode

I-enter ang ViewController.swift at tignan ang code. Una sa lahat ay nagdagdag tayo ng isang import statement para sa StoreKit at ang mga delegado nito na kailangan natin upang ma-track ang payment transactions at mga product request.

1
import StoreKit
2
3
class ViewController: UIViewController,
4
SKProductsRequestDelegate,
5
SKPaymentTransactionObserver
6
{

Pagkatapos ay nagdeklara tayo ng ilang views na maaari nating gamitin.

1
 /* Views */
2
    @IBOutlet weak var coinsLabel: UILabel!
3
    @IBOutlet weak var premiumLabel: UILabel!
4
    @IBOutlet weak var consumableLabel: UILabel!
5
    @IBOutlet weak var nonConsumableLabel: UILabel!
6
    

Ang coinsLabel at premiumLabel  ay gagamitin natin upang maipakita ang mga resulta ng mga nabili para sa parehong mga produkto. Ang consumableLabel at nonConsumableLabel ang magpapakita ng pagkakakilanlan at presyo ng bawat isnag IAP product, ang mga naunan nang nagawa sa iTunes Connect.

Ngayon naman ay oras nang magdagdag ng mga karagdagang variables:

1
/* Variables */
2
    let COINS_PRODUCT_ID = "com.iaptutorial.coins"
3
    let PREMIUM_PRODUCT_ID = "com.iaptutorial.premium"
4
    
5
    var productID = ""
6
    var productsRequest = SKProductsRequest()
7
    var iapProducts = [SKProduct]()
8
    var nonConsumablePurchaseMade = UserDefaults.standard.bool(forKey: "nonConsumablePurchaseMade")
9
    var coins = UserDefaults.standard.integer(forKey: "coins")
10
    

Ang unang dalawang linya ay para matawag muli ang ating mga product IDs. Mahalaga na ang mga strings na ito ay tugmang-tugma sa nakarehistro sa bahaging In-App Purchase ng iTunes Connect.

  • Ang productID ay isang string na gagamitin natin mamya upang malamang kung anong produkto ang pipiliin nating bilhin.
  • Ang productsRequest ay isang instance ng SKProductsRequestm, na kailangan upang maghanap ng IAP products mula sa iyong app sa iTC.
  • Ang iapProducts ay isang simpleng array ng SKProducts. Tandaan na ang unlaping SK ay nangangahulugang StoreKit, ang iOS framework na gagamitin natin upang humawak ng mga pagbili.

Ang huling dalawang linya ay magloload ng dalawang variables na may tipong Boolean at Integer na kinakailangan upang ma-track ang pagbili ng mga coins at ang premium version, pati na ang consumable at non-consumable na mga produkto.

Ang sumusunod na code sa viewDidLoad() ay nagsasagawa ng ilang mga bagay sa oras na tumakbo na ang app:

1
    // Check your In-App Purchases

2
    print("NON CONSUMABLE PURCHASE MADE: \(nonConsumablePurchaseMade)")
3
    print("COINS: \(coins)")
4
    
5
    // Set text

6
    coinsLabel.text = "COINS: \(coins)"
7
    
8
    if nonConsumablePurchaseMade { premiumLabel.text = "Premium version PURCHASED!"
9
    } else { premiumLabel.text = "Premium version LOCKED!"}
10
    
11
    // Fetch IAP Products available

12
    fetchAvailableProducts()

Una ay kailangan nating i-log ang bawat pagbili sa Xcode console. Pagkatapos ay ipapakita ang kabuuang bilang ng coins na nabili natin gamit ang coinsLabel. Dahil pinagana natin sa unang pagkakataon ang demo app, ipapakita nito ang COINS:0.

Ang if statement ay tinatakda ang nakasulat sa premiumLabel ayon sa kung ang non-consumable product ay nabili ba o hindi. Para magsimula, ipapakita nito sayo na anf Premium version ay LOCKED! dahil hindi pa tayo bumibili ng premium.

Ang huling linya ng code ay tinatawag ang method na makikita natin mamaya, na kinukuha lang ang mga produktong inilagay natin sa iTC.

Ngayon ay tignan natin ang ginagawa ng itinakda nating dalawang pagibli buttons sa ating demo app:

1
// MARK: -  BUY 10 COINS BUTTON

2
@IBAction func buy10coinsButt(_ sender: Any) {
3
    purchaseMyProduct(product: iapProducts[0])
4
}
5
    
6
    
7
// MARK: - UNLOCK PREMIUM BUTTON

8
@IBAction func unlockPremiumButt(_ sender: Any) {
9
    purchaseMyProduct(product: iapProducts[1])
10
}

Ang parehong methods ay tatawag ng isang function na magchecheck kung ang device ay maaaring gumawa ng mga purchases, at kung pwede, ang app ay tatawagin ang StoreKit delegate methods para iproseso ang purchase.

Gaya ng sinabi natin dati, kailangan natin ng ikatlong pindutan upang ibalik ang ating non-consumable purchase. Narito ang code nito:

1
// MARK: - RESTORE NON-CONSUMABLE PURCHASE BUTTON

2
@IBAction func restorePurchaseButt(_ sender: Any) {
3
    SKPaymentQueue.default().add(self)
4
    SKPaymentQueue.default().restoreCompletedTransactions()
5
}
6
    
7
func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
8
    nonConsumablePurchaseMade = true
9
    UserDefaults.standard.set(nonConsumablePurchaseMade, forKey: "nonConsumablePurchaseMade")
10
        
11
    UIAlertView(title: "IAP Tutorial",
12
    message: "You've successfully restored your purchase!",
13
    delegate: nil, cancelButtonTitle: "OK").show()
14
}
15
 

Ang IBAction function ay nakakabit sa Restore Purchase button sa Storyboard at nagsisimulang kumonnect sa In-App Purchase system ng Apple para maibalik ang pagbili kapag nagawa na ito.

Ang paymentQueueRestoreCompletedTransactionsFinished() ay isang delegate method mula sa StoreKit framework na magsesave sa ating nonConsumablePurchaseMade variable bilang true pagkatapos na ang pagbili ay matagumpay na naibalik.

Tapos na tayo sa mga pindutan, kaya naman tignan natin kung ano ang nagagawa ng fetchAvailableProducts() function.:

1
// MARK: - FETCH AVAILABLE IAP PRODUCTS

2
func fetchAvailableProducts()  {
3
        
4
    // Put here your IAP Products ID's

5
    let productIdentifiers = NSSet(objects:
6
        COINS_PRODUCT_ID,
7
        PREMIUM_PRODUCT_ID
8
    )
9
        
10
    productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers as! Set<String>)
11
    productsRequest.delegate = self
12
    productsRequest.start()
13
}
14
    

Una ay gagawa tayo ng isang instance ng NSSet, na sa madaling salita ay isang array ng strings. Ilalagay natin ang ating dalawang product ID’s na nauna na nating nai-declare dito.

Pagkatapos ay magsisimula tayo ng isang SKProductRequest base sa mga identifiers na ito, para magawa ng app na ipakita ang impormasyon ukol sa IAP Products (paglalarawan at presyo), na ipoproseso ng delegate method na ito:

1
// MARK: - REQUEST IAP PRODUCTS

2
func productsRequest (_ request:SKProductsRequest, didReceive response:SKProductsResponse) {
3
    if (response.products.count > 0) {
4
        iapProducts = response.products
5
            
6
        // 1st IAP Product (Consumable) ------------------------------------

7
        let firstProduct = response.products[0] as SKProduct
8
        
9
        // Get its price from iTunes Connect

10
        let numberFormatter = NumberFormatter()
11
        numberFormatter.formatterBehavior = .behavior10_4
12
        numberFormatter.numberStyle = .currency
13
        numberFormatter.locale = firstProduct.priceLocale
14
        let price1Str = numberFormatter.string(from: firstProduct.price)
15
        
16
        // Show its description

17
        consumableLabel.text = firstProduct.localizedDescription + "\nfor just \(price1Str!)"
18
        // ------------------------------------------------

19
        
20
        
21
        
22
        // 2nd IAP Product (Non-Consumable) ------------------------------

23
        let secondProd = response.products[1] as SKProduct
24
        
25
        // Get its price from iTunes Connect

26
        numberFormatter.locale = secondProd.priceLocale
27
        let price2Str = numberFormatter.string(from: secondProd.price)
28
        
29
        // Show its description

30
        nonConsumableLabel.text = secondProd.localizedDescription + "\nfor just \(price2Str!)"
31
        // ------------------------------------

32
    }
33
}
34
    

Sa function sa itaas, una nating kailangan i-check kung meron bang mga produkto na nakarehistro sa iTunes Connect at itakda ang ating iapProducts array ayon dito. Pagkatapos ay maaari na nating iinitialize ang dalawang SKProducts at i-print ang kanilang paglalarawang at presyo sa mga label.

Bago tumungo sa pinakamahalagang bahagi ng code ng In-App Purchase, may ilang mga function pa tayong kailangan:

1
// MARK: - MAKE PURCHASE OF A PRODUCT
2
func canMakePurchases() -> Bool {  return SKPaymentQueue.canMakePayments()  }
3
func purchaseMyProduct(product: SKProduct) {
4
    if self.canMakePurchases() {
5
        let payment = SKPayment(product: product)
6
        SKPaymentQueue.default().add(self)
7
        SKPaymentQueue.default().add(payment)
8
        
9
        print("PRODUCT TO PURCHASE: \(product.productIdentifier)")
10
        productID = product.productIdentifier
11
        
12
        
13
    // IAP Purchases dsabled on the Device
14
    } else {
15
        UIAlertView(title: "IAP Tutorial",
16
        message: "Purchases are disabled in your device!",
17
        delegate: nil, cancelButtonTitle: "OK").show()
18
    }
19
}

Ang una ay chinecheck kung ang ating device ay makakagawa ng mga pagbili. Ang ikalawang function ay ang tinatawag natin mula sa dalawang mga pindutan. Nagsisimula ito ng payment queue at binabago ang ating productID variable sa napiling productIdentifier.

Ngayon ay nakarating na tayo sa huling delegate method, ang humahawak ng mga payment results:

1
// MARK:- IAP PAYMENT QUEUE

2
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
3
    for transaction:AnyObject in transactions {
4
            if let trans = transaction as? SKPaymentTransaction {
5
                switch trans.transactionState {
6
                    
7
                case .purchased:
8
                    SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
9
                    
10
                    // The Consumable product (10 coins) has been purchased -> gain 10 extra coins!

11
                   if productID == COINS_PRODUCT_ID {
12
                        
13
                        // Add 10 coins and save their total amount

14
                        coins += 10
15
                        UserDefaults.standard.set(coins, forKey: "coins")
16
                        coinsLabel.text = "COINS: \(coins)"
17
                        
18
                        UIAlertView(title: "IAP Tutorial",
19
                        message: "You've successfully bought 10 extra coins!",
20
                        delegate: nil,
21
                        cancelButtonTitle: "OK").show()
22
                        
23
                        
24
                        
25
                    // The Non-Consumable product (Premium) has been purchased!

26
                    } else if productID == PREMIUM_PRODUCT_ID {
27
                        
28
                        // Save your purchase locally (needed only for Non-Consumable IAP)

29
                        nonConsumablePurchaseMade = true
30
                        UserDefaults.standard.set(nonConsumablePurchaseMade, forKey: "nonConsumablePurchaseMade")
31
                    
32
                        premiumLabel.text = "Premium version PURCHASED!"
33
                        
34
                        UIAlertView(title: "IAP Tutorial",
35
                        message: "You've successfully unlocked the Premium version!",
36
                        delegate: nil,
37
                        cancelButtonTitle: "OK").show()
38
                    }
39
                    
40
                    break
41
                    
42
                case .failed:
43
                    SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
44
                    break
45
                case .restored:
46
                    SKPaymentQueue.default().finishTransaction(transaction as! SKPaymentTransaction)
47
                    break
48
                    
49
                default: break
50
    }}}
51
}

Ang function na ito ay may switch statement na tinitignan ang bawat estado ng payment. Ang unang case ay tinatawag kapag ang pagbili ay matagumpay at kinukumpleto ang transaksyon.

Sa loob ng bloke na ito, kailangan nating siguruhin kung anong product ID ang pinili natin at gawin ang mga kailangang pagkilos upang mai-update ang ating app-para kung tayo, ang gagamit, ay bibili ng sampung karagdagang coins, magdadagdag tayo ng 10 sa ating coins variable, ise-save ang value nito gamit ang UserDefaults, ipakita ang bagong halaga na nakuha natin, at maglunsad ng alert tungkol dito.

Tandaan na maaari mong gawin ang pagbili na ito ng maraming beses ng walang limitasyon dahil ito ay isang consumable na IAP, at hindi na tayo mangangailangan pa ng restore purchase na function.

Kasabay nito, kung bumili tayo ng non-consumable na premium na product, itatakda ng ating ap ang ating nonConsumablePurchaseMade variable bilang true, ise-save ito, babaguhin angteksto ng premiumLabel, at magpapadala ng alert upang ipaalam sa iyo na ang purchase ay nagging matagumpay.

Ang dalawa pang ibang kaso ay humahawak sa mga resulta ng pagbabayad para sa failure at restoring. Ang app ay magpapadala ng custom alerts a sarili nito kung ang iyong transaction ay nabigo sa kung ano mang dahilan o kung nagrestore ka ng non-consumable purchase.

Iyan na yon! Ngayon, siguruhin lang na nakalog in ka gamit ang iyong Sandbox Tester credentials at patakbuhin ang app upang masubukan ito. Sa unang beses, makakakuha ka ng alert na gaya nito:

App Store Sign In alertApp Store Sign In alertApp Store Sign In alert

Piliin ang Use Existing Apple ID at muling ilagay ang iyong username at password ng Sandbox Tester upang makapagsign in. Nangyayari ito sapagkat ang app ay nakakakilala lang ng isang real user mula sa settings ng iTunes & App Store, at hindi sa isang galing sa Sandbox.

Kapag nakalog in ka na, magagawa mo na pagbili sa parehong produkto.

10 Coins purchase made10 Coins purchase made10 Coins purchase made

Non-Consumable Premium purchase madeNon-Consumable Premium purchase madeNon-Consumable Premium purchase made

CodeCanyon Templates

Kung gumagamit ka ng iOS at gusto mong mas matutunan ang Swift language at apps development, tumungo na sa ilan sa aking mga iOS app templates sa CodeCanyon.

Meron ding daan-daan pang ibang iOS app templates sa Envato Market, nakahandang magamit muli at siguradong papabilisin ang iyong pagtatrabaho. Silipin na ang mga ito!  Maaaring makatipid ka ng ilang oras ng pagtatrabaho sa iyong susunod na app.

Konklusyon

Sa pagtuturong ito, natalakay natin ang lahat ng mga hakbang na kailangan upang makagawa ng In-App Purchase na mga produkto sa iTunes Connect at kung papano sumulat ng code para mapagana ito sa iyong app. Sana ay magamit mo ang kaalaman na ito sa iyong susunod na iOS app!

Salamat sa pagbabasa, at kita-kits tayo muli! Tignan nyo rin ang iba pa naming mga kurso at mga pagtuturo tungkol sa iOS app development gamit ang Swift.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.