Edit hanya untuk iOS 11+
Gunakan 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)
Karena Anda menariknya dari HTTPCookeStorage, Anda dapat melakukan ini:
let cookies = HTTPCookieStorage.shared.cookies ?? []
for cookie in cookies {
webView.configuration.websiteDataStore.httpCookieStore.setCookie(cookie)
}
Jawaban lama untuk iOS 10 dan di bawah
Jika Anda meminta cookie Anda diatur pada permintaan pemuatan awal, Anda dapat mengaturnya pada NSMutableURLRequest. Karena cookie hanyalah header permintaan yang diformat khusus, ini dapat dicapai seperti:
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];
Jika Anda memerlukan permintaan AJAX berikutnya pada halaman untuk mengatur cookie mereka, ini dapat dicapai dengan hanya menggunakan WKUserScript untuk mengatur nilai-nilai secara terprogram melalui javascript pada awal dokumen seperti:
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];
Menggabungkan kedua teknik ini akan memberi Anda cukup alat untuk mentransfer nilai cookie dari Native App Land ke Web View Land. Anda dapat menemukan lebih banyak info tentang API javascript cookie pada halaman Mozilla jika Anda memerlukan cookie yang lebih maju.
Ya, itu menyebalkan bahwa Apple tidak mendukung banyak kebaikan UIWebView . Tidak yakin apakah mereka akan pernah mendukung mereka, tetapi mudah-mudahan mereka akan segera melakukannya. Semoga ini membantu!
Setelah bermain dengan jawaban ini (yang sangat membantu :) kami harus membuat beberapa perubahan:
NSHTTPCookieStorage
Jadi kami memodifikasi kode kami menjadi ini;
Membuat permintaan
Ini memastikan bahwa permintaan pertama memiliki cookie yang tepat, tanpa mengirim cookie apa pun dari penyimpanan bersama yang untuk domain lain, dan tanpa mengirim cookie aman apa pun ke dalam permintaan yang tidak aman.
Berurusan dengan permintaan lebih lanjut
Kami juga perlu memastikan bahwa permintaan lain telah menetapkan cookie. Ini dilakukan dengan menggunakan skrip yang dijalankan pada pemuatan dokumen yang memeriksa untuk melihat apakah ada cookie yang diatur dan jika tidak, setel ke nilai dalam
NSHTTPCookieStorage
....
Berurusan dengan perubahan cookie
Kita juga harus berurusan dengan server yang mengubah nilai cookie. Ini berarti menambahkan skrip lain untuk memanggil kembali dari tampilan web yang kami buat untuk memperbarui skrip kami
NSHTTPCookieStorage
.dan menerapkan metode delegasi untuk memperbarui cookie apa pun yang telah berubah, memastikan bahwa kami hanya memperbarui cookie dari domain saat ini!
Ini tampaknya memperbaiki masalah cookie kami tanpa harus berurusan dengan setiap tempat yang kami gunakan WKWebView secara berbeda. Kita sekarang dapat menggunakan kode ini sebagai pembantu untuk membuat tampilan web kita dan secara transparan memperbarui
NSHTTPCookieStorage
untuk kita.EDIT: Ternyata saya menggunakan kategori pribadi di NSHTTPCookie - inilah kodenya:
sumber
a=b
Anda, Anda akan berakhir dengan string cookiename=a=b;domain=.example.com;path=/
- Saya percaya bahwa standar terpecah;
dan kemudian terpecah pada yang pertama=
di pasangan kunci = nilai. Saya akan menguji ini :)Cookie harus diatur pada konfigurasi sebelum
WKWebView
dibuat. Jika tidak, bahkan denganWKHTTPCookieStore
'ssetCookie
selesai handler, cookie akan tidak andal disinkronisasikan ke tampilan web. Ini kembali ke baris ini dari dokumen padaWKWebViewConfiguration
Itu
@NSCopying
adalah salinan yang dalam. Implementasinya di luar saya, tetapi hasil akhirnya adalah kecuali Anda menetapkan cookie sebelum menginisialisasi tampilan web, Anda tidak dapat mengandalkan cookie yang ada di sana. Ini dapat memperumit arsitektur aplikasi karena menginisialisasi tampilan menjadi proses yang tidak sinkron. Anda akan berakhir dengan sesuatu seperti inidan kemudian menggunakannya seperti
Contoh di atas menolak pembuatan tampilan hingga saat terakhir yang memungkinkan, solusi lain adalah membuat konfigurasi atau tampilan web jauh sebelumnya dan menangani sifat asinkron sebelum membuat pengendali tampilan.
Catatan terakhir: setelah Anda membuat tampilan web ini, Anda membuatnya longgar, Anda tidak dapat menambahkan lebih banyak cookie tanpa menggunakan metode yang dijelaskan dalam jawaban ini . Namun Anda dapat menggunakan
WKHTTPCookieStoreObserver
api untuk setidaknya mengamati perubahan yang terjadi pada cookie. Jadi jika cookie sesi diperbarui di tampilan web, Anda dapat secara manual memperbarui sistemHTTPCookieStorage
dengan cookie baru ini jika diinginkan.Untuk informasi lebih lanjut tentang ini, lanjutkan ke 18:00 di ini Sesi Pemuatan Konten Web Kustom Sesi WWDC 2017 . Pada awal sesi ini, ada contoh kode menipu yang menghilangkan fakta bahwa tampilan web harus dibuat dalam penangan penyelesaian.
Demo langsung pukul 18:00 mengklarifikasi ini.
Sunting Pada Mojave Beta 7 dan iOS 12 Beta 7 setidaknya, saya melihat perilaku yang jauh lebih konsisten dengan cookie. The
setCookie(_:)
Metode bahkan muncul jadi pengaturan cookie setelahWKWebView
telah dibuat. Aku menemukan itu meskipun penting, untuk tidak menyentuh padaprocessPool
variabel sama sekali. Fungsionalitas pengaturan cookie bekerja paling baik ketika tidak ada kolam tambahan yang dibuat dan ketika properti itu dibiarkan begitu saja. Saya pikir aman untuk mengatakan bahwa kami mengalami masalah karena beberapa bug di WebKit.sumber
bekerja untukku
sumber
else
kondisi dia memanggildecisionHandler
penutupan dengan.cancel
begituwebview
sebenarnya tidak memuat permintaan awal. SetelahloadRequest
dipanggil dalamelse
kondisi metode delegasi ini akan dipanggil lagi untuk permintaan itu dan itu akan masuk keif
kondisi karenaCookie
header akan hadir.else
kondisi.Ini adalah versi solusi Mattrs saya di Swift untuk menyuntikkan semua cookie dari HTTPCookieStorage. Ini dilakukan terutama untuk menyuntikkan cookie otentikasi untuk membuat sesi pengguna.
sumber
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
mengatur cookie
hapus cookie
sumber
Pembaruan Swift 3:
sumber
HTTPCookieStorage.shared
juga?Setelah melihat berbagai jawaban di sini dan tidak berhasil, saya menyisir dokumentasi WebKit dan menemukan
requestHeaderFields
metode statisHTTPCookie
, yang mengubah array cookie menjadi format yang cocok untuk bidang header. Menggabungkan ini dengan wawasan mattr untuk memperbaruiURLRequest
sebelum memuatnya dengan header cookie membuat saya melewati garis finish.Swift 4.1, 4.2, 5.0:
Untuk membuatnya lebih sederhana, gunakan ekstensi:
Sekarang menjadi:
Ekstensi ini juga tersedia di LionheartExtensions jika Anda hanya ingin solusi drop-in. Bersulang!
sumber
Di iOS 11, Anda dapat mengelola cookie sekarang :), lihat sesi ini: https://developer.apple.com/videos/play/wwdc2017/220/
sumber
Alasan di balik memposting jawaban ini adalah saya mencoba banyak solusi tetapi tidak ada yang berfungsi dengan baik, sebagian besar jawabannya tidak berfungsi jika harus mengatur cookie pertama kali, dan mendapatkan cookie hasil tidak disinkronkan pertama kali, Silakan gunakan solusi ini berfungsi untuk keduanya iOS> = 11.0 <= iOS 11 hingga 8.0, juga berfungsi dengan sinkronisasi cookie pertama kali.
Untuk iOS> = 11.0 - Swift 4.2
Dapatkan http cookies dan atur di wkwebview cookie store seperti ini, ini sangat sulit untuk memuat permintaan Anda di wkwebview , harus mengirim permintaan untuk memuat ketika cookie akan diset sepenuhnya, di sini adalah fungsi yang saya tulis.
Fungsi panggilan dengan penutupan selesai Anda sebut memuat tampilan web. FYI fungsi ini hanya menangani iOS> = 11.0
Berikut ini adalah implementasi untuk fungsi syncCookies .
Untuk iOS 8 hingga iOS 11
Anda perlu mengatur beberapa hal tambahan yang Anda perlu mengatur dua cookie waktu satu melalui menggunakan WKUserScript dan jangan lupa untuk menambahkan cookie dalam permintaan juga, jika cookie Anda tidak disinkronkan pertama kali dan Anda akan melihat halaman Anda tidak memuat pertama kali dengan benar. ini adalah hal yang saya temukan untuk mendukung cookie untuk iOS 8.0
sebelum Anda membuat objek Wkwebview.
Fokus pada fungsi ini getJSCookiesString
Berikut ini langkah lain wkuserscript tidak menyinkronkan cookie segera, ada banyak cara untuk memuat halaman pertama kali dengan cookie satu adalah untuk memuat kembali tampilan web jika menghentikan proses tetapi saya tidak merekomendasikan untuk menggunakannya, itu tidak baik untuk sudut pandang pengguna , heck adalah setiap kali Anda siap untuk memuat cookie set permintaan di header permintaan juga seperti ini, jangan lupa untuk menambahkan cek versi iOS. sebelum memuat permintaan, panggil fungsi ini.
saya menulis ekstensi untuk URLRequest
sekarang Anda siap untuk menguji iOS> 8
sumber
Silakan temukan solusi yang kemungkinan besar akan berhasil untuk Anda di luar kotak. Pada dasarnya itu diubah dan diperbarui untuk Swift 4 @ user3589213 's jawaban .
sumber
Saya sudah mencoba semua jawaban di atas tetapi tidak satupun yang berhasil. Setelah begitu banyak upaya saya akhirnya menemukan cara yang dapat diandalkan untuk mengatur cookie WKWebview.
Pertama, Anda harus membuat turunan dari WKProcessPool dan mengaturnya ke konfigurasi WKWebView yang akan digunakan untuk menginisialisasi WkWebview itu sendiri:
Pengaturan WKProcessPool adalah langkah paling penting di sini.WKWebview memanfaatkan proses isolasi - yang artinya berjalan pada proses yang berbeda dari proses aplikasi Anda. Ini kadang-kadang dapat menyebabkan konflik dan mencegah cookie Anda tidak disinkronkan dengan benar dengan WKWebview.
Sekarang mari kita lihat definisi WKProcessPool
Perhatikan kalimat terakhir jika Anda berencana untuk menggunakan WKWebview yang sama untuk permintaan selanjutnya
apa yang saya maksudkan adalah bahwa jika Anda tidak menggunakan instance WKProcessPool yang sama setiap kali Anda mengkonfigurasi WKWebView untuk domain yang sama (mungkin Anda memiliki VC A yang berisi WKWebView dan Anda ingin membuat instance VC A yang berbeda di tempat yang berbeda ), mungkin ada cookie pengaturan konflik. Untuk mengatasi masalah ini, setelah pembuatan pertama WKProcessPool untuk WKWebView yang memuat domain B, saya menyimpannya dalam singleton dan menggunakan WKProcessPool yang sama setiap kali saya harus membuat WKWebView yang memuat domain B yang sama
Setelah proses inisialisasi, Anda dapat memuat URLRequest dalam blok selesai dari
httpCookieStore.setCookie
. Di sini, Anda harus melampirkan cookie ke header permintaan jika tidak akan berhasil.P / s: Saya mencuri ekstensi dari jawaban fantastis di atas oleh Dan Loewenherz
sumber
Versi saya dari jawaban nteiss. Diuji pada
iOS 11, 12, 13
. Terlihat seperti Anda tidak harus menggunakanDispatchGroup
diiOS 13
lagi.Saya menggunakan fungsi non-statis
includeCustomCookies
aktifWKWebViewConfiguration
, sehingga saya dapat memperbaruicookies
setiap kali saya membuat yang baruWKWebViewConfiguration
.Maka saya menggunakannya seperti ini:
sumber
Perbaikan yang lebih baik untuk permintaan XHR ditunjukkan di sini
Versi Swift 4:
sumber
Jika ada yang menggunakan Alamofire, maka ini adalah solusi yang lebih baik.
sumber
Ini berfungsi untuk saya: Setelah setcookies, tambahkan fetchdatarecords
sumber
Saat menambahkan item kuki multipel, Anda dapat melakukannya seperti ini: (
path
&domain
diperlukan untuk setiap item)jika tidak, hanya item cookie pertama yang akan ditetapkan.
sumber
Anda juga dapat menggunakan WKWebsiteDataStore untuk mendapatkan perilaku yang mirip dengan HTTPCookieStorage dari UIWebView.
sumber
Kode di bawah ini berfungsi dengan baik di proyek saya Swift5. coba muat url oleh WKWebView di bawah ini:
sumber
Ini adalah solusi saya untuk menangani dengan Cookie dan WKWebView di iOS 9 atau lebih baru.
sumber
Kesalahan ini yang saya lakukan adalah saya melewati seluruh url dalam atribut domain, seharusnya hanya nama domain.
sumber