prosource

WKWebView에서 사용할 쿠키를 설정할 수 있습니까?

probook 2023. 7. 17. 21:12
반응형

WKWebView에서 사용할 쿠키를 설정할 수 있습니까?

기존 앱을 에서 전환하려고 합니다.UIWebViewWKWebView합니다.webview합니다.cookies 필다니합요에 인증하기 합니다.NSHTTPCookieStore도 새로운 유감럽도새운로게스.WKWebView를 사용하지 않습니다.cookiesNSHTTPCookieStorage이것을 달성할 수 있는 다른 방법이 있습니까?

iOS 11+ 전용 편집

WKHTTP CookieStore 사용:

let cookie = HTTPCookie(properties: [
    .domain: "example.com",
    .path: "/",
    .name: "MyCookieName",
    .value: "MyCookieValue",
    .secure: "TRUE",
    .expires: NSDate(timeIntervalSinceNow: 31556926)
])! 

webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)

HTTP CookStorage에서 이러한 파일을 끌어오기 때문에 다음 작업을 수행할 수 있습니다.

let cookies = HTTPCookieStorage.shared.cookies ?? []
for cookie in cookies {
    webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
}

iOS 10 이하에 대한 이전 답변

초기 로드 요청에 쿠키를 설정해야 하는 경우 NSMutable에서 쿠키를 설정할 수 있습니다.URL 요청입니다.쿠키는 특수하게 포맷된 요청 헤더일 뿐이므로 다음과 같이 수행할 수 있습니다.

WKWebView * webView = /*set up your webView*/
NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/index.html"]];
[request addValue:@"TeskCookieKey1=TeskCookieValue1;TeskCookieKey2=TeskCookieValue2;" forHTTPHeaderField:@"Cookie"];
// use stringWithFormat: in the above line to inject your values programmatically
[webView loadRequest:request];

페이지에서 후속 AJAX 요청에 쿠키를 설정해야 하는 경우 WKUserScript를 사용하여 문서 시작 시 Javascript를 통해 다음과 같이 값을 프로그래밍 방식으로 설정하면 됩니다.

WKUserContentController* userContentController = WKUserContentController.new;
WKUserScript * cookieScript = [[WKUserScript alloc] 
    initWithSource: @"document.cookie = 'TeskCookieKey1=TeskCookieValue1';document.cookie = 'TeskCookieKey2=TeskCookieValue2';"
    injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
// again, use stringWithFormat: in the above line to inject your values programmatically
[userContentController addUserScript:cookieScript];
WKWebViewConfiguration* webViewConfig = WKWebViewConfiguration.new;
webViewConfig.userContentController = userContentController;
WKWebView * webView = [[WKWebView alloc] initWithFrame:CGRectMake(/*set your values*/) configuration:webViewConfig];

이 두 가지 기술을 결합하면 쿠키 값을 Native App Land에서 Web View Land로 전송할 수 있는 충분한 도구가 제공됩니다.추가 고급 쿠키가 필요한 경우 Mozilla의 페이지에서 쿠키 자바스크립트 API에 대한 자세한 정보를 확인할 수 있습니다.

네, Apple이 UI WebView의 많은 세부 사항을 지원하지 않는 것은 최악입니다.그들이 그들을 지지할지는 확실하지 않지만, 바라건대 그들이 곧 이것에 참여하기를 바랍니다.

답변을 가지고 논 후 (환상적으로 도움이 되었습니다 :) 우리는 몇 가지 변경을 해야 했습니다.

  • 여러 도메인 간에 개인 쿠키 정보를 유출하지 않고 여러 도메인을 처리하려면 웹 뷰가 필요합니다.
  • 안전한 쿠키를 존중하기 위해 필요합니다.
  • , 의 앱이 값에 .NSHTTPCookieStorage
  • 서버가 쿠키 값을 변경하는 경우 링크/AJAX 등을 따를 때 스크립트가 쿠키 값을 원래 값으로 재설정하지 않습니다.

그래서 우리는 코드를 이것으로 수정했습니다.

요청 생성

NSMutableURLRequest *request = [originalRequest mutableCopy];
NSString *validDomain = request.URL.host;
const BOOL requestIsSecure = [request.URL.scheme isEqualToString:@"https"];

NSMutableArray *array = [NSMutableArray array];
for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
    // Don't even bother with values containing a `'`
    if ([cookie.name rangeOfString:@"'"].location != NSNotFound) {
        NSLog(@"Skipping %@ because it contains a '", cookie.properties);
        continue;
    }

    // Is the cookie for current domain?
    if (![cookie.domain hasSuffix:validDomain]) {
        NSLog(@"Skipping %@ (because not %@)", cookie.properties, validDomain);
        continue;
    }

    // Are we secure only?
    if (cookie.secure && !requestIsSecure) {
        NSLog(@"Skipping %@ (because %@ not secure)", cookie.properties, request.URL.absoluteString);
        continue;
    }

    NSString *value = [NSString stringWithFormat:@"%@=%@", cookie.name, cookie.value];
    [array addObject:value];
}

NSString *header = [array componentsJoinedByString:@";"];
[request setValue:header forHTTPHeaderField:@"Cookie"];

// Now perform the request...

이렇게 하면 다른 도메인용 공유 저장소에서 쿠키를 보내지 않고 안전하지 않은 요청에 보안 쿠키를 보내지 않고 첫 번째 요청에 올바른 쿠키 세트가 있는지 확인할 수 있습니다.

추가 요청 처리

또한 다른 요청에도 쿠키가 설정되어 있는지 확인해야 합니다. 쿠키 세트가 없으면 세트에 합니다.NSHTTPCookieStorage.

// Get the currently set cookie names in javascriptland
[script appendString:@"var cookieNames = document.cookie.split('; ').map(function(cookie) { return cookie.split('=')[0] } );\n"];

for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
    // Skip cookies that will break our script
    if ([cookie.value rangeOfString:@"'"].location != NSNotFound) {
        continue;
    }

    // Create a line that appends this cookie to the web view's document's cookies
    [script appendFormat:@"if (cookieNames.indexOf('%@') == -1) { document.cookie='%@'; };\n", cookie.name, cookie.wn_javascriptString];
}

