通常,当向App Store提交iOS应用程序时,我做产品 – >从 Xcode存档,然后选择分发到App Store.我可以通过以下方式成功归档一个构建:
xcodebuild -scheme "myScheme" archive -archivePath /my/path/myArchive

但是如何使用正确的配置文件进行签名过程,并通过命令行进行分发?

对于特别构建,我在归档后生成我的ipa:

xcodebuild -exportArchive -exportFormat IPA -archivePath myArchive.xcarchive -exportPath /my/path/myFile.ipa -exportProvisioningProfile 'my adhoc profile name'

但是,当分发到应用商店时,我甚至需要产生一个ipa吗?无论哪种方式,如何使用正确的配置文件进行签名并通过命令行进行分发?

解决方法

请参阅答案底部的Xcode 8更新.

首先要回答问题的最后一部分 – 是的App Store配置配置文件需要通过iTunes连接提交您的应用程序.它不会通过预验证步骤,除非它具有正确的配置文件.您将需要在会员中心创建App Store分销档案

选择“App Store”,然后点击继续

问题的第一部分更困难一点,因为使用命令行工具创建,签名和分发存档和IPA文件记录不足.实施脚本解决方案充满了陷阱,因为在某些情况下工具不能像预期那样运行,需要更详细地了解开发人员帐户,钥匙串,签名证书和配置文件之间的关系.

以下是可用于使用嵌入式Ad Hoc配置文件创建归档的脚本示例,为Ad Hoc分发创建IPA.作为奖励,DSYMs zip文件被创建用于上传到TestFlight.然后再提供两个脚本.第一个将从现有xcarchive创建一个App Store版本的IPA,第二个将显示如何修改xcarchive,以便其可以由Enterprise In House分发的第三方辞职.

此自动构建脚本假定配置配置文件在使用源代码签入的名为ProvisioningProfiles的目录中可用.它还假定密码解锁钥匙串,将签名证书存储在构建用户主目录中的受保护文件中.

#!/bin/sh

# SETME
# set to name of signing certification usually starts something like "iPhone distribution: ...."
# (the associated private key must be available in the key store)
#
# use the command "security find-identity" to list all the possible values available
#
codeSignIdentity="iPhone distribution"

# SETME
# set to location of Ad Hoc provisioning profile
# (this profile must have the codeSignIdentity specified above included in it)
#
provisioningProfile=ProvisioningProfiles/MyAppAdHocdistribution.mobileprovision

# The keychain needs to be unlocked for signing,which requires the keychain
# password. This is stored in a file in the build account only accessible to
# the build account user
if [ ! -f $HOME/.pass ] ; then
    echo "no keychain password file available"
    exit 1
fi

case `stat -L -f "%p" $HOME/.pass`
in
    *400) ;;
    *)
        echo "keychain password file permissions are not restrictive enough"
        echo "chmod 400 $HOME/.pass"
        exit 1
        ;;
esac

#
# turn off tracing if it is on for security command
# to prevent logging of password
#
case `set -o | grep xtrace`
in
    *on) xon=yes ;;
    *) xon=no ;;
esac

#
# unlock the keychain,automatically lock keychain on script exit
#
[ $xon == yes ] && set +x
security unlock-keychain -p `cat $HOME/.pass` $HOME/Library/Keychains/login.keychain
[ $xon == yes ] && set -x
trap "security lock-keychain $HOME/Library/Keychains/login.keychain" EXIT

#
# Extract the profile UUID from the checked in Provisioning Profile.
#
uuid=`/usr/libexec/plistbuddy -c Print:UUID /dev/stdin <<< \
        \`security cms -D -i $provisioningProfile\``

#
# copy the profile to the location XCode expects to find it and start the build,# specifying which profile and signing identity to use for the archived app
#
cp -f $provisioningProfile \
        "$HOME/Library/MobileDevice/Provisioning Profiles/$uuid.mobileprovision"

#
# Build the xcarchive - this will only be done once,will will then
# distribute it for Ad Hoc,App Store and Enterprise In House scenarios
# (profile must be specified by UUID for this step)
#
xcodebuild \
    -workspace MyApp.xcworkspace \
    -scheme MyApp \
    -archivePath build/MyApp.xcarchive \
    archive \
    PROVISIONING_PROFILE="$uuid" \
    CODE_SIGN_IDENTITY="$codeSignIdentity"

#
# Create a zip of the DSYMs for TestFlight
#
/usr/bin/zip -r MyApp.dSYM.zip build/MyApp.xcarchive/dSYMs/MyApp.app.dSYM

#
# Now distribute the xcarchive using an Ad Hoc profile
# (for QA testing for example)
#
profileName=`/usr/libexec/plistbuddy -c Print:Name /dev/stdin <<< \
        \`security cms -D -i $provisioningProfile\``

