Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Swift preprocessor equivalent to iOS version check comparison?

Tags:

I am getting

yld: Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings 

and here's the function that is causing the error when the application is running on an iOS7 device and without even calling the function at all in the code.

func reigsterForRemoteUserNotifications(notificationTypes: UIUserNotificationType, categories: NSSet) {         let userNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: categories)         (UIApplication.sharedApplication()).registerUserNotificationSettings(userNotificationSettings)         UIApplication.sharedApplication().registerForRemoteNotifications()     } 

I don't want this method to be accessible at all when running on an iOS7 device. I do not want a select check inside of it because that means the method is available for use to begin with.

What I want is a build config parameter to check the version : I can't figure out a way to write a swift equivalent preprocessor macro to check for the correct iOS version and neglect the new and undeclared iOS 8 library functions.

#if giOS8OrGreater // declare the functions that are iOS 8 specific #else  // declare the functions that are iOS 7 specific  #endif 

In the documentation apple is suggesting functions and generics to substitute for complex macros but in this case I need a build config precompile check to avoid processing undeclared functions. Any suggestions.

like image 1000
Essa A. Haddad Avatar asked Jun 11 '14 15:06

Essa A. Haddad


People also ask

Does Swift have a preprocessor?

The Swift compiler does not include a preprocessor. Instead, it takes advantage of compile-time attributes, builds configurations, and language features to accomplish the same functionality.

What is preprocessor in Swift?

Swift. Preprocessor macros are used to bring context to a build, allowing you to transform how your app is compiled depending on why it's being built. In iOS, preprocessors are popularly used to determine which scheme was used to build an app.


1 Answers

The other answers fail to mention proper ways of checking the system version. You should absolutely never utilize: Device.systemVersion You shouldn't make custom macros to check version numbers, and you shouldn't dig beyond the libraries that Apple has specifically defined for this task.

There's a great article detailing this out here.

Note that Swift 2.0 allows you to directly check if an OS version number is available via:

if #available(iOS 10.0, *) {     // modern code } else {     // Fallback on earlier versions } 

Prior to Swift 2.0, the recommended approach was via the system macros provided:

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_9_0) {     // do stuff for iOS 9 and newer } else {     // do stuff for older versions than iOS 9 } 

or via:

    if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 10, minorVersion: 0, patchVersion: 0)) {     // modern code } 

For anything missing beyond the system macros.

Any other approach has been downplayed as unreliable and not recommended by Apple. There's actually an approach that will break in iOS 10.

Note that if you need macro like functionality in a check and you'd like to use #available you can use @available defined in this article as such:

 @available(iOS 7, *) func iOS7Work() {     // do stuff      if #available(iOS 8, *) {         iOS8Work()     } }  @available(iOS 8, *) func iOS8Work() {     // do stuff     if #available(iOS 9, *) {         iOS9Work()     } }  @available(iOS 9, *) func iOS9Work() {     // do stuff } 

For further information on attributes in Swift, you can reference Apple's documentation.

like image 71
TheCodingArt Avatar answered Sep 20 '22 14:09

TheCodingArt