Use SwiftUI for iOS 13+ with some fallback mechanism for iOS 12 and lower.

Hello,

I want to use SwiftUI, but I want to also support iOS 12 and maybe iOS 11, as - according to Apple - there is around 19% of total users, who are still not on iOS 13 (Some of which are unable to, due to older devices).

I already know how to use UIKit although I prefer not using storyboard and writing it in code, but using UIKit with pure code, sometimes is a bit problematic as it takes too much time to figure out how to do very simple things (at least in my experience :p)

Is there any good/proper (or kind of official) way to use SwiftUI for devices with iOS 13+ but also support devices with iOS 12 and iOS 11 through some other mechanism? (I am guessing that I will probably need to write the UI two times, one with SwiftUI and one with UIKit)

If not, should I create two projects, one for the future versions using SwiftUI and one for the older ones?
What do you recommend?

Thanks in Advance
Answered by andy_ in 618202022
Assuming you are using Swift, you can use the if #available conditional to check branch your code between different iOS versions that support something your minimum deployment target does not. You will also need to annotate any types that requires iOS versions higher than your minimum deployment target with the @available macro. For example, suppose you want to create ExampleView and ExampleViewController for in SwiftUI (iOS 13+) and UIKit (iOS 11 and iOS 12), you can do the following:


Code Block swift
@available(iOS 13.0, *)
struct ExampleView : View {
/* ... */
}
class ExampleViewController : UIViewController {
/* ... */
}
/* Branching between SwiftUI vs UIKit based on iOS versioning */
let destinationViewController: UIViewController
if #available(iOS 13.0, *) {
destinationViewController = UIHostingController(rootView: ExampleView())
} else {
destinationViewController = ExampleViewController()
}
self.present(destinationViewController, animated: true, completion: nil)


Similarly, if you use Objective-C, you can do the following:

Code Block objc
if (@available(iOS 13.0, *)) {
/* ... using APIs for iOS 13 and above. */
} else {
/* ... fallback on iOS 12 and below */
}


Anyone running iOS 12 and below will see ExampleViewController, whereas anyone on iOS 13 and above will see the SwiftUI view.

You will have to create separate project for SwiftUI as SwiftUI will only work on ios 13 and later
Accepted Answer
Assuming you are using Swift, you can use the if #available conditional to check branch your code between different iOS versions that support something your minimum deployment target does not. You will also need to annotate any types that requires iOS versions higher than your minimum deployment target with the @available macro. For example, suppose you want to create ExampleView and ExampleViewController for in SwiftUI (iOS 13+) and UIKit (iOS 11 and iOS 12), you can do the following:


Code Block swift
@available(iOS 13.0, *)
struct ExampleView : View {
/* ... */
}
class ExampleViewController : UIViewController {
/* ... */
}
/* Branching between SwiftUI vs UIKit based on iOS versioning */
let destinationViewController: UIViewController
if #available(iOS 13.0, *) {
destinationViewController = UIHostingController(rootView: ExampleView())
} else {
destinationViewController = ExampleViewController()
}
self.present(destinationViewController, animated: true, completion: nil)


Similarly, if you use Objective-C, you can do the following:

Code Block objc
if (@available(iOS 13.0, *)) {
/* ... using APIs for iOS 13 and above. */
} else {
/* ... fallback on iOS 12 and below */
}


Anyone running iOS 12 and below will see ExampleViewController, whereas anyone on iOS 13 and above will see the SwiftUI view.

Thanks andy_ . When I try the approach you've mentioned, It works when running the project on an iOS 13 simulator but when I change to an iOS 12.4 simulator, compilation errors are raised. My project targets iOS12.4, the SwiftUI.framework has been added and conditionals have been applied. Anything I'm missing or is it just that the project must target iOS 13? Below is an example where all the View references produce compilation errors:
Code Block language Swift
@available(iOS 13, *)
struct HomeSUIView: View { /* ERROR: use of undeclared type 'View' */
    var body: some View { /* ERROR: use of undeclared type 'View' */
/* ... */
    }
}
@available(iOS 13, *)
struct HomeSUIView_Previews: PreviewProvider { /* ERROR: use of undeclared type 'PreviewProvider' */
    static var previews: some View { /* ERROR: use of undeclared type 'View' */
        HomeSUIView()
    }
}



Use SwiftUI for iOS 13+ with some fallback mechanism for iOS 12 and lower.
 
 
Q