iOS:為 App 添加內(nèi)購買項(xiàng)目

思維導(dǎo)圖

前言

在 AppStore 里,付費(fèi)應(yīng)用的下載量往往比免費(fèi)應(yīng)用的下載量少的多森缠。上架過應(yīng)用的開發(fā)者祝闻,可能會(huì)有這樣的體會(huì):當(dāng)一個(gè)應(yīng)用免費(fèi)的時(shí)候,每天能有幾十上百次的下載甘苍,但是一旦設(shè)置為收費(fèi)的時(shí)候尝蠕,下載量立即暴跌,即使只設(shè)成了一元载庭,可能好幾星期都沒人下載看彼。

收費(fèi)的應(yīng)用不好做,與其長時(shí)間零下載囚聚,還不如設(shè)置為免費(fèi)靖榕,每天看看下載量來的舒服。

但是作為一個(gè)開發(fā)者顽铸,開發(fā)免費(fèi)應(yīng)用的動(dòng)力茁计,顯然比不上開發(fā)收費(fèi)應(yīng)用。應(yīng)用免費(fèi)了跋破,開發(fā)的動(dòng)力也少了簸淀。因此,我們可以考慮在應(yīng)用里面加入內(nèi)購買項(xiàng)目毒返,通過免費(fèi)下載吸引用戶租幕,再用內(nèi)購買項(xiàng)目讓用戶按需購買,自己賺點(diǎn)零花錢拧簸。

本文將用一個(gè)真實(shí)的例子(已上架 AppStore:Catch - 捕捉稍縱即逝的靈感)劲绪,介紹為 App 添加內(nèi)購買項(xiàng)目的流程。

必要的準(zhǔn)備

添加內(nèi)購買項(xiàng)目之前盆赤,需要有一個(gè)付費(fèi)的開發(fā)者賬號(hào)贾富,并在開發(fā)者賬號(hào)的“協(xié)議、稅務(wù)和銀行業(yè)務(wù)”里完善銀行卡等信息牺六,否則 Apple 無法將應(yīng)用的收入轉(zhuǎn)給你颤枪。

你還需要準(zhǔn)備一個(gè)已上架或者未上架的應(yīng)用,應(yīng)用在首次添加內(nèi)購買項(xiàng)目時(shí)需要與新的應(yīng)用版本一起提交審核淑际。

內(nèi)購買項(xiàng)目的用戶界面

在添加內(nèi)購買項(xiàng)目前畏纲,你需要在你的應(yīng)用里扇住,自己設(shè)計(jì)好商品展示的界面,Apple 只負(fù)責(zé)購買的流程盗胀。這個(gè)界面在接下去新建內(nèi)購買項(xiàng)目時(shí)也會(huì)用到艘蹋。

下圖是一個(gè)實(shí)際應(yīng)用的內(nèi)購商品展示界面:

在 iTunesConnect 上新建內(nèi)購買項(xiàng)目

接下來,在 iTunesConnect 上的應(yīng)用頁面票灰,選擇“功能”-“App 內(nèi)購買項(xiàng)目“女阀,點(diǎn)擊加號(hào)新建項(xiàng)目,如下圖:

之后會(huì)要求選擇內(nèi)購買項(xiàng)目的類型屑迂,這里以“消費(fèi)型項(xiàng)目”為例浸策。在接下來的表里填寫相應(yīng)的信息。產(chǎn)品 ID 一般以 App 的 Bundle ID 為前綴再加上自定義的產(chǎn)品后綴屈糊,如:com.self.purchase1的榛。在審核信息里上傳剛剛的內(nèi)購商品展示界面琼了,供審查員審核逻锐。其他信息自行填寫即可。

新建內(nèi)購買項(xiàng)目后雕薪,在內(nèi)購買項(xiàng)目列表里顯示為“準(zhǔn)備提交”狀態(tài)∶劣眨現(xiàn)在在準(zhǔn)備提交的 App 版本中添加剛剛新建的內(nèi)購買項(xiàng)目。

完成內(nèi)購買相關(guān)代碼

