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

有没有办法从命令行(作为构建脚本的一部分)使用“构建和存档”?我假设xcodebuild会以某种方式涉及到,但手册页似乎没有说任何关于这方面的内容。

Michael Grinich要求澄清;以下是你不能用命令行构建的功能,这些功能你只能在“构建和存档”之后用Xcode的管理器实现。

You can click "Share Application..." to share your IPA with beta testers. As Guillaume points out below, due to some Xcode magic, this IPA file does not require a separately distributed .mobileprovision file that beta testers need to install; that's magical. No command-line script can do it. For example, Arrix's script (submitted May 1) does not meet that requirement. More importantly, after you've beta tested a build, you can click "Submit Application to iTunes Connect" to submit that EXACT same build to Apple, the very binary you tested, without rebuilding it. That's impossible from the command line, because signing the app is part of the build process; you can sign bits for Ad Hoc beta testing OR you can sign them for submission to the App Store, but not both. No IPA built on the command-line can be beta tested on phones and then submitted directly to Apple.

我希望有人能来证明我是错的:这两个功能在Xcode GUI中都很好用,不能从命令行复制。


进入你的项目根目录,然后:

xcodebuild -project projectname -activetarget -activeconfiguration archive

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

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


你是指验证/共享/提交选项吗?我认为这些都是Xcode特有的,不适合命令行构建工具。

如果有点聪明的话,我打赌你可以编写一个脚本来为你做这件事。看起来它们只是存储在~/Library/MobileDevice/Archived Applications/中,有一个uuddi和一个plist。我也无法想象反向工程验证器会有那么难。

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


我发现了如何从命令行自动化构建和归档过程,我刚刚写了一篇博客文章来解释如何实现这一点。

你必须使用的命令是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}"

你可以在文章中找到所有的细节。如果你有任何问题,不要犹豫,尽管问。


实际上,你可以像XCode一样重新编译,这样你就可以测试和发布相同的二进制代码。例如,在我的脚本中(类似于上面的脚本),我以AdHoc构建的形式构建了我的发布版本,然后我将其归档为IPA进行测试,然后使用我的分发证书并创建一个zip文件,这是我发送给苹果的文件。相关的台词是:

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

我发现这里的其他一些答案很难展开。这篇文章为我做到了。有些路径可能需要是绝对的,正如在其他答案中提到的那样。

命令:

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"

在Xcode 4.2中,你可以使用-scheme标志来做到这一点:

xcodebuild -scheme <SchemeName> archive

执行此命令后,档案文件将显示在Xcode管理器中。


为了改进Vincent的回答,我写了一个脚本:xcodearchive 它允许您通过命令行存档(生成ipa)您的项目。 可以把它看作xcodebuild命令的姐妹,但用于归档。

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

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


我们使用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文件上传到我们的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>

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


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

运行与Xcode.app相同的测试。 构建和测试结果的结构化输出。 人性化的,ansi彩色输出。

3号非常有用。我不知道是否有人能读懂xcodebuild的控制台输出,我不能,通常它给了我一行5000+字符。比论文还难读。

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


我已经给出了一个简单的步骤描述,并在使用下面的终端生成ipa时传递参数:

Go to the folder which contains the MyApp.xcodeproject file in terminal By using the command given below you will get all the Targets of the application /usr/bin/xcodebuild -list After the above command is executed, you will get a list of targets of which you should select a specific target you need to generate .ipa /usr/bin/xcodebuild -target $TARGET -sdk iphoneos -configuration Release The above command builds the project and creates a .app file.The path to locate the .app file is ./build/Release-iphoneos/MyApp.app After Build gets succeeded then execute the following command to generate .ipa of the application using Developer Name and Provisioning Profile using the syntax below: /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”)

ipa将生成在选定的输出目录"${OUTDIR}"


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参数都是可选的。查阅xcodebuild以获得语义的详细信息。在这些例子中,iOS版本的配置文件指定了AdHoc分发配置文件,Mac应用程序的签名标识指定了作为第三方应用程序导出的开发者ID(即不通过Mac应用程序商店分发)。


用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/post/new-export-options-plist-in-xcode-9


那些在CI/CD工具(如teamcity/jenkins)中使用此工具构建项目的人,请确保您在构建代理中安装了正确的Xcode用于存档和导出。

您可以使用以下两个选项中的任何一个。

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


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


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

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

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

cd MyProjectFolder

第二步,使用Xcode或/usr/libexec/PlistBuddy exportOptions。创建导出选项的Plist文件。顺便说一下,xcrun xcodebuild -help会告诉你必须向plist文件插入哪些键。

第三步,创建。xcarchive文件(实际上是文件夹),如下所示(build/ directory将由Xcode立即自动创建),

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

第四步,像这样导出。ipa文件,这与Xcode6不同

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

现在,您将在build/ directory中获得一个ipa文件。只要把它发送到苹果应用商店。

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


更进一步,用Xcode 7通过命令行上传到iTunesConnect ! (假设您从一个.ipa开始,该ipa已经使用正确的发布概要文件和签名标识进行了签名。)

输入altool,应用程序加载器的CLI界面(文档,第38页)。 隐藏在Xcode的深处。应用程序的结构,是一个方便的功能,让我们直接上传到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文件直接上传到苹果。 密码是可选的,如果您不使用该命令,将提示您输入密码。

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

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

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

这就是它!只需登录iTunesConnect.com,选择你的新版本测试testflight。

最后注意:如果你在启动iTunesTransporter时出现异常:Transporter not found at path: /usr/local/itms/bin/iTMSTransporter。你应该重新安装应用程序,你可以按照这个SO答案上的建议,运行一个符号链接到正确的位置:

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

更新到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,一切恢复正常。


Xcode 8:


音标格式:

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

导出存档MyMobileApp。xcarchive作为一个IPA文件到路径MyMobileApp。Ipa使用 配置文件MyMobileApp分发配置文件。

应用格式:

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

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

Xcodebuild手册页


如何用命令构建iOS项目?

Clean : xcodebuild 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

**What is ExportOptions.plist?**

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

重要:ExportOptions.plist中的发布和开发方法是不同的 应用商店:

exportOptions_release ~ method = app-store

发展

exportOptions_dev ~ method = development


打开终端,拖放你的项目文件夹:

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

依次执行以下命令:

将应用程序构建为-“demo”。Xcodeproj”放入存档

Xcodebuild存档项目演示。xcodeproj -scheme demo -archivePath /Users/username/Desktop/demo.xcarchive

如果你的应用程序有Podfile fie as-"demo.xcworkspace"-

xcodebuild -workspace项目名称。xcworkspace -scheme Scheme-Name -sdk iphoneos -configuration Release provision - profile = " Provision-Name " Development_Team= " Team-ID " archive -archivePath /Path/To/Output/AppName。xcarchive存档

IPA导出构建命令

下载ExportOptions。plist文件从这里

xcodebuild -exportArchive -archivePath / ulpa /桌面/演示。xcarchive -exportPath /用户/shilpa/桌面/演示。科学exportionspite /用户/shilpa/导出