將iOS付費(fèi)App轉(zhuǎn)換成免費(fèi)加內(nèi)購(gòu)模式的最佳實(shí)踐

轉(zhuǎn)載于:https://15tar.com/ios/2017/10/09/convert-paid-app-to-freemium-with-iap.html

前段時(shí)間上線(xiàn)我的第一個(gè)收費(fèi)App——瓦工助手,雖然有下載酷师,但一天一兩個(gè)的下載量實(shí)在是有點(diǎn)太少脾猛。于是打算把付費(fèi)下載改成付費(fèi)加應(yīng)用內(nèi)購(gòu)買(mǎi)的模式,看看下載量和收益是否有提升蹬跃。下面記錄一下將收費(fèi)改成免費(fèi)加內(nèi)購(gòu)的最佳實(shí)現(xiàn)方式宗挥。

因?yàn)槭侵笆歉顿M(fèi)下載的靶壮,讓已購(gòu)買(mǎi)的用戶(hù)再來(lái)應(yīng)用內(nèi)購(gòu)買(mǎi)是不合適的维费,所以需要解決的一個(gè)核心問(wèn)題是如何識(shí)別用戶(hù)是否已經(jīng)購(gòu)買(mǎi)過(guò)App果元。

Apple提供了API(appStoreReceiptURL)可以獲取App購(gòu)買(mǎi)的Receipt,包括App購(gòu)買(mǎi)和In App Purchase犀盟,具體文檔可以參考官方的 Receipt Validation Programming Guide 而晒。簡(jiǎn)單來(lái)說(shuō),appStoreReceiptURL會(huì)返回App的購(gòu)買(mǎi)的版本(original_application_version)及應(yīng)用內(nèi)購(gòu)買(mǎi)的詳細(xì)信息(in_app)阅畴,這里關(guān)鍵的是original_application_version倡怎,它記錄的是用戶(hù)下載App時(shí)的應(yīng)用版本,對(duì)應(yīng)App的CFBundleVersion(注意不是CFBundleShortVersionString)贱枣,而且只在A(yíng)pp Store版本的App上才會(huì)返回正確的值监署,其它情況返回的都是1.0,連TestFlight也是纽哥,這個(gè)很不方便調(diào)試焦匈。

通過(guò)比對(duì)original_application_version與啟用IAP的第一個(gè)版本號(hào)就可以方便的控制是否需要應(yīng)用內(nèi)購(gòu)買(mǎi)了。

如果自己手動(dòng)去請(qǐng)求appStoreReceiptURL獲取receipt信息會(huì)比較麻煩昵仅,這里我使用的是一個(gè)第三方庫(kù):SwiftyStoreKit,大大簡(jiǎn)化了流程,推薦使用摔笤!

使用SwiftyStoreKit只需要下面簡(jiǎn)單的代碼就能夠獲取Receipt信息了:

let appleValidator = AppleReceiptValidator(service: .production)
SwiftyStoreKit.verifyReceipt(using: appleValidator, password: Constants.iapSharedSecret, forceRefresh: false) { result in
    switch result {
    case .success(let receipt):
        log.info("Verify receipt Success: \(receipt)")

        let receiptJSON = JSON(receipt)

        // 是否之前付費(fèi)下載
        if let orignalVersion = receiptJSON["receipt"]["original_application_version"].string,
            Int(orignalVersion) ?? 0 < Constants.iapStartVersion {
            IAPHelper.markPurchasedApp(purchased: true)
            log.info("Already purchased the App")
        } else {
            IAPHelper.markPurchasedApp(purchased: false)
        }

        // 是否應(yīng)用內(nèi)購(gòu)買(mǎi)
        if let inAppReceipts = receiptJSON["receipt"]["in_app"].array,
            inAppReceipts.count > 0 {
            IAPHelper.markPurchasedInApp(purchased: true)
            log.info("Already in-app purchased")
        } else {
            IAPHelper.markPurchasedInApp(purchased: false)
        }
    case .error(let error):
        log.error("Verify receipt Failed: \(error)")
    }
}

簡(jiǎn)單介紹解釋一下:

  • Constants.iapStartVersion是內(nèi)購(gòu)開(kāi)始的第一個(gè)版本够滑,如果版本號(hào)小于這個(gè)值說(shuō)明是下載的之前版本,直接跳過(guò)內(nèi)購(gòu)吕世;
  • 關(guān)于in_app的處理彰触,因?yàn)槲业腁pp只有一個(gè)內(nèi)購(gòu)Item,所以這里只判斷了數(shù)組的長(zhǎng)度命辖,你可能需要對(duì)product_id 進(jìn)行更細(xì)致的處理况毅;
  • IAPHelper對(duì)整個(gè)邏輯做了簡(jiǎn)單封裝,詳細(xì)見(jiàn)這個(gè)Gist尔艇,應(yīng)該可以拿來(lái)直接用尔许。