#
# The profile must be specified by name for this step
#
xcodebuild \
        -exportArchive \
        -exportFormat IPA \
        -archivePath build/MyApp.xcarchive \
        -exportPath MyAppForAdHoc.ipa \
        -exportProvisioningProfile "$profileName"

要使用App Store distribution配置文件重新分发xcarchive,请使用新配置文件重新导出xcarchive(Ad Hoc和App Store配置文件的签名身份相同).

# SETME
# set to location of App Store provisioning profile
#
appStoreProvisioningProfile=ProvisioningProfiles/MyAppAppStoredistribution.mobileprovision

#
# Extract the App Store profile UUID from the checked in Provisioning Profile.
#
uuid=`/usr/libexec/plistbuddy -c Print:UUID /dev/stdin <<< \
        \`security cms -D -i $appStoreProvisioningProfile\``

#
# copy the profile to the location XCode expects to find it and start the export,# specifying which profile to use for the archived app
# (Profile must match with signing identity used to create xcarchive)
#
cp -f $appStoreProvisioningProfile \
        "$HOME/Library/MobileDevice/Provisioning Profiles/$uuid.mobileprovision"

#
# Extract the enterprise profile name from the checked in App Store Provisioning Profile.
# and redistribute the xcarchive as an App Store ready IPA
#
profileName=`/usr/libexec/plistbuddy -c Print:Name /dev/stdin <<< \
        \`security cms -D -i $appStoreProvisioningProfile\``

#
# Profile must be specified by name for this step
#
xcodebuild \
    -exportArchive \
    -exportFormat IPA \
    -archivePath build/MyApp.xcarchive \
    -exportPath MyAppForStore.ipa \
    -exportProvisioningProfile "$profileName"

最后只要完成,如果你想用新的身份和配置文件来辞职xcarchive呢?如果您将内部分发xcarchives分发给第三方公司,可能会发生这种情况.收件人需要使用其企业证书签署您的xcarchive进行分发. xcodebuild不能强制覆盖xcarchive中的现有代码签名,因此必须直接使用codeignign.

# SETME
# set to name of enterprise signing certification usually starts something like
# "iPhone distribution: ...."
#
# use the command "security find-identity" to list all the possible values available
#
enterpriseCodeSignIdentity="iPhone distribution: Acme Ltd"

# SETME
# set to location of Enterprise In-House provisioning profile
# (this profile must be associated with the enterprise code signing identity)
#
enterpriseProvisioningProfile=ProvisioningProfiles/MyAppInHousedistribution.mobileprovision

# SETME
# A resigning of the app with a different certificate requires a new bundle ID
# that is registered by the Enterprise and is included in the In-House distribution
# profile (This Could be automatically extracted from the Enterprise In-House distribution
# profile,I leave that as an ETTR)
enterpriseBundleId="com.enterprise.myapp"

#
# Extract the enterprise profile UUID from the checked in Provisioning Profile.
#
euuid=`/usr/libexec/plistbuddy -c Print:UUID /dev/stdin <<< \
        \`security cms -D -i $enterpriseProvisioningProfile\``

#
# copy the profile to the location XCode expects to find it and start the build,# specifying which profile and signing identity to use for the archived app
#
cp -f $enterpriseProvisioningProfile \
        "$HOME/Library/MobileDevice/Provisioning Profiles/$euuid.mobileprovision"

#
# copy,modify and resign the xcarchive ready for Enterprise deployment
# (has to be resigned as the production certificate is different for enterprise)
#
cp -Rp build/MyApp.xcarchive build/MyAppEnterprise.xcarchive

#
# Remove old code signature
#
rm -rf build/MyAppEnterprise.xcarchive/Products/Applications/MyApp.app/_CodeSignature

#
# copy in the enterprise provisioning profile
#
cp $enterpriseProvisioningProfile \
        build/MyAppEnterprise.xcarchive/Products/Applications/MyApp.app/embedded.mobileprovision

#
# Modify the bundle id to that of the enterprise bundle id
#   
/usr/libexec/plistbuddy -c "Set:CFBundleIdentifier $enterpriseBundleId" \
        build/MyAppEnterprise.xcarchive/Products/Applications/MyApp.app/Info.plist

#
# resign the xcarchive with the enterprise code signing identity
#
/usr/bin/codesign -f -v -s $enterpriseCodeSignIdentity \
        build/MyAppEnterprise.xcarchive/Products/Applications/MyApp.app 

#
# Update the DSYM bundle id and create a zip of the DSYMs for TestFlight (if applicable)
#
/usr/libexec/plistbuddy -c "Set:CFBundleIdentifier com.apple.xcode.dsym.${enterpriseBundleId}" \
        build/MyAppEnterprise.xcarchive/dSYMs/MyApp.app.dSYM/Contents/Info.plist
