OAWebView Init #67
Replies: 5 comments 4 replies
-
How about this way? @MainActor
public class OAWebViewCoordinator: NSObject {
let webView: OAWebView?
/// The oauth reference.
let oauth: OAuth
/// Initializer
/// - Parameter webView: the webview that is being coordinated.
init(_ webView: OAWebView) {
self.webView = webView
self.oauth = webView.oauth
super.init()
}
/// Initializer for testing
/// - Parameter oauth: the oauth reference.
init(_ oauth: OAuth) {
self.webView = nil
self.oauth = oauth
super.init()
}
...
} |
Beta Was this translation helpful? Give feedback.
-
I crafted up a couple of sample PRs to help myself fully understand the implications of changing the init signatures for the the OAWebView.init(oauth: OAuth):This change alters the public signature of the OAWebView to specify an OAuth object to use. ✅ Pros:
❌ Cons:
OAWebViewCoordinator.init(oauth: OAuth):This change alters the internal signature of the OAWebViewCoordinator to specify an OAuth object to use to allow for testing. ✅ Pros:
❌ Cons:
Food for ThoughtI dunno, the test coverage differences seems negligible. I suppose it depends on how clients actually init an OAuth object and use it inside their apps. If they have a custom way of initializing an OAuth object then they would almost certainly need to either do one of the following right?: OAWebView(oauth: oauth) OR OAWebView()
.environment(\.oauth, oauth) 🤷♂️ |
Beta Was this translation helpful? Give feedback.
-
I wanted to raise a potential security concern when logging into same issuer across multiple window scenes simultaneously, as currently, the same key is used for The reason I bring this up is that by extending this scenario, we might be conflating two distinct use cases, leading to some awkwardness in the current implementation. For most users, However, for advanced users who need multiple OAuth instances (e.g., maintaining simultaneous logged-in states, multi-scene apps, or different modules within the same scene handling separate tasks, or your example of package library This could be initialized with a uniqueId (e.g., UniqueOAuth(uniqueId: uuid.uuidString)), allowing Keychain to store multiple entries per service based on this ID. Users could then manage instances freely without interference. Additionally, UniqueOAuth wouldn’t be accessible via the environment’s default values, preventing accidental misuse or bugs. Following this approach would mean having OAWebView provide two distinct initialization methods:
WindowGroup(id: "oauth") {
OAWebView()
}
let oauth = UniqueOAuth(uniqueId: uuid)
WindowGroup(id: uuid) {
OAWebView(oauth: oauth)
} PS: I'm not sure UniqueOAuth should be provided by OAuthKit, an OAuthProtocol might be enough. Further details would depend on your vision for this project. This is more of a conceptual direction at this stage rather than a fully-baked proposal. |
Beta Was this translation helpful? Give feedback.
-
Oh I missed it! You're right, So, in multi-instance cases, IMO
@main
struct OAuthSampleApp: App {
static let id1 = UUID().uuidString
static let id2 = UUID().uuidString
@State var oauth1: OAuth = .init(.main, options: [.applicationTag: Self.id1])
@State var oauth2: OAuth = .init(.main, options: [.applicationTag: Self.id2])
var body: some Scene {
WindowGroup {
VStack {
ContentView()
.environment(\.oauth, oauth1)
ContentView()
.environment(\.oauth, oauth2)
}
}
#if !os(tvOS)
WindowGroup(id: Self.id1) {
OAWebView()
.environment(\.oauth, oauth1) // If I missed this one, OAWebView will read the default OAuth(.main)
OAWebView(oauth: oauth1) // better for prevent potential bugs
}
WindowGroup(id: Self.id2) {
...
}
#endif
}
} furthermore, if private func openWebView() {
#if !os(tvOS)
openWindow(id: "oauth", value: oauth) // if cannot conform to codable, openWindow(id: "oauth", value: oauth.applicationTag)
#endif
}
WindowGroup(id: "oauth", for: OAuth.self) { oauth in
OAWebView(oauth: oauth)
} |
Beta Was this translation helpful? Give feedback.
-
Change merged into milestone 1.2.0 |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Testing SwiftUI can be relatively painful as it usually requires XCUIApplication or abstracting out bits of internal view logic into ViewModels which just offers a layer of abstraction.
Currently the
OAWebView
is initialized with an empty constructor and has the OAuth object injected withIf we change the
OAWebView
to be initialized with an OAuth object instead of using the @Environment injection, we should be able to greatly improve the test coverage because this will allow tests to call theOAWebViewCoordinator
methods without using a.default
injected OAuth object.Beta Was this translation helpful? Give feedback.
All reactions