1

There is an Obj-C file which is included into several projects with different deployment target. This file has following codeline:

[[UIApplication sharedApplication] openURL:url];

When I compile project targeting iOS 10, I get a warning:

'openURL:' is deprecated: first deprecated in iOS 10.0 - Please use openURL:options:completionHandler: instead

I tried to fix it with the following construction:

if (@available(iOS 10.0, *)) {
    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
    [[UIApplication sharedApplication] openURL:url];
}

but it still generates the same warning!

I do not want to switch this warning off globally, so what I ended with is monstrous

if (@available(iOS 10.0, *)) {
    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wdeprecated-declarations"
    [[UIApplication sharedApplication] openURL:url];
    #pragma clang diagnostic pop
}

So I wonder if I really need to have such an ugly code, or maybe I have missed something, and such situation could have been handled in another (more graceful) manner?

Nick
  • 3,205
  • 9
  • 57
  • 108
  • While a "warning" isn't ideal, if it still compiles and works on those older target devices does it really matter? iOS10+ now covers ~99% of iPhone installs, and ~80% of iPads. Unless you're developing specifically for continued support of older iPads, there's little reason or benefit to bother working around this. – mc01 Jan 14 '19 at 20:49
  • Yes, this is how you do it, but you can use the preprocessor to reduce the boilerplate. See https://stackoverflow.com/a/32515495/97337 for an example (specifically the NS_SUPPRESS_DIRECT_USE macro). If you run into a lot of this, I've often pulled this stuff into categories like `-[UIApplication rn_openURL:]` that "does the right thing" for all versions. – Rob Napier Jan 14 '19 at 22:35
  • 1
    @RobNapier But there are proper solutions that don't involve suppressing warnings. – rmaddy Jan 14 '19 at 23:07
  • Deprecated does not mean banned. You do not need to suppress this message at all. In fact if it is deprecated in iOS10, chances are it will still be available in iOS15. – GeneCode Jan 14 '19 at 23:37
  • 2
    @GeneCode Correct but most developers should strive for code that compiles clean. – rmaddy Jan 14 '19 at 23:42
  • @rmaddy Thanks for the example. It's kind of hideous to type, so I'm thinking it should be possible to macro it the same way as the link we were discussing, but I agree that the approach is better. – Rob Napier Jan 15 '19 at 13:20

1 Answers1

4

If you are targeting iOS 10 and later then there is no need to support the deprecated API. Just use the new one.

No need for an if/else. Just do:

[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];

That's it. This updated API was added in iOS 10.0. Since you are supporting only iOS 10 and later, there is no need to try to use the deprecated API.

If this code is being used by some projects that support iOS 10 and later as well as some projects that need to support something older than iOS 10, then you need something like the following:

#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0
    if (@available(iOS 10.0, *)) {
#endif
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0
    } else {
        [[UIApplication sharedApplication] openURL:url];
    }
#endif

The effect of this compiler directive is that when building in a project with a Deployment Target of iOS 10.0 or later, the compiled code simply becomes:

[[UIApplication sharedApplication] openURL:url options:@{} 

When the code is built in a project with a Deployment Target earlier than iOS 10.0, the compiled code will be:

if (@available(iOS 10.0, *)) {
    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
} else {
    [[UIApplication sharedApplication] openURL:url];
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579