2014-12-04 14 views
7

Tôi cố gắng để sử dụng NSURLSessions phù du để cung cấp cookie handling riêng biệt cho một số nhiệm vụ trong phạm vi ứng dụng của tôi. Các tác vụ này không bị ràng buộc trực tiếp với giao diện người dùng. Vấn đề: Bất cứ điều gì tôi làm, các cookieAcceptPolicy của NSHTTPCookieStorage phù du vẫn NSHTTPCookieAcceptPolicyNever.Làm thế nào để thiết lập cookieAcceptPolicy cho NSURLSession phù du

Dưới đây là mã của tôi:

// use a pure in-memory configuration with its own private cache, cookie, and credential store 
__block NSURLSessionConfiguration* config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; 

// do anything to accept all cookies 
config.HTTPShouldSetCookies = YES; 
config.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicyAlways; 
config.HTTPCookieStorage.cookieAcceptPolicy = NSHTTPCookieAcceptPolicyAlways; 

__block NSURLSession* session = [NSURLSession sessionWithConfiguration:config]; 

NSURLSessionDataTask* task = [session dataTaskWithURL:[NSURL URLWithString:@"https://test.cgmlife.com/Catalogs"] 
            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
             NSHTTPCookieStorage* cookies = session.configuration.HTTPCookieStorage; 
             NSLog(@"%@", cookies); 
             NSLog(@"%lu", cookies.cookieAcceptPolicy); 
            }]; 
[task resume]; 

Kết quả từ NSLog luôn là:

Ephemeral <NSHTTPCookieStorage cookies count:0> 
1 

trong đó 1 là giá trị cho NSHTTPCookieAcceptPolicyNever (dự kiến ​​0 cho NSHTTPCookieAcceptPolicyAlways). Các tiêu đề trong phản hồi là có.

tôi có thể làm gì để có NSHTTPCookieStorage nhớ cookie của tôi trong khi phiên giao dịch còn sống? Tôi không cần và không muốn bất kỳ sự kiên trì nào. Tôi chỉ muốn giữ cookie trong bộ nhớ để chúng được sử dụng lại cho các yêu cầu tiếp theo trong cùng một phiên.

Trả lời

2

Dường như phiên phù du không lưu trữ các tập tin cookie bao giờ hết. eskimo1 says on the devforums:

ISTR cấu hình phiên tạm thời không hoạt động theo cách mà mọi người mong đợi dựa trên tài liệu. Tôi không bao giờ có được xung quanh để nhìn vào điều này một cách chi tiết nhưng nó có vẻ như bạn có. Bạn nên nộp một lỗi về việc này; việc triển khai và tài liệu rõ ràng là đồng bộ hóa, do đó, một trong số chúng cần phải được khắc phục.

1

Dường như iOS9 ephemeralSessionConfiguration hoạt động như mong đợi. Trên iOS8, có vẻ như lưu trữ cookie trả về Không bao giờ cho chính sách của nó và không thể đặt lại. Việc triển khai dường như không lưu trữ mặc dù tên lớp riêng tư, thay vì chỉ bộ nhớ.

Đối iOS8, tôi đã có thể thay thế một thực hiện thô sơ mặc dù, và có vẻ như để làm việc (ít nhất là trong mô phỏng với thử nghiệm ánh sáng). Việc triển khai các phương thức mới có đối tượng nhiệm vụ là rất cần thiết.

#import <Foundation/Foundation.h> 
@interface MemoryCookieStorage : NSHTTPCookieStorage 
@property (nonatomic, strong) NSMutableArray *internalCookies; 
@property (atomic, assign) NSHTTPCookieAcceptPolicy policy; 
@end 

@implementation MemoryCookieStorage 

- (id)init 
{ 
    if (self = [super init]) { 
     _internalCookies = [NSMutableArray new]; 
     _policy = NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain; 
    } 
    return self; 
} 

- (NSHTTPCookieAcceptPolicy)cookieAcceptPolicy { 
    return self.policy; 
} 
- (void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)cookieAcceptPolicy { 
    self.policy = cookieAcceptPolicy; 
} 

- (NSUInteger)_indexOfCookie:(NSHTTPCookie *)target 
{ 
    return [_internalCookies indexOfObjectPassingTest:^BOOL(NSHTTPCookie *cookie, NSUInteger idx, BOOL *stop) { 
     return ([target.name caseInsensitiveCompare:cookie.name] == NSOrderedSame && 
       [target.domain caseInsensitiveCompare:cookie.domain] == NSOrderedSame && 
       (target.path == cookie.path || [target.path isEqual:cookie.path])); 
    }]; 
} 

- (void)setCookie:(NSHTTPCookie *)cookie 
{ 
    if (self.cookieAcceptPolicy != NSHTTPCookieAcceptPolicyNever) 
    { 
     @synchronized(_internalCookies) { 
      NSInteger idx = [self _indexOfCookie:cookie]; 
      if (idx == NSNotFound) 
       [_internalCookies addObject:cookie]; 
      else 
       [_internalCookies replaceObjectAtIndex:idx withObject:cookie]; 
     } 
    } 
} 

