首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iPhone:应用程序重新启动时不保存NSHTTPCookie

iPhone:应用程序重新启动时不保存NSHTTPCookie
EN

Stack Overflow用户
提问于 2010-04-18 22:27:39
回答 7查看 18.4K关注 0票数 32

在我的iPhone应用程序中,我希望在应用程序重新启动时能够重用相同的服务器端会话。服务器上的会话由cookie标识,该cookie在每次请求时发送。当我重新启动应用程序时,那个cookie就消失了,我不能再使用相同的会话了。

当我使用NSHTTPCookieStorage查找从服务器获得的cookie时,我注意到[cookie isSessionOnly]返回YES。我得到的印象是,这就是为什么我的应用程序在重启时不会保存cookie。我必须做些什么才能使我的cookie不只是会话?我必须从服务器发送哪些HTTP标头?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-05-09 23:17:29

您可以保存cookie,方法是保存其属性字典,然后在重新连接之前将其恢复为新cookie。

保存:

代码语言:javascript
复制
NSArray* allCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[NSURL URLWithString:URL]];
for (NSHTTPCookie *cookie in allCookies) {
    if ([cookie.name isEqualToString:MY_COOKIE]) { 
        NSMutableDictionary* cookieDictionary = [NSMutableDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults] dictionaryForKey:PREF_KEY]];
        [cookieDictionary setValue:cookie.properties forKey:URL];
        [[NSUserDefaults standardUserDefaults] setObject:cookieDictionary forKey:PREF_KEY];
    }
 }

负载:

代码语言:javascript
复制
NSDictionary* cookieDictionary = [[NSUserDefaults standardUserDefaults] dictionaryForKey:PREF_KEY];
NSDictionary* cookieProperties = [cookieDictionary valueForKey:URL];
if (cookieProperties != nil) {
    NSHTTPCookie* cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
    NSArray* cookieArray = [NSArray arrayWithObject:cookie];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookieArray forURL:[NSURL URLWithString:URL] mainDocumentURL:nil];
}
票数 45
EN

Stack Overflow用户

发布于 2014-04-14 20:25:55

我已经提升了@TomIrving的回答,并在这里详细说明,因为许多用户不会看到他在其中说的非常重要的评论:

您需要设置到期日期,否则cookie将假定为仅会话。

基本上,cookie将在您关闭应用程序时删除,除非cookie在将来有过期日期。

如果您可以控制服务器,并且可以要求它在将来将"Expires“头设置为某个值,则不需要在NSUserDefaults中存储和恢复cookies。如果你不能控制服务器或者不想重写服务器的行为,你可以通过改变expiresDate来“欺骗”你的应用:

使用以下命令从新创建的cookie属性中获取要修改的cookie :使用[NSHTTPCookie.cookieWithProperties:]

  • Save [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]

  • Copy
  • NSMutableDictionary"Expires"值更改为新NSMutableDictionary中的日期新cookie

当你重新打开你的应用程序时,你会注意到cookie并没有被删除。

票数 27
EN

Stack Overflow用户

发布于 2016-07-24 01:21:42

仅会话cookie将因其性质而过期。如果您确实需要,可以将它们手动存储在Keychain中。我更喜欢钥匙串,而不是保存在UserDefaults或归档中,因为cookies更安全,就像用户的密码一样。

不幸的是,保存仅会话的cookie并不是很有帮助,下面的代码只是演示了如何存储cookie,但不能以任何方式强制服务器接受这样的cookie(除非您可以控制服务器)。

Swift 2.2

代码语言:javascript
复制
// Saving into Keychain
if let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies {
    let cookiesData: NSData = NSKeyedArchiver.archivedDataWithRootObject(cookies)
    let userAccount = "some unique string to identify the item in Keychain, in my case I use username"
    let domain = "some other string you can use in combination with userAccount to identify the item"           
    let keychainQuery: [NSString: NSObject] = [
                        kSecClass: kSecClassGenericPassword,
                        kSecAttrAccount: userAccount + "cookies", 
                        kSecAttrService: domain,
                        kSecValueData: cookiesData]
    SecItemDelete(keychainQuery as CFDictionaryRef) //Trying to delete the item from Keychaing just in case it already exists there
    let status: OSStatus = SecItemAdd(keychainQuery as CFDictionaryRef, nil)
    if (status == errSecSuccess) {
        print("Cookies succesfully saved into Keychain")
    }
}

// Getting from Keychain
let userAccount = "some unique string to identify the item in Keychain, in my case I use username"
let domain = "some other string you can use in combination with userAccount to identify the item"
let keychainQueryForCookies: [NSString: NSObject] = [
                             kSecClass: kSecClassGenericPassword,
                             kSecAttrService: domain, // we use JIRA URL as service string for Keychain
                             kSecAttrAccount: userAccount + "cookies",
                             kSecReturnData: kCFBooleanTrue,
                             kSecMatchLimit: kSecMatchLimitOne]
var rawResultForCookies: AnyObject?
let status: OSStatus = SecItemCopyMatching(keychainQueryForCookies, &rawResultForCookies)
if (status == errSecSuccess) {
    let retrievedData = rawResultForCookies as? NSData
    if let unwrappedData = retrievedData {
        if let cookies = NSKeyedUnarchiver.unarchiveObjectWithData(unwrappedData) as? [NSHTTPCookie] {
            for aCookie in cookies {
                NSHTTPCookieStorage.sharedHTTPCookieStorage().setCookie(aCookie)
            }
        }
    }
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2662530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档