Редактировать только для iOS 11+
Используйте WKHTTPCookieStore :
let cookie = HTTPCookie(properties: [
.domain: "example.com",
.path: "/",
.name: "MyCookieName",
.value: "MyCookieValue",
.secure: "TRUE",
.expires: NSDate(timeIntervalSinceNow: 31556926)
])!
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
Поскольку вы извлекаете их из HTTPCookeStorage, вы можете сделать это:
let cookies = HTTPCookieStorage.shared.cookies ?? []
for cookie in cookies {
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
}
Старый ответ для iOS 10 и ниже
Если вам требуется, чтобы ваши куки были установлены при первоначальном запросе загрузки, вы можете установить их в NSMutableURLRequest. Поскольку файлы cookie - это просто специально отформатированный заголовок запроса, это может быть достигнуто следующим образом:
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 на странице были установлены файлы cookie, это можно сделать, просто используя 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];
Объединение этих двух методов должно дать вам достаточно инструментов для переноса значений файлов cookie из Native App Land в Web View Land. Вы можете найти дополнительную информацию об API cookie javascript на странице Mozilla, если вам нужны более продвинутые файлы cookie.
Да, это отстой, что Apple не поддерживает многие тонкости UIWebView . Не уверен, будут ли они когда-либо поддерживать их, но, надеюсь, они скоро доберутся до этого. Надеюсь это поможет!
После игры с этим ответом (который был фантастически полезен :) нам пришлось внести несколько изменений:
NSHTTPCookieStorage
Таким образом, мы изменили наш код, чтобы быть этим;
Создание запроса
Это гарантирует, что в первом запросе установлены правильные файлы cookie, без отправки файлов cookie из общего хранилища, предназначенных для других доменов, и без отправки каких-либо безопасных файлов cookie в незащищенный запрос.
Работа с дальнейшими запросами
Мы также должны убедиться, что для других запросов установлены файлы cookie. Это делается с помощью скрипта, который запускается при загрузке документа, который проверяет, есть ли набор файлов cookie, и если нет, задает для него значение в
NSHTTPCookieStorage
....
Работа с изменениями cookie
Нам также нужно иметь дело с сервером, меняющим значение куки. Это означает добавление другого скрипта для обратного вызова из веб-представления, которое мы создаем для обновления нашего
NSHTTPCookieStorage
.и реализуя метод делегата для обновления любых файлов cookie, которые изменились, убедившись, что мы обновляем файлы cookie только из текущего домена!
Кажется, это решает наши проблемы с файлами cookie, и нам не приходится иметь дело с каждым местом, в котором мы используем WKWebView. Теперь мы можем просто использовать этот код в качестве помощника для создания наших веб-представлений, и он прозрачно обновляется
NSHTTPCookieStorage
для нас.РЕДАКТИРОВАТЬ: Оказывается, я использовал частную категорию на NSHTTPCookie - вот код:
источник
a=b
бы вы имели значение, то вы бы получили строку cookiename=a=b;domain=.example.com;path=/
- я считаю, что стандарт разделяется,;
а затем разделяется на первый=
в паре ключ = значение. Хотя я быФайлы cookie должны быть установлены в конфигурации до
WKWebView
создания. В противном случае, даже сWKHTTPCookieStore
«SsetCookie
обработчик завершения, печенье не будет надежно синхронизироваться с веб - просмотра. Это восходит к этой строке из документов наWKWebViewConfiguration
Это
@NSCopying
что-то вроде глубокой копии. Реализация выше моего понимания, но конечный результат заключается в том, что если вы не установите файлы cookie перед инициализацией веб-просмотра, вы не сможете рассчитывать на наличие файлов cookie. Это может усложнить архитектуру приложения, поскольку инициализация представления становится асинхронным процессом. Вы закончите с чем-то вроде этогоа затем использовать что-то вроде
Приведенный выше пример откладывает создание представления до последнего возможного момента, другим решением было бы заранее создать конфигурацию или веб-представление и обработать асинхронную природу до создания контроллера представления.
Последнее замечание: как только вы создали это веб-представление, вы оставили его в свободном доступе, вы не можете добавить больше файлов cookie без использования методов, описанных в этом ответе . Тем не менее, вы можете использовать
WKHTTPCookieStoreObserver
API, чтобы, по крайней мере, наблюдать за изменениями, происходящими с файлами cookie. Таким образом, если файл cookie сеанса обновляется в веб-просмотре, вы можете вручную обновить системуHTTPCookieStorage
с помощью этого нового файла cookie, если это необходимо.Более подробную информацию можно найти в 18:00 на этой веб-загрузке пользовательского веб-контента, посвященной сессии WWDC 2017 года . В начале этого сеанса есть пример вводящего в заблуждение кода, в котором пропускается тот факт, что веб-просмотр должен быть создан в обработчике завершения.
Живая демонстрация в 18:00 разъясняет это.
Редактировать На Мохаве Beta 7 и IOS 12 Beta 7 , по крайней мере, я вижу гораздо более последовательное поведение с печеньем. Этот
setCookie(_:)
метод даже позволяет разрешить установку файлов cookie послеWKWebView
создания. Я нашел это важно , хотя, чтобы не прикоснуться кprocessPool
переменной вообще. Функциональность настройки cookie работает лучше всего, когда не создаются дополнительные пулы и когда это свойство оставлено в покое. Я думаю, можно с уверенностью сказать, что у нас были проблемы из-за некоторых ошибок в WebKit.источник
работать на меня
источник
else
состоянии, с которым он вызываетdecisionHandler
закрытие,.cancel
поэтомуwebview
фактически не загружает первоначальный запрос. ПослеloadRequest
вызова вelse
условии этот метод делегата будет вызван снова для этого запроса, и он перейдет вif
условие, потому чтоCookie
будет присутствовать заголовок.else
условие.Вот моя версия решения Mattrs в Swift для внедрения всех файлов cookie из HTTPCookieStorage. Это было сделано в основном для того, чтобы внедрить файл cookie аутентификации для создания сеанса пользователя.
источник
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
установить cookie
удалить cookie
источник
Обновление Swift 3:
источник
HTTPCookieStorage.shared
?Просмотрев здесь различные ответы и не добившись успеха, я просмотрел документацию WebKit и наткнулся на
requestHeaderFields
статический методHTTPCookie
, который преобразует массив файлов cookie в формат, подходящий для поля заголовка. Объединив это с пониманием mattr обновленияURLRequest
файла перед загрузкой с заголовками cookie, я добрался до финиша.Swift 4.1, 4.2, 5.0:
Чтобы сделать это еще проще, используйте расширение:
Теперь это просто становится:
Это расширение также доступно в LionheartExtensions, если вам просто нужно решение для прямого подключения. Ура!
источник
В iOS 11 теперь вы можете управлять файлами cookie :), см. Этот сеанс: https://developer.apple.com/videos/play/wwdc2017/220/
источник
Причина, по которой опубликован этот ответ, заключается в том, что я пробовал много решений, но никто не работал должным образом, большая часть ответа не работает в случае, когда нужно установить файл cookie в первый раз, и файл cookie результата не синхронизируется в первый раз, пожалуйста, используйте это решение, оно работает для обоих iOS> = 11.0 <= iOS 11 до 8.0, также работайте с синхронизацией файлов cookie в первый раз.
Для iOS> = 11.0 - Swift 4.2
Получите http cookie и установите в хранилище cookie wkwebview таким образом, очень сложно загрузить ваш запрос в wkwebview , необходимо отправить запрос на загрузку, когда файлы cookie будут полностью установлены, вот функция, которую я написал.
Вызов функции с закрытием в завершении вы вызываете загрузку веб-просмотра. FYI, эта функция обрабатывает только iOS> = 11.0
Вот реализация функции syncCookies .
Для iOS 8 - iOS 11
вам нужно настроить некоторые дополнительные вещи, вам нужно установить два временных файла cookie, используя WKUserScript и не забудьте также добавить файлы cookie в запрос, иначе ваш файл cookie не синхронизируется в первый раз, и вы увидите, что ваша страница не загружается должным образом в первый раз. это черт возьми, что я обнаружил, что поддерживает файлы cookie для iOS 8.0
перед созданием объекта Wkwebview.
Сосредоточьтесь на этой функции get JSCookiesString
Вот еще один шаг, который wkuserscript не синхронизирует файлы cookie сразу, там много чертов, чтобы загрузить первую страницу с файлом cookie, нужно снова перезагрузить веб-просмотр, если он завершит процесс, но я не рекомендую его использовать, это не хорошо для точки зрения пользователя , черт возьми, когда вы готовы загрузить файлы cookie набора запросов в заголовок запроса, не забудьте добавить проверку версии iOS. перед запросом загрузки вызовите эту функцию.
я написал расширение для URLRequest
Теперь вы готовы к тестированию iOS> 8
источник
Пожалуйста, найдите решение, которое, скорее всего, подойдет вам прямо из коробки. В основном это изменено и обновлено для Swift 4 @ user3589213 «s ответа .
источник
Я пробовал все ответы выше, но ни один из них не работает. После стольких попыток я наконец нашел надежный способ установить cookie WKWebview.
Сначала вам нужно создать экземпляр WKProcessPool и установить для него WKWebViewConfiguration, который будет использоваться для инициализации самого WkWebview:
Настройка WKProcessPool - самый важный шаг здесь.WKWebview использует изоляцию процессов - это означает, что он работает в другом процессе, чем процесс вашего приложения. Иногда это может вызвать конфликт и помешать правильной синхронизации вашего файла cookie с WKWebview.
Теперь давайте посмотрим на определение WKProcessPool
Обратите внимание на последнее предложение, если вы планируете использовать тот же WKWebview для запросов подпоследовательности.
Я имею в виду, что если вы не используете один и тот же экземпляр WKProcessPool каждый раз, когда настраиваете WKWebView для одного и того же домена (возможно, у вас есть VC A, который содержит WKWebView, и вы хотите создать разные экземпляры VC A в разных местах ), возможны конфликты настроек cookie. Чтобы решить эту проблему, после первого создания WKProcessPool для WKWebView, загружающего домен B, я сохраняю его в синглтоне и использую тот же самый WKProcessPool каждый раз, когда мне нужно создать WKWebView, который загружает тот же домен B.
После завершения процесса инициализации, вы можете загрузить URLRequest внутри заканчивания блока из
httpCookieStore.setCookie
. Здесь вы должны прикрепить файл cookie к заголовку запроса иначе он не будет работать.P / s: Я украл расширение из фантастического ответа Дэна Лёвенгерца выше
источник
Моя версия ответа nteiss. Проверено на
iOS 11, 12, 13
. Похоже , вы не должны использоватьDispatchGroup
наiOS 13
больше.Я использую нестатическую функцию
includeCustomCookies
onWKWebViewConfiguration
, чтобы я мог обновлятьcookies
каждый раз, когда создаю новыйWKWebViewConfiguration
.Тогда я использую это так:
источник
Лучшее исправление для запросов XHR показано здесь.
Версия Swift 4:
источник
Если кто-то использует Alamofire, то это лучшее решение.
источник
Это работает для меня: после setcookies добавьте fetchdatarecords
источник
При добавлении нескольких элементов cookie вы можете сделать это следующим образом: (
path
&domain
требуется для каждого элемента)в противном случае будет установлен только первый элемент cookie.
источник
Вы также можете использовать WKWebsiteDataStore для получения аналогичного поведения HTTPCookieStorage из UIWebView.
источник
Код ниже хорошо работает в моем проекте Swift5. попробуйте загрузить URL-адрес с помощью WKWebView ниже:
источник
Это мое решение для обработки файлов cookie и WKWebView в iOS 9 или новее.
источник
Эта ошибка, которую я делал, заключалась в том, что я передавал весь URL-адрес в атрибуте домена, это должно быть только имя домена.
источник