WKUserContentController *userContentController = [[WKUserContentController alloc] init];
WKUserScript *cookieInScript = [[WKUserScript alloc] initWithSource:script
                                                      injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                                                   forMainFrameOnly:NO];
[userContentController addUserScript:cookieInScript];

...

// Create a config out of that userContentController and specify it when we create our web view.
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.userContentController = userContentController;

self.webView = [[WKWebView alloc] initWithFrame:webView.bounds configuration:config];

쿠키 변경 처리

또한 서버가 쿠키의 값을 변경하는 것도 처리해야 합니다.은 우리가 웹하는 것을 합니다.NSHTTPCookieStorage.

WKUserScript *cookieOutScript = [[WKUserScript alloc] initWithSource:@"window.webkit.messageHandlers.updateCookies.postMessage(document.cookie);"
                                                       injectionTime:WKUserScriptInjectionTimeAtDocumentStart
                                                    forMainFrameOnly:NO];
[userContentController addUserScript:cookieOutScript];

[userContentController addScriptMessageHandler:webView
                                          name:@"updateCookies"];

변경된 쿠키를 업데이트하는 위임 방법을 구현하여 현재 도메인의 쿠키만 업데이트합니다!

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    NSArray<NSString *> *cookies = [message.body componentsSeparatedByString:@"; "];
    for (NSString *cookie in cookies) {
        // Get this cookie's name and value
        NSArray<NSString *> *comps = [cookie componentsSeparatedByString:@"="];
        if (comps.count < 2) {
            continue;
        }

        // Get the cookie in shared storage with that name
        NSHTTPCookie *localCookie = nil;
        for (NSHTTPCookie *c in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:self.wk_webView.URL]) {
            if ([c.name isEqualToString:comps[0]]) {
                localCookie = c;
                break;
            }
        }

        // If there is a cookie with a stale value, update it now.
        if (localCookie) {
            NSMutableDictionary *props = [localCookie.properties mutableCopy];
            props[NSHTTPCookieValue] = comps[1];
            NSHTTPCookie *updatedCookie = [NSHTTPCookie cookieWithProperties:props];
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:updatedCookie];
        }
    }
}

이렇게 하면 WKWebView를 사용하는 각 장소를 다르게 처리할 필요 없이 쿠키 문제를 해결할 수 있습니다. 이 웹 수 하게 업데이트할 수 있습니다.NSHTTPCookieStorage우리를 위하여


편집: 알고 보니 NSHTT Pookie의 개인 카테고리를 사용했습니다. 코드는 다음과 같습니다.

- (NSString *)wn_javascriptString {
    NSString *string = [NSString stringWithFormat:@"%@=%@;domain=%@;path=%@",
                        self.name,
                        self.value,
                        self.domain,
                        self.path ?: @"/"];

    if (self.secure) {
        string = [string stringByAppendingString:@";secure=true"];
    }

    return string;
}

쿠키는 다음을 수행하기 전에 구성에 설정해야 합니다.WKWebView생성됩니다.그렇지 않을 경우에도WKHTTPCookieStoresetCookie완료 핸들러, 쿠키가 웹 보기에 안정적으로 동기화되지 않습니다.이것은 다음 문서에서 이 줄로 돌아갑니다.WKWebViewConfiguration

@NSCopying var configuration: WKWebViewConfiguration { get }

ㅠㅠ@NSCopying약간 딥 카피에 가깝습니다.구현은 불가능하지만, 웹 보기를 초기화하기 전에 쿠키를 설정하지 않으면 쿠키가 존재하는지 확인할 수 없습니다.보기 초기화가 비동기 프로세스가 되기 때문에 앱 아키텍처가 복잡해질 수 있습니다.은 결국 될

extension WKWebViewConfiguration {
    /// Async Factory method to acquire WKWebViewConfigurations packaged with system cookies
    static func cookiesIncluded(completion: @escaping (WKWebViewConfiguration?) -> Void) {
        let config = WKWebViewConfiguration()
        guard let cookies = HTTPCookieStorage.shared.cookies else {
            completion(config)
            return
        }
        // Use nonPersistent() or default() depending on if you want cookies persisted to disk
        // and shared between WKWebViews of the same app (default), or not persisted and not shared
        // across WKWebViews in the same app.
        let dataStore = WKWebsiteDataStore.nonPersistent()
        let waitGroup = DispatchGroup()
        for cookie in cookies {
            waitGroup.enter()
            dataStore.httpCookieStore.setCookie(cookie) { waitGroup.leave() }
        }
        waitGroup.notify(queue: DispatchQueue.main) {
            config.websiteDataStore = dataStore
            completion(config)
        }
    }
}

그리고 나서 그것을 사용하는 것과 같은 것.

override func loadView() {
    view = UIView()
    WKWebViewConfiguration.cookiesIncluded { [weak self] config in
        let webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.load(request)
        self.view = webView
    }
}

위의 예에서는 뷰 작성을 가능한 마지막 순간까지 연기합니다. 또 다른 해결책은 구성 또는 웹 뷰를 미리 작성하고 뷰 컨트롤러를 작성하기 전에 비동기성을 처리하는 것입니다.

마지막 참고: 일단 이 웹 보기를 만든 후에는 야생 상태로 설정하면 이 답변에 설명된 방법을 사용하지 않고는 쿠키를 추가할 수 없습니다.그러나 사용할 수 있습니다.WKHTTPCookieStoreObserver적어도 쿠키에 일어나는 변화를 관찰하기 위한 api.따라서 웹 보기에서 세션 쿠키가 업데이트되는 경우 시스템의 쿠키를 수동으로 업데이트할 수 있습니다.HTTPCookieStorage원하는 경우 이 새로운 쿠키와 함께.

이에 대한 자세한 내용은 2017 WWDC 세션 사용자 지정 콘텐츠 로드에서 18:00으로 건너뜁니다.이 세션을 시작할 때 완료 처리기에 웹 보기를 만들어야 한다는 사실을 생략하는 기만적인 코드 샘플이 있습니다.