關(guān)于內(nèi)購買的代碼所袁,本文將使用一個(gè)現(xiàn)成的框架:SwiftyStoreKit盏档,這樣有利于理清思路。對于直接使用 StoreKit 完成整個(gè)內(nèi)購買的流程燥爷,將在下一篇文章里討論蜈亩。

首先在項(xiàng)目里添加 SwiftyStoreKit 框架。具體添加的方法上面的鏈接里已有說明前翎。
總共的代碼有三部分稚配,如下:

一、獲取商品信息港华,用于在界面上顯示:

SwiftyStoreKit.retrieveProductsInfo([productID]) {[weak self ] result in
    if let product = result.retrievedProducts.first {
        let priceString = product.localizedPrice!
        print("Product: \(product.localizedDescription), price: \(priceString)")
    }else if let invalidProductId = result.invalidProductIDs.first {
        print("Could not retrieve product info .Invalid product identifier: \(invalidProductId)")
    }else {
        print("Error: \(result.error)")
    }
}

商品信息包括商品的價(jià)格和名稱道川,保存在 SKProduct 對象里。匯率的問題 Apple 已經(jīng)幫我們處理好立宜,商品的名稱會(huì)根據(jù)我們在 iTunesConect 里填寫的本地化信息自動(dòng)選擇冒萄,因此我們只需要直接使用 localizedPricelocalizedTitlelocalizedDescription

二橙数、購買商品(當(dāng)用戶點(diǎn)擊購買后):

func purchase(_ productID: String) {
    SwiftyStoreKit.purchaseProduct(productID, atomically: true) { [weak self] result in
        if case .success(let product) = result {
        // Deliver content from server, then:
        if product.needsFinishTransaction {
            SwiftyStoreKit.finishTransaction(product.transaction)
            }
        }
        if let alert = self?.alertForPurchaseResult(result) {
            self?.showAlert(alert)
        }
    }
}

productID 就是內(nèi)購買項(xiàng)目的 ID尊流,如:com.self.appname.purchase1。productID 可以事先在程序中定義灯帮,如果想從網(wǎng)絡(luò)上獲取 productID 的話崖技,只能從自己的服務(wù)器中獲取蜘澜,iTunesConnect 并不提供獲取內(nèi)購買商品列表的 API。

三响疚、完成購買事務(wù):

func completeIAPTransactions() {
    SwiftyStoreKit.completeTransactions(atomically: true) { products in
        for product in products {
            if product.transaction.transactionState == .purchased || product.transaction.transactionState == .restored {
                if product.needsFinishTransaction {
                // Deliver content from server, then:
                    SwiftyStoreKit.finishTransaction(product.transaction)
                }
                print("purchased: \(product.productId)")
            }
        }
    }
}

在 application:didFinishLaunchingWithOptions 里調(diào)用上述的函數(shù)鄙信。因?yàn)?Apple 建議在 app 載入的時(shí)候?yàn)橘徺I事務(wù)添加一個(gè)觀察者:

Adding your app's observer at launch ensures that it will persist during all launches of your app, thus allowing your app to receive all the payment queue notifications.

SwiftyStoreKit 用 completeTransactions 函數(shù)實(shí)現(xiàn)了這個(gè)功能。這樣忿晕,如果在載入的時(shí)候有任何進(jìn)行中的事務(wù)装诡,就可以對它們進(jìn)行處理,更新 app 的狀態(tài)和 UI践盼。

內(nèi)購買測試

完成內(nèi)購買的代碼后鸦采,在提交審核之前,還應(yīng)該對它進(jìn)行測試咕幻。Apple 為應(yīng)用內(nèi)購買項(xiàng)目提供了沙箱(sandbox)測試渔伯,讓你使用虛擬的貨幣模擬內(nèi)購過程。

a) 在 iTunesConnect 的“用戶與職能”里添加沙箱技術(shù)測試員肄程。

b) 在 iPhone 設(shè)置里的 “iTunes Store 與 App Store” 將原來的賬號(hào)注銷锣吼。但是不要登陸測試員的賬號(hào)。

c) 打開待測試內(nèi)購買的 app蓝厌,點(diǎn)擊內(nèi)購買的項(xiàng)目進(jìn)行購買玄叠。這時(shí)候,會(huì)提示登錄 App Store拓提,使用沙箱測試員的賬號(hào)登錄读恃。

