可以从命令行“安装” Xcode .mobileprovision 文件吗?

Posted

技术标签:

【中文标题】可以从命令行“安装” Xcode .mobileprovision 文件吗?【英文标题】:Can an Xcode .mobileprovision file be 'installed' from the command line? 【发布时间】:2012-05-01 13:36:32 【问题描述】:

我正在尝试使用在 Mac Mini Server (OSX 10.7) 上运行的 bash 脚本来自动化为我们的客户构建应用程序的过程。

我的脚本基于来自 github 的非常有用的脚本,最初发布在 https://gist.github.com/949831

我正在使用 xcodebuild 构建应用程序,然后使用 xcrun 签名和嵌入 mobileprovision 文件。

当我使用 mobileprovision 文件执行所有这些操作时,我使用 GUI(例如双击)手动安装到 Xcode 中,它工作正常。如果我只是尝试使用复制到带有 SCP 的服务器上的 mobileprovision 文件,它会失败(代码签名错误:找不到配置文件“123abc123”。)

大概这是因为文件没有“安装”。

有没有办法从终端安装 mobileprovision 文件?我正在使用 SSH,所以使用诸如“打开”命令之类的东西将不起作用。

谢谢!

【问题讨论】:

【参考方案1】:

如果您不想下载外部依赖项(就像 Ben 所做的那样),大多数情况下应该可以使用以下方法:

uuid=`grep UUID -A1 -a adhoc.mobileprovision | grep -io "[-A-F0-9]\36\"`
cp adhoc.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/$uuid.mobileprovision

请注意UUID is composed of hexadecimal digits,因此正确的范围是[-A-F0-9],而不是[-A-Z0-9]

奖励:下载并安装配置文件

使用cupertino tool,以下 sn-p 从 Developer Portal 下载您的所有分发配置文件并安装它们。

ios profiles:download:all --type distribution

for file in *.*provision*; do
    uuid=`grep UUID -A1 -a "$file" | grep -io "[-A-F0-9]\36\"`
    extension="$file##*."
    echo "$file -> $uuid"
    mv -f "$file" ~/Library/MobileDevice/Provisioning\ Profiles/"$uuid.$extension"
done

cupertino(ios 命令)可以使用sudo gem install cupertino 安装。

【讨论】:

当我不得不在托管在另一个州的远程 jenkins 服务器中安装新的配置文件时,这非常有效。 啊..太好了!我不知道你可以 grep 二进制文件。不错。 @BenClayton 如果你在 vim 中打开文件,你会看到它基本上是一个带有二进制页眉和页脚的纯文本 plist。足以导致更少/更多给你“查看二进制文件”警告。 二进制数据是加密签名。引用this blog post:“每个配置文件实际上都是一个 PKCS#7 签名的 plist。PKCS 代表公钥加密标准。PKCS#7 是支持加密消息语法的版本。Apple 使用这些签名的 plist,因此操作系统可以验证正在安装的应用程序来自正确的开发人员,并且 plist 中的内容未被修改。” 不用grep来提取UUID,你可以使用苹果的securityPlistBuddy工具——见this answer——uuid=$(/usr/libexec/PlistBuddy -c "Print UUID" /dev/stdin <<< $(/usr/bin/security cms -D -i adhoc.mobileprovision))【参考方案2】:

自从提出这个问题后,我就自己构建了一个解决方案。秘诀是简单地将文件复制到 ~/Library/MobileDevice/Provisioning Profiles/ 文件夹,但(这里是棘手的一点)重命名为 [The UUID].mobileprovision。

UUID 保存在文件本身的文本部分中(在 plist 中)。不幸的是,该文件还包含二进制文件,因此“默认读取”无法读取它。 幸运的是 this guy 构建了一个小型命令行实用程序来获取 UUID(以及其他一些东西)。

这是我的完整工作脚本:

https://gist.github.com/2568707

【讨论】:

【参考方案3】:

所有其他答案的概要update_provisioning_profile.sh:

#!/bin/sh
#
# Download and install a single iOS provisioning profile
# Requires https://github.com/nomad/cupertino
#
# Usage
# - Login to your account once:
# ios login
# - Configure TEAM and PROFILE (instructions below)
# - Run update_provisioning_profile.sh at anytime, usually after adding/removing devices to the profile

# Configure the team identifier
# Copy it from developer portal or just use cupertino to get it:
# ios devices
# Copy the string in parens and set it as TEAM
TEAM="team id"

# Configure the profile name you want to manage
# Copy it from developer portal or use cupertino to get a list (ignoring Xcode managed profiles):
# ios profiles --team $TEAM | grep -v 'iOS Team Provisioning Profile'
# Copy the name as-is and set as PROFILE
PROFILE="profile name"