cookieStore.setCookie(cookie!) {
    webView.load(loggedInURLRequest)
}

18시에 진행되는 라이브 데모를 통해 이를 명확하게 알 수 있습니다.

적어도 모하비 베타 7과 iOS 12 베타 7의 편집에서 쿠키에 대한 훨씬 더 일관된 동작을 보고 있습니다.setCookie(_:)방법은 심지어 쿠키를 설정하는 것을 허용하는 것으로 보입니다.WKWebView가 생성되었습니다.하지만 나는 그것을 만지지 않는 것이 중요하다고 생각했습니다.processPool 속성이될 때 합니다.쿠키 설정 기능은 추가 풀이 생성되지 않고 해당 속성이 잘 유지될 때 가장 잘 작동합니다.웹킷의 버그로 인해 문제가 발생했다고 봐도 무방할 것 같습니다.

나를 위한 일

func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
    let headerFields = navigationAction.request.allHTTPHeaderFields
    var headerIsPresent = contains(headerFields?.keys.array as! [String], "Cookie")

    if headerIsPresent {
        decisionHandler(WKNavigationActionPolicy.Allow)
    } else {
        let req = NSMutableURLRequest(URL: navigationAction.request.URL!)
        let cookies = yourCookieData
        let values = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies)
        req.allHTTPHeaderFields = values
        webView.loadRequest(req)

        decisionHandler(WKNavigationActionPolicy.Cancel)
    }
}

여기 HTTP CookieStorage에서 모든 쿠키를 주입하기 위한 Swift의 Mattrs 솔루션 버전이 있습니다.이 작업은 주로 사용자 세션을 만들기 위해 인증 쿠키를 주입하기 위해 수행되었습니다.

public func setupWebView() {
    let userContentController = WKUserContentController()
    if let cookies = HTTPCookieStorage.shared.cookies {
        let script = getJSCookiesString(for: cookies)
        let cookieScript = WKUserScript(source: script, injectionTime: .atDocumentStart, forMainFrameOnly: false)
        userContentController.addUserScript(cookieScript)
    }
    let webViewConfig = WKWebViewConfiguration()
    webViewConfig.userContentController = userContentController

    self.webView = WKWebView(frame: self.webViewContainer.bounds, configuration: webViewConfig)
}

///Generates script to create given cookies
public func getJSCookiesString(for cookies: [HTTPCookie]) -> String {
    var result = ""
    let dateFormatter = DateFormatter()
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
    dateFormatter.dateFormat = "EEE, d MMM yyyy HH:mm:ss zzz"

    for cookie in cookies {
        result += "document.cookie='\(cookie.name)=\(cookie.value); domain=\(cookie.domain); path=\(cookie.path); "
        if let date = cookie.expiresDate {
            result += "expires=\(dateFormatter.stringFromDate(date)); "
        }
        if (cookie.secure) {
            result += "secure; "
        }
        result += "'; "
    }
    return result
}

세트 쿠키

self.webView.evaluateJavaScript("document.cookie='access_token=your token';domain='your domain';") { (data, error) -> Void in
        self.webView.reload()
}

쿠키 삭제

self.webView.evaluateJavaScript("document.cookie='access_token=';domain='your domain';") { (data, error) -> Void in
        self.webView.reload()
}

Swift 3 업데이트:

func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
    if let urlResponse = navigationResponse.response as? HTTPURLResponse,
       let url = urlResponse.url,
       let allHeaderFields = urlResponse.allHeaderFields as? [String : String] {
       let cookies = HTTPCookie.cookies(withResponseHeaderFields: allHeaderFields, for: url)
       HTTPCookieStorage.shared.setCookies(cookies , for: urlResponse.url!, mainDocumentURL: nil)
       decisionHandler(.allow)
    }
}

iOS 11에서는 이제 쿠키를 관리할 수 있습니다:), 다음 세션을 참조하십시오. https://developer.apple.com/videos/play/wwdc2017/220/

enter image description here

여기서 다양한 답변을 살펴보았지만 아무런 성공을 거두지 못한 후, 저는 웹킷 문서를 뒤적였고 우연히 다음과 같은 것을 발견했습니다.requestHeaderFields method on the static HTTPCookie쿠키 배열을 헤더 필드에 적합한 형식으로 변환합니다.이것과 업데이트에 대한 mattr의 통찰력을 결합합니다.URLRequest쿠키 헤더를 넣기 전에 저는 결승선을 통과했습니다.

Swift 4.1, 4.2, 5.0:

var request = URLRequest(url: URL(string: "https://example.com/")!)
let headers = HTTPCookie.requestHeaderFields(with: cookies)
for (name, value) in headers {
    request.addValue(value, forHTTPHeaderField: name)
}

let webView = WKWebView(frame: self.view.frame)
webView.load(request)

이를 더욱 쉽게 하려면 확장자를 사용합니다.

extension WKWebView {
    func load(_ request: URLRequest, with cookies: [HTTPCookie]) {
        var request = request
        let headers = HTTPCookie.requestHeaderFields(with: cookies)
        for (name, value) in headers {
            request.addValue(value, forHTTPHeaderField: name)
        }

        load(request)
    }
}

이제는 다음과 같습니다.

let request = URLRequest(url: URL(string: "https://example.com/")!)
let webView = WKWebView(frame: self.view.frame)
webView.load(request, with: cookies)

이 확장 기능은 Lionheart Extensions에서도 사용할 수 있습니다.건배!

이 답변을 올린 이유는 많은 솔루션을 시도했지만 제대로 작동하는 사람이 없었고, 쿠키를 처음 설정해야 하는 경우 대부분의 답변이 작동하지 않고, 쿠키가 동기화되지 않는 결과가 나왔습니다. iOS > = 11.0 < = iOS 11 ~ 8.0 모두 작동하며, 쿠키 동기화도 처음 작동합니다.

iOS > = 11.0의 경우 -- Swift 4.2

http 쿠키를 가져와서 wkwebview 쿠키 저장소에 이렇게 설정하면 wkwebview에서 요청을 로드하기가 매우 까다로운 지점입니다. 쿠키가 완전히 설정되면 로드 요청을 보내야 합니다. 여기 제가 작성한 기능이 있습니다.

