【问题标题】:How should I approach building a Universal iOS app that will include iOS 4 features, even though the iPad doesn't yet run iOS 4?即使 iPad 尚未运行 iOS 4,我应该如何构建一个包含 iOS 4 功能的通用 iOS 应用程序?
【发布时间】:2011-03-20 05:16:58
【问题描述】:

我想为 iPhone 和 iPad 开发一款游戏。因此,从头开始这个项目作为一个通用应用程序是有意义的。然而,iPhone 和 iPad 目前运行两个不同版本的 iOS,因为 iOS 4 还不能用于 iPad。我想在我的游戏中支持两个 iOS 4 功能(GameCenter 和 iAd)。

  1. 在这种情况下,将此项目创建为通用应用程序是不是一个坏主意?
  2. 如果不是,我在构建支持两个不同版本 iOS 的通用应用程序时应该考虑哪些想法?
  3. 是否像推测的那样押注 Apple 在秋季发布适用于 iPad 的 iOS 4?
  4. 如果是这样,我是否可以开始将这些 iOS 4 功能(GameCenter 和 iAd)构建到我的 iPad 版本的游戏中?

非常感谢您的智慧!

编辑: 我理解这个问题涉及风险管理。我知道其中的风险,但是当 iOS 分散在各种 iOS 设备中时,我对与构建通用应用程序相关的任何技术设计考虑更感兴趣。

【问题讨论】:

  • 请注意,Game Center 将在一段时间内无法使用,如果使用该功能,Apple 将不会立即接受您的申请进行审核。

标签: iphone ipad ios4 universal-binary


【解决方案1】:

如果你要构建一个Universal App,只需要记住以下两个源代码sn-ps:

  • 仅当类在当前设备上可用时才使用它们

    考虑这段代码:

    UILocalNotification* n = [[UILocalNotification alloc] init];
    

    在构建通用应用程序时,此代码将在任何运行不知道 UILocalNotification 类的 iOS 版本的设备上导致运行时错误。

    您仍然可以在代码中支持 UILocalNotification,同时使用以下代码 sn-p 保持向后兼容性:

    Class notificationClass = NSClassFromString(@"UILocalNotification");
    if (notificationClass) {
      UILocalNotification* n = [[notificationClass alloc] init];
    }
    

    此技术允许您在支持类的设备上使用某些操作系统版本中不可用的类。

  • 仅在当前设备上可用时使用方法

    假设您要执行以下操作:

    [[UIApplication sharedApplication] scheduleLocalNotification:n];
    

    使用以下代码有条件地调用该方法,以防它在当前设备上可用:

    if ([UIApplication instancesRespondToSelector:@selector(scheduleLocalNotification:)]) {
      [[UIApplication sharedApplication] scheduleLocalNotification:n];
    }
    

这两种技术可能是您创建通用应用程序所需了解的唯一内容。根据设备功能有条件地执行您的代码,您应该没问题。

话虽如此,您仍然需要考虑 iPad 可能会使用与 iPhone 不同的 UI。而且,不幸的是,您将无法使用 iOS 4 功能测试您的 iPad UI,直到它们在 iPad 上可用。但这应该不是什么大问题:如果你使用[[UIDevice currentDevice] userInterfaceIdiom] 来检查你是否在 iPad 上运行,你可以阻止你的 Universal App 执行还没有 iPad UI 的代码。一旦 Apple 发布了适用于 iPad 的 iOS 4,您就可以实施 UI,删除该检查并向商店发布更新。

【讨论】:

  • 给未来读者的快速说明:如果你正在实现 application:didReceiveLocalNotification: UIApplicationDelegate 方法,你必须弱链接 UIKit,因为它需要 UILocalNotification 作为参数。
【解决方案2】:

你主要需要做两件事:

  1. 弱链接 3.2 SDK 中不存在的任何框架。
  2. 为 iOS 4 的任何新 API 编写运行时测试。

首先,右键单击您的目标并选择“获取信息”。这些框架列在检查器中(在“常规”选项卡下),旁边有一个下拉框,允许您选择“弱”链接。这样可以确保在框架不存在的情况下应用仍然可以运行。

要执行第二个操作,您可以执行以下操作来测试 iOS 4 中新的基于块的动画:

if ([UIView respondsToSelector:@selector(animateWithDuration:animations:)]) {
    // Your awesome animation code here
} else {
    // Your almost-as-awesome, non-block-based animation code here.
}

通过使用 -respondsToSelector: 等自省方法,您可以避免调用当前运行的操作系统不支持的内容。

另请注意,如果您想支持 iPhone OS 3.0,这些规则同样适用。

最后,也可以——虽然不建议——这样做:

#ifdef __IPHONE_4_0
    // Your iOS 4.0-compatible code here
#elif defined(__IPHONE_3_2)
    // Your iPhone OS 3.2-compatible code here
#elif defined(__IPHONE_3_0)
    // Your iPhone OS 3.0-compatible code here
#endif

为什么不建议这样做?简单:只会编译 最高 编号的 iOS 版本的代码。 iPhone 应用程序不会针对不同的 iOS 版本单独编译,因此要使其真正工作,您必须发布该应用程序的多个版本。

【讨论】:

  • 从 iOS 5.0 编译 Build 时,#elif defined(__IPHONE_3_2) 之后的代码行将永远不会在任何 iOS 设备上运行。这是真的吗?
  • 没有。 iOS 版本也为所有未来版本定义,因此在为 iOS 5 编译时将定义 __IPHONE_3_2__IPHONE_OS_VERSION_MIN_REQUIRED 可能适合您的需求。
【解决方案3】:

【讨论】:

    【解决方案4】:

    这是一个关于管理风险的问题。风险包括:

    1. Apple 未发布预期的 “统一 4.1”操作系统中的 您需要的时间范围
    2. 操作系统按时发布,供您使用 需要,但 GameCenter 中的一项或两项 或 iAd 不包括在内
    3. GameCenter 和/或 iAd 包括在内, 但它们与确切的 API 不匹配 你期待
    4. API 符合您的预期,但是 他们是越野车,因为这是第一个 iPad 版
    5. 等等……

    只有您可以确定您对每种风险的承受程度、您认为每种风险的可能性有多大、您是否可以减轻每种风险以及在此过程中出现任何这些问题的成本。

    【讨论】:

    • 谢谢,shaggy,我实际上对构建通用应用程序时需要考虑的任何技术设计考虑更感兴趣,因为 iOS 在各种设备之间分散。你的想法?
    • 您提到“像推测的那样,押注 Apple 在秋季发布适用于 iPad 的 iOS 4 是否安全?”答案是“不”,因为涉及到风险。在这种情况下,想要将风险管理和技术设计考虑作为两个独立的事情来讨论并不容易。您正在尝试以无法测试的方式构建应用程序,请确保您的所有工作都不会浪费。
    猜你喜欢
    • 1970-01-01
    • 2012-06-03
    • 2012-02-12
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多