Post

Replies

Boosts

Views

Activity

SwiftUI alert dismisses immediately when presented from a nested sheet
I found a SwiftUI presentation bug with multiple alerts and sheet presentations. I submitted a Feedback Assistant report too: Feedback ID: FB24621651 The issue is that a native SwiftUI alert dismisses immediately after appearing when it is presented from a view inside a nested sheet. Minimal hierarchy: TabView -> NavigationStack -> outer sheet -> NavigationStack -> detail view -> inner sheet -> alert The inner sheet contains a normal button: struct InnerSheetRoot: View { @State private var showAlert = false var body: some View { Button("Show Alert") { showAlert = true } .alert("Alert from inner sheet", isPresented: $showAlert) { Button("OK") {} } message: { Text("This alert should remain visible.") } } } Steps to reproduce Open the attached sample project. Select the Storage tab. Tap any storage row. In the outer sheet, tap Open Inner Sheet. In the inner sheet, tap Show Alert. Actual result The alert appears briefly and dismisses immediately. It may disappear before OK can be tapped. Expected result The alert should remain visible until the user taps OK. The issue disappears when I remove either the root TabView or the second NavigationStack. It also disappears when the inner sheet is removed. Environment: Xcode: Xcode 26.6 macOS: macOS 26.6.2 iOS: iOS 26.5 Device or simulator: iPhone Simulator Deployment target: iOS 26.0 Swift version: Swift 6 The example project and a screen recording are attached to the Feedback Assistant report, but they can also be found here. I would appreciate confirmation of whether this is a known SwiftUI presentation-host issue and whether there is a recommended way to present alerts from content inside nested sheets.
6
0
328
1w
Perform MTLS connection with another device
Hello there! In our team we are looking for a way to connect to an external device to get and send live information through it. We need to do this because our app is required to work on offline environments and we can't expect to have Internet connection. The device that we connect against is a PC that may not have Internet connection as well. Because of that, we decided to implement live updates via WiFi: The PC generates a WiFi access point. The PC launches an internal server in a local IP of that local network. The phone connects to the access point and queries the PC through the server's local IP. Also we wanted to have security for this interaction. So we agreed on doing MTLS on the connection step, so we can both verify that the server is talking to the phone and viceversa. We do this storing p12 on both phone and PC and verifying their identities via certificates that contain those ids. In our phone configuration, we use the NEHotspotConfigurationManager to connect to the PC's network. Then we make sure that we are connected to the WiFi network using NEHotspotNetwork.fetchCurrent. After that, we are using URLSession to connect to the PC's server with the local IP. We are using the SessionDelegate and implement the didReceiveChallenge method. We do it in a very similar way to the one found in this other DevForum thread. Do you think we are following the right approach to this problem? Do you see any potential gaps in this implementation?
1
0
657
Sep ’23
[SwiftUI] OnAppear executed when it's not selected on the TabView
I'm trying to build an authenticated flow in my app. The app has a LoginScreenView that is going to appear first on the app. When logging in, we go to a TabView consisting of two Views, FirstView and SecondView. SecondView has a logout button, that returns the user to the login screen. On the FirstView we have a network call that is being performed always onAppear. When the user logs out, we are on the SecondView, on the second tab; however both onAppear and onDisappear functions of the FirstView are being executed, even though FirstView is not on display. This provokes in our use case to trigger the network call in the onAppear method of FirstView that will fail because we are not authenticated. Here is my code. This is LoginScreen: struct LoginScreenView: View { @EnvironmentObject private var authManager: AuthManager var body: some View { Button("Login") { authManager.isLoggedIn = true } } } This is FirstView: struct FirstView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundColor(.accentColor) Text("Hello, world!") } .tabItem { Label("Hello", systemImage: "globe") } .onAppear { print("First ✅") Task { try await loadSomeStuffFromNetwork() } } .onDisappear { print("First ❌") } } } This is SecondView: struct SecondView: View { @EnvironmentObject private var authManager: AuthManager var body: some View { VStack { Image(systemName: "flag.fill") .imageScale(.large) .foregroundColor(.accentColor) Text("Goodbye, world!") Button("Logout") { authManager.isLoggedIn = false } } .tabItem { Label("Goodbye", systemImage: "flag") } .onAppear { print("Second ✅") } .onDisappear { print("Second ❌") } } } And this is the root view of the app: struct ContentView: View { @StateObject private var authManager = AuthManager() var body: some View { TabView { Group { if isLoggedIn { FirstView() SecondView() } else { LoginScreenView() } } } .environmentObject(authManager) } } It's using the AuthManager declared in here: final class AuthManager: ObservableObject { @Published var isLoggedIn: Bool = false } As you can see in the code, we are trying to change the displayed views depending on whether we are logged in or not, and we use an if-else for that. Do you think this code is OK? Do you feel that this might be a bug? I feel like this should work out of the spot, but I don't know if I'm missing anything. I saw this question from 2022, but it seems it never got resolved (apart from the workaround of adding a condition of being logged in to perform the network call). Also, saw this other one where they propose to use a @State variable to make the view only perform one network call instead of everytime it appears (or SwiftUI decides it to appear). Are we OK on this train of thought? Should we try to build our network call in some other way? I would prefer to avoid having to add a check to see if we are authenticated every time we perform the call, because that might lead us to unexpected edge cases on our flows.
2
1
2k
May ’23
SwiftUI alert dismisses immediately when presented from a nested sheet
I found a SwiftUI presentation bug with multiple alerts and sheet presentations. I submitted a Feedback Assistant report too: Feedback ID: FB24621651 The issue is that a native SwiftUI alert dismisses immediately after appearing when it is presented from a view inside a nested sheet. Minimal hierarchy: TabView -> NavigationStack -> outer sheet -> NavigationStack -> detail view -> inner sheet -> alert The inner sheet contains a normal button: struct InnerSheetRoot: View { @State private var showAlert = false var body: some View { Button("Show Alert") { showAlert = true } .alert("Alert from inner sheet", isPresented: $showAlert) { Button("OK") {} } message: { Text("This alert should remain visible.") } } } Steps to reproduce Open the attached sample project. Select the Storage tab. Tap any storage row. In the outer sheet, tap Open Inner Sheet. In the inner sheet, tap Show Alert. Actual result The alert appears briefly and dismisses immediately. It may disappear before OK can be tapped. Expected result The alert should remain visible until the user taps OK. The issue disappears when I remove either the root TabView or the second NavigationStack. It also disappears when the inner sheet is removed. Environment: Xcode: Xcode 26.6 macOS: macOS 26.6.2 iOS: iOS 26.5 Device or simulator: iPhone Simulator Deployment target: iOS 26.0 Swift version: Swift 6 The example project and a screen recording are attached to the Feedback Assistant report, but they can also be found here. I would appreciate confirmation of whether this is a known SwiftUI presentation-host issue and whether there is a recommended way to present alerts from content inside nested sheets.
Replies
6
Boosts
0
Views
328
Activity
1w
Perform MTLS connection with another device
Hello there! In our team we are looking for a way to connect to an external device to get and send live information through it. We need to do this because our app is required to work on offline environments and we can't expect to have Internet connection. The device that we connect against is a PC that may not have Internet connection as well. Because of that, we decided to implement live updates via WiFi: The PC generates a WiFi access point. The PC launches an internal server in a local IP of that local network. The phone connects to the access point and queries the PC through the server's local IP. Also we wanted to have security for this interaction. So we agreed on doing MTLS on the connection step, so we can both verify that the server is talking to the phone and viceversa. We do this storing p12 on both phone and PC and verifying their identities via certificates that contain those ids. In our phone configuration, we use the NEHotspotConfigurationManager to connect to the PC's network. Then we make sure that we are connected to the WiFi network using NEHotspotNetwork.fetchCurrent. After that, we are using URLSession to connect to the PC's server with the local IP. We are using the SessionDelegate and implement the didReceiveChallenge method. We do it in a very similar way to the one found in this other DevForum thread. Do you think we are following the right approach to this problem? Do you see any potential gaps in this implementation?
Replies
1
Boosts
0
Views
657
Activity
Sep ’23
[SwiftUI] OnAppear executed when it's not selected on the TabView
I'm trying to build an authenticated flow in my app. The app has a LoginScreenView that is going to appear first on the app. When logging in, we go to a TabView consisting of two Views, FirstView and SecondView. SecondView has a logout button, that returns the user to the login screen. On the FirstView we have a network call that is being performed always onAppear. When the user logs out, we are on the SecondView, on the second tab; however both onAppear and onDisappear functions of the FirstView are being executed, even though FirstView is not on display. This provokes in our use case to trigger the network call in the onAppear method of FirstView that will fail because we are not authenticated. Here is my code. This is LoginScreen: struct LoginScreenView: View { @EnvironmentObject private var authManager: AuthManager var body: some View { Button("Login") { authManager.isLoggedIn = true } } } This is FirstView: struct FirstView: View { var body: some View { VStack { Image(systemName: "globe") .imageScale(.large) .foregroundColor(.accentColor) Text("Hello, world!") } .tabItem { Label("Hello", systemImage: "globe") } .onAppear { print("First ✅") Task { try await loadSomeStuffFromNetwork() } } .onDisappear { print("First ❌") } } } This is SecondView: struct SecondView: View { @EnvironmentObject private var authManager: AuthManager var body: some View { VStack { Image(systemName: "flag.fill") .imageScale(.large) .foregroundColor(.accentColor) Text("Goodbye, world!") Button("Logout") { authManager.isLoggedIn = false } } .tabItem { Label("Goodbye", systemImage: "flag") } .onAppear { print("Second ✅") } .onDisappear { print("Second ❌") } } } And this is the root view of the app: struct ContentView: View { @StateObject private var authManager = AuthManager() var body: some View { TabView { Group { if isLoggedIn { FirstView() SecondView() } else { LoginScreenView() } } } .environmentObject(authManager) } } It's using the AuthManager declared in here: final class AuthManager: ObservableObject { @Published var isLoggedIn: Bool = false } As you can see in the code, we are trying to change the displayed views depending on whether we are logged in or not, and we use an if-else for that. Do you think this code is OK? Do you feel that this might be a bug? I feel like this should work out of the spot, but I don't know if I'm missing anything. I saw this question from 2022, but it seems it never got resolved (apart from the workaround of adding a condition of being logged in to perform the network call). Also, saw this other one where they propose to use a @State variable to make the view only perform one network call instead of everytime it appears (or SwiftUI decides it to appear). Are we OK on this train of thought? Should we try to build our network call in some other way? I would prefer to avoid having to add a check to see if we are authenticated every time we perform the call, because that might lead us to unexpected edge cases on our flows.
Replies
2
Boosts
1
Views
2k
Activity
May ’23