load webview를 호출하는 종료 완료와 함께 호출 기능.참고로 이 기능은 iOS > = 11.0만 처리합니다.

self.WwebView.syncCookies {
    if let request = self.request {
       self.WwebView.load(request)
    }
}

다음은 syncCookies 함수에 대한 구현입니다.

func syncCookies(completion:@escaping ()->Void) {

if #available(iOS 11.0, *) {

      if let yourCookie = "HERE_YOUR_HTTP_COOKIE_OBJECT" {
        self.configuration.websiteDataStore.httpCookieStore.setCookie(yourCookie, completionHandler: {
              completion()
        })
     }
  } else {
  //Falback just sent 
  completion()
}
}

iOS 8부터 iOS 11까지

당신은 WKUserScript를 사용하여 두 개의 타임 쿠키를 설정해야 하며 요청에 쿠키를 추가하는 것을 잊지 마십시오. 그렇지 않으면 쿠키가 처음에 동기화되지 않고 페이지가 처음에 제대로 로드되지 않는 것을 볼 수 있습니다.이것이 iOS 8.0용 쿠키를 지원한다는 것을 알게 된 이유입니다.

wkwebview 객체를 만들기 전에.

func setUpWebView() {

    let userController: WKUserContentController = WKUserContentController.init()

    if IOSVersion.SYSTEM_VERSION_LESS_THAN(version: "11.0") {
        if let cookies = HTTPCookieStorage.shared.cookies {
            if let script = getJSCookiesString(for: cookies) {
                cookieScript = WKUserScript(source: script, injectionTime: .atDocumentStart, forMainFrameOnly: false)
                userController.addUserScript(cookieScript!)
            }
        }
    }

    let webConfiguration = WKWebViewConfiguration()
    webConfiguration.processPool = BaseWebViewController.processPool


    webConfiguration.userContentController = userController


    let customFrame = CGRect.init(origin: CGPoint.zero, size: CGSize.init(width: 0.0, height: self.webContainerView.frame.size.height))
    self.WwebView = WKWebView (frame: customFrame, configuration: webConfiguration)
    self.WwebView.translatesAutoresizingMaskIntoConstraints = false
    self.webContainerView.addSubview(self.WwebView)
    self.WwebView.uiDelegate = self
    self.WwebView.navigationDelegate = self
    self.WwebView.allowsBackForwardNavigationGestures = true // A Boolean value indicating whether horizontal swipe gestures will trigger back-forward list navigations
    self.WwebView.addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: nil)


 self.view.addConstraint(NSLayoutConstraint(item: WwebView, attribute: .trailing, relatedBy: .equal, toItem: self.webContainerView, attribute: .trailing, multiplier: 1, constant: 0))
    self.view.addConstraint(NSLayoutConstraint(item: WwebView, attribute: .leading, relatedBy: .equal, toItem: self.webContainerView, attribute: .leading, multiplier: 1, constant: 0))
    self.view.addConstraint(NSLayoutConstraint(item: WwebView, attribute: .top, relatedBy: .equal, toItem: self.webContainerView, attribute: .top, multiplier: 1, constant: 0))
    self.view.addConstraint(NSLayoutConstraint(item: WwebView, attribute: .bottom, relatedBy: .equal, toItem: self.webContainerView, attribute: .bottom, multiplier: 1, constant: 0))


}

이 함수에 초점을 맞춥니다. getJSCookies 문자열

 public func getJSCookiesString(for cookies: [HTTPCookie]) -> String? {

    var result = ""
    let dateFormatter = DateFormatter()
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
    dateFormatter.dateFormat = "EEE, d MMM yyyy HH:mm:ss zzz"

    for cookie in cookies {
        if cookie.name == "yout_cookie_name_want_to_sync" {
            result += "document.cookie='\(cookie.name)=\(cookie.value); domain=\(cookie.domain); path=\(cookie.path); "
            if let date = cookie.expiresDate {
                result += "expires=\(dateFormatter.string(from: date)); "
            }
            if (cookie.isSecure) {
                result += "secure; "
            }
            result += "'; "
        }

    }

    return result
}

여기 쿠키를 즉시 동기화하지 않는 다른 단계가 있습니다. 쿠키가 포함된 첫 페이지를 로드해야 하는 많은 문제가 있습니다. 프로세스가 종료되면 웹 뷰를 다시 로드하는 것이지만 사용하지 않는 것이 좋습니다. 사용자 관점에서 좋지 않습니다. 이런 식으로 요청 헤더에 쿠키를 로드할 준비가 되면 언제든지 문제가 됩니다.로드 요청 전에 iOS 버전 확인을 추가하는 것을 잊지 마십시오. 이 기능을 호출합니다.

request?.addCookies()

는 URLRequest를 위해 확장자를 썼습니다.

extension URLRequest {

internal mutating func addCookies() {
    //"appCode=anAuY28ucmFrdXRlbi5yZXdhcmQuaW9zLXpOQlRTRmNiejNHSzR0S0xuMGFRb0NjbUg4Ql9JVWJH;rpga=kW69IPVSYZTo0JkZBicUnFxC1g5FtoHwdln59Z5RNXgJoMToSBW4xAMqtf0YDfto;rewardadid=D9F8CE68-CF18-4EE6-A076-CC951A4301F6;rewardheader=true"
    var cookiesStr: String = ""

    if IOSVersion.SYSTEM_VERSION_LESS_THAN(version: "11.0") {
        let mutableRequest = ((self as NSURLRequest).mutableCopy() as? NSMutableURLRequest)!
        if let yourCookie = "YOUR_HTTP_COOKIE_OBJECT" {
            // if have more than one cookies dont forget to add ";" at end
            cookiesStr += yourCookie.name + "=" + yourCookie.value + ";"

            mutableRequest.setValue(cookiesStr, forHTTPHeaderField: "Cookie")
            self = mutableRequest as URLRequest

        }
    }

  }
}

이제 iOS > 8을 테스트할 준비가 되었습니다.

