Xcode从命令行“构建和存档”

时间:2010-04-19 02:18:34

标签: xcode command-line build

Xcode 3.2在Build菜单“Build and Archive”下提供了一个很棒的新功能,它生成一个适合Ad Hoc分发的.ipa文件。您也可以打开管理器,转到“已存档的应用程序”和“将应用程序提交到iTunesConnect”。

有没有办法从命令行使用“Build and Archive”(作为构建脚本的一部分)?我假设xcodebuild会以某种方式涉及,但man页似乎没有说明这一点。

更新 Michael Grinich要求澄清;这就是命令行构建无法完成的功能,在“构建和存档”后,您只能使用Xcode的管理器。

  1. 您可以点击“分享应用程序...”与Beta测试人员分享您的IPA。正如Guillaume在下面指出的,由于一些Xcode魔术,这个IPA文件不需要beta测试人员需要安装的单独分发的.mobileprovision文件;这太神奇了。没有命令行脚本可以做到这一点。例如,Arrix的脚本(5月1日提交)不符合该要求。
  2. 更重要的是,在您对测试版进行测试后,您可以点击“将应用程序提交到iTunes Connect”,将完全相同的版本提交给Apple,即您测试的二进制文件,而无需重建。这在命令行中是不可能的,因为签署应用程序是构建过程的一部分;您可以为Ad Hoc beta测试签名,或者您可以签名提交到App Store,但不能同时签署。在命令行上构建的IPA不能在手机上进行beta测试,然后直接提交给Apple。
  3. 我喜欢有人过来证明我错了:这两个功能在Xcode GUI中运行良好,无法从命令行复制。

20 个答案:

答案 0 :(得分:307)

我找到了如何从命令行自动化构建和归档过程,我刚写了一篇blog article来解释如何实现这一目标。

您必须使用的命令是xcrun

/usr/bin/xcrun -sdk iphoneos PackageApplication \
-v "${RELEASE_BUILDDIR}/${APPLICATION_NAME}.app" \
-o "${BUILD_HISTORY_DIR}/${APPLICATION_NAME}.ipa" \
--sign "${DEVELOPER_NAME}" \
--embed "${PROVISONING_PROFILE}"

您可以在the article中找到所有详细信息。如果您有任何问题,请不要犹豫。

答案 1 :(得分:274)

使用Xcode 4.2,您可以使用-scheme标志执行此操作:

xcodebuild -scheme <SchemeName> archive

在此命令之后,存档将显示在Xcode Organizer中。

答案 2 :(得分:125)

  

使用Xcode 9和Swift更新我的答案

归档

xcodebuild -workspace <ProjectName>/<ProjectName>.xcworkspace -scheme <schemeName> clean archive -configuration release -sdk iphoneos -archivePath <ProjectName>.xcarchive

IPA导出请注意导出选项plist

xcodebuild -exportArchive -archivePath  <ProjectName>.xcarchive -exportOptionsPlist  <ProjectName>/exportOptions.plist -exportPath  <ProjectName>.ipa

对于那些不了解exportOptions.plist的人, https://blog.bitrise.io/new-export-options-plist-in-xcode-9


那些使用它来构建CI / CD工具(如teamcity / jenkins)项目的人,请确保使用构建代理中安装的正确xcode进行存档和导出。

您可以使用以下2个选项之一。

  1. 使用xcodebuild的完整路径,
  2. /Applications/Xcode 9.3.1.app/Contents/Developer/usr/bin/xcodebuild

    1. 使用xcode-select,
    2. xcode-select -switch /Applications/Xcode 9.3.1.app


        

      以下是旧答案

      以下是用于创建存档和IPA示例的命令行脚本。 我有一个iPhone xcode项目,它位于Desktop / MyiOSApp文件夹中。

      逐个执行以下命令。

      cd /Users/username/Desktop/MyiOSApp/
      
      xcodebuild -scheme MyiOSApp archive \
          -archivePath /Users/username/Desktop/MyiOSApp.xcarchive
      
      xcodebuild -exportArchive -exportFormat ipa \
          -archivePath "/Users/username/Desktop/MyiOSApp.xcarchive" \
          -exportPath "/Users/username/Desktop/MyiOSApp.ipa" \
          -exportProvisioningProfile "MyCompany Distribution Profile"
      

      这是用Xcode 5测试的,对我来说很好。

