在我的iPhone应用程序中,我希望能够在我的应用程序重新启动时重用相同的服务器端会话.服务器上的会话由cookie标识,cookie在每个请求上发送.当我重新启动应用程序时,该cookie已经消失,我不能再使用相同的会话了.
当我用它NSHTTPCookieStorage查找从服务器获得的cookie 时,我注意到的是[cookie isSessionOnly]返回YES.我得到的印象是,这就是为什么不会在重新启动应用时保存Cookie的原因.我需要做什么才能使我的cookie不仅仅是会话?我必须从服务器发送哪些HTTP标头?
Mik*_*atz 44
您可以通过保存其属性字典来保存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];
}
}
Run Code Online (Sandbox Code Playgroud)
加载:
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];
}
Run Code Online (Sandbox Code Playgroud)
Abd*_*bdo 23
我赞成了@ TomIrving的回答并在此详细阐述,因为许多用户不会看到他说的非常重要的评论:
"你需要设置一个到期日期,否则假设cookie只是会话."
基本上,当您关闭应用程序时,cookie将被删除,除非cookie将来有一个到期日期.
NSUserDefaults如果您可以控制服务器,则无需在cookie中存储和恢复cookie,并且可以要求它在将来将"Expires"标题设置为某些内容.如果您无法控制服务器或者不希望覆盖服务器的行为,则可以通过更改其中的内容来"欺骗"您的应用expiresDate:
[[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]NSMutableDictionary,将"Expires"值更改为将来的日期.NSMutableDictionary使用以下命令从新建一个新cookie :[NSHTTPCookie.cookieWithProperties:][[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie newCookie]当您重新打开应用程序时,您会注意到cookie尚未删除.
仅会话的cookie会因其性质而过期。如果确实需要,可以将它们手动存储在钥匙串中。我更喜欢钥匙串而不是保存在UserDefaults或归档中,因为最好像用户密码一样保护cookie。
不幸的是,保存仅会话的cookie并不是很有帮助,下面的代码只是说明如何存储cookie,但不能强制服务器以任何方式接受此类cookie(除非您可以控制服务器)。
斯威夫特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)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16652 次 |
| 最近记录: |