参照上一篇文章:创建一个Flutter与iOS原生交互插件创建FlutterLauncher
Flugin
- 定义
FlutterLauncher
的channel
static const MethodChannel _channel = const MethodChannel('flutter_launcher');
目前iOS支持三种App Store评分方式
1.通过App打开网页,跳转到AppStore编辑评论,可评分,可评论。
- 优点:方便,快捷,不受系统版本限制,目前最常用的方式。
- 缺点:内部网页形式加载缓慢,等待时间长,加载失败概率大。
实现: - Flutter部分
FlutterLauncher
层,虽然我们这里只介绍iOS实现,但是最好留好安卓的坑,以便协作。writeReview
如果传false,支持仅评分,不评价。
static void launch({String androidAppId, String iOSAppId, bool writeReview = true}) async {
await _channel.invokeMethod(
'launch', {'android_id': androidAppId, 'ios_id': iOSAppId, 'write_review': writeReview});
-
main.dart
调用
FlutterLauncher.launch(
androidAppId: "com.xxxx.com",
iOSAppId: "585027354",
writeReview: true);
-
iOS
原生:在FlutterLauncherPlugin.h
的代理方法里接收method,并实现相应逻辑。
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result;
if ([@"launch" isEqualToString:call.method]) {
NSString *appId = call.arguments[@"ios_id"];
if (appId == (NSString *)[NSNull null]) {
result([FlutterError errorWithCode:@"ERROR"
message:@"App id cannot be null"
details:nil]);
} else if ([appId length] == 0) {
result([FlutterError errorWithCode:@"ERROR"
message:@"Empty app id"
details:nil]);
} else {
NSString *iTunesLink;
if ([call.arguments[@"write_review"] boolValue]) {
iTunesLink = [NSString stringWithFormat:@"itms-apps://itunes.apple.com/app/id%@?action=write-review", appId];
} else {
iTunesLink = [NSString stringWithFormat:@"itms-apps://itunes.apple.com/app/id%@", appId];
}
NSURL* itunesURL = [NSURL URLWithString:iTunesLink];
if ([[UIApplication sharedApplication] canOpenURL:itunesURL]) {
[[UIApplication sharedApplication] openURL:itunesURL];
}
result(nil);
}
}
-
效果:
2. iOS 6.0以后 在App内部加载AppStore 展示App信息
- 优点:展示速度较快,无需跳转App Store,避免用户流失
- 缺点:不能直接跳到编辑页,需要手动滑动到编辑入口
⚠️调用网页App Store可能加载速度慢
实现:
- Flutter部分
FlutterLauncher
层
static void inAppPresentStore({String androidAppId, String iOSAppId}) async {
_channel.invokeMethod(
'inAppPresentStore', {'android_id': androidAppId, 'ios_id': iOSAppId});
}
-
main.dart
调用
FlutterLauncher.inAppPresentStore(androidAppId:"com.xxxx.com",iOSAppId: "585027354" );
-
iOS
原生:跟方法1一样,也在handleMethodCall
代理方法里接收,
⚠️:这里要设置SKStoreProductViewController
的代理,实现代理方法。
if ([@"inAppPresentStore" isEqualToString:call.method]){
NSString *appId = call.arguments[@"ios_id"];
__weak UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController ;
SKStoreProductViewController *storeProductViewController = [[SKStoreProductViewController alloc] init];
[storeProductViewController setDelegate:self];
[storeProductViewController loadProductWithParameters:@{SKStoreProductParameterITunesItemIdentifier : appId}
completionBlock:^(BOOL result, NSError *error) {
if (error) {
NSLog(@"Error %@ with User Info %@.", error, [error userInfo]);
} else {
[rootVC presentViewController:storeProductViewController animated:YES completion:nil];
}
}];
}
- 设置代理:
@interface FlutterLauncherPlugin ()<SKStoreProductViewControllerDelegate>
@end
- 实现
#pragma mark - SKStoreProductViewControllerDelegate
- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_6_0)
{
__weak UIViewController *rootVC = [UIApplication sharedApplication].keyWindow.rootViewController ;
[rootVC dismissViewControllerAnimated:YES completion:nil];
}
@end
-
效果:
3. iOS 10.3以后可以在APP应用内评分,调用系统接口,不需要跳转
- 优点:无须跳转,应用内系统弹框
- 缺点:只能评分,一年只能使用三次弹框
实现:
- Flutter部分
FlutterLauncher
层
static void inAppLaunch() async {
await _channel.invokeMethod(
'inAppLaunch', {});
}
-
main.dart
调用
FlutterLauncher.inAppLaunch();
-
iOS
原生:跟方法1一样,也在handleMethodCall
代理方法里接收
if ([@"inAppLaunch" isEqualToString:call.method]){
if (@available(iOS 10.3, *)) {
[SKStoreReviewController requestReview];
} else {
// Fallback on earlier versions
}
}
-
效果:
that's all~