答案 3 :(得分:27)

我一直在使用自己的构建脚本来生成用于临时分发的ipa包。

die() {
    echo "$*" >&2
    exit 1
}

appname='AppName'
config='Ad Hoc Distribution'
sdk='iphoneos3.1.3'
project_dir=$(pwd)

echo using configuration $config

echo updating version number
agvtool bump -all
fullversion="$(agvtool mvers -terse1)($(agvtool vers -terse))"
echo building version $fullversion

xcodebuild -activetarget -configuration "$config" -sdk $sdk build || die "build failed"

echo making ipa...
# packaging
cd build/"$config"-iphoneos || die "no such directory"
rm -rf Payload
rm -f "$appname".*.ipa
mkdir Payload
cp -Rp "$appname.app" Payload/
if [ -f "$project_dir"/iTunesArtwork ] ; then
    cp -f "$project_dir"/iTunesArtwork Payload/iTunesArtwork
fi

ipaname="$appname.$fullversion.$(date -u +%Y%m%d%H%M%S).ipa"
zip -r $ipaname Payload

echo finished making $ipaname

该脚本还会增加版本号。如果不需要,您可以删除该部分。希望它有所帮助。

答案 4 :(得分:24)

我们开发了一个带有XCode 4.2.1的iPad应用程序,并希望将该构建集成到我们的持续集成(Jenkins)中以进行OTA分发。这是我提出的解决方案:

# Unlock keychain
security unlock-keychain -p jenkins /Users/jenkins/Library/Keychains/login.keychain

# Build and sign app
xcodebuild -configuration Distribution clean build

# Set variables
APP_PATH="$PWD/build/Distribution-iphoneos/iPadApp.app"
VERSION=`defaults read $APP_PATH/Info CFBundleShortVersionString`
REVISION=`defaults read $APP_PATH/Info CFBundleVersion`
DATE=`date +"%Y%m%d-%H%M%S"`
ITUNES_LINK="<a href=\"itms-services:\/\/?action=download-manifest\&url=https:\/\/xxx.xxx.xxx\/iPadApp-$VERSION.$REVISION-$DATE.plist\">Download iPad2-App v$VERSION.$REVISION-$DATE<\/a>"

# Package and verify app
xcrun -sdk iphoneos PackageApplication -v build/Distribution-iphoneos/iPadApp.app -o $PWD/iPadApp-$VERSION.$REVISION-$DATE.ipa

# Create plist
cat iPadApp.plist.template | sed -e "s/\${VERSION}/$VERSION/" -e "s/\${DATE}/$DATE/" -e "s/\${REVISION}/$REVISION/" > iPadApp-$VERSION.$REVISION-$DATE.plist

# Update index.html
curl https://xxx.xxx.xxx/index.html -o index.html.$DATE
cat index.html.$DATE | sed -n '1h;1!H;${;g;s/\(<h3>Aktuelle Version<\/h3>\)\(.*\)\(<h3>&Auml;ltere Versionen<\/h3>.<ul>.<li>\)/\1\
${ITUNES_LINK}\
\3\2<\/li>\
<li>/g;p;}' | sed -e "s/\${ITUNES_LINK}/$ITUNES_LINK/" > index.html

然后Jenkins将ipa,plist和html文件上传到我们的网络服务器。

这是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>items</key>
    <array>
        <dict>
            <key>assets</key>
            <array>
                <dict>
                    <key>kind</key>
                    <string>software-package</string>
                    <key>url</key>
                    <string>https://xxx.xxx.xxx/iPadApp-${VERSION}.${REVISION}-${DATE}.ipa</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>full-size-image</string>
                    <key>needs-shine</key>
                    <true/>
                    <key>url</key>
                    <string>https://xxx.xxx.xxx/iPadApp.png</string>
                </dict>
                <dict>
                    <key>kind</key>
                    <string>display-image</string>
                    <key>needs-shine</key>
                    <true/>
                    <key>url</key>
                    <string>https://xxx.xxx.xxx/iPadApp_sm.png</string>
                </dict>
            </array>
            <key>metadata</key>
            <dict>
                <key>bundle-identifier</key>
                <string>xxx.xxx.xxx.iPadApp</string>
                <key>bundle-version</key>
                <string>${VERSION}</string>
                <key>kind</key>
                <string>software</string>
                <key>subtitle</key>
                <string>iPad2-App</string>
                <key>title</key>
                <string>iPadApp</string>
            </dict>
        </dict>
    </array>
</dict>
</plist>

要进行此设置,您必须将分发证书和配置文件导入指定用户的钥匙串。

答案 5 :(得分:23)

xcodebuild工具可以使用 -exportArchive 标志构建和导出存档产品(从Xcode 5开始)。以前只能通过Xcode Organizer UI实现导出步骤。

首先归档您的应用:

xcodebuild -scheme <scheme name> archive

鉴于$ARCHIVE_PATH .xcarchive 文件的路径),请使用以下方法之一从存档中导出应用:

iOS .ipa 文件:

xcodebuild -exportArchive -exportFormat ipa -archivePath "$ARCHIVE_PATH" -exportPath "myApp.ipa" -exportProvisioningProfile "My App Provisioning profile"

Mac .app 文件:

xcodebuild -exportArchive -exportFormat app -archivePath "$ARCHIVE_PATH" -exportPath "myApp.app" -exportSigningIdentity "Developer ID Application: My Software Company"

在两个命令中, -exportProvisioningProfile -exportSigningIdentity 参数都是可选的。有关语义的详细信息,请man xcodebuild。在这些示例中,iOS版本的配置文件指定了AdHoc分发配置文件,Mac应用程序的签名标识指定了用于导出为第三方应用程序的开发者ID(即不通过Mac App Store分发)。 p>

答案 6 :(得分:16)

我发现其他一些答案很难开始。 This article对我有用。有些路径可能需要是绝对路径,如其他答案中所述。

命令:

xcrun -sdk iphoneos PackageApplication \
    "/path/to/build/MyApp.app" \
    -o "output/path/to/MyApp.ipa" \
    --sign "iPhone Distribution: My Company" \
    --embed "/path/to/something.mobileprovision"

答案 7 :(得分:15)

您实际上可以像XCode一样重新构建构建,以便您可以测试并发送相同的二进制文件。例如在我的脚本中(类似于上面那些)我构建了我的发布版本,签名为AdHoc版本,然后我将其存档为IPA进行测试,然后使用我的发行版证书辞职并创建一个zip文件,这是我发送到的苹果。相关的一行是:

codesign -f -vv -s "$DistributionIdentity" "$APPDIR"

答案 8 :(得分:14)

我已经简要介绍了要遵循的步骤,以及使用以下终端生成ipa时要传递的参数:

  1. 转到终端中包含MyApp.xcodeproject文件的文件夹

  2. 通过使用下面给出的命令,您将获得应用程序的所有目标

    /usr/bin/xcodebuild -list 
    
  3. 执行上述命令后,您将获得一个目标列表,您应该选择需要生成的特定目标.ipa

    /usr/bin/xcodebuild -target $TARGET -sdk iphoneos -configuration Release
    
  4. 上面的命令构建项目并创建.app文件。找到.app文件的路径是./build/Release-iphoneos/MyApp.app

  5. 构建成功后,执行以下命令,使用Developer Name和Provisioning Profile使用以下语法生成应用程序的.ipa:

    /usr/bin/xcrun -sdk iphoneos PackageApplication -v “${TARGET}.app” -o “${OUTDIR}/${TARGET}.ipa” –sign “${IDENTITY}” –embed “${PROVISONING_PROFILE}”
    
  6. 上述语法中每个参数的说明:

    ${TARGET}.app                == Target path (ex :/Users/XXXXXX/desktop/Application/build/Release-iphoneos/MyApp.app)
    ${OUTDIR}                    == Select the output directory(Where you want to save .ipa file)
    ${IDENTITY}                   == iPhone Developer: XXXXXXX (XXXXXXXXXX)(which can be obtained from Keychain access)
    ${PROVISONING_PROFILE}   == Path to the provisioning profile(/Users/XXXXXX/Library/MobileDevice/Provisioning Profiles/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX.mobileprovision”)
    
    1. ipa将在选定的输出目录“ $ {OUTDIR} ”生成

