Skip to content

Instantly share code, notes, and snippets.

@davidsteppenbeck
Created May 15, 2023 11:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidsteppenbeck/7f086663a5ad1fecfc19ed0d5f09f24e to your computer and use it in GitHub Desktop.
Save davidsteppenbeck/7f086663a5ad1fecfc19ed0d5f09f24e to your computer and use it in GitHub Desktop.
Global functions for providing device specific values in Swift.
import Foundation
/*
Put these global functions in a file that is compiled for all platforms.
*/
/// Returns the value for the current device from the values that are provided.
///
/// - Parameters:
/// - phoneValue: The value to use for iPhone.
/// - padValue: The value to use for iPad.
/// - macValue: The value to use for Mac.
/// - defaultValue: The default value to use for all other devices.
func valueForDevice<Value>(phone phoneValue: @autoclosure () -> Value, pad padValue: @autoclosure () -> Value, mac macValue: @autoclosure () -> Value, defaultValue: @autoclosure () -> Value) -> Value {
_valueForDevice(phone: phoneValue, pad: padValue, mac: macValue, defaultValue: defaultValue)
}
/// Returns the value for the current device from the values that are provided.
///
/// - Parameters:
/// - phoneValue: The value to use for iPhone.
/// - padValue: The value to use for iPad.
/// - macValue: The value to use for Mac.
/// - defaultValue: The default value to use for all other devices.
func valueForDevice<Value: Numeric>(phone phoneValue: @autoclosure () -> Value, pad padValue: @autoclosure () -> Value, mac macValue: @autoclosure () -> Value, defaultValue: @autoclosure () -> Value = .zero) -> Value {
_valueForDevice(phone: phoneValue, pad: padValue, mac: macValue, defaultValue: defaultValue)
}
/// Returns the value for the current device from the values that are provided.
///
/// - Parameters:
/// - phoneValue: The value to use for iPhone.
/// - padValue: The value to use for iPad.
/// - macValue: The value to use for Mac.
/// - defaultValue: The default value to use for all other devices.
func valueForDevice<Wrapped>(phone phoneValue: @autoclosure () -> Optional<Wrapped>, pad padValue: @autoclosure () -> Optional<Wrapped>, mac macValue: @autoclosure () -> Optional<Wrapped>, defaultValue: @autoclosure () -> Optional<Wrapped> = nil) -> Optional<Wrapped> {
_valueForDevice(phone: phoneValue, pad: padValue, mac: macValue, defaultValue: defaultValue)
}
/// Returns the boolean for the current device from the values that are provided.
///
/// - Parameters:
/// - phoneValue: The boolean to use for iPhone.
/// - padValue: The boolean to use for iPad.
/// - macValue: The boolean to use for Mac.
/// - defaultValue: The default boolean to use for all other devices.
func valueForDevice(phone phoneValue: @autoclosure () -> Bool, pad padValue: @autoclosure () -> Bool, mac macValue: @autoclosure () -> Bool, defaultValue: @autoclosure () -> Bool = false) -> Bool {
_valueForDevice(phone: phoneValue, pad: padValue, mac: macValue, defaultValue: defaultValue)
}
private func _valueForDevice<Value>(phone phoneValue: () -> Value, pad padValue: () -> Value, mac macValue: () -> Value, defaultValue: () -> Value) -> Value {
#if os(iOS)
valueForUIDevice(phone: phoneValue(), pad: padValue(), defaultValue: defaultValue())
#elseif os(macOS)
macValue()
#endif
}
import Foundation
/*
Put these global functions in a file that is compiled for iOS only
because they are not relevant for macOS.
*/
/// Returns the value for the current device idiom from the values that are provided.
///
/// - Parameters:
/// - phoneValue: The value to use for the iPhone idiom.
/// - padValue: The value to use for the iPad idiom.
/// - defaultValue: The default value to use for all other idioms.
func valueForUIDevice<Value>(phone phoneValue: @autoclosure () -> Value, pad padValue: @autoclosure () -> Value, defaultValue: @autoclosure () -> Value) -> Value {
_valueForUIDevice(phone: phoneValue, pad: padValue, defaultValue: defaultValue)
}
/// Returns the value for the current device idiom from the values that are provided.
///
/// - Parameters:
/// - phoneValue: The value to use for the iPhone idiom.
/// - padValue: The value to use for the iPad idiom.
/// - defaultValue: The default value to use for all other idioms.
func valueForUIDevice<Value: Numeric>(phone phoneValue: @autoclosure () -> Value, pad padValue: @autoclosure () -> Value, defaultValue: @autoclosure () -> Value = .zero) -> Value {
_valueForUIDevice(phone: phoneValue, pad: padValue, defaultValue: defaultValue)
}
/// Returns the value for the current device idiom from the values that are provided.
///
/// - Parameters:
/// - phoneValue: The value to use for the iPhone idiom.
/// - padValue: The value to use for the iPad idiom.
/// - defaultValue: The default value to use for all other idioms.
func valueForUIDevice<Wrapped>(phone phoneValue: @autoclosure () -> Optional<Wrapped>, pad padValue: @autoclosure () -> Optional<Wrapped>, defaultValue: @autoclosure () -> Optional<Wrapped> = nil) -> Optional<Wrapped> {
_valueForUIDevice(phone: phoneValue, pad: padValue, defaultValue: defaultValue)
}
/// Returns the boolean for the current device idiom from the values that are provided.
///
/// - Parameters:
/// - phoneValue: The boolean to use for the iPhone idiom.
/// - padValue: The boolean to use for the iPad idiom.
/// - defaultValue: The default boolean to use for all other idioms.
func valueForUIDevice(phone phoneValue: @autoclosure () -> Bool, pad padValue: @autoclosure () -> Bool, defaultValue: @autoclosure () -> Bool = false) -> Bool {
_valueForUIDevice(phone: phoneValue, pad: padValue, defaultValue: defaultValue)
}
private func _valueForUIDevice<Value>(phone phoneValue: () -> Value, pad padValue: () -> Value, defaultValue: () -> Value) -> Value {
switch UIDevice.current.userInterfaceIdiom {
case .phone:
return phoneValue()
case .pad:
return padValue()
default:
return defaultValue()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment