Javier Soto posted a tweet which showed a clever use property wrappers for supporting cross platform development. It has a lot of potential but does not appear to work when the value is not a short reference. It is also not clear how well it would work with the compiler when targeting each platform.
Created
April 26, 2021 19:45
-
-
Save brennanMKE/d3002c9e503239b8558c973b207ac575 to your computer and use it in GitHub Desktop.
Cross Platform Property Wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
#if canImport(UIKit) | |
import UIKit | |
#elseif canImport(AppKit) | |
import AppKit | |
#elseif canImport(WatchKit) | |
import WatchKit | |
#endif | |
@propertyWrapper | |
public struct PlatformDependentValue<T> { | |
public var wrappedValue: T { self.resolvedValue } | |
private let resolvedValue: T | |
#if os(iOS) || os(macOS) || os(watchOS) || os(tvOS) | |
init(iOS: @autoclosure () -> T, macOS: @autoclosure () -> T, | |
watchOS: @autoclosure () -> T, tvOS: @autoclosure () -> T) { | |
#if os(iOS) | |
resolvedValue = iOS() | |
#elseif os(macOS) | |
resolvedValue = macOS() | |
#elseif os(watchOS) | |
resolvedValue = watchOS() | |
#elseif os(tvOS) | |
resolvedValue = tvOS() | |
#endif | |
} | |
#endif | |
} | |
enum CrossPlatform { | |
static func deviceName() -> String { | |
#if canImport(UIKit) | |
UIDevice.current.name | |
#elseif canImport(AppKit) | |
ProcessInfo.processInfo.hostName | |
#elseif canImport(WatchKit) | |
WKInterfaceDevice.current.name | |
#endif | |
} | |
static func devicModel() -> String { | |
#if canImport(UIKit) | |
UIDevice.current.model | |
#elseif canImport(AppKit) | |
"Mac" | |
#elseif canImport(WatchKit) | |
WKInterfaceDevice.current.model | |
#endif | |
} | |
static func systemVersion() -> String { | |
#if canImport(UIKit) | |
UIDevice.current.systemVersion | |
#elseif canImport(AppKit) | |
ProcessInfo.processInfo.operatingSystemVersionString | |
#elseif canImport(WatchKit) | |
WKInterfaceDevice.current.systemVersion | |
#endif | |
} | |
static func systemName() -> String { | |
#if canImport(UIKit) | |
UIDevice.current.systemName | |
#elseif canImport(AppKit) | |
ProcessInfo.processInfo.hostName | |
#elseif canImport(WatchKit) | |
"Darwin" | |
#endif | |
} | |
} | |
struct Device { | |
@PlatformDependentValue(iOS: CrossPlatform.deviceName(), | |
macOS: CrossPlatform.deviceName(), | |
watchOS: CrossPlatform.deviceName(), | |
tvOS: CrossPlatform.deviceName()) | |
var name: String | |
@PlatformDependentValue(iOS: CrossPlatform.devicModel(), | |
macOS: CrossPlatform.devicModel(), | |
watchOS: CrossPlatform.devicModel(), | |
tvOS: CrossPlatform.devicModel()) | |
var model: String | |
@PlatformDependentValue(iOS: CrossPlatform.systemVersion(), | |
macOS: CrossPlatform.systemVersion(), | |
watchOS: CrossPlatform.systemVersion(), | |
tvOS: CrossPlatform.systemVersion()) | |
var systemVersion: String | |
@PlatformDependentValue(iOS: CrossPlatform.systemName(), | |
macOS: CrossPlatform.systemName(), | |
watchOS: CrossPlatform.systemName(), | |
tvOS: CrossPlatform.systemName()) | |
var systemName: String | |
} | |
let device = Device() | |
device.name | |
device.model | |
device.systemVersion | |
device.systemName | |
struct NumberContainer { | |
@PlatformDependentValue(iOS: 1, macOS: 2, watchOS: 3, tvOS: 4) | |
var number: Int | |
} | |
let nc = NumberContainer() | |
nc.number |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment