iOS 10.3 开始请求应用商店评分的正确姿势:SKStoreReviewController

App 开发者的最主要目标之一就是获得更多曝光,并且从用户那里接收反馈从而改进 app,以便鼓励其他用户尝试使用。多年以来,开发者都在使用第三方方法来建议用户去商店打分,大部分是基于用户使用 app 的时长和频率。但使用这些第三方方法会导致体验不够理想。通常用户会被送到 AppStore app 来撰写评价,甚至用户还要手动选择“评论”标签页才能开始写评价。

在 iOS 10.3 的更新里,Apple 在 iOS 平台上做了几个重要改动,最受开发者欢迎的就是向用户询问评分的官方方式。所以从 10.3 开始,我们可以用 StoreKit 来询问用户评分,并且 StoreKit 会替我们处理剩下的工作。可以看这里的文档。理论上来说,开发者只要加一行代码即可请求评分,但还有几点值得注意。

根据文档所述,请求评分函数使用了私有方法来分析当前是否是向用户询问评分的好时机,所以 Apple 强烈建议开发者不要在相应用户行为时调用此方法。例如,如果你把请求评分放在按钮触摸的回调函数里,但此时 iOS 可能决定不显示评分,所以用户就会认为 app 的功能出现了问题。另一方面,也不要太早让用户评分,最好等 app 运行几次之后再询问评分。尽管我们并不了解 Apple 的算法,但我们知道此方法的行为模式,所以最好在确定用户处于合适的时间时再进行询问。

注意:在开发时,所有评分请求都会通过,也就是说每次请求评分,评分对话框都会显示,但无法提交评分。在 Testflight 中,请求都不会被通过,所以如果 Testflight 测试时评分对话框没有正确显示,不要慌张。app 上架后,就会使用 Apple 方法在合适的时间显示对话框了。

不多说了,下面是用 Swift 实现请求评分的方式。

  1. 首先,import StoreKit
import StoreKit
  1. 现在就可以如下询问评分了
SKStoreReviewController.requestReview()

就这么简单!比想象中容易多了吧!

如果你想支持老的 iOS 版本,最好这么做:

if #available(iOS 10.3, *) {
    SKStoreReviewController.requestReview()
           
} else {
    // 退回老的版本
    // 尝试手写或用第三方方法。
}

一步步来

在我看来,实现 RequestReview 的正确姿势是:

  1. 在项目里创建新的 Swift 文件
  2. 导入所需框架
import Foundation
import StoreKit
  1. 定义设置变量
let runIncrementerSetting = "numberOfRuns"  // 用于存储运行次数的 UserDefauls 字典键
let minimumRunCount = 5 // 询问评分的最少运行次数       
  1. 然后写一个运行计数器,功能就是在 UserDefaults 存储运行次数。此计数器需要两个函数。一个从 UserDefaults 里读取,另一个将其加一并存回 UserDefaults。
func incrementAppRuns() {                   // app 运行次数计数器。可以在 App Delegate 中调用此方法
    
    let usD = UserDefaults()
    let runs = getRunCounts() + 1
    usD.setValuesForKeys([runIncrementerSetting: runs])
    usD.synchronize()
    
}
func getRunCounts () -> Int {               // 从 UserDefaults 里读取运行次数并返回。
    
    let usD = UserDefaults()
    let savedRuns = usD.value(forKey: runIncrementerSetting)
    
    var runs = 0
    if (savedRuns != nil) {
        
        runs = savedRuns as! Int
    }
    
    print("已运行\(runs)次")
    return runs
    
}
  1. 下一步是用于请求评分的函数。我们需要在此函数里考虑两个因素。首先,是否有足够的运行次数来询问评分。其次,检查是否是 iOS10.3 及以上版本,这样我们才能调用此函数。
func showReview() {
    
    let runs = getRunCounts()
    print("显示评分")
    
    if (runs > minimumRunCount) {
        
        if #available(iOS 10.3, *) {
            print("已请求评分")
            SKStoreReviewController.requestReview()
            
        } else {
            // 回到老版本
        }
        
    } else {
        
        print("请求评分所需的运行次数不足!")
        
    }
    
}
  1. 下一步就是从 App Delegate 里调用运行计数器。所以在 app 的 didFinishLaunchingWithOptions 函数里添加如下内容:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

        incrementAppRuns()
        return true
 }
  1. 最后一步是在合适的时间里调用 showReview()。我的建议是在用户完成 app 中某项主要工作后调用此函数。例如你在开发游戏,向用户展示分数时就可以调用此函数。记住如果要把它放在按钮回调里,就要和其它任务一起才行。例如,在 Shuffle 里面,我把 showReview() 函数放在壁纸的下载按钮中。所以用户下载完壁纸后,如果 requestReview 决定显示评分,就会显示在下载完成的壁纸上。这样就可以确保按钮总是能够正确工作,同时还能确保用户在 app 中完成主要任务时可以显示请求评分页面。
showReview()

好啦!现在可以运行你的 app 来看看效果。

需要的话,可以从 GitHub 上下载我的脚本,包含了此教程中的 1-5 步。点击下载代码

欢迎在下面评论。编程愉快!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容

  • 版本记录 前言 StoreKit框架,支持应用内购买和与App Store的互动。接下来几篇我们就一起看一下这个框...
    刀客传奇阅读 2,642评论 0 9
  • 评分与评论 关于评分与评论,相信不仅仅是开发者,甚至任何一个 iPhone 用户都不陌生。 因为很多 App 在使...
    Lision阅读 2,318评论 0 7
  • 今天我们上体育课又是跳绳了,我们一星期有好几节体育课,上体育课就是为了让我们锻炼身体,我们只有身体好才能不生病,天...
    姚姚乖乖宝阅读 137评论 0 1
  • 阳光在最后一颗白杨下流连 前面的兄弟 或战死沙场 或仓惶逃离 空气中雨滴不为所动 喉咙里最后的声音进退不得 星空不...
    陈阿臣阅读 162评论 0 0
  • 清早,听着歌漫步、看旭日东升 慢慢出行、漫无目的 择一佳地 停下来,仔细陈酿 不知觉间、许久许久过去 我也就转头...
    乡里白头翁阅读 144评论 0 3