Multi os for swiftui


Hybrid os code in swiftUI

Apple does not promote SwiftUI as “write once, run everywhere” but as “learn once, apply everywhere” and that is an important distinction. It seems at first glance that we can write once but only on a basic level. You are still going to need to design the appropriate UI for a platform, but it will be able to re-use components from the other versions of the same app.

Target iOS or macOS

Ref: https://gurjit.co/blogs/2023/how-to-implement-navigation-split-view-in-swiftui.php

@main
struct SplitApp: App {
    var body: some Scene {
        WindowGroup {
            #if os(iOS) // iphone and ipad
            Rectangle(.orange)
            #else
            Rectangle(.green)
                .frame(minWidth: 800, minHeight: 600) // Set minimum size for iPad/macOS
            #endif
        }
    }
}

Add customizations for an individual platform

Sometimes you have one SwiftUI view that works great on both iOS and macOS, but needs just a tiny modification – perhaps a little more padding on iOS, or slightly different styling.

For these times I recommend the following view extensions, which add iOS(), macOS(), tvOS(), and watchOS() methods for just this purpose:

// iOS
extension View {
    func iOS<Content: View>(_ modifier: (Self) -> Content) -> some View {
        #if os(iOS)
        return modifier(self)
        #else
        return self
        #endif
    }
}
// macOS
extension View {
    func macOS<Content: View>(_ modifier: (Self) -> Content) -> some View {
        #if os(macOS)
        return modifier(self)
        #else
        return self
        #endif
    }
}
// tvOS
extension View {
    func tvOS<Content: View>(_ modifier: (Self) -> Content) -> some View {
        #if os(tvOS)
        return modifier(self)
        #else
        return self
        #endif
    }
}
// watchOS
extension View {
    func watchOS<Content: View>(_ modifier: (Self) -> Content) -> some View {
        #if os(watchOS)
        return modifier(self)
        #else
        return self
        #endif
    }
}

Each of those follow the same pattern: they create a new method using the platform name, each of which accept a function that is able to transform the current view somehow. Inside the method there is a compiler check to see whether the current platform manages the one we expect – if so we apply the modifier function, otherwise we don’t.

Those platform checks – #if os(iOS), etc – are done at compile time, which means they will be optimized away. In fact, it’s likely the compiler will be able to optimize these methods entirely because they are so simple.

Use them like this:

Text("Hello World")
    .iOS { $0.padding(10) }

Not os

#if !os(macOS)
    .navigationBarTitleDisplayMode(.inline)
#endif

Toggle insetgroup style

https://lucajonscher.medium.com/create-an-inset-grouped-list-in-swiftui-for-macos-20c0bcfaaa7

extension View { func insetGroupedStyle<V: View>(header: V) -> some View { #if os(iOS) // iOS #else // macOS #endif } }

Resources:

  • ⭐⭐ starterkit template for macOS 3 pane app (swiftUI): https://github.com/apparata/SidebarAppTemplate
  • ⭐ 3 column app starter for swiftui: https://swiftwithmajid.com/2022/10/18/mastering-navigationsplitview-in-swiftui/
  • ⭐ Multi os kit: https://github.com/jordansinger/SwiftUI-Kit
  • hybrid app in swiftui: https://github.com/alfianlosari/NewsAppSwiftUI
  • Missing SwiftUI components: https://github.com/SwiftUIX/SwiftUIX
  • ios / ipad hybrid app: (4 years old) https://github.com/alfianlosari/SwiftUI-MovieDB/tree/master
  • all platform hybrid app: https://github.com/alfianlosari/SwiftUITMDbV2
  • Great swiftui app for iOS: https://github.com/AlexCatch/Oak
  • Great macOS app in swiftUI: https://github.com/lbrndnr/nuage-macos
  • Hybrid app (Composable Architecture): (abondoned 3 years ago) https://github.com/hadiidbouk/DEV/tree/main
  • Spotify clone in swiftui for iOS (complex code): https://github.com/denoni/SpotifyClone/tree/main
  • Device status: https://github.com/fatbobman/MovieHunter/blob/main/MovieHunter/Share/SwiftUI/DeviceStatus.swift
  • https://github.com/onmyway133/awesome-swiftui
  • https://kean.blog/post/appkit-is-done