質問しなければなりません。
1:iPhoneアプリでUIWebView
sを使用しています。ユーザーがニュースにコメントを追加することはできません。ただし、コメントするにはログインする必要があります。
そうでない場合、どのようにしてUIWebView
sのCookieを受け入れることができますか?
2:UIWebView
で作成されたCookieは、他のビューで他のUIWebView
で使用できますか?
例:LoginViewController
があり、UIWebView
が埋め込まれています。ユーザーはそこでログイン/ログアウトできます。このビューでログインした場合、CookieはCommentViewController
?
そうでない場合、どうすればこれを可能にできますか?
前もって感謝します !
UIWebView
は、Cookieを[NSHTTPCookieStorage sharedHTTPCookieStorage]
コレクション。同じアプリの起動中に、アプリ内の他のすべてのUIWebView
sで利用できるようにする必要があります。ただし、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];
を使用します。
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
の便利な拡張機能をコンパイルしました。
UserDefaults
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)
}
}
}
}
このコードを別のファイルに追加できますUserDefaults+Cookies.Swift
(たとえば)そして、ブライアンシャンブレンが 元の回答 で説明したように、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
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 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")
}
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()
}