iOS 13버전의 등장으로 UIWebView가 완전히 deprecated 되면서 wkwebview로 변경 하여야 한다.
WKWebViw경우는 iOS 8 버전이후에 도입 되었다.
두 웹뷰 간의 자세한 차이는 iOS ) UIWebView와 WKWebView의 차이를 한 번 읽어 보자.
기본적인 메소드 변경은 큰 어려움이 없다.
아래 코드는 UIWebView WkWebView 변경시 필수 메서드 변경하는 코드이다.
//1) shouldStartLoadWithRequest -> decidePolicyForNavigationAction
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSURLRequest* request = [navigationAction request];
decisionHandler(WKNavigationActionPolicyAllow); //꼭 호출 해주어야 함
//재 탐색이 필요 한 경우 처리후 아래 함수 호출
decisionHandler(WKNavigationActionPolicyCancel);
}
//2) webViewDidStartLoad -> didStartProvisionalNavigation
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
{
}
//3) webViewDidFinishLoad -> didFinishNavigation
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
}
//4) didFailLoadWithError -> didFailNavigation
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
}
// UIWebViewDelegate -> WKNavigationDelegate
// setDelegate -> setNavigationDelegate
// 로 변경 하면 된다.
매서드의 변경은 위에 코드를 통해서 간단하게 처리 할 수 가 있다.
UIWebView에서 WkWebView 변경시 가장 큰 문제는 쿠키 정보이다.
UIWevView의 경우 NSHTTPCookieStorage를 이용해서 쿠키를 자동으로 관리를 해줬다.
하지만 WKWebView의 경우 쿠키가 각각의 Cookie Storage에 저장되고 해당 쿠키 스토리지는 다른 저장소와 서로 공유가 되지 않는다.
그래서 쿠키를 직접 관리를 해줘야 한다.
iOS 11 이상 부터는 쿠키를 공유할 때에 사용 할 수 있는 WKProcessPool 이 있다. WkWebView를 생성할 때에 WKWebViewConfiguration 을 넣어 줄수 있는데 여기에 WKProcessPool을 싱글톤으로 넣어 주면 된다.
WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];
// 쿠키 공유를 위해서 싱글톤으로 만들어서 넣어 주자.
configuration.processPool = [WKProcessPool sharedProcessPool];
configuration.dataDetectorTypes = WKDataDetectorTypeAll;
// 쿠키 셋팅을 위해서 해당 플래그 설정.
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistentDataStore;
mWebView = [[[WKWebView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)
configuration:configuration] autorelease];
[mWebView setNavigationDelegate:self];
쿠키 관리는 WKHTTPCookieStore 를 통해서 관리 할 수 있다.
쿠키 관련 함수로는 setCookie, getAllCookies, delete가 가능하다.
NSHTTPCookieStorage에 있는 쿠키 데이터를 setCookie 하였지만 정상 동작을 하지 않았다.
쿠키가 적용되어서 정상적인 로드를 할 때도 있고 아닐 때도 있고 정확한 원인은 파악이 되지 않았는데.. 찾아보니 WKWebSiteDataStore에 설정을 해주니 정상적으로 쿠키 적용이 되었다.
iOS WKWebView setCookie not working!!! 해결 해당 블로그를 참고 했다.
쿠키 셋팅 후 Request 하는 코드이다.
if (@available(iOS 11.0, *))
{
dispatch_async(dispatch_get_main_queue(), ^{
NSArray *sCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
for (NSHTTPCookie *cookie in sCookies)
{
[webview.configuration.websiteDataStore.httpCookieStore setCookie:cookie completionHandler:^{
//쿠키 셋팅 후 요청
[webview loadRequest:aRequest];
}];
}
});
}
현재 프로젝트의 target 이 ios 9.0이라서 WKProcessPool을 사용 할 수가 없어서 방법을 찾아보니
request를 할때 header에 “Cookie” Field를 추가 하면 된다.
이 방법은 iOS 상위버전에서도 사용이 가능하다.
NSDictionary *cookies = [NSHTTPCookie requestHeaderFieldsWithCookies:[[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:aRequest.URL]];
if ([cookies objectForKey:@"Cookie"])
{
[aRequest addValue:cookies[@"Cookie"] forHTTPHeaderField:@"Cookie"];
[webview loadRequest:aRequest];
}
쿠키 관련 처리 때문에 변경하는데 있어서 시간이 좀 걸렸었다. 그래도 참고 할 자료가 꽤 있어서 편하게 변경 작업을 한 거 같다.
참고
Objective-CWKWebView 쿠키 관리하기 - EmilY - Medium
Stack Overflow - Where Developers Learn, Share, & Build Careers