/usr/bin/zip -r MyAppEnterprise.dSYM.zip build/MyAppEnterprise.xcarchive/dSYMs/MyApp.app.dSYM

#
# Extract the enterprise profile Name from the checked in Provisioning Profile.
#
enterpriseProfileName=`/usr/libexec/plistbuddy -c Print:Name /dev/stdin <<< \
        l\`security cms -D -i $enterpriseProvisioningProfile\``

#
# Profile must be specified by name for this step
#
xcodebuild \
    -exportArchive \
    -exportFormat IPA \
    -archivePath build/MyAppEnterprise.xcarchive \
    -exportPath MyAppEnterprise.ipa \
    -exportProvisioningProfile "$enterpriseProfileName"

如果脚本作为launchd守护进程运行,请参阅此答案https://stackoverflow.com/a/9482707/2351246来解决从launchd守护程序访问登录钥匙串的问题.

OSX小牛和优胜美地的更新

在OSX Mavericks(v10.9.5)和OSX Yosemite上,您可能会看到代码签名错误:

Codesign check fails : ...../MyApp.app: resource envelope is obsolete

检查这里发贴的原因xcodebuild – codesign -vvvv says”resource envelope is obsolete”

要在引用的帖子中实现Apple Support建议的更改,请运行以下命令:

sudo perl -pi.bak -e 's/--verify"./--verify","--no-strict",/ if /codesign.*origApp/;' `xcrun -sdk iphoneos -f PackageApplication`

Xcode8的更新

在Xcode8中,我以前的答案中描述的过程不再适用于新的自动管理签名功能,因此您需要选择手动签名才能使用此方法.

如果您希望使用自动签名,以下是我们尝试使其与IBM Jazz和Jenkins CI环境相结合的一些观察结果.

>如果您有一台CI机器可以获得自动代码签名,这是可能的.我发现你必须创建一个开发者帐户到CI机器上的Xcode实例.这是一个手动步骤,我没有找到方法从命令行导入开发人员配置文件.
>如果您使用具有多个构建机器的分布式CI环境,则它不能正常工作.首先,您有上述问题,您必须手动将开发人员帐户添加到所有Xcode实例,其次,每个帐户必须是不同的Apple ID,否则您将获得常见构建帐户的证书生成问题(所有计算机正在共享一个导致开发人员证书发生冲突的帐户,因为它绑定到特定的机器).

我们运行一个分布式的Jenkins CI环境,所以我们停留了手动签名,但是导出IPA的方法改变了,现在必须使用-exportOptionsPlist选项.

更改归档命令:

#
# Build the xcarchive - this will only be done once,App Store and Enterprise In House scenarios
#
xcodebuild \
    -workspace MyApp.xcworkspace \
    -scheme MyApp \
    -archivePath build/MyApp.xcarchive \
    archive

存档使用与构建帐户相关联的iOS开发人员证书进行签名(因此请确保它已在钥匙串中安装了一个).现在可以使用-exportOptionsPlist选项将档案导出为Ad-hoc,Enterprise和App Store的IPA格式.

创建一个名为exportAppStore.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>method</key>
    <string>app-store</string>
</dict>
</plist>

有关可用于-exportOptionsPlist选项的键的完整列表,请参阅输出xcodebuild -help.

现在修改export archive命令以使用新的导出选项plist文件

xcodebuild \
    -exportArchive \
    -archivePath build/MyApp.xcarchive \
    -exportOptionsPlist exportAppStore.plist \
    -exportPath MyAppForStore.ipa

通过命令行存档和分发iOS应用程序到App Store的更多相关文章

  1. HTML5 播放 RTSP 视频的实例代码

    目前大多数网络摄像头都是通过 RTSP 协议传输视频流的,但是 HTML 并不标准支持 RTSP 流。本文重点给大家介绍HTML5 播放 RTSP 视频的实例代码,需要的朋友参考下吧

  2. 利用Node实现HTML5离线存储的方法

    这篇文章主要介绍了利用Node实现HTML5离线存储的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. 详解如何通过H5(浏览器/WebView/其他)唤起本地app

    这篇文章主要介绍了详解如何通过H5(浏览器/WebView/其他)唤起本地app的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. H5混合开发app如何升级的方法

    本篇文章主要介绍了H5混合开发app如何升级的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. AmazeUI 折叠面板的实现代码

    这篇文章主要介绍了AmazeUI 折叠面板的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码

    这篇文章主要介绍了HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

  7. Html5 video标签视频的最佳实践

    这篇文章主要介绍了Html5 video标签视频的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  8. html5唤起app的方法

    这篇文章主要介绍了html5唤起app的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. HTML5拍照和摄像机功能实战详解

    这篇文章主要介绍了HTML5拍照和摄像机功能实战详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部