在我的iPhone应用程序中,我希望在应用程序重新启动时能够重用相同的服务器端会话。服务器上的会话由cookie标识,该cookie在每次请求时发送。当我重新启动应用程序时,那个cookie就消失了,我不能再使用相同的会话了。
当我使用NSHTTPCookieStorage查找从服务器获得的cookie时,我注意到[cookie isSessionOnly]返回YES。我得到的印象是,这就是为什么我的应用程序在重启时不会保存cookie。我必须做些什么才能使我的cookie不只是会话?我必须从服务器发送哪些HTTP标头?
发布于 2011-05-09 23:17:29
您可以保存cookie,方法是保存其属性字典,然后在重新连接之前将其恢复为新cookie。
保存:
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];
}
}负载:
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];
}发布于 2014-04-14 20:25:55
我已经提升了@TomIrving的回答,并在这里详细说明,因为许多用户不会看到他在其中说的非常重要的评论:
您需要设置到期日期,否则cookie将假定为仅会话。
基本上,cookie将在您关闭应用程序时删除,除非cookie在将来有过期日期。
如果您可以控制服务器,并且可以要求它在将来将"Expires“头设置为某个值,则不需要在NSUserDefaults中存储和恢复cookies。如果你不能控制服务器或者不想重写服务器的行为,你可以通过改变expiresDate来“欺骗”你的应用:
使用以下命令从新创建的cookie属性中获取要修改的cookie :使用[NSHTTPCookie.cookieWithProperties:]
[[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]
NSMutableDictionary将"Expires"值更改为新NSMutableDictionary中的日期新cookie当你重新打开你的应用程序时,你会注意到cookie并没有被删除。
发布于 2016-07-24 01:21:42
仅会话cookie将因其性质而过期。如果您确实需要,可以将它们手动存储在Keychain中。我更喜欢钥匙串,而不是保存在UserDefaults或归档中,因为cookies更安全,就像用户的密码一样。
不幸的是,保存仅会话的cookie并不是很有帮助,下面的代码只是演示了如何存储cookie,但不能以任何方式强制服务器接受这样的cookie(除非您可以控制服务器)。
Swift 2.2
// 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)
}
}
}
}https://stackoverflow.com/questions/2662530
复制相似问题