- (void)deleteCookie:(NSHTTPCookie *)cookie 
{ 
    @synchronized(_internalCookies) { 
     NSInteger idx = [self _indexOfCookie:cookie]; 
     if (idx != NSNotFound) 
      [_internalCookies removeObjectAtIndex:idx]; 
    } 
} 

- (NSArray *)cookies 
{ 
    @synchronized(_internalCookies) { 
     return [_internalCookies copy]; 
    } 
} 

static BOOL HasCaseSuffix(NSString *string, NSString *suffix) 
{ 
    return [string rangeOfString:suffix options:NSCaseInsensitiveSearch|NSAnchoredSearch|NSBackwardsSearch].length > 0; 
} 
static BOOL IsDomainOK(NSString *cookieDomain, NSString *host) 
{ 
    return ([cookieDomain caseInsensitiveCompare:host] == NSOrderedSame || 
      ([cookieDomain hasPrefix:@"."] && HasCaseSuffix(host, cookieDomain)) || 
      (cookieDomain && HasCaseSuffix(host, [@"." stringByAppendingString:cookieDomain]))); 
} 
- (NSArray *)cookiesForURL:(NSURL *)URL 
{ 
    NSMutableArray *array = [NSMutableArray new]; 
    NSString *host = URL.host; 
    NSString *path = URL.path; 

    @synchronized(_internalCookies) 
    { 
     for (NSHTTPCookie *cookie in _internalCookies) 
     { 
      if (!IsDomainOK(cookie.domain, host)) 
       continue; 

      BOOL pathOK = cookie.path.length == 0 || [cookie.path isEqual:@"/"] || [path hasPrefix:cookie.path]; 
      if (!pathOK) 
       continue; 

      if (cookie.isSecure && [URL.scheme caseInsensitiveCompare:@"https"] != NSOrderedSame) 
       continue; 

      if ([cookie.expiresDate timeIntervalSinceNow] > 0) 
       continue; 

      [array addObject:cookie]; 
     } 
    } 

    array = (id)[array sortedArrayUsingComparator:^NSComparisonResult(NSHTTPCookie *c1, NSHTTPCookie *c2) { 
     /* More specific cookies, i.e. matching the longest portion of the path, come first */ 
     NSInteger path1 = c1.path.length; 
     NSInteger path2 = c2.path.length; 
     if (path1 > path2) 
      return NSOrderedAscending; 
     if (path2 > path1) 
      return NSOrderedDescending; 
     return [c1.name caseInsensitiveCompare:c2.name]; 
    }]; 

    return array; 
} 

- (NSArray *)sortedCookiesUsingDescriptors:(NSArray *)sortOrder 
{ 
    return [[self cookies] sortedArrayUsingDescriptors:sortOrder]; 
} 

- (void)getCookiesForTask:(NSURLSessionTask *)task completionHandler:(void (^) (NSArray *taskCookies))completionHandler 
{ 
    NSArray *urlCookies = [self cookiesForURL:task.currentRequest.URL]; 
    completionHandler(urlCookies); 
} 

- (void)setCookies:(NSArray *)newCookies forURL:(NSURL *)URL mainDocumentURL:(NSURL *)mainDocumentURL 
{ 
    NSString *host = mainDocumentURL.host; 
    for (NSHTTPCookie *cookie in newCookies) 
    { 
     switch (self.cookieAcceptPolicy) 
     { 
      case NSHTTPCookieAcceptPolicyAlways: 
       [self setCookie:cookie]; 
       break; 
      case NSHTTPCookieAcceptPolicyNever: 
       break; 
      case NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain: 
       if (IsDomainOK(cookie.domain, host)) 
        [self setCookie:cookie]; 
       break; 
     } 
    } 
} 

- (void)storeCookies:(NSArray *)taskCookies forTask:(NSURLSessionTask *)task 
{ 
    NSURL *mainURL = task.currentRequest.mainDocumentURL ?: task.originalRequest.mainDocumentURL ?: task.originalRequest.URL; 
    [self setCookies:taskCookies forURL:task.currentRequest.URL mainDocumentURL:mainURL]; 
} 

@end 

Nó phải có khả năng kiểm tra sessionConfiguration.HTTPCookieStorage.cookieAcceptPolicy == NSHTTPCookieAcceptPolicyNever sau khi tạo phiên phù du để xem nếu HTTPCookieStorage cần phải được thay thế bằng một thể hiện của lớp trên (không cần nó trên iOS9). Có lẽ một số lỗi ... Tôi chỉ cần điều này cho một bản demo và nó đã làm việc đủ tốt cho điều đó. Nhưng họ không nên quá khó khăn để sửa chữa nếu có.

Các vấn đề liên quan