为 App Store 提交设置 iOS 版本(没有 Xcode !!!)

Posted

技术标签:

【中文标题】为 App Store 提交设置 iOS 版本(没有 Xcode !!!)【英文标题】:Set iOS Version for App Store submission (without Xcode!!!) 【发布时间】:2013-02-01 12:06:48 【问题描述】:

亲爱的***ers!

我目前正在准备一个 iPhone 应用程序以提交到 App Store。这是一个更大的跨平台 C++ 项目,为此我不得不放弃 Xcode 作为 IDE 并转向更“跨平台类型”的构建系统。现在这是一个简单的 Makefile。在开发过程中一切正常,只是利用了 XCode 构建链,而不是使用 XCode 本身。但是,现在还有一个我不太知道如何通过的最后一道关卡:

在发生了很多其他与打包相关的错误之后,Apple 的 Application Loader 吐出了我的 .ipa 文件,最后一个:

"The bundle is invalid. Apple is not currently accepting applications built with this version of the SDK or Xcode."

我发现我显然不是唯一遇到此错误的人,但大多数其他描述如何解决此问题的文章都是关于通过 Xcode 设置解决的,或者显然已经过时(2011 年或更早)。

关于应用的事实:

两天前,该应用仍与 ios 5.0 SDK 关联。鉴于该错误,我花了一些时间将应用程序与最新的 SDK 6.1 链接起来。所以这是出路,仍然是错误(但是,我没想到apploader后面的服务器会尝试“解析”我的可执行文件以查看我的SDK链接到哪个版本......或者这样做,并且有是否有一些指向 iOS 5.0 的残留链接?)

接下来,我的 Info.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>CFBundleDevelopmentRegion</key>
  <string>en</string>
  <key>CFBundleDisplayName</key>
  <string>Drone game</string>
  <key>CFBundleExecutable</key>
  <string>game</string>
  <key>CFBundleIconFiles</key>
  <array>
    <string>icon.png</string>
    <string>icon@2x.png</string>
    <string>icon-iPad.png</string>
  </array>
  <key>CFBundleIdentifier</key>
  <string>[The bundle identifier]</string>
  <key>CFBundleInfoDictionaryVersion</key>
  <string>6.0</string>
  <key>CFBundleIconFile</key>
  <string>icon.png</string>
  <key>CFBundleName</key>
  <string>Drone game</string>
  <key>CFBundlePackageType</key>
  <string>APPL</string>
  <key>CFBundleShortVersionString</key>
  <string>1.0</string>
  <key>CFBundleSignature</key>
  <string>????</string>
  <key>CFBundleVersion</key>
  <string>1.0</string>
  <key>LSRequiresIPhoneOS</key>
  <true/>
  <key>NSMainNibFile</key>
  <string>MainView</string>
  <key>CFBundleResourceSpecification</key>
  <string>ResourceRules.plist</string>
  <key>UIRequiredDeviceCapabilities</key>
  <array>
    <string>armv7</string>
  </array>
  <key>UISupportedInterfaceOrientations</key>
  <array>
    <string>UIInterfaceOrientationLandscapeRight</string>
  </array>
  <key>UIApplicationExitsOnSuspend</key>
  <true/>
  <key>UIStatusBarHidden</key>
  <true/>
  <key>LSApplicationCategoryType</key>
  <string></string>
  <key>UIInterfaceOrientation</key>
  <string>UIInterfaceOrientationLandscapeRight</string>
  <key>MinimumOSVersion</key>
  <string>6.1</string>
  <key>LSRequiredIPhoneOS</key>
  <true/>
  <key>UILaunchImageFile</key>
  <string>Default.png</string>
  <key>CFBundleGetInfoString</key>
  <string></string>
  <key>UIDeviceFamily</key>
  <array>
    <integer>1</integer>
    <integer>2</integer>
  </array>
</dict>
</plist>

我假设应用程序的属性列表中仍然缺少一些选项,这些选项被应用程序加载器检测到,或者某些值的填充方式错误。部分问题在于 Apple 的开发人员指南在不使用 Xcode 时并没有真正的帮助。有很多键标有“不使用,由Xcode填写”,几乎没有解释(例如:MinimumOSVersion)。

问题本质上是:有人知道应用程序加载器从哪里获取使用的 SDK 版本吗?或者应用程序加载器是否关心“Xcode 版本”并且需要在某处指定?任何建议都会很棒!

【问题讨论】:

从 XCode 以外的任何地方向 App Store 提交应用程序可能不会被接受,如果它完全有效的话。看看你能不能做到会很有趣。 我永远不会放弃一个活跃的 *** 问题,并让您了解解决方案的最新信息 ;-) 【参考方案1】:

其决定所依据的数据可能不在 Info.plist 中。至于信息在哪里,我不知道,因为这部分过程完全是黑匣子,也没有关于它的文档。

为了让事情变得更简单、更简单,我的建议是保留您的跨平台 IDE 用于开发和测试,但是当您准备好发布时,请使用 Xcode。我有几个理由让你这样做:

    归档版本在 Xcode 中轻而易举。这可以很好地管理您已归档的应用程序版本列表,以便您可以使用 dSYM 和代码供您以后调试。此归档过程已集成到应用上传系统中,有助于跟踪您在该时间点发布的代码。

    应用程序加载器是 Xcode 的一部分;为了确保一切都兼容等,.ipa 应该由相同版本的 Xcode 生成。然后,如果捆绑包被拒绝,您只需尝试不同的版本,您知道这不是您构建过程的一部分。

我似乎在回避您的问题,但最终当您将上传到 App Store 路线时,Apple 已经完全涵盖了这一点。因此,我们必须遵守他们的规则。他们希望防止任何形式的不可靠构建进入 App Store,因此他们有自己策划的上传流程。

