Skip to content

Commit

Permalink
Fix AlertState.init availability (#198)
Browse files Browse the repository at this point in the history
In SwiftUI Navigation 1.0, `AlertState` had many initializers to match
the various interfaces in SwiftUI, and they matched the availability of
the SwiftUI interfaces. We simplified to a single interface in 2.0, but
didn't consider the availability mismatch.

While we could bring back the old APIs, it might be nice to favor the
modern builder style. The one caveat is that it will be possible to
render alerts pre-iOS 15 that are configured with more than the maximum
2 buttons at that time. We can emit a runtime warning if we detect this,
but we are losing some of the compile-time check of the previous
version.
  • Loading branch information
stephencelis authored Aug 12, 2024
1 parent dfe94f7 commit 47cfd14
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 9 deletions.
1 change: 0 additions & 1 deletion Sources/SwiftNavigation/AlertState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ public struct AlertState<Action>: Identifiable {
/// - title: The title of the alert.
/// - actions: A ``ButtonStateBuilder`` returning the alert's actions.
/// - message: The message for the alert.
@available(iOS 15, macOS 12, tvOS 15, watchOS 8, *)
public init(
title: () -> TextState,
@ButtonStateBuilder<Action> actions: () -> [ButtonState<Action>] = { [] },
Expand Down
31 changes: 23 additions & 8 deletions Sources/SwiftUINavigation/Alert.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#if canImport(SwiftUI)
import IssueReporting
import SwiftUI

@available(iOS 15, macOS 12, tvOS 15, watchOS 8, *)
Expand Down Expand Up @@ -214,18 +215,25 @@
/// - action: An action handler, called when a button with an action is tapped, by passing the
/// action to the closure.
public init<Action>(_ state: AlertState<Action>, action: @escaping (Action?) -> Void) {
if state.buttons.count == 2 {
if state.buttons.count <= 1 {
self.init(
title: Text(state.title),
message: state.message.map { Text($0) },
primaryButton: .init(state.buttons[0], action: action),
secondaryButton: .init(state.buttons[1], action: action)
dismissButton: state.buttons.first.map { .init($0, action: action) }
)
} else {
if state.buttons.count > 2 {
reportIssue(
"""
'Alert' handed 'AlertState' with too many buttons. Will only display the first two.
"""
)
}
self.init(
title: Text(state.title),
message: state.message.map { Text($0) },
dismissButton: state.buttons.first.map { .init($0, action: action) }
primaryButton: .init(state.buttons[0], action: action),
secondaryButton: .init(state.buttons[1], action: action)
)
}
}
Expand All @@ -240,18 +248,25 @@
_ state: AlertState<Action>,
action: @escaping @Sendable (Action?) async -> Void
) {
if state.buttons.count == 2 {
if state.buttons.count <= 1 {
self.init(
title: Text(state.title),
message: state.message.map { Text($0) },
primaryButton: .init(state.buttons[0], action: action),
secondaryButton: .init(state.buttons[1], action: action)
dismissButton: state.buttons.first.map { .init($0, action: action) }
)
} else {
if state.buttons.count > 2 {
reportIssue(
"""
'Alert' handed 'AlertState' with too many buttons. Will only display the first two.
"""
)
}
self.init(
title: Text(state.title),
message: state.message.map { Text($0) },
dismissButton: state.buttons.first.map { .init($0, action: action) }
primaryButton: .init(state.buttons[0], action: action),
secondaryButton: .init(state.buttons[1], action: action)
)
}
}
Expand Down

0 comments on commit 47cfd14

Please sign in to comment.