Skip to content

Add advanced introspect(_:onOrAfter:...) modifier #284

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions Sources/Introspect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,21 @@ extension View {
/// ```
public func introspect<SwiftUIViewType: IntrospectableViewType, PlatformSpecificEntity: PlatformEntity>(
_ viewType: SwiftUIViewType,
on platforms: (PlatformViewVersions<SwiftUIViewType, PlatformSpecificEntity>)...,
on platforms: (PlatformViewVersionGroup<SwiftUIViewType, PlatformSpecificEntity>)...,
scope: IntrospectionScope? = nil,
customize: @escaping (PlatformSpecificEntity) -> Void
) -> some View {
self.modifier(IntrospectModifier(viewType, platforms: platforms, scope: scope, customize: customize))
self.modifier(IntrospectModifier(viewType, on: platforms, scope: scope, customize: customize))
}

@_spi(Advanced)
public func introspect<SwiftUIViewType: IntrospectableViewType, PlatformSpecificEntity: PlatformEntity>(
_ viewType: SwiftUIViewType,
onOrAfter platforms: (PlatformViewVersionSingle<SwiftUIViewType, PlatformSpecificEntity>)...,
scope: IntrospectionScope? = nil,
customize: @escaping (PlatformSpecificEntity) -> Void
) -> some View {
self.modifier(IntrospectModifier(viewType, onOrAfter: platforms, scope: scope, customize: customize))
}
}

Expand All @@ -57,12 +67,27 @@ struct IntrospectModifier<SwiftUIViewType: IntrospectableViewType, PlatformSpeci

init(
_ viewType: SwiftUIViewType,
platforms: [PlatformViewVersions<SwiftUIViewType, PlatformSpecificEntity>],
on platforms: [PlatformViewVersionGroup<SwiftUIViewType, PlatformSpecificEntity>],
scope: IntrospectionScope?,
customize: @escaping (PlatformSpecificEntity) -> Void
) {
self.scope = scope ?? viewType.scope
if let platform = platforms.first(where: \.containsCurrent) {
self.selector = platform.selector ?? .default
} else {
self.selector = nil
}
self.customize = customize
}

init(
_ viewType: SwiftUIViewType,
onOrAfter platforms: [PlatformViewVersionSingle<SwiftUIViewType, PlatformSpecificEntity>],
scope: IntrospectionScope?,
customize: @escaping (PlatformSpecificEntity) -> Void
) {
self.scope = scope ?? viewType.scope
if let platform = platforms.first(where: \.isCurrent) {
if let platform = platforms.first(where: \.isCurrentOrPast) {
self.selector = platform.selector ?? .default
} else {
self.selector = nil
Expand Down
132 changes: 74 additions & 58 deletions Sources/PlatformVersion.swift
Original file line number Diff line number Diff line change
@@ -1,195 +1,211 @@
import Foundation

public enum PlatformVersionCondition {
case past
case current
case future
}

public protocol PlatformVersion {
var isCurrent: Bool { get }
var condition: PlatformVersionCondition { get }
}

extension PlatformVersion {
public var isCurrent: Bool {
condition == .current
}

public var isCurrentOrPast: Bool {
condition == .current || condition == .past
}
}

public struct iOSVersion: PlatformVersion {
public let isCurrent: Bool
public let condition: PlatformVersionCondition

public init(isCurrent: () -> Bool) {
self.isCurrent = isCurrent()
public init(condition: () -> PlatformVersionCondition) {
self.condition = condition()
}
}

extension iOSVersion {
public static let v13 = iOSVersion {
if #available(iOS 14, *) {
return false
return .past
}
if #available(iOS 13, *) {
return true
return .current
}
return false
return .future
}

public static let v14 = iOSVersion {
if #available(iOS 15, *) {
return false
return .past
}
if #available(iOS 14, *) {
return true
return .current
}
return false
return .future
}

public static let v15 = iOSVersion {
if #available(iOS 16, *) {
return false
return .past
}
if #available(iOS 15, *) {
return true
return .current
}
return false
return .future
}

public static let v16 = iOSVersion {
if #available(iOS 17, *) {
return false
return .past
}
if #available(iOS 16, *) {
return true
return .current
}
return false
return .future
}

public static let v17 = iOSVersion {
if #available(iOS 18, *) {
return false
return .past
}
if #available(iOS 17, *) {
return true
return .current
}
return false
return .future
}
}

public struct tvOSVersion: PlatformVersion {
public let isCurrent: Bool
public let condition: PlatformVersionCondition

public init(isCurrent: () -> Bool) {
self.isCurrent = isCurrent()
public init(condition: () -> PlatformVersionCondition) {
self.condition = condition()
}
}

extension tvOSVersion {
public static let v13 = tvOSVersion {
if #available(tvOS 14, *) {
return false
return .past
}
if #available(tvOS 13, *) {
return true
return .current
}
return false
return .future
}

public static let v14 = tvOSVersion {
if #available(tvOS 15, *) {
return false
return .past
}
if #available(tvOS 14, *) {
return true
return .current
}
return false
return .future
}

public static let v15 = tvOSVersion {
if #available(tvOS 16, *) {
return false
return .past
}
if #available(tvOS 15, *) {
return true
return .current
}
return false
return .future
}

public static let v16 = tvOSVersion {
if #available(tvOS 17, *) {
return false
return .past
}
if #available(tvOS 16, *) {
return true
return .current
}
return false
return .future
}

public static let v17 = tvOSVersion {
if #available(tvOS 18, *) {
return false
return .past
}
if #available(tvOS 17, *) {
return true
return .current
}
return false
return .future
}
}

public struct macOSVersion: PlatformVersion {
public let isCurrent: Bool
public let condition: PlatformVersionCondition

public init(isCurrent: () -> Bool) {
self.isCurrent = isCurrent()
public init(condition: () -> PlatformVersionCondition) {
self.condition = condition()
}
}

extension macOSVersion {
public static let v10_15 = macOSVersion {
if #available(macOS 11, *) {
return false
return .past
}
if #available(macOS 10.15, *) {
return true
return .current
}
return false
return .future
}

public static let v10_15_4 = macOSVersion {
if #available(macOS 11, *) {
return false
return .past
}
if #available(macOS 10.15.4, *) {
return true
return .current
}
return false
return .future
}

public static let v11 = macOSVersion {
if #available(macOS 12, *) {
return false
return .past
}
if #available(macOS 11, *) {
return true
return .current
}
return false
return .future
}

public static let v12 = macOSVersion {
if #available(macOS 13, *) {
return false
return .past
}
if #available(macOS 12, *) {
return true
return .current
}
return false
return .future
}

public static let v13 = macOSVersion {
if #available(macOS 14, *) {
return false
return .past
}
if #available(macOS 13, *) {
return true
return .current
}
return false
return .future
}

public static let v14 = macOSVersion {
if #available(macOS 15, *) {
return false
return .past
}
if #available(macOS 14, *) {
return true
return .current
}
return false
return .future
}
}
Loading