首页 文章

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

提问于
浏览
360

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

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

UPDATE Michael Grinich要求澄清;这里's what exactly you can' t使用命令行构建,只有在你"Build and Archive."后才可以使用Xcode的管理器

  • 您可以单击"Share Application..."与Beta测试人员共享您的IPA . 正如Guillaume在下面指出的,由于一些Xcode魔术,这个IPA文件不需要beta测试人员需要安装的单独分发的.mobileprovision文件; 's magical. No command-line script can do it. For example, Arrix' s脚本(5月1日提交)不符合该要求 .

  • 更重要的是,在命令行中无法实现've beta tested a build, you can click 863206 to submit that EXACT same build to Apple, the very binary you tested, without rebuilding it. That'之后,因为签署应用程序是构建过程的一部分;您可以为Ad Hoc beta测试签名,或者您可以签名提交到App Store,但不能同时签署 . 在命令行上构建的IPA不能在手机上进行beta测试,然后直接提交给Apple .

我喜欢有人过来证明我错了:这两个功能在Xcode GUI中运行良好,无法从命令行复制 .

18 回答

  • 4

    我找到了如何从命令行自动化构建和归档过程,我刚刚写了一个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中找到所有详细信息 . 如果您有任何问题,请不要犹豫 .

  • 2

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

    xcodebuild -scheme <SchemeName> archive
    

    在此命令之后,存档将显示在Xcode管理器中 .

  • 14

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

    Archive

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

    IPA Export (请注意导出选项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个选项之一 .

    • 使用xcodebuild的完整路径,

    /Applications/Xcode 9.3.1.app/Contents/Developer/usr/bin/xcodebuild

    • 使用xcode-select,

    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测试的,对我来说工作正常 .

  • 304

    我一直在使用自己的构建脚本来生成用于临时分发的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
    

    该脚本还会增加版本号 . 如果不需要,您可以删除该部分 . 希望能帮助到你 .

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

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

  • 16

    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分发) .

  • 8

    我发现其他一些答案很难开始 . This article对我而言 . 某些路径可能需要是绝对的,如其他答案中所述 .

    The Command:

    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"
    
  • 2

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

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

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

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

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

    cd MyProjectFolder
    

    Step 2 ,使用Xcode或 /usr/libexec/PlistBuddy exportOptions.plist 创建导出选项plist文件 . 顺便说一句, xcrun xcodebuild -help 会告诉你必须插入plist文件的键 .

    Step 3 ,创建.xcarchive文件(实际上是文件夹)如下(build /目录将由Xcode自动创建),

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

    Step 4 ,像这样导出为.ipa文件,与Xcode6不同

    xcrun xcodebuild -exportArchive -exportPath build/ -archivePath build/MyApp.xcarchive/ -exportOptionsPlist exportOptions.plist
    

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

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

  • 2

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

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

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

    /usr/bin/xcodebuild -list
    
    • 执行上述命令后,您将获得一个目标列表,您应该选择要生成的特定目标.ipa
    /usr/bin/xcodebuild -target $TARGET -sdk iphoneos -configuration Release
    
    • 以上命令构建项目并创建.app文件 . 找到.app文件的路径是 ./build/Release-iphoneos/MyApp.app

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

    /usr/bin/xcrun -sdk iphoneos PackageApplication -v “${TARGET}.app” -o “${OUTDIR}/${TARGET}.ipa” –sign “${IDENTITY}” –embed “${PROVISONING_PROFILE}”
    

    Explanation of each Parameter in the above syntax:

    ${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”)
    
    • ipa将在选定的输出目录“ $ ”生成
  • 3

    Xcode 8:


    IPA Format:

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

    使用配置文件MyMobileApp分发配置文件将存档MyMobileApp.xcarchive作为IPA文件导出到路径MyMobileApp.ipa .

    APP Format:

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

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

    Xcodebuild man page

  • 15

    转到项目根目录的文件夹,然后:

    xcodebuild -project projectname -activetarget -activeconfiguration archive
    
  • 27

    更进一步,通过命令行上传到iTunesConnect Xcode 7 ! (假设您使用的是已使用正确的发布配置文件和签名身份签名的 .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进行测试 .

    Final Note: 如果收到错误提示 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
    
  • 116

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

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

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

  • 23

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

    • 运行与Xcode.app相同的测试 .

    • 构建和测试结果的结构化输出 .

    • 人性化,ANSI色的输出 .

    No.3非常有用 . 我不知道如果有人能读取xcodebuild的控制台输出,我不能,通常它给了我一行5000个字符 . 比论文更难阅读 .

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

  • 269

    如果您使用下一个工具: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

  • 1

    更新到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}"
    

    由于某些签名问题,无法启动命令 . 该日志表示“警告:不推荐使用PackageApplication,而是使用xcodebuild -exportArchive .

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

  • 13

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

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

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

相关问题