# Fetch the profile using `cupertino` tool
# you need to run `ios login` once to setup the account
ios profiles:download "$PROFILE" --team $TEAM
PROFILE_FILE=`echo $PROFILE | tr ' ' '_'` # `cupertino` tool will replace spaces with _
UUID=`/usr/libexec/PlistBuddy -c 'Print :UUID' /dev/stdin <<< $(security cms -D -i $PROFILE_FILE.mobileprovision)`

# copy where Xcode can find it
cp $PROFILE_FILE.mobileprovision "$HOME/Library/MobileDevice/Provisioning Profiles/$UUID.mobileprovision"

# clean
rm $PROFILE_FILE.mobileprovision

易于适应您的配置需求。

【讨论】:

Cupertino 由于最近在 Apple Developer Portal 上的更改而停止工作。一个维护的替代方法是使用 spaceship 与 Apple 的 Developer 后端通信,或使用任何 fastlane 工具,如 match 或 sigh。 github.com/nomad/cupertino【参考方案4】:

我们在 Jenkins 中运行我们的构建并遇到了类似的问题。我们的 Ad Hoc 配置文件经常更改,我们不想在每次更改时都在 xcode 中安装每个构建从站,所以这就是我要做的工作:

/usr/bin/xcrun -sdk iphoneos PackageApplication -v <path to yourapp.app> -o <path to your .ipa file> --sign "<Name of signing identity>" --embed <path to .mobileprovision file>

“”是您在目标的构建设置中的“代码签名”部分下看到的内容。

【讨论】:

这很有趣,谢谢!不幸的是,这种方法对我不起作用,因为我每次都尝试为新客户端自动构建(例如,与您的情况不同,每次构建的“签名身份的名称”都会改变)并且 xcodebuild 找不到他们的配置profile 除非我使用答案中的脚本执行了“安装”步骤。【参考方案5】:

看起来 Apple 在每个键值对下方的 .mobileprovision 配置文件中添加了空行,并且 grep 选项不再起作用。

这里是如何使用 PlistBuddy 和使用 python 脚本的安全性来检索它

command = "/usr/libexec/PlistBuddy -c 'Print :UUID' /dev/stdin <<< $(security cms -D -i abc.mobileprovision)"
uuid = os.popen(command).readline().rstrip('\n')

【讨论】:

我可以确认 Apple 在每个键值对下方添加了一个空行。但由于它不在键和值之间,grepping 仍然适用于我测试过的每个文件。 @nschum,那我可能对 grep 有疑问。但无论如何,如果 Apple 对配置文件格式进行进一步更改,我认为我现在使用的方法比文本搜索更好。 @nschum,我刚刚检查了我正在使用的 grep,它看起来就像你在原始答案中的样子。它对我来说坏了,重命名后配置文件的名称为空。 我刚刚注意到一些配置文件现在有小写 UUID。在那种情况下,这可能是原因。【参考方案6】:

使用 fastlane sigh 安装特定的临时文件,或者您可以创建一个新文件。

fastlane sigh renew --adhoc -n "provisional-profile-name" --app_identifier "app-identifier" -u "user-name" --ignore_profiles_with_different_name

provisional-profile-name 只是配置文件的名称,不包含 .mobileprovision 扩展名。

要创建一个添加了所有设备 UUID 的新临时配置文件,

fastlane sigh --adhoc --app_identifier "app-identifier" -u "username"

快速文件,

lane :build do

sigh(
adhoc: true,
app_identifier: "***APP_ID**",
provisioning_name: "**Profile_name**",
username: "Apple_ID",
force: true,
skip_certificate_verification: true,
)


gym(
#export_options: "exportPlist.plist",
scheme: "**scheme-name**",
export_method: "ad-hoc",
xcargs: "PROVISIONING_PROFILE=$SIGH_UUID",
)
end

【讨论】:

【参考方案7】:

cupertino 最近似乎没有任何进展。 Fastlane 有一个名为 sigh 的工具来管理配置文件(创建、下载、更新、修复):https://github.com/fastlane/fastlane/tree/master/sigh#readme

【讨论】:

以上是关于可以从命令行“安装” Xcode .mobileprovision 文件吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 bash 验证是不是已安装 xcode 命令行工具?

Xcode 8 打包发布流程

如何安装 Xcode 命令行工具

如何在Mac上安装命令行工具?

Xcode 命令行安装到设备

在哪里可以找到从命令行开始的 XCode UI 测试报告