-
iOS/Swift WKWebView 쿠키 공유하기Language/iOS,AOS 2024. 9. 23. 16:54
iOS/Swift로 하이브리드 앱으로 개발된 서비스에서 새창일경우 View하나 만들어서 WKWebView로 페이지를 띄우는데 새창의 웹뷰에서 로그인이 되었을 경우에 부모창에는 쿠키가 공유되지 않는 문제가 발생하였다.
현재 버전에서 문제점을 파악하고 후딱 처리해보자.
웹에서 Bridge를 통해서 Native 함수를 호출하고 Native상 메소드에서 부모 WebView에 쿠키를 공유하는 방법으로 진행하였다.
React
Common library
// 자식창에서 로그인 후 부모창의 세션정보를 업데이트 하기 위해 사용 static updateSessionOfOpener() { if (Util.Browser.isAndroidApp()) { AndroidBridge.callOpener('Common.Native.updateSession'); } else if (Util.Browser.isIosApp()) { // IOS 자식창에서 로그인 후 부모창의 세션정보를 업데이트 window.updateSessionOfOpenerCallback = (jsonData) => { if (jsonData['result'] === false) { // updateSessionOfOpener이 Native에 없을떄 후처리 // alert('FAIL'); } else { // alert('SUCCESS'); } }; const message = { action: 'updateSessionOfOpener', callback: 'window.updateSessionOfOpenerCallback', }; window.webkit.messageHandlers.IosBridge1.postMessage(message); } else { if (window.opener && window.opener.sessionHandler) { window.opener.sessionHandler.update(); } } }
Swift
MainViewController
// MARK: - iOS Bridge // 웹 액션 정의 : WebAction을 구분하는데 사용되는 타입 enum WebAction: String { case setAppData case getAppData case getAppVersion case getVersionCode case loginWithKakao case loginWithNaver case loginWithFacebook case loginWithApple case windowFullPDF case windowFull case windowFrame case openExternalLink case windowClose case windowCloseAndOpenerReload case getNotificationId case getDeepLink case share case isNotificationAuthorization case updateSessionOfOpener } extension MainViewController: WKScriptMessageHandler { func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { guard message.name == IOS_BRIDGE_NAME, let messageBody = message.body as? [String: Any], let action = messageBody["action"] as? String else { return } let webAction = WebAction(rawValue: action) Utils.Log("@@@@@@@@@@@@@@@@@@@@@@@ \(action)") switch webAction { ... case .updateSessionOfOpener: // 로그인 후 팝업 웹뷰의 쿠키를 메인 웹뷰로 동기화 if let popupWKWebView = self.getActiveWkWebView(), let mainWKWebView = wKMainWeb { // 쿠키 동기화 후 메인 웹뷰만 새로고침 Utils.syncCookies(from: popupWKWebView, to: mainWKWebView) { // 쿠키 동기화 완료 후에 메인 웹뷰를 새로고침 mainWKWebView.reload() // 혹시 모르니 콜백 guard let callback = messageBody["callback"] as? String else { return } let jsonData: [String: Any] = [ "result": true ] if let jsonString = Utils.convertDictionaryToJSONString(dictionary: jsonData) { self.executeJavasScript(wKWeb: self.getActiveWkWebView(), callback: "\(callback)(\(jsonString));") } else { Utils.Log("Failed to convert dictionary to JSON string.") } } } default: Utils.Log("undefined action") // 콜백 함수 실행 guard let callback = messageBody["callback"] as? String else { return } let jsonData: [String: Any] = [ "result": false, "message": "undefined action" ] if let jsonString = Utils.convertDictionaryToJSONString(dictionary: jsonData) { self.executeJavasScript(wKWeb: self.getActiveWkWebView(), callback: "\(callback)(\(jsonString));") } else { Utils.Log("Failed to convert dictionary to JSON string.") } } } }
Utils
class Utils: NSObject { ... static func syncCookies(from sourceWebView: WKWebView, to targetWebView: WKWebView, completion: @escaping () -> Void) { sourceWebView.configuration.websiteDataStore.httpCookieStore.getAllCookies { cookies in for cookie in cookies { targetWebView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie) } // 쿠키 동기화가 끝난 후 completion 호출 completion() } } ... }
끝!
'Language > iOS,AOS' 카테고리의 다른 글
iOS, Swift에서 swipe back 제스처 인식기 추가 (0) 2024.12.26 CocoaPods 버전 올리기 (0) 2024.12.26 iOS에서 코코아팟 버전 업데이트 (0) 2024.09.23 iOS Swift Notification 권한 확인하는 방법 (0) 2024.07.10 네이티브 & React 배포 버전 이슈 처리 (0) 2024.07.10