代码之家  ›  专栏  ›  技术社区  ›  Dan Fabulich

命令行中的xcode“build and archive”

  •  365
  • Dan Fabulich  · 技术社区  · 14 年前

    Xcode3.2在build菜单下提供了一个很棒的新特性,“build and archive”,它生成了一个适合临时分发的.ipa文件。您还可以打开管理器,转到“存档的应用程序”和“将应用程序提交到iTunesConnect”。

    有没有办法从命令行使用“build and archive”(作为构建脚本的一部分)?我想 xcodebuild 可能会有牵连,但是 man 佩奇似乎什么也没说。

    更新 michael grinich要求澄清;下面是命令行构建的具体操作,在“构建和归档”之后,您只能使用xcode的组织者来完成这些功能。

    1. 您可以单击“共享应用程序…”与beta测试人员共享您的ipa。正如Guillaume在下面指出的,由于一些Xcode的魔力,这个IPA文件不需要一个单独分布的.mobileProvision文件,测试人员需要安装它;这很神奇。没有命令行脚本可以做到这一点。例如,arrix的脚本(5月1日提交)不符合这一要求。
    2. 更重要的是,在测试了一个版本之后,你可以点击“提交应用到iTunes连接”将这个完全相同的版本提交给苹果,也就是你测试的二进制版本,而不需要重新构建它。这在命令行中是不可能的,因为对应用程序进行签名是构建过程的一部分;您可以为临时beta测试签名bits,也可以为提交到应用程序商店而签名bits,但不能同时签名。没有一个建立在命令行上的ipa可以在手机上测试,然后直接提交给苹果。

    我希望有人来证明我错了:这两个特性在xcode gui中都很好,不能从命令行复制。

    19 回复  |  直到 6 年前
        1
  •  305
  •   mles    6 年前

    我发现了如何从comand行自动化构建和归档过程,我刚刚写了一个 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
  •  270
  •   Besi    13 年前

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

    xcodebuild -scheme <SchemeName> archive
    

    执行此命令后,存档将显示在xcode管理器中。

        3
  •  120
  •   Raj    6 年前

    用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。

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

    1. 使用xcodebuild的完整路径,

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

    1. 使用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测试的,对我来说很好。

        4
  •  27
  •   Arrix    14 年前

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

    脚本还会增加版本号。如果不需要的话,你可以把那部分去掉。希望有帮助。

        5
  •  24
  •   FuePi    12 年前

    我们开发了一个带有xcode 4.2.1的ipad应用程序,并希望将其集成到我们的ota发行版的持续集成(jenkins)中。这是我想出的解决办法:

    # 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文件上传到我们的web服务器。

    这是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>
    

    要设置此设置,必须将分发证书和配置文件导入指定用户的密钥链。

        6
  •  23
  •   Nik    11 年前

    这个 xcodebuild 工具可以使用 -导出存档 标志(从xcode 5开始)。以前只能通过xcode管理器ui执行导出步骤。

    首先存档应用程序:

    xcodebuild -scheme <scheme name> archive
    

    鉴于 $ARCHIVE_PATH (通往 XCARCHIVE 文件),使用以下选项之一从存档中导出应用程序:

    网间网操作系统 IPA 文件:

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

    雨衣 应用程序 文件:

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

    在这两个命令中 -导出配置文件 -出口显著性 参数是可选的。 man xcodebuild 有关语义的详细信息。在这些示例中,ios构建的配置文件指定了临时分发配置文件,mac应用程序的签名标识指定了要导出为第三方应用程序的开发人员id(即不通过mac应用程序商店分发)。

        7
  •  16
  •   zekel lepture    13 年前

    我发现其他一些答案很难找到。 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"
    
        8
  •  15
  •   Duane Fields    14 年前

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

    codesign -f -vv -s "$DistributionIdentity" "$APPDIR"
    
        9
  •  14
  •   DawnSong David H    8 年前

    为了 XCODE 7 ,您有一个更简单的解决方案。唯一额外的工作是您必须创建一个配置plist文件来导出归档文件。

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

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

    cd MyProjectFolder
    

    步骤2 ,使用xcode或 /usr/libexec/PlistBuddy exportOptions.plist 创建导出选项plist文件。顺便说一句, xcrun xcodebuild-帮助 将告诉您必须将哪些密钥插入plist文件。

    步骤3 ,创建.xcarfile文件(实际上是文件夹),如下所示(现在xcode将自动创建build/directory)。

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

    步骤4 ,导出为.ipa文件,与xcode6不同

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

    现在,在build/目录中获得一个ipa文件。直接发送到苹果应用商店。

    顺便说一下,xcode 7创建的ipa文件比xcode 6创建的要大得多。

        10
  •  14
  •   seenukarthi    7 年前

    我简要介绍了使用Terrminal生成IPA时要遵循的步骤和要通过的参数,如下所示:

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

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

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

      /usr/bin/xcodebuild -target $TARGET -sdk iphoneos -configuration Release
      
    4. 上面的命令生成项目并创建一个.app文件。 ./build/Release-iphoneos/MyApp.app

    5. 生成成功后,执行以下命令以使用开发人员名称生成应用程序的.ipa,并使用以下语法设置配置文件:

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

    以上语法中每个参数的说明:

    ${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 }
        11
  •  8
  •   Suhaib    8 年前

    XCODE 8:


    IPA格式:

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

    使用 正在设置配置文件MyMobileApp分发配置文件。

    应用程序格式:

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

    使用应用程序将归档文件mymacapp.xcachive作为pkg文件导出到路径mymacapp.pkg 阳离子签名身份开发者ID应用程序:我的团队。安装程序签名标识 developer id installer:我的团队被隐式地用于签署导出的包。

    Xcodebuild man page

        12
  •  6
  •   erick2red    14 年前

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

    xcodebuild -project projectname -activetarget -activeconfiguration archive
    
        13
  •  4
  •   Community datashaman    7 年前

    更进一步,通过命令行上传到itunesconnect XCODE 7 ! (假设你是从 .ipa 已使用正确的发布配置文件和签名标识签名的。)

    进入 altool ,应用程序加载程序的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 直奔苹果。 密码是可选的,如果不使用该命令,它将提示您输入密码。

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

    您可能需要将路径导出到 阿尔科特 如果你不想保存它的位置。

    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
    
        14
  •  3
  •   Guillaume    13 年前

    根据文森特的回答,我写了一个剧本: xcodearchive
    它允许您通过命令行存档(生成ipa)项目。 把它想象成 xcodebuild 命令,但用于存档。

    github上提供了代码: http://github.com/gcerquant/xcodearchive


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

        15
  •  2
  •   Zitao Xiong    11 年前

    试试xctool吧,它是苹果xcodebuild的替代品,可以更容易地构建和测试ios和mac产品。这对持续集成特别有帮助。它有一些额外的功能:

    1. 运行与xcode.app相同的测试。
    2. 构建和测试结果的结构化输出。
    3. 人性化,ANSI彩色输出。

    3号非常有用。如果有人能读取xcodebuild的控制台输出,我就不会,通常它会给我一行5000多个字符。比论文更难读。

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

        16
  •  2
  •   Community datashaman    7 年前

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

        17
  •  2
  •   Suhaib    8 年前

    在更新到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-导出存档 一切都恢复了正常。

        18
  •  1
  •   Michael Grinich    14 年前

    你是说验证/分享/提交选项?我认为这些是xcode特有的,不适合命令行构建工具。

    我敢打赌,只要你聪明一点,你一定能为自己编一个剧本。看起来它们只是储存在 ~/Library/MobileDevice/Archived Applications/ 有一个uudi和一个plist。我也无法想象反向工程验证器有多困难。

    我感兴趣的自动化过程是将构建发送给beta测试人员。(由于app store提交很少发生,我不介意手动执行,特别是因为我经常需要添加新的描述文本。)通过使用xcode的cli执行pseudo build+archive,我可以从每次代码提交中触发自动生成,使用嵌入的配置文件创建ipa文件把它发电子邮件给测试人员。

        19
  •  0
  •   Hasnain Haider K Niazi    6 年前

    如何用命令构建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?

    Xcode中需要exportoptions.plist。它允许您在创建IPA文件时指定一些选项。使用xcode存档应用程序时,可以在友好的ui中选择选项。

    重要的 :exportoptions.plist中的释放和开发方法不同。

    AppStore:

    exportoptions_release~method=应用程序商店

    发展

    exportoptions_dev~方法=开发