Application Loader 上传 .ipa 实战:原理、altool 命令与 5 大坑位排查
简介Application Loader是苹果官方提供的独立应用上传工具专门用于将IPA包提交至App Store是开发者在Xcode上传失败、大文件传输缓慢或需严格验证签名时的可靠备选方案。压缩包共1280个文件整体约99.26MB包含Application Loader主程序、altool命令行工具、动态库dylib、界面布局nib、语言本地化strings、Java运行组件jar、大量png/tiff图标资源以及plist配置、证书文件等几乎覆盖工具运行所需的全部组件。工具在上传前会执行代码签名与元数据校验能提前暴露证书配置、Info.plist信息等隐患这类结构也适合开发者离线获取完整环境便于排查因组件缺失导致的上传异常。资源同时带有cacerts安全证书、fontconfig字体配置、readme说明文档等支持性文件可辅助处理证书信任、字符渲染及基础环境问题。已有865人学习下载对正在上架iOS、watchOS或tvOS应用的开发者尤其是需要绕过Xcode提交瓶颈的技术人员具备直接参考价值。1. Application Loader 这个老工具为什么值得每个发布人再学一遍很多人以为 Application Loader 早被 Xcode 淘汰了其实它依然躺在连接 iOS 生态上传链路的最底层。当你遇到 Xcode Organizer 上传卡死、新版 Transporter 下载不动、命令行工具找不到路径时Application Loader 那套以 .ipa 为中心的上传逻辑反而是最快的兜底方案。这篇笔记解决三类人的需求初次接触 .ipa 上传的新手想跑通第一次提审独立开发者想把上传动作写进脚本团队运维想搞清楚各类上传工具之间的边界与坑。我会从它在上传链路中的位置讲起再给你两套可复现的上传路径最后把最典型的五个踩坑场景按现象、原因、解决顺序拆开。操作上它能做的事情非常具体把打包好的 .ipa 文件附加到某个 App 的记录下并通过 ITMSP 传输协议送达 App Store Connect 的服务器同时向开发者返回验证结果。全程不涉及代码编译也不负责签名只是一个纯粹的交付通道。正因为它只做好一件事出问题时反而容易定位。下面按上传链路、操作路径、坑位排查三层来展开你按章节跳过或细读都行。2. Application Loader 在上传链路里的位置三个必懂的概念与选型理由在打开任何上传工具之前先理解 .ipa 从你本地到审核后台之间发生了什么。你看到的“上传”其实包含三个独立动作客户端校验包内容、用开发者凭据换取上传会话、通过 ITMSP 把二进制分块传上去。Application Loader 和后来的 Transporter 都只是这个过程的客户端实现区别在于界面和日志粒度。把链路拆清楚之后工具反而没那么重要因为无论你在哪里点上传背后的协议和检查顺序是一样的。2.1 上传链路从 .ipa 到审核队列要过的四道检查第一道检查是本地校验。Application Loader 会读取你的 .ipa 里的 Info.plist、签名信息、包含的架构确认它不是一个空壳或伪造包。这一步会在你点击 Upload 后立刻发生耗时通常几秒到十几秒和包大小无关。如果 Info.plist 缺少 CFBundleVersion 或 CFBundleShortVersionString工具会直接拒绝继续因为后台需要用这两个字段确定对应哪个版本。如果你在打包时没有用 Xcode 的 Archive 流程而是手动包了一个 zip 改名 .ipa那么这里十有八九会卡住提示包格式无效。第二道是账号验证。你的开发者账号或者 App 专用密码需要能访问对应 App 的记录。这一步会向认证服务器发起请求确认你所选团队有没有权限操作目标 App。如果有多个团队工具会返回一个团队列表让你选选择完后才进入下一步。命令行情况下没有交互式选择界面的 altool 需要你用 --team-id 显式指定团队否则会报 “multiple teams found” 错误。很多新手第一次用 altool 就卡在这因为图形界面会自动弹选择框而命令行不会。第三道是服务端校验。App Store Connect 会检查 Bundle ID、SDK 版本、最低系统版本是否满足当时的上传规范。比如某个架构缺失、携带了不允许使用的隐私 API、图标尺寸不对都会在这一步被拦截。服务端校验的结果通常是一个或一串错误码Application Loader 会把它们显示在传输前的确认框里提示你 “Do you want to continue?”。此时如果忽略提示继续上传后台仍会在处理阶段把包标记为无效。所以我建议你第一次上传时如果看到这个确认框先不要急点头停下来读一遍错误码。第四道是二进制运输。整个传输走 ITMSP 协议过程中断会尝试断点续传但如果超时阈值设置太小会出现“上传 99% 报错”的假象。ITMSP 会把 .ipa 分块每块上去后服务器返回确认客户端再发下一块。你的网络越不稳定重传块数越多最终展示的进度条也就越接近一种模糊估计。传输结束后服务器会返回一个收到的包版本号这个版本号会在 App Store Connect 的活动页出现。如果你没有在活动页看到它说明传输其实没有完成只是客户端假报成功。我一般在遇到团队新成员问“为什么传不上去”时会先问他卡在哪一步因为日志文件里的关键行能区分本地校验失败还是服务端拒绝。Application Loader 的窗口虽然简陋但它会把你输入密码后到底认证成功与否、传输有没有收到服务器响应拆成不同阶段的提示。搞清楚这一点你就知道后续所有工具其实干的是同一件事只是把步骤藏得更深。2.2 Bundle ID、App ID 和 Team ID三个最容易搞混的标识上传失败很大一部分原因是标识填错。Bundle ID 是你的 App 在这个系统内的唯一产品标识形如 com.某公司.某产品它在 Xcode 项目里被设置也写在 .ipa 包内。App ID 是在开发者后台创建的 Bundle ID 与一组能力的组合比如是否开启推送、内购。Team ID 则是你这个开发者账号所属团队的唯一标识一张开发证书和 provisioning profile 都绑定它。上传工具需要你的 Team ID 来判断你是否有权更新某个 App 记录如果你用错了账号或者选错了团队就会在登录之后立刻被拒绝。这三个标识的关系可以这样记Bundle ID 是产品名App ID 是产品容器Team ID 是产品归属者。你在 Xcode 里 Signing 配置中看到的 Team 下拉框选的就是 Team ID 对应的团队名。上传工具读取 .ipa 里的 provisioning profile得出一个 Team ID然后和登录账号所属团队比对。如果账号 A 能访问团队 A但 profile 是团队 B 签的工具就会认为你没有权限上传。独立开发者常因为一家公司下挂多个团队而遇到这个问题尤其是给外包项目签名时最容易发生。实际排错中常见的情况是一个人拥有多个团队登录时弹窗让你选团队你选了 A但包里的 Team ID 和证书是 B 的。Application Loader 对这种错配会显示 “bundle identifier does not match” 或者直接提示无权限。我的习惯是在上传前先确认 .ipa 内的签名信息而不是等到错误码出现再猜。具体做法是把 .ipa 后缀改成 .zip 解压然后对 Payload 里的 App 执行 codesign -dvvv看输出的 TeamIdentifier 和 CDHash。这样能提前判断签名的团队归属也能顺便看出证书是否过期。2.3 认证方式开发者账号密码与 App 专用密码的边界上传工具默认支持账号密码登录但当你开启了双重认证账号密码往往不够用。账号密码会频繁触发验证码验证Application Loader 作为命令行优先的老工具对交互式验证码支持并不好。因此iOS 生态的后台建议为上传这类非交互操作申请 App 专用密码。所谓 App 专用密码就是给某个特定客户端生成的一串独立密码它只对生成时指定的服务有效不能帮你收 iCloud 邮件、也改不了账号设置。这里有两个容易误解的点。第一App 专用密码不是开发者后台的“API Key”或“App Store Connect API 密钥”。API 密钥是为直接调用服务接口准备的另一套凭证与上传工具无关。第二App 专用密码在某个账号被重置或密码修改后会失效需要重新生成如果你发现之前跑得好好的 altool 突然验证失败先去检查专用密码是否被重置。生成专用密码的入口通常在你账号的安全设置里搜索 “App-specific password”选择生成得到一串由字母和短横线组成的密码。命令行工具里账号参数只接受完整邮箱不接受昵称。你可能会看到别人写 altool --username teamexample.com --password xxxx-xxxx-xxxx-xxxx其中账号必须是你的开发者账号邮箱。之前见过有人把开发者后台的 Team ID 当成账号结果一直认证失败。密码复制时也要注意App 专用密码里的短横线是真实字符有的邮件客户端换行后容易漏掉最后一段。我一般生成后直接粘到本地密码文件不回显到终端。2.4 选型理由什么时候该用 Application Loader 而不是 TransporterTransporter 是当前 iOS 生态主推的上传客户端界面更像一个文件投递工具支持拖拽。但 Application Loader 并没有马上消失在一些旧开发环境里它仍然是唯一能用的上传端。更重要的区别是日志粒度Application Loader 把传输过程拆成可见的步骤Transporter 却常常只给一句“已上传”出问题后你得去 Xcode 的存档日志里翻。对于需要自动化脚本的团队Application Loader 自带的 altool 命令行在很长一段时间里是 CI 上的首选后来 Transporter 也有 iTMSTransporter但参数和返回格式有变化。因此了解 Application Loader 的机制等于掌握了上传工具的底层逻辑换到哪个客户端都能快速上手。如果你要在一台没装完整 Xcode 的机器上紧急传包常见做法是找一台装过 Xcode 的机器把 Application Loader.app 目录连同 altool 一起拷过去放到本机对应路径再给可执行权限。这个做法在团队里我经常用来救急。但要注意altool 依赖 Xcode 的 Developer 目录里的框架纯拷一个二进制不一定能跑通所以更稳妥的是借助 Xcode 自带的版本。真正决定选型的是你的网络环境。Application Loader 的 altool 传输时对网络转发配置比较敏感如果系统装了流量拦截工具却没有给 TCP 长连接放行上传会反复中断。Transporter 则对更现代的 TLS 和断点续传做了优化大包上传时更省心。但 Transporter 的图形界面如果长时间没有界面响应也会让人失去耐心。我的建议是机器上两个工具都留着日常用 Transporter遇到问题或想写脚本时切回 altool。千万不要因为新工具界面好看就把旧工具删光你会在某一个上报错误需要看具体步骤时后悔。3. 用 Application Loader 上传 .ipa图形界面与命令行两种可复现路径这一章给两套操作方法。第一套适合手动提审第二套适合想写进脚本的人。两套方法殊途同归但命令行那套我强烈建议你在第一次上传时人工走一遍因为你会看到更完整的返回码。图形界面更适合偶尔传一次的场景而命令行一旦跑通后续就是一条命令的事。3.1 图形界面操作步骤从选中 .ipa 到状态变更为“已上传”首先找到 Application Loader。在旧版 Xcode 里菜单栏的 Xcode Open Developer Tool Application Loader 可以打开它。新版 Xcode 移除了这个入口但如果你在 /Applications/Xcode.app/Contents/Applications/Application Loader.app 下还存在这个包可以直接右键打开。打开后登录你的开发者账号注意选择正确的团队。如果登录时提示需要验证码建议直接切换 App 专用密码方式避免在图形界面里的验证码输入框反复找不到。点击 Next 进入上传页把 .ipa 文件拖拽进窗口或者通过 Choose 按钮选择。紧接着页面下方会列出 App 名称、版本号、Bundle ID 等信息这些是从包体内读出来的你可以核对是否与后台记录一致。这里有一个容易被忽略的操作如果后台里还没有创建该 Bundle ID 对应的 App 记录Application Loader 会提示找不到匹配的 App而不是自动新建。你需要先去 App Store Connect 的后台手动新增一个 App填入完全相同的外部名称和 Bundle ID再回来上传。很多新手卡在这一步误以为是工具坏了。确认后点击 Upload工具会先做本地校验然后进入传输。整个传输没有进度条只有状态文字失败时会给出一个错误码和描述。传输完成后回到 App Store Connect 的后台刷新页面会看到该版本处于“正在处理”或“已上传”状态。如果你在后台同时看到了“正在处理”和“无效二进制”两个状态说明服务端校验未通过需要用 altool 的验证模式重新查具体原因。图形界面适合不常传包的人因为它每一步都有文字提示。但它的缺点是状态信息会滚动你未必能抓到关键一行。我一般会在上传前开启 Mac 的日志收集或直接做屏幕录像以防出错后没看清。更专业一点可以用 Console.app 过滤 Application Loader 进程的输出但它不把日志写到固定文件所以排查时不如命令行直观。3.2 命令行上传altool 的最小可用命令与完整参数说明在终端中altool 的真实路径通常是这样/Applications/Xcode.app/Contents/Developer/usr/bin/altool这个路径在 Xcode 版本更新后基本保持稳定。还有一个历史遗留路径是 Application Loader.app 内部但如果 Xcode 变了那个路径可能不存在。我一般建议在脚本里先做一层路径检测比如用 xcode-select -p 拿到 Developer 目录再拼出 bin/altool这样即使 Xcode 改位置也找得到。最小上传命令如下# 上传前先确认进入 .ipa 所在目录 cd /path/to/ipa # 用 altool 的 upload-app 动作上传密码栏填 App 专用密码 /Applications/Xcode.app/Contents/Developer/usr/bin/altool \ --upload-app \ --file MyApp.ipa \ --username yourexample.com \ --password abcd-efgh-ijkl-mnop这段命令的意思是指定上传 App 动作指定要上传的 .ipa 文件用邮箱账号和 App 专用密码做认证。注意 --password 处填的必须是 App 专用密码而不是账号登录密码。如果你是第一次用 altool建议先加一个 --verbose 参数让日志输出更详细# 加 --verbose 后能看到认证、校验、传输每个阶段的详细响应 /Applications/Xcode.app/Contents/Developer/usr/bin/altool \ --upload-app \ --file MyApp.ipa \ --username yourexample.com \ --password abcd-efgh-ijkl-mnop \ --verbose--verbose 会把每一步请求和响应打印出来包括你当前使用的 Team ID、上传目标 App 的标识、服务端返回的状态码。排查问题时这段输出比图形界面有用得多。你可以看到类似 “Processing finished successfully” 或者 “ERROR ITMS-90000” 这样的信息。ITMS 开头的错误码通常来自服务端规则需要按码去查对应说明。常见的进阶参数还包括 --platform ios有时候 --upload-app 需要配合它来指定平台尤其在包类型不明确时# 指定目标平台防止多平台仓库场景下识别错 /Applications/Xcode.app/Contents/Developer/usr/bin/altool \ --upload-app \ --file MyApp.ipa \ --username yourexample.com \ --password abcd-efgh-ijkl-mnop \ --platform ios如果 App Store Connect 后台同时存在多个 App 记录与不同分发类型altool 会默认上传到与包内 Bundle ID 匹配的 App 记录。如果你想在脚本里解析返回值可以加上 --output-format xml让控制台输出变成机器可读的 XML# 输出 XML 格式便于脚本解析状态码 /Applications/Xcode.app/Contents/Developer/usr/bin/altool \ --upload-app \ --file MyApp.ipa \ --username yourexample.com \ --password abcd-efgh-ijkl-mnop \ --output-format xml \ --verbose这里有一点需要注意altool 的行为在不同版本里有细微差别。早期版本 --platform 的取值是 ios后来可以省略但保留它不会出错。如果遇到 “error: Invalid command line argument” 之类的提示通常是版本兼容问题检查当前 Xcode 的 altool 是否支持该参数。3.3 altool 关键参数速查表从类别到出错时的读法参数作用出错时的典型表现--upload-app触发上传动作不传这个参数时工具会执行其他功能如验证。提示 Missing action--file指定上传的 .ipa 路径支持绝对路径和相对路径。找不到文件--username登录开发者账号的完整邮箱。认证失败提示--password填入 App 专用密码而不是账号密码。密码错误或没有启用双因素--platform声明平台ios / osx 等。包类型不匹配时服务端拒绝--output-format可选 xml / normal影响返回格式。无--verbose输出更详细日志。无--validate-app只做验证不实际上传是上传前最好的自检手段。错误码直接列出这张表是我实际配置脚本时最常关心的几个参数。注意 --validate-app 和 --upload-app 是互斥动作不要同时传。如果你写脚本时把它们都放进去altool 只会认第一个 action 参数。还要注意文件路径里的空格要用引号包住否则 shell 会把路径拆成多个参数。我建议你把上传命令存成一个 shell 函数参数用变量传入。这样每次只改文件路径和版本号不用把整个命令背下来。注意不要把密码直接明文放在命令行里因为进程列表里会显示它。在个人电脑上风险不大在共享 CI 机器上建议用 --password file 方式从文件读取避免密码暴露。后面第 5 章的封装脚本会给你一个可运行模板。4. Application Loader 避坑与排查五个高频问题与解决路径下面这些坑几乎每个用过 altool 的人都会遇到我按现象、原因、解决三部分写并且给出验证是否修复的检查点。不要指望一次看文字就能避开所有问题最佳做法是把这些条目保存在你们团队的发布手册里每次上传报错时对照着看。4.1 坑一新版 Xcode 里找不到 Application Loader 入口现象在 Xcode 的 Open Developer Tool 菜单里已经找不到 Application Loader鼠标双击 /Applications/Xcode.app/Contents/Applications/Application Loader.app 也没有反应或者提示已损坏。原因iOS 生态逐步收紧独立上传工具把功能合并到 Transporter 和 Xcode OrganizerApplication Loader 不再作为默认组件。但旧系统上残留的包仍可能留在原路径当它依赖的框架路径被更新版 Xcode 覆盖后双击就没反应。解决别在菜单里找。检查 /Applications/Xcode.app/Contents/Applications/Application Loader.app 是否存在如果没有则用 altool 代替因为 altool 还随 Xcode 提供。如果连 altool 也没有就在开发者目录里找 iTMSTransporter或者直接装 Transporter。实际上底层逻辑相同不需要执着一个窗口。如果你在旧版 macOS 上还能打开 Application Loader也不建议继续用它做主工具因为服务端接口会随时间调整太老的客户端版本可能无法连接。验证是否修复的方法很简单在终端执行 altool --help如果能输出参数列表说明命令行路径可用就不用纠结窗口了。4.2 坑二上传到 90% 报 A potential error occurred 或网络断连现象传输到一半甚至 99% 时界面直接报错提示网络异常重试仍失败换了一个包再传也一样。原因大 .ipa 上传需要长连接很多网络环境里的转发设置、防火墙会掐断长时间空闲连接。另外上传工具默认超时时间较短如果你的包超过 500MB很容易触发超时。这里的转发设置不一定是用户手动开的很多安全软件或流量审计工具同样会中断长连接。解决先关闭系统网络转发设置和任何流量拦截工具重新尝试。如果还不行调大 altool 的超时时间通过 --timeout 参数例如 1200 秒。也可以把包压缩后再传但要注意 .ipa 本身就是 zip压不掉多少。更常见的是换一个低峰期上传或者改用分块上传的 Transporter。检查点确认日志中没有 “Server connection interrupted” 之类的关键词。同时可以查看 /var/log 里是否有网络断开的系统日志如果有说明是网络层问题不是工具问题。4.3 坑三登录被拒验证码弹窗让命令行工具崩溃现象使用账号密码登录时后台强制要求输入验证码命令行的交互界面根本没法输入或者图形界面频繁弹窗后自动失败。原因你的账号启用了双重认证Application Loader 这类非浏览器客户端不接受该认证方式必须使用 App 专用密码。原因是双因素认证的验证码必须通过受信任设备或受信任浏览器接收而命令行工具无法在其中展示输入框。解决去账号安全页生成 App 专用密码。注意生成后只显示一次复制时不要把空格漏掉。在 altool 中把专用密码填入 --password 参数账号栏仍然写完整邮箱。这样验证码环节会被跳过。如果你还想用常规密码需要临时在一个可交互的浏览器环境里通过验证后再回到工具但这种做法很麻烦不推荐。检查点上传前在本地执行 curl -s -o /dev/null -w %{http_code} https://example.com 看网络连通性如果返回 000说明设备根本连不上服务不要纠结密码。生成专用密码后先用 altool --validate-app 测试一次如果认证通过它会继续校验包内容而不是立刻报密码错误。4.4 坑四上传成功但后台显示图标或版本信息不对现象上传完成后App Store Connect 后台显示的图标、版本号与本地 .ipa 不一致或者出现 “Binary upload failed” 的后置错误。原因Application Loader 只负责把二进制传上去后台在解包时还会检查 IDFA、图标尺寸、最低系统版本等。很多包在 Xcode 里能构建成功是因为构建时没有严格校验所有元数据而上传后台校验更苛刻。比如 Assets.xcassets 里 AppIcon 缺少适配尺寸上传时仍能通过后台处理时才会拒绝。解决上传前先用 altool 的验证模式跑一遍不发送实际上传。命令为# 验证模式只做检查不消耗上传配额 /Applications/Xcode.app/Contents/Developer/usr/bin/altool \ --validate-app \ --file MyApp.ipa \ --username yourexample.com \ --password abcd-efgh-ijkl-mnop \ --verbose验证模式会做与上传同样的检查但只返回错误列表不发送二进制。如果它报出图标尺寸不对去工程 Assets.xcassets 里补齐对应尺寸再重新打包。我习惯把验证命令写进打包脚本的最后一步只有验证通过才允许跑上传。检查点在后台“活动”页签里看到 “Processing” 后等几分钟刷新如果变成 “Invalid Binary”立刻回去看 altool 的验证输出不要反复重新上传同一个包。4.5 坑五用错 IPA 导出方式上传后分不到正确的地方现象上传成功但 App Store 审核版本无法选择某版本或者 TestFlight 里却多了一个构建TestFlight 和 App Store 两个区域混在一起。原因.ipa 的导出方式决定它携带的 entitlements 和签名字段。给 TestFlight 导出的包有时与商店版本在设备支持上不同而且一套包内嵌的分发目标信息让后台把它关联到了错误的分发类型。解决确认打包时在 Xcode 的 Archive 导出窗口里选择的类型是 “App Store Connect”而不是 “Ad Hoc” 或 “Development”。上传前检查包内签名# 查看 .ipa 的签名团队和 profile 信息 unzip -q MyApp.ipa -d /tmp/ipa_extract codesign -dvvv /tmp/ipa_extract/Payload/MyApp.app 21 | grep -E TeamIdentifier|Authority如果看到 TeamIdentifier 与你当前上传账号的团队不匹配就得重新导出。如果匹配再看 profile 的 Entitlements 里是否包含 beta-reports-active 之类的字段。Ad Hoc 导出包会缺少 App Store 发布所需的字段。如果搞混了只能重新导出正确包上传并在后台删除误传的构建。这是血泪教训团队里一定要把导出类型固定成一个配置选项不要每次打包时手动选。5. 进阶把上传变成一条命令、一个 CI 步骤以及与 Transporter 的切换技巧当你跑通一次手动上传后接下来自然想把上传纳入构建脚本。Application Loader 这条路线的精髓在于 altool 的可自动化能力。最后这章给你两个进阶技巧。5.1 把 altool 封装成一条可复用命令将以下内容保存为 upload.sh修改四个变量即可#!/bin/bash # 用法./upload.sh [ipa路径] IPA_PATH${1:-./build/MyApp.ipa} USERNAMEyourexample.com PASSWORD$(cat ./app_specific_password.txt) TEAM_IDABCDE12345 /Applications/Xcode.app/Contents/Developer/usr/bin/altool \ --upload-app \ --file $IPA_PATH \ --username $USERNAME \ --password $PASSWORD \ --team-id $TEAM_ID \ --output-format xml \ --verbose这里用 --team-id 显式指定团队避免多团队账号时选错。密码从文件读取可以防止密码出现在 shell 历史和进程参数里。cat 命令读取文件但注意文件权限要设成 600防止被同机其他用户读走。脚本里第一个参数是 .ipa 路径留空时使用默认值。运行前先 chmod x upload.sh然后 ./upload.sh ./build/MyApp.ipa。脚本返回后用 echo $? 看输出结果0 表示成功非 0 时查看日志。altool 出错时通常会在 stderr 打印一个错误码比如 1009 是认证失败2001 是网络连接失败具体可以对照你拿到的输出排查。5.2 从 Application Loader 过渡到 Transporter日志思维不变如果你在最新环境里已经没法打开 Application Loader那么上传工作交给 Transporter。Transporter 的图形界面拖入 .ipa 后会先显示校验结果再开始上传这一点比 Application Loader 更友好。但在命令行自动化上Transporter 提供的是 iTMSTransporter 工具参数风格更接近 ITMSP和 altool 完全不是一套。迁移时只需要把脚本的逻辑骨架保留下来校验文件、认证、上传、解析返回码换掉调用命令和参数名即可。如果不想换工具还有一个习惯值得保持上传前永远先跑验证模式再看 App Store Connect 后台的“活动”页签确认构建状态。这能省掉大量因为急上传导致的返工。我自己的习惯是无论换什么工具都会保留一个不传只验证的脚本每次打包后先验证验证过了再上传。这个习惯救了我很多次尤其在上传时间紧张的时候避免把一个签错名的包发到对方后台。希望帮到你。本文还有配套的精品资源点击获取