使用可配置的包标识符构建和签署iOS应用程序以支持多个构建配置的问题

时间:2013-11-08 04:26:53

标签: ios build jenkins codesign bundle-identifier

我正在尝试构建我的应用程序的多个并发构建(一个用于模拟环境,一个用于开发环境,一个用于测试环境,一个用于生产发布)。

我已经做了很多工作,但我遇到了使用自动生成的捆绑标识符(一个运行变量)的应用程序的代码签名问题。

我已经完成了什么

我正在使用xhode 4.6.3使用adhoc配置文件。

为了尝试让它工作,我在info plist文件中设置我的包标识符以稍微运行一个变量 - 所以可以用不同的方式对应用程序进行签名。 例如。我的实际包标识符是:

  • UXXXXXX.au.com.blah.MOCK
  • UXXXXXX.au.com.blah.DEV
  • UXXXXXX.au.com.blah.TEST
  • UXXXXXX.au.com.blah.PROD

因此,我的信息plist中的我的包标识符已配置为" UXXXXXX.au.com.blah。$ {BUNDLE_SUFFIX}"

现在允许我为每个版本构建不同的应用程序,我做了以下内容:

  • 我有4个不同的捆绑标识符,其中4个不同的配置文件分配给这些捆绑标识符
  • 首先,我添加了一个名为" MOCK"的新配置。 (我将在后面添加其他内容)
  • 然后在项目构建设置下,我在项目中添加了一个BUNDLE_SUFFIX用户定义变量,并将其设置为MOCK以进行MOCK配置(稍后我会添加其他的)。这用于为使用MOCK配置的构建设置包标识符。
  • 然后在项目构建设置下,为构建设置中的MOCK配置选择了我的MOCK配置文件
  • 我注意到如果我转到我的应用目标的摘要视图,它会将包ID显示为UXXXXXX.au.com.blah.MOCK,其中包含' MOCK'部分是灰色字体 - 所以它已经拾取了包后缀变量
  • 然后我创建了一个名为MOCK的新方案,将MOCK配置用于' Profile'和'存档'。我保留了其余的默认值(使用DEBUG)。

所以现在我可以运行xcodebuild并使用方案MOCK来执行特定于MOCK的构建,该构建将使用MOCK配置将包标识符设置为.MOCK并将我的provisoning配置文件设置为使用_MOCK配置文件。

然后我运行一个jenkins构建,它执行xcodebuild和xcrun(将调用codesign)。

这是我的xcodebuild命令:

/usr/bin/xcodebuild -scheme MOCK -sdk iphoneos -project MyApp.xcodeproj -configuration MOCK clean build "CONFIGURATION_BUILD_DIR=/Users/CI/Documents/workspace/build3" ONLY_ACTIVE_ARCH=NO DEPLOY_ENVIRONMENT=MOCK "CODE_SIGN_IDENTITY=iPhone Distribution: My Company" "PROVISIONING_PROFILE=XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

这是我的xcrun命令:

/usr/bin/xcrun -sdk iphoneos PackageApplication -v "/Users/Shared/Jenkins/Home/jobs/MyApp.app" -o "/Users/Shared/Jenkins/Home/jobs/MyApp/workspace/build/MyApp-0.9.5.0.ipa" --embed "/Users/Shared/Jenkins/Home/Library/MobileDevice/Provisioning Profiles/20130816_Distribution_MOCK.mobileprovision" --sign "iPhone Distribution: My Company"

注意:我使用MOCK配置文件专门为应用程序签名,因为我发现我无法使用。*配置文件对应用程序进行签名,因为该应用程序使用推送通知,如果我使用。*构建应用程序,然后使用正确的配置文件重新签名应用程序,我的embedded.mobileprovision配置文件会更新,但.app文件中的实际可执行文件永远不会更新。这会导致推送通知永远不会到达设备。所以我需要工作的是能够从命令行构建和签署应用程序,其中应用程序具有使用变量动态填充的包ID。而且我似乎无法使其发挥作用。

结果

xcodebuild成功运行并且运行正常。该应用程序似乎构建并正确签名为.MOCK并使用_MOCK配置文件!

BUT!生成IPA文件有一个问题,我有一个codeign问题。