答案 9 :(得分:14)

对于 Xcode 7 ,您有一个更简单的解决方案。唯一的额外工作是您必须创建用于导出存档的配置plist文件。

(与Xcode 6相比,在xcrun xcodebuild -help的结果中,-exportFormat-exportProvisioningProfile选项不再被提及;前者被删除,后者被{{取代1}}。)

第1步,将目录更改为包含.xcodeproject或.xcworkspace文件的文件夹。

-exportOptionsPlist

第2步,使用Xcode或cd MyProjectFolder 创建导出选项plist文件。顺便说一句,/usr/libexec/PlistBuddy exportOptions.plist将告诉您必须将哪些键插入到plist文件中。

第3步,按如下方式创建.xcarchive文件(实际上是文件夹)(build /目录将立即由Xcode自动创建),

xcrun xcodebuild -help

第4步,导出为.ipa文件,与Xcode6不同

xcrun xcodebuild -scheme MyApp -configuration Release archive -archivePath build/MyApp.xcarchive

现在,您在build /目录中获得了一个ipa文件。只需将其发送到Apple App Store。

顺便说一句,Xcode 7创建的ipa文件比Xcode 6大得多。

答案 10 :(得分:8)

Xcode 8:

IPA格式:

xcodebuild -exportArchive -exportFormat IPA -archivePath MyMobileApp.xcarchive -exportPath MyMobileApp.ipa -exportProvisioningProfile 'MyMobileApp Distribution Profile'

将存档MyMobileApp.xcarchive作为IPA文件导出到MyMobileApp.ipa路径,使用                   配置文件MyMobileApp Distribution Profile。

APP格式:

xcodebuild -exportArchive -exportFormat APP -archivePath MyMacApp.xcarchive -exportPath MyMacApp.pkg -exportSigningIdentity 'Developer ID Application: My Team'

使用应用程序将存档MyMacApp.xcarchive作为PKG文件导出到MyMacApp.pkg路径               阳离子签名身份开发者ID申请:我的团队。安装程序签名标识               开发者ID安装程序:我的团队隐式用于签署导出的包。

Xcodebuild man page

答案 11 :(得分:6)

转到项目根目录的文件夹:

xcodebuild -project projectname -activetarget -activeconfiguration archive

答案 12 :(得分:4)

更进一步,使用 Xcode 7 通过命令行上传到iTunesConnect! (假设您开始使用已使用正确版本配置文件和签名身份签名的.ipa。)

输入altool,Application Loader的CLI界面(docs,第38页)。 深藏在Xcode.app的结构中,是一个方便的功能,让我们直接上传到ItunesConnect。

/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool

只需运行$ altool --upload-app -f file -u username [-p password]即可将新发布的.ipa直接上传到Apple。 密码是可选的,如果您将其保留在命令之外,它将提示您输入密码。

如果在验证步骤中应用程序出现任何问题,控制台会将其打印出来。

如果您不想保存其位置,则可能必须将路径导出到altool

export PATH=$PATH:/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/

多数民众赞成!只需登录iTunesConnect.com并选择新版本,即可使用testflight进行测试。

最终注意事项:如果您收到错误Exception while launching iTunesTransporter: Transporter not found at path: /usr/local/itms/bin/iTMSTransporter. You should reinstall the application,则可以按照this SO answer上的建议运行符号链接到正确的位置:

ln -s /Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/itms /usr/local/itms

答案 13 :(得分:3)

改进文森特的回答,我写了一个脚本来做到这一点:xcodearchive
它允许您通过命令行存档(生成ipa)项目。 可以把它想象成xcodebuild命令的姐妹,但是要归档。

代码可在github上找到:http://github.com/gcerquant/xcodearchive


该脚本的一个选项是在时间戳存档中启用dSYM符号的存档。没有理由不再保留符号,也无法象征您以后可能收到的崩溃日志。

答案 14 :(得分:2)

