loading...

Support older versions of iOS

gualtierofr profile image Gualtiero Frigerio ・2 min read

One of the things I like about iOS development is that the latest version of the operating system has usually a very good adoption rate, but iOS 13 doesn’t support a pretty popular model like iPhone 6 and sometimes your customers need to use older devices, I still have to support iOS 9 so devices like the iPhone 4s and iPad 2.

@available

The first thing you can do it mark a class, a struct or a function as available only for a particular version of the operating system.
For example you can write @available(iOS 13.0, *) to specify that the class/function declared below is available only on iOS 13. You can specify many platforms, for example @available(iOS 13.0, macOS 10.12, *). You may wonder about the meaning of the *, this tells the compiler that the class/function is available on the minimum deployment target of all the other platforms, like tvOS and watchOS for example.

if #available

What if you need to call a new API in you code? You can use this syntax

if #available (iOS 13.0, *) {
// call the new API
else {
// legacy code
}

and inside the if you may call a function marked as @available(iOS 13.0).

Xcode 11 and older iOS versions

iOS 13 introduced the concept of Scene and SceneDelegate, and if you create a new project you have a SceneDelegate in addition to the old AppDelegate we’ve used for years in our projects.
If you try to set the deployment target to an older version of iOS you start seeing compiler errors about UIScene and UISceneSession being available only on 13.0 or newer.
As we said we can silence this errors by prefixing the classes with @available, so you have to open SceneDelegate.swift and put @available(iOS 13.0, *) before the class declaration.

import UIKit

@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// SceneDelegate implementation
}

Inside AppDelegate.swift place @available before the two functions that didn’t exist before iOS 13.
There is one more thing you have to do, you need to create a window variable so type
var window:UIWindow?
at the beginning of your AppDelegate class. If you don’t do that the app will compile but run with a blank screen.

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow? // remember to add this

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        return true
    }

    // MARK: UISceneSession Lifecycle

    @available(iOS 13.0, *)
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
    @available(iOS 13.0, *)
    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {

    }
}

That was a really quick tip but can save time when you start a new project and have to support older versions of iOS. Happy coding :)

Original post at http://www.gfrigerio.com/support-older-versions-of-ios/

Posted on Feb 18 by:

gualtierofr profile

Gualtiero Frigerio

@gualtierofr

Senior iOS developer at Epress spa

Discussion

markdown guide
 

Curiously I researched for this yesterday and ended up applying a very similar solution. Still getting accustomed to the introduction of Scenes!