From 8b1353133ac18631e39484712fca4dd04845ddad Mon Sep 17 00:00:00 2001 From: Valentin Perignon Date: Thu, 30 Oct 2025 08:41:25 +0100 Subject: [PATCH 1/8] feat: Add associated domains --- Euria/Resources/Euria.entitlements | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Euria/Resources/Euria.entitlements b/Euria/Resources/Euria.entitlements index acc5e17..68d3b99 100644 --- a/Euria/Resources/Euria.entitlements +++ b/Euria/Resources/Euria.entitlements @@ -2,6 +2,12 @@ + com.apple.developer.associated-domains + + applinks:euria.infomaniak.com + applinks:ksuite.infomaniak.com + activitycontinuation:ksuite.infomaniak.com + com.apple.security.application-groups group.com.infomaniak.euria From 6bba35bccc8421c9c0851cb6f889349ab7c49fc6 Mon Sep 17 00:00:00 2001 From: Baptiste Griva Date: Thu, 30 Oct 2025 15:00:09 +0100 Subject: [PATCH 2/8] feat: Deeplinks # Conflicts: # EuriaFeatures/MainView/MainView.swift # Conflicts: # EuriaFeatures/MainView/EuriaWebViewDelegate.swift # EuriaFeatures/MainView/MainView.swift # Conflicts: # EuriaFeatures/MainView/WebView.swift --- Euria/Sources/EuriaApp.swift | 17 ++++++++ EuriaCore/UniversalLinkHandler.swift | 43 +++++++++++++++++++ .../Shared State/UniversalLinksState.swift | 25 +++++++++++ EuriaFeatures/MainView/MainView.swift | 10 ++++- EuriaFeatures/MainView/WebView.swift | 4 +- 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 EuriaCore/UniversalLinkHandler.swift create mode 100644 EuriaCoreUI/Shared State/UniversalLinksState.swift diff --git a/Euria/Sources/EuriaApp.swift b/Euria/Sources/EuriaApp.swift index 29bc0d9..5e69d08 100644 --- a/Euria/Sources/EuriaApp.swift +++ b/Euria/Sources/EuriaApp.swift @@ -31,13 +31,30 @@ struct EuriaApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate @StateObject private var rootViewState = RootViewState() + @StateObject var universalLinksState = UniversalLinksState() var body: some Scene { WindowGroup { RootView() .environmentObject(rootViewState) + .environmentObject(universalLinksState) .ikButtonTheme(.euria) + .onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { activity in + guard let url = activity.webpageURL else { return } + handleURL(url) + } + .onOpenURL(perform: handleURL) } .defaultAppStorage(.shared) } + + func handleURL(_ url: URL) { + Task { + let linkHandler = UniversalLinkHandler() + guard let universalLink = linkHandler.handlePossibleUniversalLink(url) else { + return + } + universalLinksState.linkedWebView = universalLink + } + } } diff --git a/EuriaCore/UniversalLinkHandler.swift b/EuriaCore/UniversalLinkHandler.swift new file mode 100644 index 0000000..82b8132 --- /dev/null +++ b/EuriaCore/UniversalLinkHandler.swift @@ -0,0 +1,43 @@ +/* + Infomaniak Euria - iOS App + Copyright (C) 2025 Infomaniak Network SA + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +import Foundation +import InfomaniakCore + +public struct UniversalLinkHandler { + public init() {} + + public func handlePossibleUniversalLink(_ url: URL) -> String? { + let path = url.path + if path.starts(with: "/all") { + if let range = path.range(of: "euria/") { + let result = String(path[range.upperBound...]) + let res = "\(ApiEnvironment.current.euriaHost)/\(result)" + return res + } + + } else { + let stringPath = String(path) + let result = stringPath.replacingOccurrences(of: "/euria", with: "") + let res = "\(ApiEnvironment.current.euriaHost)\(result)" + return res + } + + return nil + } +} diff --git a/EuriaCoreUI/Shared State/UniversalLinksState.swift b/EuriaCoreUI/Shared State/UniversalLinksState.swift new file mode 100644 index 0000000..55082c4 --- /dev/null +++ b/EuriaCoreUI/Shared State/UniversalLinksState.swift @@ -0,0 +1,25 @@ +/* + Infomaniak Euria - iOS App + Copyright (C) 2025 Infomaniak Network SA + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + */ + +import Foundation + +public class UniversalLinksState: ObservableObject { + @Published public var linkedWebView: String? + + public init() {} +} diff --git a/EuriaFeatures/MainView/MainView.swift b/EuriaFeatures/MainView/MainView.swift index 57ccaf0..d58e40c 100644 --- a/EuriaFeatures/MainView/MainView.swift +++ b/EuriaFeatures/MainView/MainView.swift @@ -30,6 +30,8 @@ import SwiftUI import WebKit public struct MainView: View { + @EnvironmentObject var universalLinksState: UniversalLinksState + @StateObject private var webViewDelegate: EuriaWebViewDelegate @State private var isShowingWebView = true @@ -56,7 +58,7 @@ public struct MainView: View { ZStack { if isShowingWebView { WebView( - url: URL(string: "https://\(ApiEnvironment.current.euriaHost)/")!, + url: URL(string: "https://\(currentUrl)/")!, webConfiguration: webViewDelegate.webConfiguration, webViewCoordinator: webViewDelegate ) @@ -89,6 +91,12 @@ public struct MainView: View { guard !webViewDelegate.isLoaded else { return } isShowingWebView = isConnected } + .onChange(of: universalLinksState.linkedWebView) { url in + if let url { + currentUrl = url + universalLinksState.linkedWebView = nil + } + } .sceneLifecycle(willEnterForeground: willEnterForeground) } diff --git a/EuriaFeatures/MainView/WebView.swift b/EuriaFeatures/MainView/WebView.swift index a91a31c..e29934f 100644 --- a/EuriaFeatures/MainView/WebView.swift +++ b/EuriaFeatures/MainView/WebView.swift @@ -36,6 +36,7 @@ struct WebView: UIViewRepresentable { let webView = EuriaWebView(frame: .zero, configuration: webConfiguration) setupWebView(webView, coordinator: webViewCoordinator) + } let request = URLRequest(url: url) webView.load(request) @@ -43,7 +44,8 @@ struct WebView: UIViewRepresentable { } func updateUIView(_ uiView: WKWebView, context: Context) { - // Update the view. + if uiView.url != url { + uiView.load(URLRequest(url: url)) } private func setupWebView(_ webView: WKWebView, coordinator webViewCoordinator: WebViewCoordinator?) { From 44ef68e55ca05f1c1f23641b46da0221038d3e13 Mon Sep 17 00:00:00 2001 From: Baptiste Griva Date: Fri, 31 Oct 2025 08:12:12 +0100 Subject: [PATCH 3/8] chore: Rename var --- Euria/Sources/EuriaApp.swift | 7 ++----- EuriaCore/UniversalLinkHandler.swift | 12 ++++++------ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/Euria/Sources/EuriaApp.swift b/Euria/Sources/EuriaApp.swift index 5e69d08..59f65c2 100644 --- a/Euria/Sources/EuriaApp.swift +++ b/Euria/Sources/EuriaApp.swift @@ -39,17 +39,14 @@ struct EuriaApp: App { .environmentObject(rootViewState) .environmentObject(universalLinksState) .ikButtonTheme(.euria) - .onContinueUserActivity(NSUserActivityTypeBrowsingWeb) { activity in - guard let url = activity.webpageURL else { return } - handleURL(url) - } .onOpenURL(perform: handleURL) } .defaultAppStorage(.shared) } + @MainActor func handleURL(_ url: URL) { - Task { + Task { let linkHandler = UniversalLinkHandler() guard let universalLink = linkHandler.handlePossibleUniversalLink(url) else { return diff --git a/EuriaCore/UniversalLinkHandler.swift b/EuriaCore/UniversalLinkHandler.swift index 82b8132..98da95c 100644 --- a/EuriaCore/UniversalLinkHandler.swift +++ b/EuriaCore/UniversalLinkHandler.swift @@ -26,16 +26,16 @@ public struct UniversalLinkHandler { let path = url.path if path.starts(with: "/all") { if let range = path.range(of: "euria/") { - let result = String(path[range.upperBound...]) - let res = "\(ApiEnvironment.current.euriaHost)/\(result)" - return res + let remainingPath = String(path[range.upperBound...]) + let destinationLink = "\(ApiEnvironment.current.euriaHost)/\(remainingPath)" + return destinationLink } } else { let stringPath = String(path) - let result = stringPath.replacingOccurrences(of: "/euria", with: "") - let res = "\(ApiEnvironment.current.euriaHost)\(result)" - return res + let remainingPath = stringPath.replacingOccurrences(of: "/euria", with: "") + let destinationLink = "\(ApiEnvironment.current.euriaHost)\(remainingPath)" + return destinationLink } return nil From 91d43655670d9c9ce8856c84a6ffb6bf9b53589a Mon Sep 17 00:00:00 2001 From: Valentin Perignon Date: Fri, 31 Oct 2025 09:15:30 +0100 Subject: [PATCH 4/8] chore: Clean code --- Euria/Sources/EuriaApp.swift | 16 +++--- EuriaCore/UniversalLinkHandler.swift | 52 ++++++++++++++----- .../Shared State/UniversalLinksState.swift | 3 +- EuriaFeatures/MainView/MainView.swift | 14 ++--- EuriaFeatures/MainView/WebView.swift | 8 ++- 5 files changed, 62 insertions(+), 31 deletions(-) diff --git a/Euria/Sources/EuriaApp.swift b/Euria/Sources/EuriaApp.swift index 59f65c2..93af5cd 100644 --- a/Euria/Sources/EuriaApp.swift +++ b/Euria/Sources/EuriaApp.swift @@ -31,7 +31,7 @@ struct EuriaApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate @StateObject private var rootViewState = RootViewState() - @StateObject var universalLinksState = UniversalLinksState() + @StateObject private var universalLinksState = UniversalLinksState() var body: some Scene { WindowGroup { @@ -44,14 +44,12 @@ struct EuriaApp: App { .defaultAppStorage(.shared) } - @MainActor - func handleURL(_ url: URL) { - Task { - let linkHandler = UniversalLinkHandler() - guard let universalLink = linkHandler.handlePossibleUniversalLink(url) else { - return - } - universalLinksState.linkedWebView = universalLink + private func handleURL(_ url: URL) { + let linkHandler = UniversalLinkHandler() + guard let universalLink = linkHandler.handlePossibleUniversalLink(url) else { + return } + + universalLinksState.linkedWebView = universalLink } } diff --git a/EuriaCore/UniversalLinkHandler.swift b/EuriaCore/UniversalLinkHandler.swift index 98da95c..863bad1 100644 --- a/EuriaCore/UniversalLinkHandler.swift +++ b/EuriaCore/UniversalLinkHandler.swift @@ -19,25 +19,49 @@ import Foundation import InfomaniakCore -public struct UniversalLinkHandler { +public struct IdentifiableURL: Identifiable, Equatable { + public var id: String { return url.absoluteString } + public let url: URL + + init(url: URL) { + self.url = url + } + + init?(string: String) { + guard let url = URL(string: string) else { return nil } + self.init(url: url) + } +} + +public struct UniversalLinkHandler: Sendable { public init() {} - public func handlePossibleUniversalLink(_ url: URL) -> String? { - let path = url.path - if path.starts(with: "/all") { - if let range = path.range(of: "euria/") { - let remainingPath = String(path[range.upperBound...]) - let destinationLink = "\(ApiEnvironment.current.euriaHost)/\(remainingPath)" - return destinationLink - } + public func handlePossibleUniversalLink(_ url: URL) -> IdentifiableURL? { + if let euriaUniversalLink = tryToHandleEuriaUniversalLink(url) { + return euriaUniversalLink + } - } else { - let stringPath = String(path) - let remainingPath = stringPath.replacingOccurrences(of: "/euria", with: "") - let destinationLink = "\(ApiEnvironment.current.euriaHost)\(remainingPath)" - return destinationLink + if let kSuiteUniversalLink = tryToHandleKSuiteUniversalLink(url) { + return kSuiteUniversalLink } return nil } + + private func tryToHandleEuriaUniversalLink(_ url: URL) -> IdentifiableURL? { + guard url.host() == ApiEnvironment.current.euriaHost else { return nil } + return IdentifiableURL(url: url) + } + + private func tryToHandleKSuiteUniversalLink(_ url: URL) -> IdentifiableURL? { + let urlPath = url.path() + + if urlPath.starts(with: "/all"), let range = urlPath.range(of: "euria/") { + let remainingPath = String(urlPath[range.upperBound...]) + return IdentifiableURL(string: "\(ApiEnvironment.current.euriaHost)/\(remainingPath)") + } else { + let remainingPath = urlPath.replacingOccurrences(of: "/euria", with: "") + return IdentifiableURL(string: "\(ApiEnvironment.current.euriaHost)\(remainingPath)") + } + } } diff --git a/EuriaCoreUI/Shared State/UniversalLinksState.swift b/EuriaCoreUI/Shared State/UniversalLinksState.swift index 55082c4..7f29113 100644 --- a/EuriaCoreUI/Shared State/UniversalLinksState.swift +++ b/EuriaCoreUI/Shared State/UniversalLinksState.swift @@ -16,10 +16,11 @@ along with this program. If not, see . */ +import EuriaCore import Foundation public class UniversalLinksState: ObservableObject { - @Published public var linkedWebView: String? + @Published public var linkedWebView: IdentifiableURL? public init() {} } diff --git a/EuriaFeatures/MainView/MainView.swift b/EuriaFeatures/MainView/MainView.swift index d58e40c..ea6a140 100644 --- a/EuriaFeatures/MainView/MainView.swift +++ b/EuriaFeatures/MainView/MainView.swift @@ -34,6 +34,8 @@ public struct MainView: View { @StateObject private var webViewDelegate: EuriaWebViewDelegate + @State private var webViewURL = URL(string: "https://\(ApiEnvironment.current.euriaHost)/")! + @State private var isShowingWebView = true @State private var isShowingErrorAlert = false @@ -58,7 +60,7 @@ public struct MainView: View { ZStack { if isShowingWebView { WebView( - url: URL(string: "https://\(currentUrl)/")!, + url: webViewURL, webConfiguration: webViewDelegate.webConfiguration, webViewCoordinator: webViewDelegate ) @@ -91,11 +93,11 @@ public struct MainView: View { guard !webViewDelegate.isLoaded else { return } isShowingWebView = isConnected } - .onChange(of: universalLinksState.linkedWebView) { url in - if let url { - currentUrl = url - universalLinksState.linkedWebView = nil - } + .onChange(of: universalLinksState.linkedWebView) { identifiableURL in + guard let identifiableURL else { return } + + webViewURL = identifiableURL.url + universalLinksState.linkedWebView = nil } .sceneLifecycle(willEnterForeground: willEnterForeground) } diff --git a/EuriaFeatures/MainView/WebView.swift b/EuriaFeatures/MainView/WebView.swift index e29934f..9d3ef8b 100644 --- a/EuriaFeatures/MainView/WebView.swift +++ b/EuriaFeatures/MainView/WebView.swift @@ -29,9 +29,15 @@ final class EuriaWebView: WKWebView { struct WebView: UIViewRepresentable { let url: URL - var webConfiguration = WKWebViewConfiguration() + let webConfiguration: WKWebViewConfiguration var webViewCoordinator: WebViewCoordinator? + init(url: URL, webConfiguration: WKWebViewConfiguration = WKWebViewConfiguration(), webViewCoordinator: WebViewCoordinator?) { + self.url = url + self.webConfiguration = webConfiguration + self.webViewCoordinator = webViewCoordinator + } + func makeUIView(context: Context) -> WKWebView { let webView = EuriaWebView(frame: .zero, configuration: webConfiguration) setupWebView(webView, coordinator: webViewCoordinator) From a6c035e5b29aa5b9e60c30e9f96236521173d8d8 Mon Sep 17 00:00:00 2001 From: Valentin Perignon Date: Fri, 31 Oct 2025 09:44:57 +0100 Subject: [PATCH 5/8] chore: Add https scheme --- EuriaCore/UniversalLinkHandler.swift | 4 ++-- EuriaFeatures/MainView/WebView.swift | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/EuriaCore/UniversalLinkHandler.swift b/EuriaCore/UniversalLinkHandler.swift index 863bad1..9c91888 100644 --- a/EuriaCore/UniversalLinkHandler.swift +++ b/EuriaCore/UniversalLinkHandler.swift @@ -58,10 +58,10 @@ public struct UniversalLinkHandler: Sendable { if urlPath.starts(with: "/all"), let range = urlPath.range(of: "euria/") { let remainingPath = String(urlPath[range.upperBound...]) - return IdentifiableURL(string: "\(ApiEnvironment.current.euriaHost)/\(remainingPath)") + return IdentifiableURL(string: "https://\(ApiEnvironment.current.euriaHost)/\(remainingPath)") } else { let remainingPath = urlPath.replacingOccurrences(of: "/euria", with: "") - return IdentifiableURL(string: "\(ApiEnvironment.current.euriaHost)\(remainingPath)") + return IdentifiableURL(string: "https://\(ApiEnvironment.current.euriaHost)\(remainingPath)") } } } diff --git a/EuriaFeatures/MainView/WebView.swift b/EuriaFeatures/MainView/WebView.swift index 9d3ef8b..afe9dce 100644 --- a/EuriaFeatures/MainView/WebView.swift +++ b/EuriaFeatures/MainView/WebView.swift @@ -49,9 +49,13 @@ struct WebView: UIViewRepresentable { return webView } - func updateUIView(_ uiView: WKWebView, context: Context) { - if uiView.url != url { - uiView.load(URLRequest(url: url)) + func updateUIView(_ webView: WKWebView, context: Context) { + guard webView.url != url else { + return + } + + let request = URLRequest(url: url) + webView.load(request) } private func setupWebView(_ webView: WKWebView, coordinator webViewCoordinator: WebViewCoordinator?) { @@ -71,6 +75,9 @@ struct WebView: UIViewRepresentable { if let uiDelegate = webViewCoordinator as? WKUIDelegate { webView.uiDelegate = uiDelegate } + + let request = URLRequest(url: url) + webView.load(request) } private func configureScrollView(_ webView: WKWebView) { From 9788245f66896c961c6a44c8aff49bf4dec1e911 Mon Sep 17 00:00:00 2001 From: Valentin Perignon Date: Tue, 4 Nov 2025 16:34:11 +0100 Subject: [PATCH 6/8] chore: Clea code --- Euria/Sources/EuriaApp.swift | 2 +- EuriaFeatures/MainView/MainView.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Euria/Sources/EuriaApp.swift b/Euria/Sources/EuriaApp.swift index 93af5cd..3bb2323 100644 --- a/Euria/Sources/EuriaApp.swift +++ b/Euria/Sources/EuriaApp.swift @@ -49,7 +49,7 @@ struct EuriaApp: App { guard let universalLink = linkHandler.handlePossibleUniversalLink(url) else { return } - + universalLinksState.linkedWebView = universalLink } } diff --git a/EuriaFeatures/MainView/MainView.swift b/EuriaFeatures/MainView/MainView.swift index ea6a140..77b5e0f 100644 --- a/EuriaFeatures/MainView/MainView.swift +++ b/EuriaFeatures/MainView/MainView.swift @@ -30,7 +30,7 @@ import SwiftUI import WebKit public struct MainView: View { - @EnvironmentObject var universalLinksState: UniversalLinksState + @EnvironmentObject private var universalLinksState: UniversalLinksState @StateObject private var webViewDelegate: EuriaWebViewDelegate From c57f6769f239e405e708a40863b65b4a29f3ffa6 Mon Sep 17 00:00:00 2001 From: Baptiste Griva Date: Fri, 7 Nov 2025 12:47:25 +0100 Subject: [PATCH 7/8] chore: Remove "/" in deeplink Url --- EuriaCore/UniversalLinkHandler.swift | 4 ++-- EuriaFeatures/MainView/WebView.swift | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/EuriaCore/UniversalLinkHandler.swift b/EuriaCore/UniversalLinkHandler.swift index 9c91888..0a7a4c7 100644 --- a/EuriaCore/UniversalLinkHandler.swift +++ b/EuriaCore/UniversalLinkHandler.swift @@ -56,9 +56,9 @@ public struct UniversalLinkHandler: Sendable { private func tryToHandleKSuiteUniversalLink(_ url: URL) -> IdentifiableURL? { let urlPath = url.path() - if urlPath.starts(with: "/all"), let range = urlPath.range(of: "euria/") { + if urlPath.starts(with: "/all"), let range = urlPath.range(of: "euria") { let remainingPath = String(urlPath[range.upperBound...]) - return IdentifiableURL(string: "https://\(ApiEnvironment.current.euriaHost)/\(remainingPath)") + return IdentifiableURL(string: "https://\(ApiEnvironment.current.euriaHost)\(remainingPath)") } else { let remainingPath = urlPath.replacingOccurrences(of: "/euria", with: "") return IdentifiableURL(string: "https://\(ApiEnvironment.current.euriaHost)\(remainingPath)") diff --git a/EuriaFeatures/MainView/WebView.swift b/EuriaFeatures/MainView/WebView.swift index afe9dce..512f372 100644 --- a/EuriaFeatures/MainView/WebView.swift +++ b/EuriaFeatures/MainView/WebView.swift @@ -42,7 +42,6 @@ struct WebView: UIViewRepresentable { let webView = EuriaWebView(frame: .zero, configuration: webConfiguration) setupWebView(webView, coordinator: webViewCoordinator) - } let request = URLRequest(url: url) webView.load(request) From 72fe2fe4ffc67fab016df62a8355a23253c76424 Mon Sep 17 00:00:00 2001 From: Valentin Perignon Date: Mon, 10 Nov 2025 12:45:03 +0100 Subject: [PATCH 8/8] feat: Sleep a few milliseconds before updating the state --- Euria/Sources/EuriaApp.swift | 9 ++++++++- EuriaFeatures/MainView/MainView.swift | 11 +++++------ EuriaFeatures/MainView/WebView.swift | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Euria/Sources/EuriaApp.swift b/Euria/Sources/EuriaApp.swift index 3bb2323..753edac 100644 --- a/Euria/Sources/EuriaApp.swift +++ b/Euria/Sources/EuriaApp.swift @@ -50,6 +50,13 @@ struct EuriaApp: App { return } - universalLinksState.linkedWebView = universalLink + Task { + // Sometimes, when navigating from a universal link, Euria can’t access the local storage right away, + // which causes the user to be logged out. + // To avoid this, we wait a few milliseconds before updating the state, giving Euria time to access it. + try? await Task.sleep(for: .milliseconds(500)) + + universalLinksState.linkedWebView = universalLink + } } } diff --git a/EuriaFeatures/MainView/MainView.swift b/EuriaFeatures/MainView/MainView.swift index 77b5e0f..bb54838 100644 --- a/EuriaFeatures/MainView/MainView.swift +++ b/EuriaFeatures/MainView/MainView.swift @@ -34,8 +34,7 @@ public struct MainView: View { @StateObject private var webViewDelegate: EuriaWebViewDelegate - @State private var webViewURL = URL(string: "https://\(ApiEnvironment.current.euriaHost)/")! - + @State private var webViewURL: URL @State private var isShowingWebView = true @State private var isShowingErrorAlert = false @@ -50,10 +49,10 @@ public struct MainView: View { } public init(session: any UserSessionable) { - _webViewDelegate = StateObject(wrappedValue: EuriaWebViewDelegate( - host: ApiEnvironment.current.euriaHost, - session: session - )) + let euriaHost = ApiEnvironment.current.euriaHost + + _webViewURL = State(wrappedValue: URL(string: "https://\(euriaHost)/")!) + _webViewDelegate = StateObject(wrappedValue: EuriaWebViewDelegate(host: euriaHost, session: session)) } public var body: some View { diff --git a/EuriaFeatures/MainView/WebView.swift b/EuriaFeatures/MainView/WebView.swift index 512f372..6085e6d 100644 --- a/EuriaFeatures/MainView/WebView.swift +++ b/EuriaFeatures/MainView/WebView.swift @@ -49,7 +49,7 @@ struct WebView: UIViewRepresentable { } func updateUIView(_ webView: WKWebView, context: Context) { - guard webView.url != url else { + guard url != webView.url else { return }