【问题标题】:Developing apps for multiple iOS version为多个 iOS 版本开发应用程序
【发布时间】:2012-11-16 16:42:32
【问题描述】:

我正在装有 iOS 5.1 的 iPhone 4 和装有 iOS 6.0 的 iPad 4 上测试一个应用程序。我环顾四周,令人惊讶地没有发现类似的问题:

1- 我的应用程序有一些在 iOS 6.0 中已被弃用的方法,所以我相信我必须构建一些 if/then 条件来测试系统版本,使用:[[UIDevice currentDevice] systemVersion],然后使用适当的版本方法。这是最有效的方法吗?

2- 我的理解是,只有一个目标,“项目”部署目标和“目标”部署目标具有相同的目的。而且我需要将其中之一或两者都作为 iOS 5.1,因为这是支持的最低 iOS。令人困惑的是,如果目标是基于 iOS 5.1 构建的,它如何在 iOS 6.0 的 iPad4 上运行:

  • iPad OS 是在运行前检查目标版本还是只是尝试运行代码,而 iOS 5.1 目标没有任何与 6.0 不兼容的代码?

  • 即使是这样,5.1 目标如何支持我为有条件地替换已弃用方法而构建的 6.0 方法?

非常感谢!

【问题讨论】:

标签: ios compiler-construction build target deprecated


【解决方案1】:

不推荐使用的方法

如果您的目标是在这些方法被弃用之前发布的 iOS 版本,则可以使用弃用的方法。但是假设您的部署目标设置正确,您不会收到任何编译器错误,除非那些已弃用的方法总是在您的目标版本中被弃用。换句话说,如果您在代码中看到弃用警告,您需要修复它们或检查您的部署目标设置是否正确。不要忽视他们!

Xcode 设置级别

您提到您可以在目标和项目级别定义部署目标设置。目标级别的 Xcode 构建设置将覆盖项目设置。因此,仅在其中一个级别定义部署目标,然后转到另一个并点击删除,这样您就没有重复的值。如果您只有一个目标,那么在目标或项目级别定义它并不重要。

向后和向前兼容性

最后,有许多因素会影响向后和向前兼容性。有时会有新的 iOS 6 方法,如 supportedInterfaceOrientations,在旧的 iOS 版本上将被忽略。其他时候您需要添加显式检查:

  • 如果您在对象上调用方法并且该方法仅在 iOS 6 中引入,您将需要添加 respondsToSelector: 检查,如下所示:

    // only available on iOS 6
    if ([locationManager respondsToSelector:@selector(pausesLocationUpdatesAutomatically)]) {
        locationManager.pausesLocationUpdatesAutomatically = YES;
    }
    
  • 如果要检查当前iOS版本上是否存在特定类,可以像这样检查+class方法的返回值:

    // Only available on iOS 6
    if ([UICollectionView class]) {
        // ...
    } else {
        // class doesn't exist in this iOS version
    }
    
  • 如果您想检查某个特定功能是否可用,请对其执行简单的 if 语句:

    // Only available in iOS 6
    if (ABAddressBookCreateWithOptions) {
        ABAddressBookCreateWithOptions(...);
    } else {
        ABAddressBookCreate(...);
    }
    
  • 最后,如果你想检查一个常量是否可用,检查它的地址:

    // Only available in iOS 4
    if (&UIApplicationProtectedDataDidBecomeAvailable) {
        // subscribe to notification
    }
    

您的 Base SDK 设置应始终设置为“最新”。

如果您遵循所有这些准则,您将能够解决大部分问题,而无需添加明确的版本检查。检查 iOS 版本或设备 ID 非常脆弱,很可能会导致您的应用在未来的版本中崩溃。你真的想避免它。

【讨论】:

  • 非常好的和有用的答案。谢谢!
【解决方案2】:
  1. 您可以使用[[UIDevice currentDevice] systemVersion] 来检测操作系统版本,这样可以。除了检测操作系统版本,您还可以使用respondsToSelector: 查看存在哪些方法,使用NSClassFromString() != nil 查看类是否存在,如果该方法不可用则回退。

  2. iOS 向后兼容,因此 iOS 6 可以正常运行 iOS 5 应用程序。但是,如果您想使用 iOS 6 的特定功能但仍支持 iOS 5.1,则必须:

    • 使用 6.0 SDK 进行编译,以便编译器了解新的 API
    • 将您的目标版本设置为支持的最低版本,也就是。 5.1。任何高于该数字的系统都将运行代码。任何更低的都不会尝试。
    • 使用 1. 中描述的方法之一确保每个设备执行操作系统支持的代码。

我希望这很清楚,如果您有更多问题,请不要犹豫

【讨论】:

  • 我认为#2 的措辞不正确。 iOS 向后兼容的,但您给出的示例显示的是向前兼容,而不是向后兼容。
  • 我的意思是新版本可以运行为旧版本编写的应用程序。那就是向后兼容。但是英语不是我的母语,所以可能不太清楚。
  • 不,这是向前兼容性。 en.wikipedia.org/wiki/Forward_compatibility
  • 不,不是。从您链接到的文章中:向前兼容的设计可以接受来自其未来版本的数据。在这里,我谈论一个接受过去版本的系统。
【解决方案3】:

您必须做的是检测功能,而不是 iOS 版本,请查看此线程:

Conditional support of iOS 6 features in an iOS 5 app

【讨论】:

    【解决方案4】:

    您不应检查系统版本,而应检查您尝试使用的功能。请记住,已弃用并不意味着已删除,因此您尝试做的任何事情都可能适用于 iOS6。要检查特定功能,您可以执行以下操作:

    if([TheClassInQuestion class] != nil)
    {
        //use it
    }
    

    【讨论】:

    【解决方案5】:

    iOS 向后兼容。如果你为 iOS 5.1 编译你的应用程序,它也可以在 iOS 6 上完美运行。无需重新实现已弃用的类。

    但是如果您将部署版本从 5.0 更改为 6.0,如果您使用不推荐使用的方法,Xcode 会向您显示警告

    如果您想使用仅在 iOS 6 中可用的方法,您可以使用此检查:

    if ([self respondsToSelector:@selector(doSomething:)]) {
            [self doSomething];
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-19
      • 1970-01-01
      • 1970-01-01
      • 2018-01-21
      相关资源
      最近更新 更多