일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- RxCocoa
- HIG
- SWIFT
- 애니메이션
- rxswift
- Clean Code
- uitableview
- 클린 코드
- MVVM
- swiftUI
- Human interface guide
- UITextView
- Xcode
- 리펙터링
- clean architecture
- UICollectionView
- ribs
- collectionview
- Protocol
- Observable
- swift documentation
- 리펙토링
- uiscrollview
- ios
- Refactoring
- map
- combine
- tableView
- 스위프트
- 리팩토링
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 2. WKWebView - Header 설정, Cookie 설정, access token 전달, deeplink 수신 방법 본문
[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
- web site에서 특정 link를 클릭한 경우 > "mailto", "tel"과 같은 scheme인 경우,UIApplication을 통해 해당 화면을 디바이스에서 띄워주도록 설정
ex) WKWebView에서 특정 화면 이동, 클릭 시 webView(_:decidePolicyFor:decisionHandler:)에서 url 수신
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
print("링크 =>\(navigationAction.request.url)")
decisionHandler(.allow)
}
- WebView로부터 url을 수신했을 때, 네이티브에서 오픈하도록 처리 추가
- mailto, tel 이동 관련 개념은 이곳 참고: https://ios-development.tistory.com/435
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)
}
* 전체 소스 코드: 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/