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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:44:38  来源:igfitidea点击:

Are cookies in UIWebView accepted?

iosobjective-ciphonecookiesuiwebview

提问by ThibaultV

I have to question for you.

我得替你提问。

1 : I'm using UIWebViews 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 UIWebViews ?

如果没有,我如何接受UIWebViews 中的cookie ?

2 : Are the cookies created in on UIWebViewavailable in others UIWebViewin 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 UIWebViewwill automatically store the cookies in the [NSHTTPCookieStorage sharedHTTPCookieStorage]collection, and should be available in all other UIWebViews within your app, during the same app launch. However the UIWebViewclass 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 cookiescan be archived using NSKeyedArchiver, you don't need to extract every single cookie property yourself. Furthermore, you will want to remove the NSUserDefaultscookie 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 AppDelegateas 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 UserDefaultsthat shortens the necessary code.

从这个问题的所有其他很棒的答案中,我编译了一个方便的扩展,UserDefaults它缩短了必要的代码。

UserDefaultsExtension for Swift 3

UserDefaultsSwift 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 AppDelegateas 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:

使用此代码行:

##代码##