관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 2. WKWebView - Header 설정, Cookie 설정, access token 전달, deeplink 수신 방법 본문

iOS 응용 (swift)

[iOS - swift] 2. WKWebView - Header 설정, Cookie 설정, access token 전달, deeplink 수신 방법

jake-kim 2021. 11. 7. 20:16

* WKWebView 기초 개념은 이곳 먼저 참고: https://ios-development.tistory.com/700

 

1. WKWebView - UIToolBar 사용하여 뒤로가기, 앞으로가기  구현 (goBack(), goForward())

2. WKWebView - Header 설정, Cookie 설정, access token 전달, deeplink 수신 방법

3. WKWebView - 양방향 통신, WKUserScript, WKScriptMessageHandler 델리게이트를 구현하여 JavaScript interface 사용 방법


Header 주입 방법

  • WebViewController에 header 프로퍼티 정의
private var headers: [String: String] {
    let bundleVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
    var header = ["Content-Type": "application/json"]
    header["app-device-uuid"] = UUID()
    header["app-device-os-version"] = UIDevice.current.systemVersion
    header["app-device-device-manufacturer"] = "apple"
    header["app-version"] = bundleVersion
    return header
}
  • load할 때 인수로 사용되는 urlRequest 인스턴스에 header정보를  setValue(_:forHTTPHeaderField:)를 통해 추가
private func loadWebPage() {
    let urlRequest = URLRequest(url: url)
    headers.forEach { urlRequest.setValue($0.value, forHTTPHeaderField: $0.key) } // <- 추가
    webView.load(urlRequest)
}

Cookie 설정

  • Cookie란?
    • 웹 사이트 접속 시 접속자의 개인장치에 다운로드되고 브라우저에 저장되는 텍스트 파일
  • 일반적인 Cookie를 사용하는 이유
    • 필수적인 Cookie: 웹사이트 기본적인 기능 활성화, 보안영역 접속 등을 위해 사용자 동의 없이 활성화되는 쿠키
    • 기능 Cookie: 웹사이트가 접속자의 지역, 언어를 보고 접속자의 설정에 따른 맞춤 기능
    • 성능 Cookie: 웹사이트 운영자가 더욱 최적화된 웹사이트 개발에 기여하기 위하여 통계 자료에 사용
    • 마케팅 Cookie: 유저 경향, 패턴을 파악하여 유저에게 관련성 높은 광고 제공
    • WKWebView에서 Cookie를 쓰는 경우
      • domain, path, name, 사용자 토큰 전달
    • Cookie를 주입하는 방법
      • 1) WKWebView를 생성할 때 configuration 인스턴스에 Cookie정보 주입 - 쿠키가 변경되면 대응이 불가능한 단점 존재
      • 2) WKNavigationDelegate의 webView(_:decidePolicyFor:decisionHandler:) 델리게이트에서 주입 - 쿠키가 변경되는 리다이렉트같은 방법에서 사용

access token를 WebView에 전달 방법

    • Cookie를 통해 accessToken을 전달 (위 "1)번" 방법으로 구현)
    • WebViewController에 HTTPCookie 프로피티 정의
private var authCookie: HTTPCookie? {
    let cookie = HTTPCookie(properties: [
        .domain: "https://ios-development.tistory.com/",
        .path: "748",
        .name: "CID_AUTH",
        .value: "test-access-token",
        .maximumAge: 7200, // Cookie의 유효한 지속시간
        .secure: "TRUE"
    ])
    return cookie
}
  • webView를 만들 때 WKWebViewConfiguration() 인스턴스를 주입할 수 있는데, 이 인스턴스에 cookie를 세팅하여 주입
    • WKWebsiteDataStore 인스턴스를 만들어서 이 인스턴스를 WKWebViewConfiguration 인스턴스에 주입
private func setupWebView() {
    let configuration = WKWebViewConfiguration()
    if let authCookie = authCookie {
        let dataStore = WKWebsiteDataStore.nonPersistent()
        dataStore.httpCookieStore.setCookie(authCookie)
        configuration.websiteDataStore = dataStore
    }

    webView = WKWebView(frame: .zero, configuration: configuration)
    webView.allowsBackForwardNavigationGestures = true
    webView.navigationDelegate = self
}
  • WKWebsiteDataStore란?
    • 웹 사이트에 관한 데이터를 관리하는 인스턴스이고 cookie와 같은 데이터를 관리
    • default()는 웹 사이트 데이터를 디스크에 영구적으로 저장
    • nonPersistent()는 access token이 필요한 웹 사이트와 같이 private한 곳에서 사용

deeplink 수신 방법

  • webView(_ webView:WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler @escaping (WKNavigationActionPolicy) -> Void) 메소드에서 구현
    • url정보 획득: navigationAction.request.url

ex) WKWebView에서 특정 화면 이동, 클릭 시 webView(_:decidePolicyFor:decisionHandler:)에서 url 수신

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    print("링크 =>\(navigationAction.request.url)")
    decisionHandler(.allow)
}

링크 클릭 시 해당 메소드에서 url 수신

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

    if let url = navigationAction.request.url, url.scheme == "mailto" || url.scheme == "tel" {
        if UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        }
        // url이 mailto, tel인 경우, webView에서 열리지 않도록 .cancel
        decisionHandler(.cancel)
    }

    // url이 네이티브에서 여는작업이 아닌 경우, webView에서 열리도록 .allow
    decisionHandler(.allow)
}

tel: 링크를 webView에서 누른 경우 통화로 이동

* 전체 소스 코드: https://github.com/JK0369/ExWKWebView/tree/ImplementCookie

 

* 참고

- webView(_:decidePolicyFor:decisionHandler:): https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455641-webview

- WKWebsiteDataStore: https://developer.apple.com/documentation/webkit/wkwebsitedatastore

- cookie의 개념: https://kobrekim.com/footer-ko-kr/cookie-policy-ko-kr/what-are-cookies-and-why-we-use-them-ko-kr/

Comments