Flutter上架TestFlight排坑流程
准备工作
我们公司的开发者账号不是在开发者手里,所以问题反馈会比较慢.每天都要询问账号持有者,双重验证码,很麻烦,建议先将自己的邮箱加入到开发者对应的团队成员下面,赋予管理者权限,这样你就可以通过你自己的邮箱账号登录,进行上架App一系列操作.双重验证码也是你自己手机获取.
点击下方,进入点➕ 添加即可.
排坑过程
问题出现:
Flutter打包和iOS原生打包是一样的,利用Xcode进行打包,配置发布证书上传AppStore,如下图(这是已经上传好的图)
出现的问题是:打包上传成功后,在iOS构建版本里查看的时候,刚开始有,过一会就自动消失了.出现这种为问题的原因不外乎两种:
- info.plist里的权限不全,或者没有声明对应的字符串 (很大概率)
- 调用了私有的Api (很小概率)
备注:这里出现了一个很奇葩的原因,一般来说构建版本失败都会有苹果发的邮件,但是我连续构建了好几个版本,等待了一天也没有任何邮件.
尝试解决:
第一次尝试:
因为没有邮件,不知道原因,于是尝试盲改.把用到的没用到的权限在info.plist中都加了一遍,结果仍然打包失败.卒.已经第二天了,看了下邮件,还是没有,选择主动出击
https://developer.apple.com/contact/topic/select
通过这个网站,选择App审核里TestFlight,上架问题然后在下午4点半发送邮件询问了为何打包报错 却没有报错邮件的原因.
过了一天,上午10点半,苹果回复了内容如下
意思就是:第三方库里有的地方用到了某些权限,但是我没有声明用途字符串.还是权限问题.并没有回复为什么没有错误邮件的问题.也并没有指出到底缺少哪些权限...所以这个邮件等于回复了个寂寞.😭😭
第二次尝试:
知道了问题是因为三方的库导致的,我就要想法子找出哪些三方导致被拒的.项目中用到了微信SDK,极光SDK,科大讯飞SDK,还有很多三方插件如下👇👇👇
这么多的三方插件我不可能每一个挨个删除打包测试...所以现在需要做的是缩小排查的范围.查了一些资料,看到有人说是一些三方插件和一些三方库调用了私有API导致构建版本失败.于是乎根据教程安装了 iOS-private-api-checker-master 来检测项目中是否有调用了私有API.根据下面的教程配置环境是可以的,亲测有效.(但是这个检测工具是4 5年前的了,太久没更新,不知道好不好使,只能试一下)
https://www.jianshu.com/p/07779e293ca7
打包了一个ipa丢了上去.第一次检测的结果如下👇👇👇
好家伙,这么多地方调用了私有API,检测是检测出来了,但是怎么搜索都是哪些三方库用到了这些私有API呢?网上说的用逆向方法,class-dump来查找,但是真的绕的太远了.我没那样做.我使用了一个命令:
find . -type f | grep -e ".a" -e ".framework" | xargs grep -s
cd到项目的文件夹. 假如我要查找第一条:
find . -type f | grep -e ".a" -e ".framework" | xargs grep -s didBecomeDownloadTask:
结果如下👇👇👇
这就代表这Jcore库里有用到这个私有API.挨个尝试打印.最终得到了
-
JPush
-
Jcore
-
WechatOpenSDK
-
Sentry
-
KTVCocoaHTTPServer
-
KTVHTTPCache
上面的6个库用到了上面检测出来的私有API,于是就开始了注释代码工作,这是一个漫长的过程....把上面的库和相关代码注释移除以后,重新打包,等待奇迹的出现
结果:仍然失败!!!!! 心态有点小崩.... 下班的点了,出去透了下气儿,把脑子放空一下.心里不断想着权限,权限...突然灵机一动!!!!
第三次尝试:
既然是权限问题,那还是要从权限问题找起,上面检测出来的私有API,都是大厂比较成熟的SDK和三方,这种如果有打包上架问题,公司的原生组应该早就遇见到,但是询问后,得知他们集成了这些三方打包时候并没有出现这种问题,所以很大概率并不是上述SDK调用了私有API的问题.还是要回归权限问题.
然后在Flutter项目里搜了权限二字,有一个醒目的三方插件出现在了我的眼前,就是下面这个
👇👇👇
permission_handler : 此插件提供跨平台(iOS、Android)API 来请求权限并检查其状态。
您还可以打开设备的应用程序设置,以便用户授予权限
这是Flutter安卓同事在开发flutter的时候集成的一个三方库,用于授予安卓权限.我尝试着把这个库注释掉,然后打包,果然成功了!!!
既然定位到了问题,剩下的就很简单了.常规思路去 permission_handler 插件的github读相关的README和issues,终于找到了原因:
permission_handler一开始会申请多个权限,如下👇👇👇
每一个都必须写上用途字符串,否则打包就会失败.
同时需要再Podfile文件里填写一些东西,完整的Podfile文件如下:
# Uncomment this line to define a global platform for your project
platform :ios, '11.0'
use_frameworks!
pod 'YYKit'
#pod 'YYModel'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
#config.build_settings['ENABLE_BITCODE'] = 'NO'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.calendar
# 'PERMISSION_EVENTS=1',
## dart: PermissionGroup.reminders
# 'PERMISSION_REMINDERS=1',
## dart: PermissionGroup.contacts
# 'PERMISSION_CONTACTS=1',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=1',
## dart: PermissionGroup.microphone
'PERMISSION_MICROPHONE=1',
## dart: PermissionGroup.speech
'PERMISSION_SPEECH_RECOGNIZER=1',
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=1',
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
# 'PERMISSION_LOCATION=1',
## dart: PermissionGroup.notification
# 'PERMISSION_NOTIFICATIONS=1',
## dart: PermissionGroup.mediaLibrary
# 'PERMISSION_MEDIA_LIBRARY=1',
## dart: PermissionGroup.sensors
# 'PERMISSION_SENSORS=1',
## dart: PermissionGroup.bluetooth
# 'PERMISSION_BLUETOOTH=1',
## dart: PermissionGroup.appTrackingTransparency
# 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',
## dart: PermissionGroup.criticalAlerts
# 'PERMISSION_CRITICAL_ALERTS=1'
]
end
end
end
上述关于permission-handler插件的配置和问题原因如下链接:
原因:
https://github.com/Baseflow/flutter-permission-handler/issues/26
配置方法:
https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler/README.md
构建版本成功,准备提审:
在这里点击加号,把刚才构建成功的版本,放在这里,等待审核就行了,大概需要1-2天时间,剩下的外部测试TestFlight步骤就不赘述了,很多教程,一搜就有.
总结:
这里主要是分享了一些解决问题思路,一开始也走了很多弯路,对于Flutter-iOS上架的问题,要注意的是一些常用的三方库,哪些会对iOS的环境配置造成一些影响,因为上述插件不是我集成的,所以不出这个问题,我是不会知道在集成 permission-handler 插件的时候,还需要进行一些环境配置.这也是一个经验积累的过程.
不过为什么打包,构建版本失败,苹果没有发送邮件,还不清楚原因.