webentwicklung-frage-antwort-db.com.de

Werden Cookies in UIWebView akzeptiert?

Ich muss für dich fragen.

1: Ich verwende UIWebViews in meiner iPhone App. Ich möchte nicht, dass die Benutzer in den Nachrichten Kommentare hinzufügen können. Aber zum Kommentieren müssen sie sich einloggen. 

Wenn nicht, wie kann ich Cookies in UIWebViews akzeptieren?

2: Sind die in UIWebView erstellten Cookies in anderen UIWebView in einer anderen Ansicht verfügbar?

Bsp .: Ich habe meine LoginViewController mit einer eingebetteten UIWebView, in die sich mein Benutzer einloggen/abmelden kann. Wenn sie sich in dieser Ansicht anmelden, ist das Cookie in der Variable CommentViewController noch verfügbar.

Wenn nicht, wie kann ich das möglich machen?

Danke im Voraus !

17
ThibaultV

Die UIWebView speichert die Cookies automatisch in der [NSHTTPCookieStorage sharedHTTPCookieStorage]-Sammlung und sollte während des App-Starts in allen anderen UIWebViews Ihrer App verfügbar sein. Die UIWebView-Klasse speichert jedoch nicht automatisch Cookies für die Seiten, die zwischen App-Starts geladen werden. Sie müssen Cookies manuell speichern, wenn die App in den Hintergrund verschoben wird, und die Werte erneut laden, wenn die App wieder in den Vordergrund gebracht wird.

Fügen Sie den folgenden Code in Ihre AppDelegate-Klasse ein:

- (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];
}
44
Brian Shamblen

Erweiterung der anderen Antworten:

Da NSHTTPCookieStorage cookies mit NSKeyedArchiver archiviert werden kann, müssen Sie nicht jede einzelne Cookie-Eigenschaft selbst extrahieren. Außerdem möchten Sie die Cookie-Eigenschaft NSUserDefaults entfernen, wenn keine Cookies gespeichert werden sollen.

So können Sie das Speichern/Laden von Cookies in diese Erweiterung vereinfachen:

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

Dann verwenden Sie einfach [[NSHTTPCookieStorage sharedHTTPCookieStorage] loadFromUserDefaults]; und [[NSHTTPCookieStorage sharedHTTPCookieStorage] saveToUserDefaults]; in Ihrer AppDelegate, wie oben erwähnt.

11
Robert

Swift 3 klare Version

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

Aus all den großen anderen Antworten auf diese Frage habe ich eine praktische Erweiterung zu UserDefaults zusammengestellt, die den notwendigen Code verkürzt.

UserDefaults Erweiterung für 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 { $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)
            }
        }
    }

}

Sie können diesen Code zu einer separaten Datei UserDefaults+Cookies.Swift hinzufügen (zum Beispiel) und dann die Methoden aus Ihrer AppDelegate aufrufen, wie von Brian Shamblen in seiner original answer beschrieben:

Anrufe von 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()
}
7
Mischa

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

Hier ist eine sauberere und sicherere Swift Version:

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()
}
3
Andrey Gordeev

Swift 2.0 Version

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

Swift 4.2

Bitte fügen Sie diese Erweiterung Ihrem Controller hinzu

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

}

Und ersetzen Sie in AppDelegate diese Codezeilen:

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

mit diesen Codezeilen:

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