내가 하고 있던 이 실수는 도메인 속성의 전체 URL을 전달하는 것입니다. 도메인 이름이어야 합니다.

let cookie = HTTPCookie(properties: [
.domain: "example.com",
.path: "/",
.name: "MyCookieName",
.value: "MyCookieValue",
.secure: "TRUE",
])! 

webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)

iOS 10+용 솔루션

세부 사항

  • 스위프트 5.1
  • Xcode 11.6(11E708)

해결책

import UIKit
import WebKit
extension WKWebViewConfiguration {
    func set(cookies: [HTTPCookie], completion: (() -> Void)?) {
        if #available(iOS 11.0, *) {
            let waitGroup = DispatchGroup()
            for cookie in cookies {
                waitGroup.enter()
                websiteDataStore.httpCookieStore.setCookie(cookie) { waitGroup.leave() }
            }
            waitGroup.notify(queue: DispatchQueue.main) { completion?() }
        } else {
            cookies.forEach { HTTPCookieStorage.shared.setCookie($0) }
            self.createCookiesInjectionJS(cookies: cookies) {
                let script = WKUserScript(source: $0, injectionTime: .atDocumentStart, forMainFrameOnly: false)
                self.userContentController.addUserScript(script)
                DispatchQueue.main.async { completion?() }
            }
        }
    }

    private func createCookiesInjectionJS (cookies: [HTTPCookie],  completion: ((String) -> Void)?) {
        var scripts: [String] = ["var cookieNames = document.cookie.split('; ').map(function(cookie) { return cookie.split('=')[0] } )"]
        let now = Date()

        for cookie in cookies {
            if let expiresDate = cookie.expiresDate, now.compare(expiresDate) == .orderedDescending { continue }
            scripts.append("if (cookieNames.indexOf('\(cookie.name)') == -1) { document.cookie='\(cookie.javaScriptString)'; }")
        }
        completion?(scripts.joined(separator: ";\n"))
    }
}

extension WKWebView {
    func loadWithCookies(request: URLRequest) {
        if #available(iOS 11.0, *) {
            load(request)
        } else {
            var _request = request
            _request.setCookies()
            load(_request)
        }
    }
}

extension URLRequest {

    private static var cookieHeaderKey: String { "Cookie" }
    private static var noAppliedcookieHeaderKey: String { "No-Applied-Cookies" }

    var hasCookies: Bool {
        let headerKeys = (allHTTPHeaderFields ?? [:]).keys
        var hasCookies = false
        if headerKeys.contains(URLRequest.cookieHeaderKey) { hasCookies = true }
        if !hasCookies && headerKeys.contains(URLRequest.noAppliedcookieHeaderKey) { hasCookies = true }
        return hasCookies
    }

    mutating func setCookies() {
        if #available(iOS 11.0, *) { return }
        var cookiesApplied = false
        if let url = self.url, let cookies = HTTPCookieStorage.shared.cookies(for: url) {
            let headers = HTTPCookie.requestHeaderFields(with: cookies)
            for (name, value) in headers { setValue(value, forHTTPHeaderField: name) }
            cookiesApplied = allHTTPHeaderFields?.keys.contains(URLRequest.cookieHeaderKey) ?? false
        }
        if !cookiesApplied { setValue("true", forHTTPHeaderField: URLRequest.noAppliedcookieHeaderKey) }
    }
}

/// https://github.com/Kofktu/WKCookieWebView/blob/master/WKCookieWebView/WKCookieWebView.swift
extension HTTPCookie {

    var javaScriptString: String {
        if var properties = properties {
            properties.removeValue(forKey: .name)
            properties.removeValue(forKey: .value)

            return properties.reduce(into: ["\(name)=\(value)"]) { result, property in
                result.append("\(property.key.rawValue)=\(property.value)")
            }.joined(separator: "; ")
        }

        var script = [
            "\(name)=\(value)",
            "domain=\(domain)",
            "path=\(path)"
        ]

        if isSecure { script.append("secure=true") }

        if let expiresDate = expiresDate {
            script.append("expires=\(HTTPCookie.dateFormatter.string(from: expiresDate))")
        }

        return script.joined(separator: "; ")
    }

    private static let dateFormatter: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "en_US")
        dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
        dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
        return dateFormatter
    }()
}

사용.

여기에 솔루션 코드를 붙여넣는 것을 잊지 마십시오.

class WebViewController: UIViewController {
   
    private let host = "google.com"
    private weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupWebView()
    }
    
    func setupWebView() {
        let cookies: [HTTPCookie] = []
        let configuration = WKWebViewConfiguration()
        configuration.websiteDataStore = .nonPersistent()
        configuration.set(cookies: cookies) {
            let webView = WKWebView(frame: .zero, configuration: configuration)
            /// ..
            self.webView = webView
            
            self.loadPage(url: URL(string:self.host)!)
        }
    }
    
    private func loadPage(url: URL) {
        var request = URLRequest(url: url)
        request.setCookies()
        webView.load(request)
    }
}

extension WebViewController: WKNavigationDelegate {

     // https://stackoverflow.com/a/47529039/4488252
     func webView(_ webView: WKWebView,
                  decidePolicyFor navigationAction: WKNavigationAction,
                  decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

         if #available(iOS 11.0, *) {
             decisionHandler(.allow)
         } else {
             guard let url = navigationAction.request.url, let host = url.host, host.contains(self.host) else {
                 decisionHandler(.allow)
                 return
             }

             if navigationAction.request.hasCookies {
                 decisionHandler(.allow)
             } else {
                 DispatchQueue.main.async {
                     decisionHandler(.cancel)
                     self.loadPage(url: url)
                 }
             }
         }
     }
 }

전체 샘플

여기에 솔루션 코드를 붙여넣는 것을 잊지 마십시오.

import UIKit
import WebKit

class ViewController: UIViewController {

    private weak var webView: WKWebView!
    let url = URL(string: "your_url")!
    
