ios 是否接受 UIWebView 中的 cookie?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26005641/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Are cookies in UIWebView accepted?
提问by ThibaultV
I have to question for you.
我得替你提问。
1 : I'm using UIWebView
s in my iPhone App. I wan't the users be able to add comments in the news. But, to comment they have to log-in.
1 : 我UIWebView
在我的 iPhone 应用程序中使用s。我不希望用户能够在新闻中添加评论。但是,要发表评论,他们必须登录。
If not, how can I accept cookies in UIWebView
s ?
如果没有,我如何接受UIWebView
s 中的cookie ?
2 : Are the cookies created in on UIWebView
available in others UIWebView
in an other View ?
2:在其他视图中创建的cookie是否在其他视图中UIWebView
可用UIWebView
?
Ex : I have my LoginViewController
, with an embedded UIWebView
, where my user can login/logout. If they log-in in this view, the cookie will be still available in the CommentViewController
?
例如:我的LoginViewController
, 带有嵌入式UIWebView
,我的用户可以在其中登录/注销。如果他们在此视图中登录,cookie 仍将在CommentViewController
?
If not, how can I make this possible ?
如果没有,我怎样才能做到这一点?
Thanks in advance !
提前致谢 !
回答by Brian Shamblen
The UIWebView
will automatically store the cookies in the [NSHTTPCookieStorage sharedHTTPCookieStorage]
collection, and should be available in all other UIWebView
s within your app, during the same app launch. However the UIWebView
class does not automatically store cookies for the pages that are loaded between app launches. You need to manually store cookies when the app is moved into the background and reload the values when the app is brought back into the foreground.
该UIWebView
饼干将自动存储在[NSHTTPCookieStorage sharedHTTPCookieStorage]
收集,并应在所有其他可用UIWebView
的应用程序内S,同样的应用程序启动时。但是,UIWebView
该类不会为在应用程序启动之间加载的页面自动存储 cookie。您需要在应用程序移入后台时手动存储 cookie,并在应用程序返回前台时重新加载值。
Place the following code in your AppDelegate class:
将以下代码放在您的 AppDelegate 类中:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Other existing code
[self loadHTTPCookies];
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
//Other existing code
[self saveHTTPCookies];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[self loadHTTPCookies];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
//Other existing code
[self saveHTTPCookies];
}
-(void)loadHTTPCookies
{
NSMutableArray* cookieDictionary = [[NSUserDefaults standardUserDefaults] valueForKey:@"cookieArray"];
for (int i=0; i < cookieDictionary.count; i++)
{
NSMutableDictionary* cookieDictionary1 = [[NSUserDefaults standardUserDefaults] valueForKey:[cookieDictionary objectAtIndex:i]];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieDictionary1];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
}
-(void)saveHTTPCookies
{
NSMutableArray *cookieArray = [[NSMutableArray alloc] init];
for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
[cookieArray addObject:cookie.name];
NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:cookie.name forKey:NSHTTPCookieName];
[cookieProperties setObject:cookie.value forKey:NSHTTPCookieValue];
[cookieProperties setObject:cookie.domain forKey:NSHTTPCookieDomain];
[cookieProperties setObject:cookie.path forKey:NSHTTPCookiePath];
[cookieProperties setObject:[NSNumber numberWithUnsignedInteger:cookie.version] forKey:NSHTTPCookieVersion];
[cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];
[[NSUserDefaults standardUserDefaults] setValue:cookieProperties forKey:cookie.name];
[[NSUserDefaults standardUserDefaults] synchronize];
}
[[NSUserDefaults standardUserDefaults] setValue:cookieArray forKey:@"cookieArray"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
回答by Robert
Expanding the other answers:
扩展其他答案:
Since NSHTTPCookieStorage cookies
can be archived using NSKeyedArchiver
, you don't need to extract every single cookie property yourself. Furthermore, you will want to remove the NSUserDefaults
cookie property, when there are no cookies to store.
由于NSHTTPCookieStorage cookies
可以使用 存档NSKeyedArchiver
,因此您无需自己提取每个 cookie 属性。此外,NSUserDefaults
当没有要存储的cookie 时,您将需要删除cookie 属性。
So you can simplify your cookie storing/loading to this extension:
所以你可以简化你的 cookie 存储/加载到这个扩展:
static NSString *const kCookiesKey = @"cookies";
@implementation NSHTTPCookieStorage (Persistence)
- (void)saveToUserDefaults
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if (self.cookies != nil && self.cookies.count > 0) {
NSData *cookieData = [NSKeyedArchiver archivedDataWithRootObject:self.cookies];
[userDefaults setObject:cookieData forKey:kCookiesKey];
} else {
[userDefaults removeObjectForKey:kCookiesKey];
}
[userDefaults synchronize];
}
- (void)loadFromUserDefaults
{
NSData *cookieData = [[NSUserDefaults standardUserDefaults] objectForKey:kCookiesKey];
if (cookieData != nil) {
NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookieData];
for (NSHTTPCookie *cookie in cookies) {
[self setCookie:cookie];
}
}
}
@end
Then just use [[NSHTTPCookieStorage sharedHTTPCookieStorage] loadFromUserDefaults];
and [[NSHTTPCookieStorage sharedHTTPCookieStorage] saveToUserDefaults];
in your AppDelegate
as mentioned above.
然后就像上面提到的那样使用[[NSHTTPCookieStorage sharedHTTPCookieStorage] loadFromUserDefaults];
and 。[[NSHTTPCookieStorage sharedHTTPCookieStorage] saveToUserDefaults];
AppDelegate
回答by Wane
swift 3 clear version
swift 3 清晰版
func saveCookies() {
guard let cookies = HTTPCookieStorage.shared.cookies else {
return
}
let array = cookies.flatMap { (cookie) -> [HTTPCookiePropertyKey: Any]? in
cookie.properties
}
UserDefaults.standard.set(array, forKey: "cookies")
UserDefaults.standard.synchronize()
}
func loadCookies() {
guard let cookies = UserDefaults.standard.value(forKey: "cookies") as? [[HTTPCookiePropertyKey: Any]] else {
return
}
cookies.forEach { (cookie) in
guard let cookie = HTTPCookie.init(properties: cookie) else {
return
}
HTTPCookieStorage.shared.setCookie(cookie)
}
}
回答by Mischa
From all the great other answers to this question I compiled a handy extension on UserDefaults
that shortens the necessary code.
从这个问题的所有其他很棒的答案中,我编译了一个方便的扩展,UserDefaults
它缩短了必要的代码。
UserDefaults
Extension for Swift 3
UserDefaults
Swift 3 的扩展
extension UserDefaults {
/// A dictionary of properties representing a cookie.
typealias CookieProperties = [HTTPCookiePropertyKey: Any]
/// The `UserDefaults` key for accessing cookies.
private static let cookieKey = "cookies"
/// Saves all cookies currently in the shared `HTTPCookieStorage` to the shared `UserDefaults`.
func saveCookies() {
guard let cookies = HTTPCookieStorage.shared.cookies else {
return
}
let cookiePropertiesArray = cookies.flatMap { func applicationDidBecomeActive(_ application: UIApplication) {
UserDefaults.standard.loadCoookies()
}
func applicationWillEnterForeground(_ application: UIApplication) {
UserDefaults.standard.loadCoookies()
}
func applicationDidEnterBackground(_ application: UIApplication) {
UserDefaults.standard.saveCookies()
}
func applicationWillTerminate(_ application: UIApplication) {
UserDefaults.standard.saveCookies()
}
.properties }
set(cookiePropertiesArray, forKey: UserDefaults.cookieKey)
synchronize()
}
/// Loads all cookies stored in the shared `UserDefaults` and adds them to the current shared `HTTPCookieStorage`.
func loadCoookies() {
let cookiePropertiesArray = value(forKey: UserDefaults.cookieKey) as? [CookieProperties]
cookiePropertiesArray?.forEach {
if let cookie = HTTPCookie(properties: func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any] ? ) - > Bool {
loadHTTPCookies()
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
saveCookies()
}
func applicationWillEnterForeground(_ application: UIApplication) {
loadHTTPCookies()
}
func applicationWillTerminate(_ application: UIApplication) {
saveCookies()
}
func loadHTTPCookies() {
if let cookieDict = UserDefaults.standard.value(forKey: "cookieArray") as? NSMutableArray {
for c in cookieDict {
let cookies = UserDefaults.standard.value(forKey: c as!String) as!NSDictionary
let cookie = HTTPCookie(properties: cookies as![HTTPCookiePropertyKey: Any])
HTTPCookieStorage.shared.setCookie(cookie!)
}
}
}
func saveCookies() {
let cookieArray = NSMutableArray()
if let savedC = HTTPCookieStorage.shared.cookies {
for c: HTTPCookie in savedC {
let cookieProps = NSMutableDictionary()
cookieArray.add(c.name)
cookieProps.setValue(c.name, forKey: HTTPCookiePropertyKey.name.rawValue)
cookieProps.setValue(c.value, forKey: HTTPCookiePropertyKey.value.rawValue)
cookieProps.setValue(c.domain, forKey: HTTPCookiePropertyKey.domain.rawValue)
cookieProps.setValue(c.path, forKey: HTTPCookiePropertyKey.path.rawValue)
cookieProps.setValue(c.version, forKey: HTTPCookiePropertyKey.version.rawValue)
cookieProps.setValue(NSDate().addingTimeInterval(2629743), forKey: HTTPCookiePropertyKey.expires.rawValue)
UserDefaults.standard.setValue(cookieProps, forKey: c.name)
UserDefaults.standard.synchronize()
}
}
UserDefaults.standard.setValue(cookieArray, forKey: "cookieArray")
}
) {
HTTPCookieStorage.shared.setCookie(cookie)
}
}
}
}
You can add this code to a separate file UserDefaults+Cookies.swift
(for example) and then call the methods from your AppDelegate
as described by Brian Shamblen in his original answer:
您可以将此代码添加到单独的文件中UserDefaults+Cookies.swift
(例如),然后AppDelegate
按照 Brian Shamblen 在其原始答案中的描述调用您的方法:
Calls from AppDelegate
来自 AppDelegate 的调用
private func loadCookies() {
guard let cookies = NSUserDefaults.standardUserDefaults().valueForKey("cookies") as? [[String: AnyObject]] else {
return
}
for cookieProperties in cookies {
if let cookie = NSHTTPCookie(properties: cookieProperties) {
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(cookie)
}
}
}
private func saveCookies() {
guard let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies else {
return
}
var array = [[String: AnyObject]]()
for cookie in cookies {
if let properties = cookie.properties {
array.append(properties)
}
}
NSUserDefaults.standardUserDefaults().setValue(array, forKey: "cookies")
NSUserDefaults.standardUserDefaults().synchronize()
}
回答by zombie
Swift 3
斯威夫特 3
func loadCookies() {
let cookieDict : NSMutableArray? = NSUserDefaults.standardUserDefaults().valueForKey("cookieArray") as? NSMutableArray
if cookieDict != nil {
for var c in cookieDict! {
let cookies = NSUserDefaults.standardUserDefaults().valueForKey(c as! String) as! NSDictionary
let cookie = NSHTTPCookie(properties: cookies as! [String : AnyObject])
NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(cookie!)
}
}
}
func saveCookies() {
var cookieArray = NSMutableArray()
let savedC = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies
for var c : NSHTTPCookie in savedC! {
var cookieProps = NSMutableDictionary()
cookieArray.addObject(c.name)
cookieProps.setValue(c.name, forKey: NSHTTPCookieName)
cookieProps.setValue(c.value, forKey: NSHTTPCookieValue)
cookieProps.setValue(c.domain, forKey: NSHTTPCookieDomain)
cookieProps.setValue(c.path, forKey: NSHTTPCookiePath)
cookieProps.setValue(c.version, forKey: NSHTTPCookieVersion)
cookieProps.setValue(NSDate().dateByAddingTimeInterval(2629743), forKey: NSHTTPCookieExpires)
NSUserDefaults.standardUserDefaults().setValue(cookieProps, forKey: c.name)
NSUserDefaults.standardUserDefaults().synchronize()
}
NSUserDefaults.standardUserDefaults().setValue(cookieArray, forKey: "cookieArray")
}
回答by Andrey Gordeev
Here is a cleaner and more safe Swiftversion:
这是一个更干净、更安全的Swift版本:
extension UserDefaults {
/// A dictionary of properties representing a cookie.
typealias CookieProperties = [HTTPCookiePropertyKey: Any]
/// The `UserDefaults` key for accessing cookies.
private static let cookieKey = "cookies"
/// Saves all cookies currently in the shared `HTTPCookieStorage` to the shared `UserDefaults`.
func saveCookies() {
guard let cookies = HTTPCookieStorage.shared.cookies else {
return
}
let cookiePropertiesArray = cookies.compactMap { func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
.properties }
set(cookiePropertiesArray, forKey: UserDefaults.cookieKey)
synchronize()
}
/// Loads all cookies stored in the shared `UserDefaults` and adds them to the current shared `HTTPCookieStorage`.
func loadCoookies() {
let cookiePropertiesArray = value(forKey: UserDefaults.cookieKey) as? [CookieProperties]
cookiePropertiesArray?.forEach {
if let cookie = HTTPCookie(properties: func applicationDidBecomeActive(_ application: UIApplication) {
UserDefaults.standard.loadCoookies()
}
func applicationWillEnterForeground(_ application: UIApplication) {
UserDefaults.standard.loadCoookies()
}
func applicationDidEnterBackground(_ application: UIApplication) {
UserDefaults.standard.saveCookies()
}
func applicationWillTerminate(_ application: UIApplication) {
UserDefaults.standard.saveCookies()
}
) {
HTTPCookieStorage.shared.setCookie(cookie)
}
}
}
}
回答by chrisby
Swift 2.0 Version
斯威夫特 2.0 版本
##代码##回答by malibayram91
Swift 4.2
斯威夫特 4.2
Please add this extension to your controller
请将此扩展添加到您的控制器
##代码##And replace in AppDelegate this code lines:
并在 AppDelegate 中替换此代码行:
##代码##with this code lines:
使用此代码行:
##代码##