请注意,我构建的应用程序没有任何代码签名权利。 codesign给了我这个错误: 警告:应用程序失败编码验证。签名无效,包含不允许的权利,或者未使用iPhone分发证书签名。 (-19011) 可执行= /用户/ CI /文档/工作区/ build3中/ MyApp.app / MyApp的 codesign_wrapper-4.1:使用Apple CA进行配置文件评估 非法授权键/值对:application-identifier, UXXXXXX.au.com.blah。 AssertMacros:filter_entitlements(entitlements_whitelist,entitlements_requested,allowable_entitlements),file:codesign_wrapper.c,line:932   - (null

请注意,它尚未获取bundle_suffix。此外,当我查看编码引用的MyApp.xcent文件时,我注意到它中有 UXXXXXX.au.com.blah。。它没有获得bundle_suffix的值!

那么,我尝试的是为我的MOCK构建配置创建一个entitlements.plist文件,并在“代码签名权利”下添加一个指向该文件的链接。用于构建设置下的MOCK配置。但现在我得到了一个不同的错误,而且相当令人不安:

/usr/bin/codesign --force --sign 5XXXXXXXXXXXXXXXXXXX2c --resource-rules=/Users/CI/Documents/workspace/build3/MyApp.app/ResourceRules.plist --entitlements /Users/CI/Library/Developer/Xcode/DerivedData/MyApp-fasiktlyysoxjpgalujkfjpyiyeo/Build/Intermediates/MyApp.build/MOCK-iphoneos/MyApp.build/MyApp.xcent /Users/CI/Documents/workspace/build3/MyApp.app

验证/Users/CI/Documents/workspace/build3/MyApp.app     cd / Users / Shared / Jenkins / Home / jobs / MyApp-MOCK-HourlyBuilds / workspace     setenv PATH" /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/ usr / bin:/仓:/ usr / sbin目录:/ sbin目录:在/ usr / local / bin中:在/ usr /本地/ GIT中/ bin中"     setenv PRODUCT_TYPE com.apple.product-type.application     /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/Validation /Users/CI/Documents/workspace/build3/MyApp.app 警告:此捆绑包无效。应用程序标识符权利格式不正确;它应包含您的10个字符的App ID Seed,后跟一个点,后跟您的包标识符:UXXXXXXXX.au.com.amp.blah.MOCK(-19054) 无法验证您的申请。 - (null)

这次实际上已经拿到了合适的捆绑标识符!!它说MOCK它。但它抱怨这个捆绑无效......但它看起来对我来说完全有效!!为什么不起作用?

这是我手动创建并添加到项目中的entitlements.plist文件(以及'代码签名权利中的引用'):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>application-identifier</key>
    <string>UXXXXXXXXXXX.au.com.amp.blah.MOCK</string>
    <key>aps-environment</key>
    <string>production</string>
    <key>get-task-allow</key>
    <false/>
    <key>keychain-access-groups</key>
    <array>
            <string>UXXXXXXXXXXX.au.com.amp.blah.MOCK</string>
    </array>
</dict>
</plist>

非常感谢任何帮助,非常感谢!

P.S。我知道解决这个问题的方法是为我的每个构建创建一个不同的Target。但我真的不想要这个,因为这是一个痛苦维持多个目标。如果可以的话,我真的想尝试在没有多个目标的情况下侥幸逃脱。

P.S.S。我知道另一种解决此问题的方法是首先使用。*配置文件签署应用程序,然后使用正确的配置文件重新签名应用程序,但这对我不起作用。由于.app中的可执行文件仍然保留对。*配置文件的引用。因此,此设备永远无法获取推送通知。我得到了“无效的&#39; aps-environment&#39;为应用程序找到的权利字符串“错误。

1 个答案:

答案 0 :(得分:0)

我正在通过Jenkins为我的iOS版本运行类似的设置,目标是允许并行安装应用程序(生产,登台,qa,dev)并遇到与您相同的问题。

最后,我偶然发现this answer并将其修改为包含.xcent文件,该文件是--entitlements标志的xcodebuild(检查路径的构建输出)的一部分。这意味着您不必手动创建权利文件,但可以使用xcodebuild为您生成的确切文件。

我也使用xcrun PackageApplication,但这不支持权利,因此使用此工具重新签名将失去权利。

因此,在运行xcodebuild之后,我使用plistbuddy来修改我的info.plist文件以更新设置包等(这可能不是您需要的)并且我解压缩ipa,将配置文件和info.plist复制到解包有效载荷,重新签名并重新包装:

pushd ${SCRIPT_DIR}
unzip "${PROJECT_NAME}.${CURRENT_ENV_NAME}.ipa"
rm -r "Payload/${PROJECT_NAME}.app/_CodeSignature" "Payload/${PROJECT_NAME}.app/CodeResources" 2> /dev/null | true
cp "${PROFILE}" "Payload/${PROJECT_NAME}.app/embedded.mobileprovision"
cp "${BUILD_DIR}/${BUILD_TARGET}-iphoneos/${PROJECT_NAME}.app/Info.plist" "Payload/Yappem.app/Info.plist"
/usr/bin/codesign -f -s "${CODE_SIGN_IDENTITY}" --resource-rules "Payload/${PROJECT_NAME}.app/ResourceRules.plist" --entitlements "${XCENT_FILE}" "Payload/${PROJECT_NAME}.app"
if [ $? != 0 ]; then
  echo Error Signing Project
  exit 1
fi
rm "${PROJECT_NAME}.${CURRENT_ENV_NAME}.ipa"
zip -qr "${PROJECT_NAME}.${CURRENT_ENV_NAME}.ipa" Payload
popd