You need to mark the SwiftUI framework as being imported weakly. The normal way to include frameworks in Swift apps is to do nothing—the compiler uses the import statements to determine which modules to load, and generates the linker commands to that effect. You can customize this behavior in Xcode, but you first need to explicitly link against SwiftUI, then you can mark the framework as optional.
- In the Xcode Project navigator, select your project file (blue Xcode icon, topmost in the tree).
- In the editor that opens, ensure your app target is selected (or whichever target you're using SwiftUI from).
- Select the “Build Phases” tab.
- Pop open the “Link Binary With Libraries” section.
- Click the + button under the list that appears.
- Type “SwiftUI” into the search field of the popup sheet, select “SwiftUI.framework,” and click “Add.”
- On the new row in the table, click the “Required” popup button in the last column.
- Change the value to “Optional.”
Build your app/framework now, and if you look at the logs for the link step you'll see
-weak_framework SwiftUIin the arguments. This is what tells the linker that the SwiftUI framework is optional, and it shouldn't crash if it's not available (all imported symbols will be zero, and will now cause a crash only if used).
If you feel like going the extra mile to check on things, you can use
otool -lvVto check the output binary, where you'll see something like this:
Load command 13 cmd LC_LOAD_WEAK_DYLIB cmdsize 80 name /System/Library/Frameworks/SwiftUI.framework/SwiftUI (offset 24) time stamp 2 Wed Dec 31 16:00:02 1969 current version 1.0.0 compatibility version 1.0.0 Load command 14 cmd LC_LOAD_DYLIB cmdsize 88 name /System/Library/Frameworks/Foundation.framework/Foundation (offset 24) time stamp 2 Wed Dec 31 16:00:02 1969 current version 1673.126.0 compatibility version 300.0.0
Note that SwiftUI uses LC_LOAD_WEAK_DYLIB while Foundation uses LC_LOAD_DYLIB. This is what we want.
Now, I don't have any iOS 12 devices or simulators around to check this myself, but this ought to be everything you need to get things up & running—just make sure you're properly wrapping all your SwiftUI code in @available blocks, as you've already started to do.
That fixed it, thanks!