是否接受UIWebView中的cookie



我必须为你提问。

1:我在iPhone应用程序中使用UIWebView。我希望用户不能在新闻中添加评论。但是,要发表评论,他们必须登录。

如果没有,我如何在UIWebView s中接受cookie?

2:在UIWebView上创建的cookie在其他视图中的其他UIWebView中可用吗?

例如:我有一个嵌入UIWebViewLoginViewController,我的用户可以在那里登录/注销。如果他们在此视图中登录,则cookie在CommentViewController中仍然可用?

如果没有,我如何才能做到这一点?

提前感谢!

UIWebView将自动将cookie存储在[NSHTTPCookieStorage sharedHTTPCookieStorage]集合中,并且在同一应用程序启动期间,该cookie应在应用程序内的所有其他UIWebView中可用。然而,UIWebView类不会自动存储在应用程序启动之间加载的页面的cookie。当应用程序移动到后台时,您需要手动存储cookie,并在应用程序返回前台时重新加载值。

在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];
}

扩展其他答案:

由于NSHTTPCookieStorage cookies可以使用NSKeyedArchiver存档,因此您不需要自己提取每一个cookie属性。此外,当没有可存储的cookie时,您将希望删除NSUserDefaults cookie属性。

因此,您可以将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

然后在AppDelegate中使用[[NSHTTPCookieStorage sharedHTTPCookieStorage] loadFromUserDefaults];[[NSHTTPCookieStorage sharedHTTPCookieStorage] saveToUserDefaults];,如上所述。

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)
    }
}

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

Swift 3的UserDefaults扩展

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 { $0.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: $0) {
                HTTPCookieStorage.shared.setCookie(cookie)
            }
        }
    }
}

您可以将此代码添加到一个单独的文件UserDefaults+Cookies.swift中(例如),然后从您的AppDelegate中调用方法,如Brian Shamblen在其原始答案中所述

来自AppDelegate的调用

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()
}

Swift 3

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")
}

这里有一个更干净、更安全的Swift版本:

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()
}

Swift 4.2

请将此扩展添加到您的控制器

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 { $0.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: $0) {
                HTTPCookieStorage.shared.setCookie(cookie)
            }
        }
    }
}

并在AppDelegate中替换以下代码行:

    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:.
    }

使用以下代码行:

    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()
    }

Swift 2.0版本

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")
}

最新更新