    var cookiesData: [String : Any]  {
        [
            "access_token": "your_token"
        ]
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let configuration = WKWebViewConfiguration()
        
        guard let host = self.url.host else { return }
        configuration.set(cookies: createCookies(host: host, parameters: self.cookiesData)) {
            let webView = WKWebView(frame: .zero, configuration: configuration)
            self.view.addSubview(webView)
            self.webView = webView
            webView.navigationDelegate = self
            webView.translatesAutoresizingMaskIntoConstraints = false
            webView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
            webView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
            self.view.bottomAnchor.constraint(equalTo: webView.bottomAnchor).isActive = true
            self.view.rightAnchor.constraint(equalTo: webView.rightAnchor).isActive = true

            self.loadPage(url: self.url)
        }
    }

    private func loadPage(url: URL) {
        var request = URLRequest(url: url)
        request.timeoutInterval = 30
        request.setCookies()
        webView.load(request)
    }
    
    private func createCookies(host: String, parameters: [String: Any]) -> [HTTPCookie] {
        parameters.compactMap { (name, value) in
            HTTPCookie(properties: [
                .domain: host,
                .path: "/",
                .name: name,
                .value: "\(value)",
                .secure: "TRUE",
                .expires: Date(timeIntervalSinceNow: 31556952),
            ])
        }
    }
}

extension ViewController: WKNavigationDelegate {

    // https://stackoverflow.com/a/47529039/4488252
    func webView(_ webView: WKWebView,
                 decidePolicyFor navigationAction: WKNavigationAction,
                 decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        if #available(iOS 11.0, *) {
            decisionHandler(.allow)
        } else {
            guard let url = navigationAction.request.url, let host = url.host, host.contains(self.url.host!) else {
                decisionHandler(.allow)
                return
            }

            if navigationAction.request.hasCookies {
                decisionHandler(.allow)
            } else {
                DispatchQueue.main.async {
                    decisionHandler(.cancel)
                    self.loadPage(url: url)
                }
            }
        }
    }
}

정보.plist

Info.plist 전송 보안 설정에 추가

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

즉시 사용할 수 있는 솔루션을 찾으십시오.기본적으로 Swift 4 @user3589213님답변에 맞게 수정 및 업데이트 되었습니다.

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    let headerKeys = navigationAction.request.allHTTPHeaderFields?.keys
    let hasCookies = headerKeys?.contains("Cookie") ?? false

    if hasCookies {
        decisionHandler(.allow)
    } else {
        let cookies = HTTPCookie.requestHeaderFields(with: HTTPCookieStorage.shared.cookies ?? [])

        var headers = navigationAction.request.allHTTPHeaderFields ?? [:]
        headers += cookies

        var req = navigationAction.request
        req.allHTTPHeaderFields = headers

        webView.load(req)

        decisionHandler(.cancel)
    }
}

위의 모든 답변을 시도해 보았지만 모두 작동하지 않습니다.많은 시도 끝에 저는 마침내 웹뷰 쿠키를 설정하는 믿을 수 있는 방법을 찾았습니다.

먼저 WKProcessPool 인스턴스를 생성하고 WKWebView 자체를 초기화하는 데 사용할 WKWebViewConfiguration으로 설정해야 합니다.

    private lazy var mainWebView: WKWebView = {
        let webConfiguration = WKWebViewConfiguration()
        webConfiguration.processPool = WKProcessPool()
        let webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.navigationDelegate = self
        return webView
    }()

WK ProcessPool 설정은 여기서 가장 중요한 단계입니다.WKWebview는 프로세스 분리를 사용합니다. 즉, 앱의 프로세스와는 다른 프로세스에서 실행됩니다.이로 인해 충돌이 발생하고 쿠키가 WK 웹 보기와 올바르게 동기화되지 않을 수 있습니다.

이제 WK ProcessPool의 정의를 살펴보겠습니다.

웹 보기와 연결된 프로세스 풀은 해당 웹 보기 구성으로 지정됩니다.구현 정의 프로세스 제한에 도달할 때까지 각 웹 보기에는 자체 웹 콘텐츠 프로세스가 제공됩니다. 그 후 프로세스 풀이 동일한 웹 보기는 Web Content 프로세스를 공유하게 됩니다.

후속 요청에 동일한 WKWebview를 사용할 계획인 경우 마지막 문장에 주의하십시오.

동일한 프로세스 풀을 가진 웹 보기는 Web Content 프로세스를 공유하게 됩니다.

즉, 동일한 도메인에 대해 WKebView를 구성할 때마다 동일한 WKProcessPool 인스턴스를 사용하지 않는 경우(WKebView가 포함된 VCA가 있을 수 있으며 다른 위치에 다른 VCA 인스턴스를 생성하려는 경우) 쿠키 설정 충돌이 발생할 수 있습니다.이 문제를 해결하기 위해 도메인 B를 로드하는 WKWebView에 대한 WKProcessPool을 처음 만든 후 싱글톤에 저장하고 동일한 도메인 B를 로드하는 WKWebView를 생성해야 할 때마다 동일한 WKProcessPool을 사용합니다.

private lazy var mainWebView: WKWebView = {
    let webConfiguration = WKWebViewConfiguration()
    if Enviroment.shared.processPool == nil {
        Enviroment.shared.processPool = WKProcessPool()
    }
    webConfiguration.processPool = Enviroment.shared.processPool!
    webConfiguration.processPool = WKProcessPool()
    let webView = WKWebView(frame: .zero, configuration: webConfiguration)
    webView.navigationDelegate = self
    return webView
}()

초기화 프로세스가 끝나면 다음의 완료 블록 내에 URLRequest를 로드할 수 있습니다.httpCookieStore.setCookie여기서 쿠키를 요청 헤더에 첨부해야 합니다. 그렇지 않으면 작동하지 않습니다.

P/s: 저는 댄 로웬허즈의 위의 환상적인 답변에서 확장자를 훔쳤습니다.

mainWebView.configuration.websiteDataStore.httpCookieStore.setCookie(your_cookie) {
        self.mainWebView.load(your_request, with: [your_cookie])
}

extension WKWebView {
   func load(_ request: URLRequest, with cookies: [HTTPCookie]) {
      var request = request
      let headers = HTTPCookie.requestHeaderFields(with: cookies)
      for (name, value) in headers {
         request.addValue(value, forHTTPHeaderField: name)
      }        
      load(request)
   }
}

