1

亲爱的stackoverflowers!

我目前正在准备一个 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 版本”并且需要在某处指定?任何建议都会很棒!

4

2 回答 2

0

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

为了让事情变得更容易和不那么复杂,我建议保留你的跨平台 IDE 用于开发和测试,但是当你准备好发布时,使用 Xcode。我有几个理由让你这样做:

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

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

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

Cross Platform IDE/Development 是一条很好的路线,看起来你已经解决了所有问题,但是当涉及到上传到专有的应用商店系统时,它就不能再跨平台了。

于 2013-02-01T15:21:16.123 回答
0

好的,这花了一些时间,但上周我成功地使用 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>

更改为旧版本,似乎对 Application Loader 的拒绝不负责任,无论如何 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”-目录或将其部署在您的手机上进行检查使用水果带- 很棒的工具!)。我选择了一个 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 的 Mobile Provisioning Center 下载的分发配置文件。只需将其复制粘贴到您的 .app 目录中即可。

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

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

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

于 2013-02-13T14:07:59.280 回答