From 09728e012c48a9a3201d384fb720cb5244746d3d Mon Sep 17 00:00:00 2001 From: dusanbaek Date: Sat, 1 Aug 2026 13:26:23 +0900 Subject: [PATCH] Fix Naver/Daum login not syncing back to the in-app WebView Login popups were opened in the system default browser via NSWorkspace, which stores cookies in a completely separate data store from the app's WKWebView. Logging in there never reflected in the app. Popups are now presented in an in-app window using the same WKWebViewConfiguration WebKit hands to createWebViewWith(_:for:), so the login session lands in the same cookie store as the main dictionary view. The main view reloads once the popup closes. --- Allkdic/Views/DictionaryWebView.swift | 49 +++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/Allkdic/Views/DictionaryWebView.swift b/Allkdic/Views/DictionaryWebView.swift index 24d5782..95cbeaf 100644 --- a/Allkdic/Views/DictionaryWebView.swift +++ b/Allkdic/Views/DictionaryWebView.swift @@ -57,12 +57,13 @@ private struct WebView: NSViewRepresentable { } @MainActor - class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate { + class Coordinator: NSObject, WKNavigationDelegate, WKUIDelegate, NSWindowDelegate { @Binding var isLoading: Bool var dictionary: DictionaryType var lastLoadedURL: String? weak var webView: WKWebView? private nonisolated(unsafe) var popoverObserver: NSObjectProtocol? + private var popupWindow: NSWindow? init(isLoading: Binding, dictionary: DictionaryType) { _isLoading = isLoading @@ -131,16 +132,50 @@ private struct WebView: NSViewRepresentable { self.lastLoadedURL = nil } + // Naver/Daum 로그인은 팝업 창(window.open)으로 뜨는데, 이걸 외부 브라우저로 보내면 + // 로그인 세션 쿠키가 앱의 WKWebView 데이터스토어와 공유되지 않아 로그인이 반영되지 않는다. + // 전달받은 configuration을 그대로 재사용해 같은 데이터스토어를 쓰는 팝업 웹뷰를 앱 안에 띄운다. func webView( _: WKWebView, - createWebViewWith _: WKWebViewConfiguration, - for navigationAction: WKNavigationAction, + createWebViewWith configuration: WKWebViewConfiguration, + for _: WKNavigationAction, windowFeatures _: WKWindowFeatures, ) -> WKWebView? { - if let url = navigationAction.request.url { - NSWorkspace.shared.open(url) - } - return nil + self.popupWindow?.close() + + let popupWebView = WKWebView(frame: NSRect(x: 0, y: 0, width: 480, height: 640), configuration: configuration) + popupWebView.navigationDelegate = self + popupWebView.uiDelegate = self + + let window = NSWindow( + contentRect: popupWebView.frame, + styleMask: [.titled, .closable, .resizable], + backing: .buffered, + defer: false, + ) + window.isReleasedWhenClosed = false + window.title = self.dictionary.title + window.contentView = popupWebView + window.delegate = self + window.center() + window.makeKeyAndOrderFront(nil) + NSApp.activate(ignoringOtherApps: true) + + self.popupWindow = window + return popupWebView + } + + // 로그인 완료 후 팝업이 스스로 닫힐 때(window.close()) 호출된다. + func webViewDidClose(_: WKWebView) { + self.popupWindow?.close() + } + + // 팝업이 어떤 경로로든(로그인 완료, 사용자가 직접 닫기) 닫히면 + // 로그인 세션이 반영되도록 메인 웹뷰를 새로고침한다. + func windowWillClose(_ notification: Notification) { + guard notification.object as? NSWindow === self.popupWindow else { return } + self.popupWindow = nil + self.webView?.reload() } } }