跨平台IDE/开发是一个不错的途径,看起来你已经解决了所有问题,但是当要上传到专有的应用商店系统时,它就不能再跨平台了。

【讨论】:

这是一个更令人大开眼界的答案,我倾向于同意:即使我现在可以让它工作,也不能保证它可以与下一个版本的 Xcode/the应用加载器。然而,到目前为止,构建过程的每一步都是透明的,可通过 Xcode 的构建日志进行逆向工程:编译器调用、代码签名等。我希望这只是一个小配置问题,暂时不要考虑这个问题,如果有人知道。否则,我会采纳你的建议,让 Xcode 尝试通过 Xcode 项目打包我的二进制文件。【参考方案2】:

好的,这花了一些时间,但上周我成功地使用 Application Loader 提交了我的程序,并且没有使用 Xcode。问题是一堆未记录的密钥,我从 XCode 构建的项目中逆向工程。对于想要完成类似事情的每个人,这里更改后的 Info.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>

带有所用操作系统版本字符串的新魔法键。我不知道如何生成这个字符串,这是Xcode在另一个plist中写的,我复制了它。

    <key>BuildMachineOSBuild</key>
    <string>11G63b</string>

.

    <key>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleDisplayName</key>
    <string>Drone game</string>
    <key>CFBundleExecutable</key>
    <string>game</string>
    <key>CFBundleIconFiles</key>
    <array>
        <string>icon.png</string>
        <string>icon@2x.png</string>
        <string>icon-iPad.png</string>
    </array>
    <key>CFBundleIdentifier</key>
    <string>[The bundle identifer]</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>NSHumanReadableCopyright</key>
    <string>[Copyright notice]</string>
    <key>CFBundleIconFile</key>
    <string>icon.png</string>
    <key>CFBundleName</key>
    <string>Drone game</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>

真正的魔法在这里。再次,一些无处记录的密钥,但是,鉴于问题描述中的错误消息,我怀疑密钥 DTSDKName 和 DTSDKBuild 特别重要。嗯,是的,但是 Xcode 的版本字符串(为什么苹果想知道这个?)和 iphone;再一次,我不知道如何生成这些。

    <key>DTCompiler</key>
    <string></string>
    <key>DTPlatformBuild</key>
    <string>10B141</string>
    <key>DTPlatformName</key>
    <string>iphoneos</string>
    <key>DTPlatformVersion</key>
    <string>6.1</string>
    <key>DTSDKBuild</key>
    <string>10B141</string>
    <key>DTSDKName</key>
    <string>iphoneos6.1</string>
    <key>DTXcode</key>
    <string>0460</string>
    <key>DTXcodeBuild</key>
    <string>4H127</string>

也改了这个,我想这是复制粘贴的神器,因为我不记得改了....

    <key>CFBundleSignature</key>
    <string>ASDR</string>

.

    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>NSMainNibFile</key>
    <string>MainView</string>
    <key>CFBundleResourceSpecification</key>
    <string>ResourceRules.plist</string>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UIApplicationExitsOnSuspend</key>
    <true/>
    <key>UIStatusBarHidden</key>
    <true/>
    <key>LSApplicationCategoryType</key>
    <string></string>
    <key>UIInterfaceOrientation</key>
    <string>UIInterfaceOrientationLandscapeRight</string>

更改为旧版本,似乎无法对应用程序加载器的拒绝负责,无论如何 5.0 都是正确的

    <key>MinimumOSVersion</key>
    <string>5.0</string>  

.

    <key>UILaunchImageFile</key>
    <string>Default.png</string>
    <key>CFBundleGetInfoString</key>
    <string></string>
    <key>UIDeviceFamily</key>
    <array>
        <integer>1</integer>
    </array>
</dict>
</plist>

捆绑

最后,假设您可以编译一个有效的“.app”目录,您需要从中生成一个包(通过尝试使用ios-sim 在模拟器上执行“.app”目录或部署它来检查在您的手机上使用fruitstrap - 很棒的工具!)。我选择了一个 ipa 捆绑包。我使用以下脚本从 .app 目录生成它:

#!/bin/bash
cp embedded.mobileprovision [.app directory]
codesign --force --sign "[Distribution Key Identifer]" --entitlements Entitlements.plist [.app directory]
cd [.app directory]
ln -s _CodeSignature/CodeResources CodeResources
cd ..
/usr/bin/xcrun -verbose -log -sdk iphoneos PackageApplication -v [.app directory] -o "$(pwd)/[bundle name].ipa" --sign "[Distribution Key Identifer]" --embed embedded.mobileprovision

embedded.mobileprovision 是您从 Apple 的移动配置中心下载的分发配置文件。只需将其复制粘贴到您的 .app 目录中即可。

[Distribution Key Identifer] 是您的密钥卡中分发签名的标识符。

请注意,代码签名会执行两次,一次是作为“PackageApplication”的一部分,一次是手动调用。显然,我不知道构建有效的 .ipa 需要什么,但这很有效。您可以通过删除不必要的步骤来改进这一点。

希望这会帮助那些试图实现类似目标的人,干杯!

【讨论】:

以上是关于为 App Store 提交设置 iOS 版本(没有 Xcode !!!)的主要内容,如果未能解决你的问题,请参考以下文章

App Store 提交的版本号问题

目标设置为 iOS 13 的 iOS 应用在 App Store 上不提供旧版本

iOS提交应用至App Store流程及真机调试 一,证书配置文件

在 Test Flight 测试后提交应用到 App Store

iOS提交应用至App Store流程及真机调试 一,证书配置文件

将 iOS 应用设置为对 App Store 上的选定用户可见