내가 만든 엔티스의 대답.에서 iOS 11, 12, 13당신이 사용할 필요가 없는 것처럼 보입니다.DispatchGroupiOS 13더이상.

이지 않은 기능을 사용합니다.includeCustomCookiesWKWebViewConfiguration 할 수 ㅠㅠㅠㅠㅠㅠㅠㅠㅠcookies 새로생때마다할성▁new다때▁time▁i마를 만들 때마다WKWebViewConfiguration.

extension WKWebViewConfiguration {
    func includeCustomCookies(cookies: [HTTPCookie], completion: @escaping  () -> Void) {
        let dataStore = WKWebsiteDataStore.nonPersistent()
        let waitGroup = DispatchGroup()

        for cookie in cookies {
            waitGroup.enter()
            dataStore.httpCookieStore.setCookie(cookie) { waitGroup.leave() }
        }

        waitGroup.notify(queue: DispatchQueue.main) {
            self.websiteDataStore = dataStore
            completion()
        }
    }
}

그런 다음 이렇게 사용합니다.

let customUserAgent: String = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 Safari/605.1.15"

let customCookies: [HTTPCookie] = {
    let cookie1 = HTTPCookie(properties: [
        .domain: "yourdomain.com",
        .path: "/",
        .name: "auth_token",
        .value: APIManager.authToken
    ])!

    let cookie2 = HTTPCookie(properties: [
        .domain: "yourdomain.com",
        .path: "/",
        .name: "i18next",
        .value: "ru"
    ])!

    return [cookie1, cookie2]
}()

override func viewDidLoad() {
    super.viewDidLoad()

    activityIndicatorView.startAnimating()

    let webConfiguration = WKWebViewConfiguration()
    webConfiguration.includeCustomCookies(cookies: customCookies, completion: { [weak self] in
        guard let strongSelf = self else { return }
        strongSelf.webView = WKWebView(frame: strongSelf.view.bounds, configuration: webConfiguration)
        strongSelf.webView.customUserAgent = strongSelf.customUserAgent
        strongSelf.webView.navigationDelegate = strongSelf
        strongSelf.webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        strongSelf.view.addSubview(strongSelf.webView)
        strongSelf.view.bringSubviewToFront(strongSelf.activityIndicatorView)
        strongSelf.webView.load(strongSelf.request)
    })
}

드디어 ios 11+에서 작동하는 솔루션을 얻었습니다.내 코드를 여기에 붙여넣는 중...

extension WKWebViewConfiguration {

static func includeCookie(preferences:WKPreferences, completion: @escaping (WKWebViewConfiguration?) -> Void) {
    let config = WKWebViewConfiguration()
    
    guard let cookies = HTTPCookieStorage.shared.cookies else {
        completion(config)
        return
    }
    
    config.preferences = preferences
    let dataStore = WKWebsiteDataStore.nonPersistent()
    HTTPCookieStorage.shared.cookieAcceptPolicy = .always
    
    DispatchQueue.main.async {
        let waitGroup = DispatchGroup()
        
        for cookie in cookies{
            waitGroup.enter()
            let customCookie = HTTPCookie(properties: [
                .domain: cookie.domain,
                .path: cookie.path,
                .name: cookie.name,
                .value: cookie.value,
                .secure: cookie.isSecure,
                .expires: cookie.expiresDate ?? NSDate(timeIntervalSinceNow: 31556926)
            ])
            if let cookieData = customCookie{
                dataStore.httpCookieStore.setCookie(cookieData) {
                    waitGroup.leave()
                }
            }
        }
        
        waitGroup.notify(queue: DispatchQueue.main) {
            config.websiteDataStore = dataStore
            completion(config)
        }
    }
}
}

WKwebViewConfiguration에서 쿠키를 설정한 후 동일한 구성을 사용하여 웹 뷰를 로드합니다...

WKWebViewConfiguration.includeCookie(preferences: preferences, completion: {
            [weak self] config in
    if let `self` = self {
        if let configuration = config {
            webview = WKWebView(frame: self.contentView.bounds, configuration: config)
            webview.configuration.websiteDataStore.httpCookieStore.getAllCookies { (response) in
                print("")
            }

            self.contentView.addSubview(webview)

            if let filePath = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "packageDetailWevview") {

                if let requestUrl = filePath {
                    let request = URLRequest(url: requestUrl)
                    webview.load(request)
                }
            }
        }
    }
})

마침내 스위프트 5에서 작동했습니다.


extension WebController{

  func save_cookies(){
    let cookieStore = self.webView.configuration.websiteDataStore.httpCookieStore
    cookieStore.getAllCookies { (cookies) in
      let array = cookies.compactMap { (cookie) -> [HTTPCookiePropertyKey: Any]? in
          cookie.properties
      }
      UserDefaults.standard.set(array, forKey: "cookies")

    }
  }

  func load_cookies(){
    // get status from cookies
    // cookies are pre-installed from native code.
    guard let cookies = UserDefaults.standard.value(forKey: "cookies") as? [[HTTPCookiePropertyKey: Any]] else {
        return
    }
    cookies.forEach { (cookie) in
      guard let cookie = HTTPCookie(properties: cookie ) else{return}
      let cookieStore = self.webView.configuration.websiteDataStore.httpCookieStore
      cookieStore.setCookie(cookie, completionHandler: nil)
    }

    webView.evaluateJavaScript("checkcookie_delay_1second()", completionHandler: nil)
  }


}

XHR 요청에 대한 더 나은 수정은 여기에 나와 있습니다.

Swift 4 버전:

func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Swift.Void) {
    guard
        let response = navigationResponse.response as? HTTPURLResponse,
        let url = navigationResponse.response.url
    else {
        decisionHandler(.cancel)
        return
    }

    if let headerFields = response.allHeaderFields as? [String: String] {
        let cookies = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: url)
        cookies.forEach { (cookie) in
            HTTPCookieStorage.shared.setCookie(cookie)
        }
    }

    decisionHandler(.allow)
}

