Xcode 11 提交审核的方式
本文前面是完全参考Xcode11找不到Application Loader解决方式
,只有后半段是本人的的内容,只为记录和对原作者文章的一些补充。
概述
Xcode 11 Release Notes
从Xcode 11开始,Application Loader不再集成在Xcode中。开发者可以在组织窗口或者使用xcodebuild和xcrun altool命令上传应用.
Xcode supports uploading apps from the Organizer window or from the command line with xcodebuild or xcrun altool. Application Loader
is no longer included with Xcode. (29008875)
使用旧版 Application Loader
如果是觉得使用命令行的方式麻烦,也可以复制旧版Application Loader到Xcode对应路径下,重启Xcode即可使用。
../Applications/Xcode.app/Contents/Applications/
这个是Xcode10.3下的
链接:https://pan.baidu.com/s/1BZVkXhZW83zF_jCCRlu53A 密码:y6ib
使用 xcrun altool
Xcode11以下的命令是这样的:
Copyright (c) 2009-2019, Apple Inc. Version 4.00.1181
Usage: altool --validate-app -f -t -u {[-p ] | --apiKey --apiIssuer }
altool --upload-app -f -t -u {[-p ] | --apiKey --apiIssuer }
altool --notarize-app -f --primary-bundle-id -u {[-p ] | --apiKey --apiIssuer } [--asc-provider ]
altool --notarization-info -u {[-p ] | --apiKey --apiIssuer }
altool --notarization-history -u {[-p ] | --apiKey --apiIssuer } [--asc-provider ]
altool --list-apps -u {[-p ] | --apiKey --apiIssuer }
altool --store-password-in-keychain-item -u -p
Authentication: Most commands require authorization.
There are two methods available: user name with password, and apiKey with apiIssuer.
-u, --username Username. Required to connect for validation, upload, and notarization.
-p, --password Password. Required if username specified and apiKey/apiIssuer are not.
If this argument is not supplied on the command line, it will be read from stdin.
Alternatively to entering in plaintext, it may also be specified using a '@keychain:'
or '@env:' prefix followed by a keychain password item name or environment variable name.
Example: '-p @keychain:' uses the password stored in the keychain password item named .
You can create and update keychain items with the
--store-password-in-keychain-item command.
Example: '-p @env:' uses the value in the environment variable named
--apiKey apiKey. Required for JWT authentication while using validation, upload, and notarization.
This option will search the following directories in sequence for a private key file
with the name of 'AuthKey_.p8': './private_keys', '~/private_keys', '~/.private_keys',
and '~/.appstoreconnect/private_keys'.
--apiIssuer Issuer ID. Required if --apiKey is specified.
-f, --file specifies the path to the file to process.
-t, --type {osx | ios | appletvos} Specify the platform of the file.
--primary-bundle-id Used with --notarize-app to uniquely identify a package.
--asc-provider Required with --notarize-app and --notarization-history when a user account is associated with multiple
providers.
-v, --validate-app Validates an app archive for the App Store. Authentication and -f are required.
--upload-app Uploads the given app archive to the App Store. Authentication and -f are required.
--list-apps Display all apps associated with your account(s).
--notarize-app Uploads the given app package, dmg or zip file for notarization. Authentication, -f,
and --primary-bundle-id are required. --asc-provider is required for an account associated with multiple providers.
If successful, the UUID associated with the upload is returned.
--notarization-info Returns the status and log file URL of a package previously uploaded for notarization with the specified .
Authentication is required. The log file can be retrieved with 'curl '.
--notarization-history Returns a list of all uploads submitted for notarization. specifies a range of entries where 0
returns the most recent number of entries. A new page value will be returned which can be used as the
value to the next use of --notarization-history and so forth until no more items are returned.
Authentication is required. --asc-provider is required for an account associated with multiple providers.
--store-password-in-keychain-item -u -p
Stores the password in the keychain item named associated with the account .
If an item with that name and account already exists in the keychain, its password will be updated. Otherwise a new item
is created with that name. You can use this keychain item with the -p option to mask your password with other commands.
Example: altool --store-password-in-keychain-item MY_SECRET -u [email protected] -p "MyP@ssw0rd!@78"
altool --notarize-app -u [email protected] -p @keychain:MY_SECRET [...]
--output-format {xml | normal} Specifies how the output is formatted. 'xml' displays the output in a structured format; 'normal' displays in
an unstructured format (default).
--verbose Enable logging output.
-h, --help Display this output.
账号密码的方式上传包体,如下:
- 先验证
xcrun altool --validate-app -f 包体绝对路径.ipa -t ios -u 用户名 -p 密码
- 再上传
xcrun altool --upload-app -f 包体绝对路径.ipa -t ios -u 用户名 -p 密码
如果出错:
*** Error: Unable to validate archive '/Users/jingyin/Desktop/***.ipa':
( "Error Domain=ITunesSoftwareServiceErrorDomain Code=-22020 "We are unable to create an authentication session."
UserInfo={NSLocalizedDescription=We are unable to create an authentication session.,
NSLocalizedFailureReason=Unable to validate your application.}"
有可能是密码需要使用动态密码。而不是原来账号的密码。需要先登录账号,获取到动态密码,再用在此处。Apple官方动态密码配置
使用apiKey和apiIssuer的方式上传包体,如下:
Creating API Keys for App Store Connect API
--apiKey apiKey. Required for JWT authentication while using validation, upload, and notarization.
This option will search the following directories in sequence for a private key file
with the name of 'AuthKey_.p8': './private_keys', '~/private_keys', '~/.private_keys',
and '~/.appstoreconnect/private_keys'.
--apiIssuer Issuer ID. Required if --apiKey is specified.
- 获取apiKey和apiIssuer
登录iTunesconnect,选择“用户和访问”,点击“密钥”,然后添加密钥即可。
- 保存apiKey的私钥文件
生成密钥的私钥文件需要以'AuthKey_
如果找不到可自行创建。
- 先验证
xcrun altool --validate-app -f 包体绝对路径.ipa -t ios --apiKey 密钥 ID --apiIssuer Issuer ID
- 再上传
xcrun altool --upload-app -f 包体绝对路径.ipa -t ios --apiKey 密钥 ID --apiIssuer Issuer ID
如果验证成功:
No errors validating archive at '/Users/xxxx/Desktop/***.ipa'
上传成功:
No errors uploading '/Users/xxxx/Desktop/***.ipa'
我的选择
最终我选择了以apiKey和apiIssuer验证的方式上传包。仅仅个人觉得比较方便。
为了以后每次上传不需要复制粘粘命令行了和修改命令。我简易地写了一个Python3的脚本去实现。只需要在命令行执行:
Python3 ios_upload.py 绝对路径.ipa
代码如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import subprocess
apiKey = '379PUR452B'
apiIssuer = '69a6de88-628b-47e3-e053-5b8c7c11a4d1'
if __name__ == '__main__':
count = sys.argv.__len__()
if count > 1:
path = sys.argv[1]
cmd = 'xcrun altool --validate-app -f {} -t ios --apiKey {} --apiIssuer {} --verbose'.format(path, apiKey, apiIssuer)
print(cmd)
s = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
print(s.stdout.read().decode('utf-8'))
s.wait()
cmd = 'xcrun altool --upload-app -f {} -t ios --apiKey {} --apiIssuer {} --verbose'.format(path, apiKey, apiIssuer)
print(cmd)
s = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
print(s.stdout.read().decode('utf-8'))
s.wait()
else:
print('please input ipa absolute path')
个人感想
不知道是不是错觉,个人感觉通过xcrun altool命令上传比Application Loader要快。不过缺点是没有Application Loader那么直观查看错误信息。