Editar apenas para iOS 11 ou superior
Use 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)
Como você está puxando-os do HTTPCookeStorage, você pode fazer isso:
let cookies = HTTPCookieStorage.shared.cookies ?? []
for cookie in cookies {
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
}
Resposta antiga para iOS 10 e abaixo
Se você precisar que seus cookies sejam definidos na solicitação de carregamento inicial, será possível configurá-los em NSMutableURLRequest. Como os cookies são apenas um cabeçalho de solicitação especialmente formatado, isso pode ser alcançado da seguinte maneira:
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];
Se você solicitar que as solicitações AJAX subseqüentes na página tenham seus cookies definidos, isso pode ser alcançado simplesmente usando WKUserScript para definir os valores programaticamente via javascript no início do documento, da seguinte maneira:
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];
A combinação dessas duas técnicas deve fornecer ferramentas suficientes para transferir valores de cookies do Native App Land para o Web View Land. Você pode encontrar mais informações na API de cookies javascript na página da Mozilla se precisar de alguns cookies mais avançados.
Sim, é péssimo que a Apple não suporte muitas das vantagens do UIWebView . Não tenho certeza se eles irão apoiá-los, mas espero que eles continuem com isso em breve. Espero que isto ajude!
Depois de jogar com esta resposta (que foi extraordinariamente útil :), tivemos que fazer algumas alterações:
NSHTTPCookieStorage
Então, modificamos nosso código para ser esse;
Criando uma solicitação
Isso garante que a primeira solicitação tenha os cookies corretos definidos, sem enviar cookies do armazenamento compartilhado para outros domínios e sem enviar cookies seguros para uma solicitação não segura.
Lidar com pedidos adicionais
Também precisamos garantir que outras solicitações tenham os cookies definidos. Isso é feito usando um script que é executado em carga documento que verifica para ver se há um conjunto de cookies e se não, defina-o para o valor
NSHTTPCookieStorage
....
Lidando com alterações de cookies
Também precisamos lidar com o servidor alterando o valor de um cookie. Isso significa adicionar outro script para retornar à visualização na web que estamos criando para atualizar nossa
NSHTTPCookieStorage
.e implementando o método delegate para atualizar os cookies que foram alterados, certificando-se de que estamos atualizando apenas os cookies do domínio atual!
Isso parece resolver nossos problemas de cookies sem precisar lidar com cada local em que usamos o WKWebView de maneira diferente. Agora, podemos apenas usar esse código como um auxiliar para criar nossas visualizações da Web e ele é atualizado de forma transparente
NSHTTPCookieStorage
.Edição: Acontece que eu usei uma categoria privada no NSHTTPCookie - aqui está o código:
fonte
a=b
você terminaria com a sequência de cookiesname=a=b;domain=.example.com;path=/
- acredito que o padrão se divide;
e depois se divide no primeiro=
no par chave = valor. No entanto, eu testaria isso :) :)Os cookies devem ser definidos na configuração antes da
WKWebView
criação. Caso contrário, mesmo comWKHTTPCookieStore
osetCookie
manipulador de conclusão, os cookies não serão sincronizados de maneira confiável com a visualização da web. Isso remonta a essa linha nos documentos emWKWebViewConfiguration
Isso
@NSCopying
é uma cópia profunda. A implementação está além de mim, mas o resultado final é que, a menos que você defina cookies antes de inicializar a visualização na web, não poderá contar com a presença dos cookies. Isso pode complicar a arquitetura do aplicativo, pois a inicialização de uma exibição se torna um processo assíncrono. Você vai acabar com algo assime então usar algo como
O exemplo acima adia a criação de visualizações até o último momento possível; outra solução seria criar a configuração ou a visualização na Web com bastante antecedência e lidar com a natureza assíncrona antes da criação de um controlador de exibição.
Uma observação final: depois de criar essa visualização na Web, você a soltou na natureza, não poderá adicionar mais cookies sem usar os métodos descritos nesta resposta . No entanto, você pode usar a
WKHTTPCookieStoreObserver
API para observar pelo menos as alterações ocorridas nos cookies. Portanto, se um cookie de sessão for atualizado na visualização da web, você poderá atualizar manualmente o sistemaHTTPCookieStorage
com esse novo cookie, se desejar.Para saber mais, pule para as 18:00 neste carregamento personalizado de conteúdo da web da sessão da WWDC de 2017 . No início desta sessão, há um exemplo de código enganoso que omite o fato de que a visualização da web deve ser criada no manipulador de conclusão.
A demonstração ao vivo às 18:00 esclarece isso.
Editar No Mojave Beta 7 e iOS 12 Beta 7, pelo menos, estou vendo um comportamento muito mais consistente com os cookies. O
setCookie(_:)
método até parece permitir a configuração de cookies após aWKWebView
criação. Mas achei importante não tocar naprocessPool
variável. A funcionalidade de configuração de cookie funciona melhor quando nenhum pool adicional é criado e quando essa propriedade é deixada em paz. Eu acho que é seguro dizer que estávamos tendo problemas devido a alguns erros no WebKit.fonte
trabalhe para mim
fonte
else
condição em que ele está chamando odecisionHandler
fechamento,.cancel
para quewebview
ele não carregue a solicitação inicial. Depois deloadRequest
chamado naelse
condição, esse método delegado será chamado novamente para essa solicitação e entrará naif
condição porque oCookie
cabeçalho estará presente.else
condição.Aqui está minha versão da solução Mattrs no Swift para injetar todos os cookies do HTTPCookieStorage. Isso foi feito principalmente para injetar um cookie de autenticação para criar uma sessão do usuário.
fonte
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
definir cookie
excluir cookie
fonte
Atualização Swift 3:
fonte
HTTPCookieStorage.shared
?Depois de analisar várias respostas aqui e não ter sucesso, vasculhei a documentação do WebKit e deparei-me com o
requestHeaderFields
método estáticoHTTPCookie
, que converte uma matriz de cookies em um formato adequado para um campo de cabeçalho. Combinar isso com o insight do mattr de atualizar oURLRequest
antes de carregá-lo com os cabeçalhos dos cookies me levou até a linha de chegada.Swift 4.1, 4.2, 5.0:
Para tornar isso ainda mais simples, use uma extensão:
Agora, apenas se torna:
Esta extensão também está disponível no LionheartExtensions se você deseja apenas uma solução drop-in. Felicidades!
fonte
No iOS 11, você pode gerenciar o cookie agora :), consulte esta sessão: https://developer.apple.com/videos/play/wwdc2017/220/
fonte
A razão por trás da postagem desta resposta é que eu tentei muitas soluções, mas ninguém funciona corretamente, a maioria das respostas não funciona no caso em que é necessário definir o cookie pela primeira vez e o resultado obtido não é sincronizado pela primeira vez. Use esta solução para ambos iOS> = 11.0 <= iOS 11 até 8.0, também funciona com sincronização de cookies pela primeira vez.
Para iOS> = 11.0 - Swift 4.2
Obtenha cookies http e defina na loja de cookies wkwebview dessa maneira, é um ponto muito complicado para carregar sua solicitação no wkwebview , deve-se enviar uma solicitação para carregar quando os cookies serão definidos completamente, aqui está a função que eu escrevi.
Chamar a função com o fechamento concluído, você chama carregar a webview. Para sua informação, esta função suporta apenas iOS> = 11.0
Aqui está a implementação da função syncCookies .
Para iOS 8 até iOS 11
você precisa configurar algumas coisas extras para definir dois cookies únicos, usando o WKUserScript e também não se esqueça de adicionar cookies no pedido, caso contrário, o cookie não será sincronizado pela primeira vez e você verá que a página não será carregada corretamente pela primeira vez. este é o diabo que eu encontrei para suportar cookies para iOS 8.0
antes de criar o objeto Wkwebview.
Concentre-se nessa função getJSCookiesString
Aqui está outra etapa em que o wkuserscript não sincroniza os cookies imediatamente; há muitas coisas para carregar a primeira página com o cookie 1: recarregar a visualização na web novamente se ela terminar o processo, mas eu não recomendo usá-la, isso não é bom para o ponto de vista do usuário , heck, sempre que você estiver pronto para carregar os cookies do conjunto de solicitações no cabeçalho da solicitação, assim, não esqueça de adicionar a verificação de versão do iOS. antes da solicitação de carregamento, chame esta função.
eu escrevi extensão para URLRequest
agora você está pronto para testar o iOS> 8
fonte
Encontre a solução que provavelmente funcionará para você imediatamente. Basicamente, é modificado e atualizado para a resposta do Swift 4 @ user3589213 .
fonte
Eu tentei todas as respostas acima, mas nenhuma delas funciona. Após tantas tentativas, finalmente encontrei uma maneira confiável de definir o cookie WKWebview.
Primeiro, você deve criar uma instância do WKProcessPool e configurá-la como WKWebViewConfiguration que será usada para inicializar o próprio WkWebview:
A configuração do WKProcessPool é a etapa mais importante aqui. O WKWebview faz uso do isolamento do processo - o que significa que ele é executado em um processo diferente do processo do seu aplicativo. Às vezes, isso pode causar conflitos e impedir que seu cookie seja sincronizado corretamente com o WKWebview.
Agora, vejamos a definição de WKProcessPool
Preste atenção na última frase se você planeja usar o mesmo WKWebview para solicitações subsequentes
o que quero dizer é que, se você não usar a mesma instância do WKProcessPool cada vez que configurar um WKWebView para o mesmo domínio (talvez você tenha um VC A que contém um WKWebView e deseje criar instâncias diferentes do VC A em locais diferentes ), pode haver cookies de configuração de conflito. Para resolver o problema, após a primeira criação do WKProcessPool para um WKWebView que carrega o domínio B, eu o salvo em um singleton e uso o mesmo WKProcessPool toda vez que tenho que criar um WKWebView que carrega o mesmo domínio B
Após o processo de inicialização, você pode carregar um URLRequest dentro do bloco de conclusão de
httpCookieStore.setCookie
. Aqui, você deve anexar o cookie ao cabeçalho da solicitação, caso contrário não funcionará.P / s: roubei a extensão da fantástica resposta acima de Dan Loewenherz
fonte
Minha versão da resposta de nteiss. Testado em
iOS 11, 12, 13
. Parece que você não tem que usarDispatchGroup
emiOS 13
mais.Eu uso função non-static
includeCustomCookies
onWKWebViewConfiguration
, para que eu possa atualizarcookies
cada vez que eu criar novosWKWebViewConfiguration
.Então eu uso assim:
fonte
A melhor correção para solicitações XHR é mostrada aqui
Versão Swift 4:
fonte
Se alguém estiver usando o Alamofire, essa é a melhor solução.
fonte
Isso funciona para mim: Após setcookies, adicione fetchdatarecords
fonte
Ao adicionar itens de cookie multiplicados, você pode fazer o seguinte: (
path
edomain
é necessário para cada item)caso contrário, apenas o primeiro item do cookie será definido.
fonte
Você também pode usar o WKWebsiteDataStore para obter um comportamento semelhante ao HTTPCookieStorage no UIWebView.
fonte
O código abaixo funciona bem no meu projeto Swift5. tente carregar o URL pelo WKWebView abaixo:
fonte
Esta é a minha solução para lidar com cookies e WKWebView no iOS 9 ou posterior.
fonte
Esse erro que eu estava cometendo era passar o URL inteiro no atributo de domínio, que deveria ser apenas o nome de domínio.
fonte