为多个iOS版本开发应用程序

Kha*_*azi 6 compiler-construction build deprecated target ios

我正在使用iOS 5.1和带有iOS 6.0的iPad 4测试iPhone 4上的应用程序.我环顾四周,出乎意料地没有找到类似的问题:

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

2-我的理解是,只有一个目标,"项目"部署目标和"目标"部署目标服务于同一目的.我需要将其中一个或两个作为iOS 5.1,因为这是iOS支持的最低要求.令人困惑的是,如果目标是基于iOS 5.1构建的,它将如何在iOS4的iPad4上运行:

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

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

非常感谢!

Mik*_*ler 28

不推荐的方法

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

Xcode设置级别

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

向后兼容兼容性

最后,有许多因素可用于向后兼容.有时会有新的iOS 6方法supportedInterfaceOrientations,在旧的iOS版本中会被忽略.其他时候您需要添加显式检查:

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

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

    // Only available on iOS 6
    if ([UICollectionView class]) {
        // ...
    } else {
        // class doesn't exist in this iOS version
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果要检查特定函数是否可用,请在其上执行简单的if语句:

    // Only available in iOS 6
    if (ABAddressBookCreateWithOptions) {
        ABAddressBookCreateWithOptions(...);
    } else {
        ABAddressBookCreate(...);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 最后,如果要检查常量是否可用,请检查它的地址:

    // Only available in iOS 4
    if (&UIApplicationProtectedDataDidBecomeAvailable) {
        // subscribe to notification
    }
    
    Run Code Online (Sandbox Code Playgroud)

您的Base SDK设置应始终设置为"最新".

如果您遵循所有这些准则,您将能够解决大多数问题,而无需添加显式版本检查.检查iOS版本或设备ID非常脆弱,可能会导致您的应用在未来版本中中断.你真的想避免它.