尝试使用xctool,它是Apple xcodebuild的替代品,可以更轻松地构建和测试iOS和Mac产品。它对持续集成特别有用。它有一些额外的功能:

  1. 运行与Xcode.app相同的测试。
  2. 构建和测试结果的结构化输出。
  3. 人性化,ANSI色的输出。
  4. No.3非常有用。我不知道是否有人可以读取xcodebuild的控制台输出,我不能,通常它给了我一行5000+个字符。比论文更难阅读。

    xctool: https://github.com/facebook/xctool

答案 15 :(得分:2)

如果您使用下一个工具:https://github.com/nomad/shenzhen

那么这项任务非常简单:

which ipa 1>/dev/null 2>&1 || echo 'no shenzhen. to install use: sudo gem install shenzhen --no-ri --no-rdoc'
ipa build --verbose --scheme "${schemeName}"

source

答案 16 :(得分:2)

更新到Xcode 8后,我发现企业ipa由

生成
/usr/bin/xcrun -sdk iphoneos PackageApplication -v "${RELEASE_BUILDDIR}/${APPLICATION_NAME}.app" -o "${BUILD_HISTORY_DIR}/${APPLICATION_NAME}.ipa" --sign "${DEVELOPER_NAME}" --embed "${PROVISONING_PROFILE}" 
  

由于某些签名问题,无法启动命令。日志   表示&#34;警告:不推荐使用PackageApplication,请使用   而是xcodebuild -exportArchive

所以我切换到xcodebuild -exportArchive,一切都恢复正常。

答案 17 :(得分:1)

您的意思是验证/分享/提交选项?我认为这些特定于Xcode,并不适合命令行构建工具。

有一些聪明,我打赌你可以制作一个脚本来为你做。看起来它们只是存储在~/Library/MobileDevice/Archived Applications/中,带有UUDI和plist。我无法想象对验证器进行逆向工程也很难。

我感兴趣的自动化过程是向beta测试人员发送构建版本。 (由于App Store提交很少发生,我不介意手动执行,特别是因为我经常需要添加新的描述文本。)通过使用Xcode的CLI执行伪Build + Archive,我可以从每个代码提交触发自动构建,使用嵌入式配置文件创建IPA文件,并通过电子邮件发送给测试人员。

答案 18 :(得分:1)

如何使用命令构建iOS项目?

Clean : codebuild clean -workspace work-space-name.xcworkspace -scheme scheme-name 

&&

Archive : xcodebuild archive -workspace work-space-name.xcworkspace -scheme "scheme-name" -configuration Release -archivePath IPA-name.xcarchive 

&&

Export : xcodebuild -exportArchive -archivePath IPA-name.xcarchive -exportPath IPA-name.ipa -exportOptionsPlist exportOptions.plist


什么是ExportOptions.plist?

ExportOptions.plist在Xcode中是必需的。创建ipa文件时,它可以让您指定一些选项。使用Xcode存档应用程序时,可以在友好的UI中选择选项。

重要:ExportOptions.plist中发布和开发的方法不同

AppStore:

  

exportOptions_release〜方法=应用商店

发展

  

exportOptions_dev〜方法=开发

答案 19 :(得分:0)

打开终端并拖放项目文件夹:

cd /用户/用户名/桌面/演示/

一一执行以下命令:

将应用程序as-“ demo.xcodeproj”构建为存档文件

xcodebuild存档-project demo.xcodeproj -scheme演示-archivePath /Users/username/Desktop/demo.xcarchive

如果您的应用具有Podfile文件,例如-“ demo.xcworkspace”-

xcodebuild -workspace项目名称.xcworkspace-方案计划名称-sdk iphoneos-配置发行Provisioning_Profile =“ Provision-Name” Development_Team =“ Team-ID”存档-archivePath /Path/To/Output/AppName.xcarchive存档

IPA导出构建命令

Here下载

ExportOptions.plist文件

xcodebuild -exportArchive -archivePath /Users/shilpa/Desktop/demo.xcarchive -exportPath /Users/shilpa/Desktop/demo.ipa -exportOptionsPlist /Users/shilpa/Downloads/ExportOptions.plist

您将在article中使用终端详细信息找到.xcarchive到.ipa。