d) 之后會(huì)彈出購買信息確認(rèn)窗口,注意窗口內(nèi)的提示信息 “Environment: Sandbox“代态,表示是在沙箱中測試寺惫,購買的貨幣是虛擬的。如果沒有這一行的話蹦疑,則是在真實(shí)的環(huán)境中進(jìn)行交易西雀,使用的就是真實(shí)的貨幣了。

結(jié)語

測試完成后就可以提交審核了必尼。如果是首次添加內(nèi)購買項(xiàng)目蒋搜,記得在 app 審核頁添加內(nèi)購項(xiàng)目一起提交審核。當(dāng)再次添加內(nèi)購買項(xiàng)目判莉,就可以獨(dú)立審核內(nèi)購買項(xiàng)目豆挽,而無需提交新的 app 版本。當(dāng)然券盅,這樣做的前提是 app 能夠從自己的服務(wù)器上獲取內(nèi)購買項(xiàng)目的 productID帮哈,否則 app 無法獲取新內(nèi)購買項(xiàng)目的信息。

本文是以消費(fèi)性內(nèi)購買項(xiàng)目為例锰镀,對于其他類型的內(nèi)購買項(xiàng)目娘侍,方法大同小異咖刃,更多的信息請參考官方文檔

歡迎訪問我的Github:LinShiwei (Lin Shiwei) · GitHub

有任何疑問的話憾筏,歡迎在下方評論區(qū)討論嚎杨。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市氧腰,隨后出現(xiàn)的幾起案子枫浙,更是在濱河造成了極大的恐慌,老刑警劉巖古拴,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件箩帚,死亡現(xiàn)場離奇詭異,居然都是意外死亡黄痪,警方通過查閱死者的電腦和手機(jī)紧帕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桅打,“玉大人是嗜,你說我怎么就攤上這事∮投睿” “怎么了叠纷?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長潦嘶。 經(jīng)常有香客問我,道長崇众,這世上最難降的妖魔是什么掂僵? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮顷歌,結(jié)果婚禮上锰蓬,老公的妹妹穿的比我還像新娘。我一直安慰自己眯漩,他們只是感情好芹扭,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赦抖,像睡著了一般舱卡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上队萤,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天轮锥,我揣著相機(jī)與錄音,去河邊找鬼要尔。 笑死舍杜,一個(gè)胖子當(dāng)著我的面吹牛新娜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播既绩,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼概龄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了饲握?” 一聲冷哼從身側(cè)響起旁钧,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎互拾,沒想到半個(gè)月后歪今,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颜矿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年寄猩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骑疆。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡田篇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出箍铭,到底是詐尸還是另有隱情泊柬,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布诈火,位于F島的核電站兽赁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏冷守。R本人自食惡果不足惜刀崖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拍摇。 院中可真熱鬧亮钦,春花似錦、人聲如沸充活。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽混卵。三九已至映穗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淮菠,已是汗流浹背男公。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人枢赔。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓澄阳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親踏拜。 傳聞我的和親對象是個(gè)殘疾皇子碎赢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,506評論 25 707
  • 原文地址:http://blog.csdn.net/xiaominghimi/article/details/69...
    LuxDark閱讀 5,970評論 2 4
  • 在我們應(yīng)用開發(fā)中我們經(jīng)常在自己的項(xiàng)目中使用到支付,下面我們來談?wù)刬OS這塊的支付速梗;iOS支付主要分為兩類肮塞,第三方支...
    Hither閱讀 8,256評論 9 42
  • 現(xiàn)實(shí)真的很殘酷,身邊沒有一個(gè)真心朋友姻锁,經(jīng)歷多了枕赵,就很難再把自己的心交出去。 “你以為別人都和你想的一樣嗎位隶,真心...
    DYdream閱讀 254評論 0 0
  • 如果次元允許涧黄,我想活在動(dòng)漫里篮昧! 我向黨和人民保證,我有了特異功能一定不會(huì)干違法亂紀(jì)的事笋妥。 (胸前的紅領(lǐng)巾更鮮艷了呢...
    小酒官兒閱讀 346評論 0 1