說(shuō)點(diǎn)題外話(huà),瓦工助手從付費(fèi)App改成免費(fèi)加內(nèi)購(gòu)已經(jīng)有一個(gè)星期左右的時(shí)間了终娃,下載量確實(shí)呈指數(shù)級(jí)增長(zhǎng)味廊,但收入?yún)s下降了,這跟我的IAP設(shè)置有關(guān)棠耕,目前我的設(shè)置是管理一臺(tái)VPS免費(fèi)余佛,管理多臺(tái)VPS才需要內(nèi)購(gòu),而大部分用戶(hù)都是只有一臺(tái)VPS的窍荧。所以辉巡,往往產(chǎn)品的設(shè)計(jì)比技術(shù)本身更重要。:)

很多人可能見(jiàn)不到production環(huán)境下的Receipt數(shù)據(jù)到底長(zhǎng)啥樣蕊退,在這里貼一個(gè)出來(lái):

["status": 0, "receipt": {
    "adam_id" = 1267833691;
    "app_item_id" = 1267833691;
    "application_version" = 31;
    "bundle_id" = "com.0x1024.Bandwagon";
    "download_id" = 62034015496213;
    "in_app" =     (
                {
            "is_trial_period" = false;
            "original_purchase_date" = "2017-10-08 02:55:13 Etc/GMT";
            "original_purchase_date_ms" = 1507431313000;
            "original_purchase_date_pst" = "2017-10-07 19:55:13 America/Los_Angeles";
            "original_transaction_id" = 220000373453498;
            "product_id" = "bangon_iap";
            "purchase_date" = "2017-10-08 02:55:13 Etc/GMT";
            "purchase_date_ms" = 1507431313000;
            "purchase_date_pst" = "2017-10-07 19:55:13 America/Los_Angeles";
            quantity = 1;
            "transaction_id" = 220000373453498;
        }
    );
    "original_application_version" = 31;
    "original_purchase_date" = "2017-10-08 02:47:56 Etc/GMT";
    "original_purchase_date_ms" = 1507430876000;
    "original_purchase_date_pst" = "2017-10-07 19:47:56 America/Los_Angeles";
    "receipt_creation_date" = "2017-10-08 02:55:13 Etc/GMT";
    "receipt_creation_date_ms" = 1507431313000;
    "receipt_creation_date_pst" = "2017-10-07 19:55:13 America/Los_Angeles";
    "receipt_type" = Production;
    "request_date" = "2017-10-09 02:35:01 Etc/GMT";
    "request_date_ms" = 1507516501916;
    "request_date_pst" = "2017-10-08 19:35:01 America/Los_Angeles";
    "version_external_identifier" = 823885941;
}, "environment": Production]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末郊楣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子咕痛,更是在濱河造成了極大的恐慌痢甘,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,029評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茉贡,死亡現(xiàn)場(chǎng)離奇詭異塞栅,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)腔丧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)放椰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人愉粤,你說(shuō)我怎么就攤上這事砾医。” “怎么了衣厘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,570評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵如蚜,是天一觀(guān)的道長(zhǎng)压恒。 經(jīng)常有香客問(wèn)我,道長(zhǎng)错邦,這世上最難降的妖魔是什么探赫? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,535評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮撬呢,結(jié)果婚禮上伦吠,老公的妹妹穿的比我還像新娘。我一直安慰自己魂拦,他們只是感情好毛仪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著芯勘,像睡著了一般箱靴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上借尿,一...
    開(kāi)封第一講書(shū)人閱讀 49,850評(píng)論 1 290
  • 那天刨晴,我揣著相機(jī)與錄音,去河邊找鬼路翻。 笑死狈癞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的茂契。 我是一名探鬼主播蝶桶,決...
    沈念sama閱讀 39,006評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼掉冶!你這毒婦竟也來(lái)了真竖?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,747評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤厌小,失蹤者是張志新(化名)和其女友劉穎恢共,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體璧亚,經(jīng)...
    沈念sama閱讀 44,207評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡讨韭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了癣蟋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片透硝。...
    茶點(diǎn)故事閱讀 38,683評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖疯搅,靈堂內(nèi)的尸體忽然破棺而出濒生,到底是詐尸還是另有隱情,我是刑警寧澤幔欧,帶...
    沈念sama閱讀 34,342評(píng)論 4 330
  • 正文 年R本政府宣布罪治,位于F島的核電站丽声,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏规阀。R本人自食惡果不足惜恒序,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谁撼。 院中可真熱鬧,春花似錦滋饲、人聲如沸厉碟。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,772評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)箍鼓。三九已至,卻和暖如春呵曹,著一層夾襖步出監(jiān)牢的瞬間款咖,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,004評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工奄喂, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铐殃,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,401評(píng)論 2 360
  • 正文 我出身青樓跨新,卻偏偏與公主長(zhǎng)得像富腊,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子域帐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評(píng)論 2 349

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