알라모파이어를 사용하는 사람이 있다면, 이것이 더 나은 해결책입니다.

  let cookies = Alamofire.SessionManager.default.session.configuration.httpCookieStorage?.cookies(for: URL(string: BASE_URL)!)
  for (cookie) in cookies ?? [] {
      webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
  }

쿠키를 설정한 후 데이터 레코드 가져오기 추가

   let cookiesSet = NetworkProvider.getCookies(forKey : 
    PaywallProvider.COOKIES_KEY, completionHandler: nil)
                let dispatchGroup = DispatchGroup()
                for (cookie) in cookiesSet {
                    if #available(iOS 11.0, *) {
                        dispatchGroup.enter()
                        self.webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie){
                            dispatchGroup.leave()
                            print ("cookie added: \(cookie.description)")
                            }
                        } else {
                                            // TODO Handle ios 10 Fallback on earlier versions
                        }
                    }
                    dispatchGroup.notify(queue: .main, execute: {


    self.webView.configuration.websiteDataStore.fetchDataRecords(ofTypes: 
    WKWebsiteDataStore.allWebsiteDataTypes()) { records in
                            records.forEach { record in

                                print("[WebCacheCleaner] Record \(record)")
                            }
                            self.webView.load(URLRequest(url: 
    self.dataController.premiumArticleURL , 
    cachePolicy:NSURLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData,
                                                         timeoutInterval: 10.0))
                        }

                    })
                }

항목을 과 같이 할 수path&domain항목에 )입니다.

NSString *cookie = [NSString stringWithFormat:@"document.cookie = 'p1=%@;path=/;domain=your.domain;';document.cookie = 'p2=%@;path=/;domain=your.domain;';document.cookie = 'p3=%@;path=/;domain=your.domain;';", p1_string, p2_string, p3_string];

WKUserScript *cookieScript = [[WKUserScript alloc]
            initWithSource:cookie
            injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];

[userContentController addUserScript:cookieScript];

그렇지 않으면 첫 번째 쿠키 항목만 설정됩니다.

또한 WKWebsiteDataStore를 사용하여 UIWebView에서 HTTP CookieStorage와 유사한 동작을 가져올 수 있습니다.

let dataStore = WKWebsiteDataStore.default()
let cookies = HTTPCookieStorage.shared.cookies ?? [HTTPCookie]()
cookies.forEach({
    dataStore.httpCookieStore.setCookie($0, completionHandler: nil)
})

아래 코드는 제 프로젝트 Swift5에서 잘 작동합니다. 아래의 WKWebView에 의한 로드 url을 시도하십시오.

    private func loadURL(urlString: String) {
        let url = URL(string: urlString)
        guard let urlToLoad = url else { fatalError("Cannot find any URL") }

        // Cookies configuration
        var urlRequest = URLRequest(url: urlToLoad)
        if let cookies = HTTPCookieStorage.shared.cookies(for: urlToLoad) {
            let headers = HTTPCookie.requestHeaderFields(with: cookies)
            for header in headers { urlRequest.addValue(header.value, forHTTPHeaderField: header.key) }
        }

        webview.load(urlRequest)
    }

이것은 iOS 9 이상에서 쿠키 및 WKWebView로 처리하는 저의 솔루션입니다.

import WebKit

extension WebView {

    enum LayoutMode {
        case fillContainer
    }

    func autoLayout(_ view: UIView?, mode: WebView.LayoutMode = .fillContainer) {
        guard let view = view else { return }
        self.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(self)

        switch mode {
        case .fillContainer:
                NSLayoutConstraint.activate([
                self.topAnchor.constraint(equalTo: view.topAnchor),
                self.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                self.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                self.bottomAnchor.constraint(equalTo: view.bottomAnchor)
            ])
        }
    }

}

class WebView : WKWebView {

    var request : URLRequest?

    func load(url: URL, useSharedCookies: Bool = false) {
        if useSharedCookies, let cookies = HTTPCookieStorage.shared.cookies(for: url) {
            self.load(url: url, withCookies: cookies)
        } else {
            self.load(URLRequest(url: url))
        }
    }

    func load(url: URL, withCookies cookies: [HTTPCookie]) {
        self.request = URLRequest(url: url)
        let headers = HTTPCookie.requestHeaderFields(with: cookies)
        self.request?.allHTTPHeaderFields = headers
        self.load(request!)
    }

}

내가 어떻게...

initWebConfig를 호출하여 diddidFinishLaunchingWithAppDelegate 옵션(또는 WebView를 만들기 전에 아무 곳에서나)을 호출하지 않으면 쿠키가 제대로 동기화되지 않을 수 있습니다.

    func initWebConfig() {
        self.webConfig = WKWebViewConfiguration()
        self.webConfig.websiteDataStore = WKWebsiteDataStore.nonPersistent()
    }
           
    func setCookie(key: String, value: AnyObject, domain: String? = nil, group: DispatchGroup? = nil) {
                        
                        let cookieProps: [HTTPCookiePropertyKey : Any] = [
                            .domain: domain ?? "google.com",
                            .path: "/",
                            .name: key,
                            .value: value,
                        ]
                        
                        if let cookie = HTTPCookie(properties: cookieProps) {
                            group?.enter()
                            let webConfig = (UIApplication.shared.delegate as? AppDelegate)?.webConfig
          
webConfig?.websiteDataStore.httpCookieStore.setCookie(cookie) {
                                group?.leave()
                            }
                        }
                    }

필요한 경우, 쿠키를 디스패치 그룹에 설정

 let group = DispatchGroup()
                self.setCookie(key: "uuid", value: "tempUdid" as AnyObject, group: group)
                self.setCookie(key: "name", value: "tempName" as AnyObject, group: group)
                
                group.notify(queue: DispatchQueue.main) {
                    //Create and Load WebView here 
                    let webConfig = (UIApplication.shared.delegate as? AppDelegate)?.webConfig ?? WKWebViewConfiguration()
                    //create urlRequest
                    let webView = WKWebView(frame: .zero, configuration: webConfig)
                    self.webView.load(urlRequest)
                }

언급URL : https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview

반응형