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

时间:2012-05-01 13:36:33

标签: ios bash xcodebuild xcrun

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

我的脚本基于最初发布在https://gist.github.com/949831

的github上非常有用的脚本

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

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

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

有没有办法从终端安装mobileprovision文件?我正在使用SSH,所以使用诸如'open'命令之类的东西是行不通的。

谢谢!

7 个答案:

答案 0 :(得分:69)

如果您不想下载外部依赖项(如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,以下代码段从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一起安装。

答案 1 :(得分:26)

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

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

这是我的完整工作脚本:

https://gist.github.com/2568707

答案 2 :(得分:6)

所有其他答案的汇编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

轻松适应您的配置需求。

答案 3 :(得分:3)

看起来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')

答案 4 :(得分:2)

我们在Jenkins中运行我们的构建并遇到类似的问题。我们的Ad Hoc配置文件经常更改,我们不希望每次更改时都在每个我们的构建从服务器中安装它们,所以这就是我的工作:

/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>

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

public class LocalizationUpdaterActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        private String[] languages = { "Inglese", "Italiano", "Francese" };
        Spinner spinner = (Spinner) findViewById(R.id.spinner1);
        spinner.setPrompt("select language");

        ArrayAdapter<string> adapter = new ArrayAdapter<string>(this,
        android.R.layout.simple_spinner_item, languages);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);

        spinner.setOnItemSelectedListener(new OnItemSelectedListener() {

            public void onItemSelected(AdapterView arg0, View arg1,
                                        int arg2, long arg3) {
                Configuration config = new Configuration();
                switch (arg2) {
                    case 0:
                        config.locale = Locale.ENGLISH;
                        break;
                    case 1:
                        config.locale = Locale.ITALIAN;
                        break;
                    case 2:
                        config.locale = Locale.FRENCH;
                        break;
                    default:
                        config.locale = Locale.ENGLISH;
                        break;
                }
                getResources().updateConfiguration(config, null);
            }

            public void onNothingSelected(AdapterView arg0) {
                // TODO Auto-generated method stub
            }
        });
    }

    public void onClick(View v){
        startActivity(new Intent(getBaseContext(), TextActivity.class));
    }
}
  

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

要创建添加了所有设备UUID的新adhoc配置文件,

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

中fastfile,

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