打一个ios包给测试验证
因为是先给的android版本,flutter build apk, 然后给apk包给测试验证。 误以为ios也一样, flutter build ipa, 实际上ipa包不是能直接安装的。
ipa包是什么,为什么它不能像apk一样直接安装
1.iOS 系统实施了严格的封闭策略,所有应用必须通过官方的 App Store 安装
2.但是可以先修改xcode 的 scheme,直接把项目安装到手机上。 xcode/product/scheme/edit scheme debug模式,设备一旦断了数据线,app就不能跑不起来。 但是修改成profile或者release模式就行。
什么是 IPA 包?
IPA(iOS App Store Package)是 iOS 应用程序的安装包格式,类似于 Android 的 APK 文件。IPA 文件是一个压缩包,包含应用的可执行文件、资源文件(如图片、音频等)、配置文件以及其他必要的元数据。
IPA 文件的结构:
- Payload 文件夹:包含应用的
.app文件,这是应用的核心部分。 - Info.plist:描述应用的基本信息,例如应用名称、版本号、Bundle ID 等。
- 签名文件:用于验证应用的真实性和完整性。
为什么 IPA 包不能像 APK 一样直接安装?
1. iOS 的封闭生态系统
- APK 的开放性:Android 是一个开放的平台,允许用户通过多种方式安装应用程序,包括从 Google Play 商店、第三方应用商店或直接下载 APK 文件安装。
- iOS 的封闭性:苹果对 iOS 系统实施了严格的封闭策略,所有应用必须通过官方的 App Store 安装,以确保应用的安全性和质量。
2. 代码签名机制
- 在 iOS 上,每个应用都必须经过苹果的代码签名才能运行。代码签名的作用是验证应用的开发者身份,并确保应用在分发过程中未被篡改。
- 对于普通用户,只有通过 App Store 下载的应用才会自动完成签名和验证过程。
- 如果需要通过其他方式安装 IPA 文件(例如企业分发或测试),必须使用有效的 Apple Developer 账号进行签名。
3. 设备绑定
- 苹果要求开发者将应用与特定设备绑定。对于非 App Store 分发的应用,开发者需要将目标设备的 UDID(唯一设备标识符)添加到开发者账号中,并生成相应的 provisioning profile。
- 这意味着你不能随意将一个 IPA 文件安装到任意设备上,除非该设备已被授权。
4. 安全性和隐私保护
- 苹果希望通过 App Store 的审核机制来确保应用的安全性和合规性,防止恶意软件或不合规的应用进入用户的设备。
- 直接安装 IPA 文件可能会绕过这些安全检查,因此苹果限制了这种行为。
IPA 包的安装方式
尽管 IPA 文件不能像 APK 一样直接安装,但可以通过以下几种方式实现安装:
1. 通过 App Store
- 这是最常见的方式,适用于大多数普通用户。开发者将应用提交到 App Store,用户通过 App Store 下载并安装。
2. 企业分发
- 如果你是企业开发者,可以使用 Apple Enterprise Program 提供的企业证书来分发应用。
- 用户可以通过 Safari 浏览器访问一个特定的链接,下载并安装 IPA 文件。
- 注意:企业证书仅适用于内部员工或合作伙伴使用,不得用于公开分发。
3. TestFlight
- TestFlight 是苹果提供的测试工具,允许开发者邀请测试人员通过 TestFlight 安装应用。
- 开发者需要将测试人员的 Apple ID 添加到 App Store Connect 中,然后发送安装邀请。
4. 手动安装(需越狱或特殊工具)
- 如果设备已越狱,可以通过第三方工具(如 Cydia Impactor)手动安装 IPA 文件。
- 但这通常违反苹果的使用条款,并可能带来安全风险。
archive ipa包并分发到TestFlight供测试人员测试(在隔离机环境下)
此时我就必须通过分发testflight供测试人员测试了,因为隔离机和测试机,都是为该app独有的。我不能把生产的证书和apple developer账号在我的开发电脑上登陆。用于上架的开发者账号是在隔离机上登陆的,所以签名证书都在隔离机上,由于in-app-purchased能力,我自己的开发账号没办法配置这些,也没办法验证。通过隔离机的证书和apple developer账号,分发到test flight才能验证in-app-purchased能力。
可以通过flutter build ipa归档,或者xcode/product/archive归档。
flutter build ipa包,有2种情况。
1.没有build成功,但是拿到了app.archive归档文件。 打开归档文件,调起xcode的distribute app 步骤,接着分发app.archive,xcode会生成ipa包,最后一步选择upload用xcode上传ipa包(xcode有 bug,这一步一般都卡死), 所以我选择export ipa包,然后用transporter工具上传ipa包(必定会成功)
2.build ipa成功后,直接用tansporter上传ipa包
提审前需要生成证书和provising profile文件
1.生成证书
打开mac的钥匙串、请求证书,得到CertificateRequest文件
去apple开发者平台上传CertificateRequest
按用途选择对应的证书类型,因为我是要用来打包分发到testFlight和上传到app store,所以选 apple disitibution。
选择CertificateRequest即可生成证书
2.创建app
设置app的bundleId,选择用到的Capibilities。
注册即可,现在在Identifiers里就能看到自己的app。
3.生成Profile签名文件
这里由于我是为里上架app到app store商店审核,所以选择该类型。如果是为了在开发中使用capabilities,那么就选择ios app development,生成一个测试环境的dev-profile,这样测试环境就能使用capabilities了。
下一步选择对应的app id
选择第一步生成的证书
设置profile文件的名字即可生成
生成证书后可以选择下载到本地
4.Xcode手动配置证书 (折腾了一下午得到的宝贵经验:如果流程无误,但是xcode仍然无法识别,重启电脑)
一般刚在apple开发平台生成的证书,Xcode automatically manager signing自动注册大概率没能及时更新。 所以需要手动导入证书。 填写bundle id 和 import profile,选择刚下载下来的profile即可。
上传证书成功,状态正常,capabilities里会出现profile提供的能力.
下面就是我们在apple 开发者平台为app选择的能力,注意每当在apple更改capabilities都要重新生成profile文件。
有时候开发过程中不需要某些能力,就可以把它删掉,比如push notification能力,可能会导致一些新同事用自己的apple id没法运行项目,就可以删掉。
5.Apple connect提审ipa包
在构建ipa包前,记得把开发过程中临时删掉的capabilities能力加回来再构建。
上传ipa包失败的错误解决
用到的2个平台
Apple 开发者 developer.apple.com/account/res… (配置证书,创建app和bundleid,配置app支持的capabilities,生成provision profile签名文件,添加测试设备) 上传ipa包分为2个环节: delivered 和 processing,大概要20min才会有结果。
Apple Connect appstoreconnect.apple.com/apps/674222… (上架app,分发app到testflight供测试人员测试,编辑app审核信息)
遇到了以下几种失败的情况 1.info.plist文件少了配置,权限配置等。
2.xcode配置的capabilities 和 provising profile的capabilities能力不匹配。
3.bit code问题: 遇到某些库bit code,解决方案找了半天。 blog.csdn.net/wywinstonwy…
-
通过
cd命令进入到HappyDNS.framework的路径。
如果是通过pod install获取的SDK,则进入pods文件夹。 -
执行以下命令检查
framework是否包含bitcode,返回0即为不包含。
otool -l HappyDNS | grep __LLVM | wc -l
- 如果检测结果不是
0,则继续执行以下命令移除HappyDNS.framework的Bitcode。
xcrun bitcode_strip -r HappyDNS -o HappyDNS
————————————————
以in-app-purchased能力为例,我在appple平台上为app配置了in-app-purchased功能,但是在用xcode打包归档的时候,xcode没有选择in-app-purchased。那么上传ipa的时候就会报错,要确保xcode的 capabilities和apple开发者平台上的配置的一致。
等提示变成 app is ready for submission后,
Apple connect就可以看到构建出来的版本。
在apple connect里构建版本,可以查看历史的构建版本。
提审前需要在Apple Connect填写完信息
具体哪些要填写,在这里会有个添加至待审核。 如果信息没填写完,点击添加至待审核,是会提示的。 填写完毕就可以添加至待审核了。
关于In-App-Purchased App支付的坑。
以下是使用in_app_purchase库实现的app内产品购买。 产品购买是拿到ProductDetails productDetail,这一步是直接调用苹果的api,不会出什么问题。 问题是查询app内购买项目productDetail时,会因为apple connect里的一些配置导致查询的为空。
防止查询内购商品为空的注意点:
1.apple 开发者平台app能力配置 in-app-purchased,配置了要重新生成profile,供xcode使用。
2.在Apple Connect里要添加app内可购买的产品
内购商品的状态必须是“准备提交”或“已批准”,不能是“草稿”状态。
3.Apple Connect里商务模块,填写银行账户
4.Apple Connect 用户和访问生成app内购买密钥,供后端使用(不确定是不是生成这个,总之新app要生成一个支付的key给后端)
// 查询商品信息
Future<Map<String, ProductDetails>> getProductDetails(
List<String> ids,
) async {
bool isAvailable = false;
try {
isAvailable = await _inAppPurchase.isAvailable();
} catch (e) {
ToastUtil.showCenterToast('$e');
}
LogUtil.i('不支持app购买');
if (!isAvailable) {
ToastUtil.showCenterToast('Purchase not available');
}
final Set<String> productIds = Set.from(ids);
// ToastUtil.showCenterToast('setIds:$productIds');
final ProductDetailsResponse response =
await _inAppPurchase.queryProductDetails(productIds);
if (response.notFoundIDs.isNotEmpty) {
ToastUtil.showCenterToast('notfoundIds: ${response.notFoundIDs}');
return {};
}
if (response.error != null) {
EasyLoading.showInfo('query error: ${response.error!.message}');
LogUtil.i('查询商品信息失败 ${response.error!.message}');
return {};
}
return {for (var product in response.productDetails) product.id: product};
}
关于验证app内购买的问题
之前由于严格要求不能在我的开发电脑上登陆上架提审用的开发者账号。 所以我Xcode登陆的事自己的apple 账户,它没办法验证支付购买。 我必须去隔离机,在隔离机的xcode登陆公司的提供的apple账户,上架ipa包,然后分发到test flight下载,才能测试。
这一趟下来半个小时就过去了。
公司有一台电脑A是可以用来验证的, 我需要在隔离机生成 ios Development类型的证书,然后生成对应的dev-profile。 把证书和profile弄到电脑A上。 然后项目搞到电脑A上, 就可以跑测试环境验证in-app-purchased了。
噢对,还要在Apple开发者平台注册用来跑测试环境的设备(该设备也是隔离的,不能用平常自己的测试机,而是专门为本app腾出的测试机,即下载testflight里的app的测试机)
设备连接上电脑,查看UUID。
注册了设备后,就能在本设备跑app测试环境,验证app内购买了。