无需付费 Apple Developer Program,如何侧载 Swift app?
结论
使用免费 Apple ID 和 Xcode Personal Team 时,开发签名只有 7 天有效期。修改证书、描述文件或系统时间,都无法合法延长这个期限。
脚本、AltStore 等工具可以定期重新签名,相当于反复刷新这 7 天,并不能生成长期有效的免费签名。设备、Mac 或签名服务没有按时工作,都可能导致 app 暂时无法启动。
如果需要更稳定、接近 “set and forget” 的使用方式,Apple 官方体系内较省心的选择是加入 Apple Developer Program。付费开发签名也要定期续期,维护周期比 7 天长得多,但并非永久有效。
免费签名为什么只有 7 天
Xcode 通过免费 Apple ID 创建的是 Personal Team 开发签名,主要用于开发和真机调试,存在以下限制:
- provisioning profile 的有效期为 7 天。
- 到期后,设备上已安装的 app 通常无法继续启动。
- app 需要重新构建或签名,再次安装到设备。
- Personal Team 无法使用某些 entitlement 和服务。
- Apple Configurator、备份恢复和直接复制
.ipa都无法绕过签名有效期。
这些限制同样适用于只安装在个人 iPad 上的 app。修改设备日期,或者使用来源不明的企业证书、共享证书,可靠性都很差,还可能造成证书被撤销、账号泄露或数据泄露。
方案一:继续使用 Xcode,每周刷新
可以保留现有工作流,在签名到期前重新运行项目:
- 在 Xcode 的
Signing & Capabilities中启用Automatically manage signing。 - 在
Team中选择自己的 Personal Team。 - 使用 USB 连接 iPad,或者在 Xcode 中启用无线设备连接。
- 确认 iPad 已信任这台 Mac,并按系统要求打开 Developer Mode。
- 至少每 7 天运行一次项目。
如果 bundle identifier 没有变化,也没有事先删除 app,覆盖安装通常可以保留沙盒数据。重要数据仍要单独备份,重新安装不能代替数据备份。
方案二:用命令行自动构建和安装
在 Xcode 中完成账号登录、设备配对和自动签名设置后,可以使用 xcodebuild 构建,再通过 devicectl 安装。
以下示例适用于较新的 Xcode。请将项目名、scheme、Team ID、设备 UDID 和 app 名称替换为自己的值:
#!/bin/zsh
set -euo pipefail
PROJECT_PATH="/path/to/MyApp.xcodeproj"
SCHEME_NAME="MyApp"
TEAM_ID="ABCDE12345"
DEVICE_UDID="00000000-0000000000000000"
DERIVED_DATA="/tmp/MyAppDerivedData"
APP_PATH="$DERIVED_DATA/Build/Products/Debug-iphoneos/MyApp.app"
xcodebuild \
-project "$PROJECT_PATH" \
-scheme "$SCHEME_NAME" \
-configuration Debug \
-destination "platform=iOS,id=$DEVICE_UDID" \
-derivedDataPath "$DERIVED_DATA" \
-allowProvisioningUpdates \
DEVELOPMENT_TEAM="$TEAM_ID" \
CODE_SIGN_STYLE=Automatic \
build
xcrun devicectl device install app \
--device "$DEVICE_UDID" \
"$APP_PATH"
Team ID 可以在 Xcode 的账号或项目签名设置中查看。设备 UDID 可以从 Xcode 的设备窗口获取,也可以尝试运行:
xcrun devicectl list devices
devicectl 的命令形式可能随 Xcode 版本变化。如果当前版本不支持示例中的参数,请查看该版本的帮助信息:
xcrun devicectl device install app --help
还可以让 macOS 的 launchd 每隔几天执行一次脚本。假设脚本保存在 /Users/yourname/bin/refresh-myapp.sh,先赋予它执行权限:
chmod +x /Users/yourname/bin/refresh-myapp.sh
对应的 LaunchAgent 可以这样配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"https://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.myapp.refresh</string>
<key>ProgramArguments</key>
<array>
<string>/Users/yourname/bin/refresh-myapp.sh</string>
</array>
<key>StartInterval</key>
<integer>345600</integer>
<key>StandardOutPath</key>
<string>/tmp/myapp-refresh.log</string>
<key>StandardErrorPath</key>
<string>/tmp/myapp-refresh-error.log</string>
</dict>
</plist>
345600 秒等于 4 天,可以为失败重试留出一些时间。将配置保存为:
~/Library/LaunchAgents/local.myapp.refresh.plist
然后加载:
launchctl bootstrap \
"gui/$(id -u)" \
"$HOME/Library/LaunchAgents/local.myapp.refresh.plist"
自动刷新依赖一些运行条件:Mac 需要开机,iPad 必须可以访问,设备配对和 Xcode 账号凭据也要保持有效。安装时是否需要解锁设备,取决于系统版本、配对状态和安全设置,所以这套流程无法保证完全无人值守。
不要把 Apple ID 密码直接写入脚本或 plist。
方案三:使用 AltStore 或 SideStore 定期刷新
第三方侧载工具通常也使用个人 Apple ID 为 app 签名,因此同样受 7 天有效期限制。
AltStore 通常按以下方式工作:
- Mac 或 PC 上运行 AltServer。
- iPad 与电脑处在可以互相通信的网络环境中。
- AltStore 在签名到期前尝试刷新已安装的 app。
SideStore 等方案可以减少对电脑常驻运行的依赖,但可能需要 pairing file、特定网络配置或本地 VPN。系统升级、配对状态变化和工具更新都有可能影响刷新。
这类工具可以减少手动操作,但不属于 Apple 官方的 Xcode 开发工作流。使用前需要了解项目来源和维护状态,并确认工具如何处理 Apple ID 凭据。可以单独准备一个 Apple ID 并启用双重认证,避免将主账号密码交给无法审计的软件。
哪种方案最合适
如果可以接受偶尔维护,并且希望完全免费,可以每周通过 Xcode 运行一次项目,也可以使用本地脚本或可信的刷新工具,在 7 天期限内自动重新签名。
对于必须随时可用的 app,或者可能长期离开开发用 Mac 的设备,免费签名不适合长期部署。更稳定的官方方案是加入 Apple Developer Program,再通过 Xcode 自动签名并安装到已注册的设备。会员资格和 provisioning profile 仍有到期时间,通常按年处理。
TestFlight 也无法用于永久部署。它需要付费开发者账号,每个测试构建都有有效期,不适合需要长期无人维护的个人 app。
实际建议
普通个人工具可以继续使用 Personal Team,将自动刷新周期设为 4 到 5 天,并保留失败日志。即使某次自动刷新没有成功,也还有时间手动处理。
如果 app 用于健康记录、家庭控制、工作凭据或其他不能中断的场景,建议使用付费开发者账号。免费方案能节省费用,但 7 天签名期限造成的可用性风险依然存在。
备注:内容仅供参考。
