AFNetworking 支援cookies的解決方案
AFNetworking是支援cookies,只不過它把這個邏輯交給了iOS 底層的api處理了。
多話不說了,很討厭網上那些人云亦云的帖子,三人成虎!
本次我們的專案重構,需要用到cookies,我直接給出解決方案吧:
(cookie使用支援的簡單思路是:首次請求時,伺服器取回cookies,然後每次請求時附加上cookie,如此反覆即可,至於cookies中有啥內容,我們不用關注,伺服器要就給她)
我使用的是AFNetworking的AFHTTPClient進行網路訪問的,我就直接在AFHTTPClient.h新增兩個支援cookies的方法,一個是為post寫的,另一個是為get寫的。
1、在AFHTTPClient.h新增兩個支援cookies的方法,每次請求時,都傳送出本地cookies
1 2 3 4 5 | // add by block cheng - ( void )blockGetPath:(NSString *)path parameters:(NSDictionary *)parameters success:( void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:( void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; |
1 2 3 4 5 | //add by block cheng - ( void )blockPostPath:(NSString *)path parameters:(NSDictionary *)parameters success:( void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:( void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; |
其實現是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | - ( void )blockGetPath:(NSString *)path parameters:(NSDictionary *)parameters success:( void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:( void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { if (!path) { path = @ "" ; } NSArray *arcCookies = [NSKeyedUnarchiver unarchiveObjectWithData: [[NSUserDefaults standardUserDefaults] objectForKey: @ "sessionCookies" ]]; NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; for (NSHTTPCookie *cookie in arcCookies){ [cookieStorage setCookie: cookie]; } NSURL *dataUrl = [NSURL URLWithString:path relativeToURL:self.baseURL]; NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:dataUrl]; //id: NSHTTPCookie NSDictionary *sheaders = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies]; NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)); __strong NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:dataUrl cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.f]; [request setHTTPMethod:@ "GET" ]; [request addValue:@ "iOS" forHTTPHeaderField:@ "User-Agent" ]; [request setValue:[NSString stringWithFormat:@ "application/x-www-form-urlencoded; charset=%@" , charset] forHTTPHeaderField:@ "Content-Type" ]; // [request setHTTPBody:[AFQueryStringFromParametersWithEncoding(parameters, NSUTF8StringEncoding) dataUsingEncoding:NSUTF8StringEncoding]]; [request setAllHTTPHeaderFields:sheaders]; if (parameters) { dataUrl = [NSURL URLWithString:[[dataUrl absoluteString] stringByAppendingFormat:[path rangeOfString:@ "?" ].location == NSNotFound ? @ "?%@" : @ "&%@" , AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding)]]; [request setURL:dataUrl]; } AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self enqueueHTTPRequestOperation:operation]; } |
post實現是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | - ( void )blockPostPath:(NSString *)path parameters:(NSDictionary *)parameters success:( void (^)(AFHTTPRequestOperation *operation, id responseObject))success failure:( void (^)(AFHTTPRequestOperation *operation, NSError *error))failure { if (!path) { path = @ "" ; } NSArray *arcCookies = [NSKeyedUnarchiver unarchiveObjectWithData: [[NSUserDefaults standardUserDefaults] objectForKey: @ "sessionCookies" ]]; NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; for (NSHTTPCookie *cookie in arcCookies){ [cookieStorage setCookie: cookie]; } NSURL *dataUrl = [NSURL URLWithString:path relativeToURL:self.baseURL]; NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:dataUrl]; //id: NSHTTPCookie NSDictionary *sheaders = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies]; NSString *charset = (NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)); __strong NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:dataUrl cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.f]; [request setHTTPMethod:@ "Post" ]; [request addValue:@ "iOS" forHTTPHeaderField:@ "User-Agent" ]; [request setValue:[NSString stringWithFormat:@ "application/x-www-form-urlencoded; charset=%@" , charset] forHTTPHeaderField:@ "Content-Type" ]; // [request setHTTPBody:[AFQueryStringFromParametersWithEncoding(parameters, NSUTF8StringEncoding) dataUsingEncoding:NSUTF8StringEncoding]]; [request setAllHTTPHeaderFields:sheaders]; if (parameters) { NSString *charset = (__bridge NSString *)CFStringConvertEncodingToIANACharSetName(CFStringConvertNSStringEncodingToEncoding(self.stringEncoding)); NSError *error = nil; switch (self.parameterEncoding) { case AFFormURLParameterEncoding:; [request setValue:[NSString stringWithFormat:@ "application/x-www-form-urlencoded; charset=%@" , charset] forHTTPHeaderField:@ "Content-Type" ]; [request setHTTPBody:[AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding) dataUsingEncoding:self.stringEncoding]]; break ; case AFJSONParameterEncoding:; [request setValue:[NSString stringWithFormat:@ "application/json; charset=%@" , charset] forHTTPHeaderField:@ "Content-Type" ]; [request setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:0 error:&error]]; break ; case AFPropertyListParameterEncoding:; [request setValue:[NSString stringWithFormat:@ "application/x-plist; charset=%@" , charset] forHTTPHeaderField:@ "Content-Type" ]; [request setHTTPBody:[NSPropertyListSerialization dataWithPropertyList:parameters format:NSPropertyListXMLFormat_v1_0 options:0 error:&error]]; break ; } if (error) { NSLog(@ "%@ %@: %@" , [self class ], NSStringFromSelector(_cmd), error); } } AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; [self enqueueHTTPRequestOperation:operation]; } |
對應的使用方法分別是:
2、每次請求返回時,儲存cookie,以供以後使用
get的使用方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | /** *執行get請求,支援cookie *TODO: 需要完善 **/ -( void )asynchronousCookiesGET:(NSString *)path witParams:(NSMutableDictionary *)params { AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:BASE_URL_SESSION]]; self.client = httpClient; [httpClient release]; [self.client blockGetPath:path parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { D_END; LogNET(@ "------------------------GET--->------------------------------" ); LogNET(@ "netWorking url:: %@" ,operation.request.URL.absoluteString); LogNET(@ "netWorking params:: %@" ,params); LogNET(@ "net working statuCode:: %d" ,operation.response.statusCode); LogNET(@ "net working responseString:: %@" ,operation.responseString); LogNET(@ "------------------------GET---<-----------------------------" ); NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]; for (NSHTTPCookie *cookie in cookies) { // Here I see the correct rails session cookie NSLog(@ "Block cookie: %@" , cookie); } NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject: cookiesData forKey: @ "sessionCookies" ]; [defaults synchronize]; //handle server return data; }failure:^(AFHTTPRequestOperation *operation, NSError* error) { LogNET(@ "------------------------GET--->------------------------------" ); LogNET(@ "netWorking url:: %@" ,operation.request.URL.absoluteString); LogNET(@ "net working statuCode:: %d" ,operation.response.statusCode); LogNET(@ "net working responseString:: %@" ,operation.responseString); LogNET(@ "------------------------GET---<-----------------------------" ); WebExceptionEntity* exception = [[WebExceptionEntity alloc] initWithExceptionString:operation.responseString withStatusCode:operation.response.statusCode withError:error]; self.webException= exception; [exception release]; if (self.exceptionBlock) { self.exceptionBlock(self,self.webException); } } ]; } |
Post的使用方式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /** *執行post請求:支援cookie的版本 **/ -( void )asynchronousCookiesPost:(NSString *)path witParams:(NSMutableDictionary *)params { AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:BASE_URL_SESSION]]; self.client = httpClient; [httpClient release]; if (self.preBlcok) { self.preBlcok(self); } [self.client blockPostPath:path parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { D_END; LogNET(@ "------------------------POST--->------------------------------" ); LogNET(@ "netWorking url:: %@" ,operation.request.URL.absoluteString); LogNET(@ "netWorking params:: %@" ,params); LogNET(@ "net working statuCode:: %d" ,operation.response.statusCode); LogNET(@ "net working responseString:: %@" ,operation.responseString); LogNET(@ "------------------------POST---<-----------------------------" ); NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]; for (NSHTTPCookie *cookie in cookies) { // Here I see the correct rails session cookie NSLog(@ "cookie: %@" , cookie); } NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject: cookiesData forKey: @ "sessionCookies" ]; [defaults synchronize]; //handle server return data }failure:^(AFHTTPRequestOperation *operation, NSError* error) { LogNET(@ "------------------------POST--->------------------------------" ); LogNET(@ "netWorking url:: %@" ,operation.request.URL.absoluteString); LogNET(@ "net working statuCode:: %d" ,operation.response.statusCode); LogNET(@ "net working responseString:: %@" ,operation.responseString); LogNET(@ "------------------------POST---<-----------------------------" ); WebExceptionEntity* exception = [[WebExceptionEntity alloc] initWithExceptionString:operation.responseString withStatusCode:operation.response.statusCode withError:error]; self.webException= exception; [exception release]; if (self.exceptionBlock) { self.exceptionBlock(self,self.webException); } }]; } |
測試執行:
1 2 3 4 5 6 | 2014-02-14 10:00:53.465 TripPlus[15245:60b] cookie: <NSHTTPCookie version:0 name: "ssid" value: "79244stsh4p3shv1ftd1125d90" expiresDate:(null) created:2014-02-14 02:00:53 +0000 (4.14036e+08) sessionOnly:TRUE domain: "192.168.1.199" path: "/" isSecure:FALSE> //-- 使用cookies TPTripPlusDetailViewController.m:141 .... 開始請求 AFHTTPClient.m:706 post add cookie:<NSHTTPCookie version:0 name: "acb5f57bfaec0550abdb337d5e8f0f40" value: "1febc174d86a8f5473af180658a7d9369b1e35daa%3A4%3A%7Bi%3A0%3Bs%3A1%3A%221%22%3Bi%3A1%3Bs%3A17%3A%22test%40joviainc.com%22%3Bi%3A2%3Bi%3A2592000%3Bi%3A3%3Ba%3A0%3A%7B%7D%7D" expiresDate:2014-03-16 02:00:50 +0000 created:2001-01-01 00:00:01 +0000 (1) sessionOnly:FALSE domain: "192.168.1.199" path: "/" isSecure:FALSE> AFHTTPClient.m:706 post add cookie:<NSHTTPCookie version:0 name: "ssid" value: "79244stsh4p3shv1ftd1125d90" expiresDate:(null) created:2001-01-01 00:00:01 +0000 (1) sessionOnly:TRUE domain: "192.168.1.199" path: "/" isSecure:FALSE> |
從結果可看出,完美執行。
相關文章
- ios不支援fixed解決解決方案iOS
- AFNetworking 3.0 Code=-1016 錯誤解決方案
- 移動端canvas不支援rem的解決方案CanvasREM
- 解決CORS跨域不能傳遞cookies的問題CORS跨域Cookie
- Android 5.0及以上WebView不能使用第三方Cookies解決方案AndroidWebViewCookie
- 解決cookies儲存中文報錯問題Cookie
- 瀏覽器支援ES6的最優解決方案瀏覽器
- 關於AS5SSH支援key認證的完全解決方案
- java:錯誤:不支援發行版本1.4解決方案Java
- 微信配置Universal Link解決方案支援多個appAPP
- 分享兩種實現Winform程式的多語言支援的解決方案ORM
- HTML5支援所有瀏覽器的SHIV解決方案HTML瀏覽器
- Linux Mint 沒有 language support 語言支援解決方案Linux
- 使用weiXinRecorded不支援targetSdkVersion升級23及以上問題的解決方案
- 解決方案| anyRTC金融音視訊解決方案
- 雲剪輯解決方案,支援雲端剪輯私有化部署
- G450 雙頭Linux驅動支援解決方案(轉)Linux
- 詳解AFNetworking的HTTPS模組HTTP
- LAMP解決方案LAMP
- pycharm不支援django的解決方法PyCharmDjango
- koala 編譯scss不支援中文(包括中文註釋),解決方案如下編譯CSS
- 安卓9.0不支援明文請求解決方案安卓
- 關於Create React App不支援裝飾器的終極無傷解決方案ReactAPP
- 高併發解決方案詳解(9大常見解決方案)
- Jou 的解決方案系列:序言
- 分散式鎖的解決方案分散式
- 佈局的常用解決方案
- mpvue使用sass的解決方案Vue
- mpvue 使用sass的解決方案Vue
- 前端跨域的解決方案前端跨域
- 探索ABP的EventHub解決方案
- 人工智慧的解決方案人工智慧
- 浮動坍塌的解決方案
- 介面測試的解決方案
- ajax跨域的解決方案跨域
- CA的安全解決方案(轉)
- 不同解決方案的比較
- 親測有用的解決方案