我已经看到了一些答案,但对它们不满意并得到了一些想法,但不知道如何正确使用它,以便它将以正确的方式执行,尽管我认为它应该在App委托{{{ 1}},但我想确定在Live应用程序中实现它之前没有任何喧嚣。
didFinishLaunching
仅适用于ios 10.3我所阅读的内容,任何人都可以用迅速和客观的c解释一点代码。
更新
实际上我对调用方法SKStoreReviewController
很困惑,我需要在哪里调用这个方法?在requestReview()
的{{1}}或rootViewController
的{{1}}中?
感谢。
答案 0 :(得分:68)
SKStoreReviewController
在iOS 10.3及更高版本中可用。
根据APPLE的文件:
您可以要求用户在使用该应用时对其进行评分或评论, 无需将它们发送到App Store。您可以确定其中的点数 用户体验,调用API和系统是有意义的 照顾其他人。
为了在应用内显示评分/评论,您必须添加StoreKit
框架。
请找到两种语言的示例代码:
目标C:
#import <StoreKit/StoreKit.h>
- (void)DisplayReviewController {
if([SKStoreReviewController class]){
[SKStoreReviewController requestReview] ;
}
}
因为xCode 9你可以这样做:
#import <StoreKit/StoreKit.h>
- (void)DisplayReviewController {
if (@available(iOS 10.3, *)) {
[SKStoreReviewController requestReview];
}
}
夫特:
import StoreKit
func DisplayReviewController {
if #available( iOS 10.3,*){
SKStoreReviewController.requestReview()
}
}
更新:Ask for a rating only after the user has demonstrated engagement with your app
答案 1 :(得分:8)
对于目标C,
1-)从 Link Binary With Library 添加了StoreKit框架
2-)添加了框架
#import <StoreKit/StoreKit.h>
3-)添加了以下代码,您可以在其中调用App-Review弹出窗口。在这种情况下,我添加了viewDidLoad。
- (void)viewDidLoad {
[super viewDidLoad];
[SKStoreReviewController requestReview];
}
4-)当您在调试模式下进行测试时,您应该了解Apple的以下解释
当您的应用仍处于开发模式时调用此方法时,将始终显示评级/评论请求视图,以便您可以测试用户界面和体验。但是,当您在使用TestFlight分发的应用程序中调用此方法时,此方法无效。
答案 2 :(得分:4)
我认为直接调用以下内容不是一个好主意
SKStoreReviewController.requestReview()
可以像用户打开你的应用程序10(10,20,30,... 100)的倍数那样你可以显示以供审查
所以首先你需要创建一个文件来负责所有事情,例如在userdefaults中保存你的应用程序打开计数,检索应用程序打开计数并显示requestReview() 请看下面的代码片段
new ol.layer.Image({
extent: [-13884991, 2870341, -7455066, 6338219],
source: new ol.source.ImageWMS({
url: 'https://ahocevar.com/geoserver/wms',
params: {'LAYERS': 'topp:states,topp:population'}, // <---
ratio: 1,
serverType: 'geoserver'
})
})
}
答案 3 :(得分:3)
在上面添加了呵叻的好答案...
如果您支持旧版Objective-C应用程序,并且希望在几个应用程序打开后调用DisplayReviewController,请执行以下操作:
在您的类AppDelegate.m中添加以下内容:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
int count = [[NSUserDefaults standardUserDefaults] integerForKey:@"LaunchCount"];
if(count < 0) count = 0;
[[NSUserDefaults standardUserDefaults] setInteger:count+1 forKey:@"LaunchCount"];
}
//The application was in background and become active
- (void)applicationWillEnterForeground:(UIApplication *)application {
int count = [[NSUserDefaults standardUserDefaults] integerForKey:@"LaunchCount"];
if(count < 0) count = 0;
[[NSUserDefaults standardUserDefaults] setInteger:count+1 forKey:@"LaunchCount"];
}
并在控制器中要调用该函数:
- (void)applicationDidBecomeActive {
if ([[NSUserDefaults standardUserDefaults] integerForKey:@"LaunchCount"] == 5) {
[self DisplayReviewController];
}
}
答案 4 :(得分:1)
我认为你可以实现一个方法来计算他们运行应用程序并将其存储在UserDefaults中,然后调用requestReview(),如果计数数字是5或10或类似的东西(这取决于你),通过这种方式你有更多机会获得好评。
答案 5 :(得分:1)
这是我正在为自己的用例开发的实用程序函数,它可能会帮助很多其他人。 (随意烘烤和改进/更正我的代码:D)。我正在开发一个语音练习应用程序,我想在用户完成一些录音后要求评分。我将添加 main 函数,然后添加它下面使用的其他辅助函数。简单的逻辑是,您一年可以申请 3 次审核,因此如果 1 year has passed,我将询问计数重置为 0。此外,不会为每个询问显示审核请求。所以在我不允许应用程序再尝试审核请求之前,我有 30 个请求的上限。如果应用版本发生变化,则不会考虑这一点,因为您可以再次要求对新应用版本进行审核。
/// Requests review from user based on certain conditions.
/// 1. Should have recorderd at least 3 recordings (if you want to force attept a review ask don't pass any parameter)
/// 2. Has not already asked for a review today
/// 3. A probabitly of 50% if will ask today
/// 4. If review has not been asked more than 30 times in the same year for the current version
/// - Parameter numberOfRecordings: If the number of recordings is greater than 3 then a review will be asked.
func askForReview(numberOfRecordings: Int = 5) {
let defaults = UserDefaults.standard
let lastAskedReviewAt = defaults.double(forKey: lastAskedReviewAtKey)
let dateStringForLastReviewAsk = getDateString(from: lastAskedReviewAt)
let dateForLastReviewAsk = getDate(from: dateStringForLastReviewAsk) ?? Date(timeIntervalSince1970: 0)
let askedReviewToday = Calendar.current.isDateInToday(dateForLastReviewAsk)
var appReviewRequestsCount = defaults.integer(forKey: appReviewRequestsCountKey)
if Date().localDate().years(from: dateForLastReviewAsk) >= 1 {
defaults.setValue(0, forKey: appReviewRequestsCountKey)
appReviewRequestsCount = 0
}
var isAskingReviewForSameVersion = false
if let currentlyInstalledVersion = getInstalledVersionNumber(), let lastReviewAskedForVersion = defaults.string(forKey: lastReviewAskedForVersionKey) {
if currentlyInstalledVersion == lastReviewAskedForVersion {
isAskingReviewForSameVersion = true
} else {
appReviewRequestsCount = 0
defaults.setValue(0, forKey: appReviewRequestsCountKey)
}
}
let askingReviewTooManyTimes = appReviewRequestsCount >= 30 && isAskingReviewForSameVersion
let totalRecordingsTillDateCount = defaults.integer(forKey: totalRecordingsTillDateCountKey)
let localNumberOfRecordings = max(numberOfRecordings, totalRecordingsTillDateCount)
if localNumberOfRecordings > 3 && Bool.random() && !askedReviewToday && !askingReviewTooManyTimes {
SKStoreReviewController.requestReview()
defaults.setValue(Date().timeIntervalSince1970, forKey: lastAskedReviewAtKey)
if let versionNumber = getInstalledVersionNumber() {
defaults.setValue(versionNumber, forKey: lastReviewAskedForVersionKey)
}
defaults.setValue(appReviewRequestsCount + 1, forKey: appReviewRequestsCountKey)
}
}
字典键:
let lastAskedReviewAtKey = "LastAskedReviewAt"
let appReviewRequestsCountKey = "AppReviewRequestsCount"
let lastReviewAskedForVersionKey = "AskedReviewForVersion"
let appVersionNumberKey = "CFBundleShortVersionString"
辅助函数:
/// Get a string representation in current local time for a timestamp
/// - Parameter timestamp: Timestamp to be converted to date string
/// - Returns: A date string from passed timestamp in dd MMM yyy format
func getDateString(from timestamp: Double) -> String {
let dateFormatter = getDateFormatter()
let date = Date(timeIntervalSince1970: timestamp)
let dateString = dateFormatter.string(from: date)
return dateString
}
/// Get a date from a string of date format dd MMM yyyy.
/// - Parameter dateString: Date string formated as dd MMM yyyy
/// - Returns: A date object by parsing date in dd MMM yyy format
func getDate(from dateString: String) -> Date? {
// print("Date String: ", dateString)
let dateFormatter = getDateFormatter()
return dateFormatter.date(from: dateString) ?? nil
}
//Ref: https://stackoverflow.com/questions/27182023/getting-the-difference-between-two-dates-months-days-hours-minutes-seconds-in
extension Date {
/// Returns the amount of years from another date
func years(from date: Date) -> Int {
return Calendar.current.dateComponents([.year], from: date, to: self).year ?? 0
}
/// Returns the amount of months from another date
func months(from date: Date) -> Int {
return Calendar.current.dateComponents([.month], from: date, to: self).month ?? 0
}
/// Returns the amount of weeks from another date
func weeks(from date: Date) -> Int {
return Calendar.current.dateComponents([.weekOfMonth], from: date, to: self).weekOfMonth ?? 0
}
/// Returns the amount of days from another date
func days(from date: Date) -> Int {
return Calendar.current.dateComponents([.day], from: date, to: self).day ?? 0
}
/// Returns the amount of hours from another date
func hours(from date: Date) -> Int {
return Calendar.current.dateComponents([.hour], from: date, to: self).hour ?? 0
}
/// Returns the amount of minutes from another date
func minutes(from date: Date) -> Int {
return Calendar.current.dateComponents([.minute], from: date, to: self).minute ?? 0
}
/// Returns the amount of seconds from another date
func seconds(from date: Date) -> Int {
return Calendar.current.dateComponents([.second], from: date, to: self).second ?? 0
}
/// Returns the a custom time interval description from another date
func offset(from date: Date) -> String {
if years(from: date) > 0 { return "\(years(from: date))y" }
if months(from: date) > 0 { return "\(months(from: date))M" }
if weeks(from: date) > 0 { return "\(weeks(from: date))w" }
if days(from: date) > 0 { return "\(days(from: date))d" }
if hours(from: date) > 0 { return "\(hours(from: date))h" }
if minutes(from: date) > 0 { return "\(minutes(from: date))m" }
if seconds(from: date) > 0 { return "\(seconds(from: date))s" }
return ""
}
}
//Ref: https://stackoverflow.com/questions/28404154/swift-get-local-date-and-time
extension Date {
func localDate() -> Date {
let nowUTC = Date()
let timeZoneOffset = Double(TimeZone.current.secondsFromGMT(for: nowUTC))
guard let localDate = Calendar.current.date(byAdding: .second, value: Int(timeZoneOffset), to: nowUTC) else {return Date()}
return localDate
}
}
func getInstalledVersionNumber() -> String? {
guard let infoDictionary = Bundle.main.infoDictionary, let currentVersionNumber = infoDictionary[appVersionNumberKey] as? String else { return nil}
return currentVersionNumber
}