iOS 網(wǎng)絡(luò)請(qǐng)求以及用戶token存儲(chǔ)
關(guān)于網(wǎng)絡(luò)請(qǐng)求的重要性不用說(shuō)太多了吧。對(duì)于移動(dòng)客戶端來(lái)說(shuō),網(wǎng)絡(luò)的重要性不言而喻。常見(jiàn)的網(wǎng)絡(luò)請(qǐng)求有同步GET、同步POST、異步GET、異步POST接下來(lái)簡(jiǎn)單說(shuō)一下實(shí)現(xiàn)方式。
很多項(xiàng)目里面,需要在用戶登錄后保持登錄狀態(tài),使用的不是存儲(chǔ)用戶名和密碼,每次模擬去登錄。而是登錄成功時(shí),從服務(wù)器接受token,token是服務(wù)器生存的一個(gè)字符串,唯一標(biāo)識(shí)一個(gè)用戶,并且會(huì)在一段時(shí)間后銷毀,所以我門很久不登錄app,會(huì)要求重新登錄。利用一個(gè)工具類,進(jìn)行token的存儲(chǔ)、刪除和讀取。登錄成功進(jìn)行存儲(chǔ),下一次打開(kāi)app進(jìn)行讀取,退出時(shí)進(jìn)行刪除。如果有refreshtoken,可以進(jìn)行更新,就不用再次登錄。
網(wǎng)絡(luò)請(qǐng)求
常見(jiàn)的請(qǐng)求方式
- GET請(qǐng)求
- POST請(qǐng)求
- 不同點(diǎn)
- 給服務(wù)器傳輸數(shù)據(jù)的方式不同,GET是通過(guò)網(wǎng)址字符串,POST是通過(guò)data
- 傳輸數(shù)據(jù)的大小,GET:網(wǎng)址的字符串最多255個(gè)字節(jié),POST使用NSData容量超過(guò)1G
- 安全性:GET:所有傳輸給服務(wù)端的數(shù)據(jù),顯示在網(wǎng)址里,類似于密碼的明文輸入,直接可見(jiàn)。POST:數(shù)據(jù)被轉(zhuǎn)換成NSData(二進(jìn)制數(shù)據(jù)),類似于密碼的密文數(shù)據(jù),無(wú)法直接讀取。
連接方式(主要針對(duì)NSURLConnection)
- 同步連接:只有數(shù)據(jù)請(qǐng)求完成了之后才會(huì)執(zhí)行后面的代碼,容易出現(xiàn)頁(yè)面的卡死。
- 異步連接:在請(qǐng)求數(shù)據(jù)的同時(shí)不影響后面的代碼的執(zhí)行。
- 異步連接有兩種實(shí)現(xiàn)方式(1.設(shè)置代理,接收數(shù)據(jù) 2.實(shí)現(xiàn)block)
- 在iOS7之后使用NSURLSession來(lái)代替。
GET請(qǐng)求
1.創(chuàng)建一個(gè)URL對(duì)象
NSString *urlStr = @"http://www.baidu.com";
NSURL *url = [NSURL URLWithString:urlStr];
2.創(chuàng)建一個(gè)請(qǐng)求
NSURLRequest *request = [NSURLRequest requestWithURL:url]; WithURL:url];
3.發(fā)送請(qǐng)求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//參數(shù)的解釋
//response 響應(yīng)頭的信息
//data 我們所需要的信息
//connectionError 鏈接服務(wù)器的錯(cuò)誤信息
}];
POST請(qǐng)求
1.創(chuàng)建一個(gè)URL對(duì)象
NSString *urlStr = @"http://www.baidu.com";
NSURL *url = [NSURL URLWithString:urlStr];
2.設(shè)置請(qǐng)求方式(注:只有NSMutableURLRequest才可以設(shè)置網(wǎng)絡(luò)請(qǐng)求的方式,NSURLRequest默認(rèn)GET請(qǐng)求。當(dāng)我們不設(shè)置請(qǐng)求方式的時(shí)候,默認(rèn)GET)
NSMutableURLRequest * mutableRequest = [NSMutableURLRequest requestWithURL:url];
//設(shè)置請(qǐng)求方式
mutableRequest setHTTPMethod:@"POST";
3.設(shè)置參數(shù)
NSString *dataString = @"date=20151031&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";
[mutableRequest setHTTPBody:[dataString dataUsingEncoding:NSUTF8StringEncoding]];
4.創(chuàng)建Session對(duì)象用來(lái)進(jìn)行POST請(qǐng)求
NSURLSession * session = [NSURLSession sharedSession];
5.建立請(qǐng)求
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:mutableRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
}];
// 一定要記得啟動(dòng)任務(wù),否則請(qǐng)求是不會(huì)開(kāi)的
[dataTask resume];
NSURLSession(Delegate)協(xié)議代理方式
下面只列舉GET方式的協(xié)議代理的請(qǐng)求方式,POST的請(qǐng)求方式只需要另外設(shè)置一下NSMutableRequest請(qǐng)求的方式,再設(shè)置參數(shù)就可以了,具體的協(xié)議代理的方法和GET請(qǐng)求時(shí)使用的是一樣的在使用協(xié)議的方法請(qǐng)求數(shù)據(jù)的時(shí)候,我們需要先遵循<NSURLSessionTaskDelegate,NSURLSessionDataDelegate>這兩個(gè)協(xié)議
1.創(chuàng)建一個(gè)URL對(duì)象
NSString *urlStr = @"http://www.baidu.com";
NSURL *url = [NSURL URLWithString:urlStr];
2.因?yàn)镹SURLSession的delegates是只讀的,需要下面的方法來(lái)簽訂協(xié)議
NSURLSession * session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc]init]];
3.創(chuàng)建請(qǐng)求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
4.創(chuàng)建請(qǐng)求任務(wù),啟動(dòng)任務(wù)
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request];
[dataTask resume];
5.聲明一個(gè)NSData類型的屬性用于接收請(qǐng)求回來(lái)的數(shù)據(jù)
@interface RootViewController ()<NSURLSessionTaskDelegate,NSURLSessionDataDelegate>
@property (strong, nonatomic)NSMutableData *data;//用于接收協(xié)議代理請(qǐng)求回來(lái)的數(shù)據(jù)
@end
6.實(shí)現(xiàn)代理方法接收數(shù)據(jù)
/**
服務(wù)器開(kāi)始響應(yīng),準(zhǔn)備返回?cái)?shù)據(jù)
@param session session description
@param dataTask 任務(wù)
@param response 響應(yīng)
@param completionHandler block
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
completionHandler(NSURLSessionResponseAllow);
self.data = [NSMutableData data];
}
/**
客戶端開(kāi)始接收數(shù)據(jù)
@param session session description
@param dataTask 任務(wù)請(qǐng)求
@param data 數(shù)據(jù)
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
[self.data appendData:data];
}
/**
數(shù)據(jù)接收完成,網(wǎng)絡(luò)請(qǐng)求成功(失敗信息在error)
@param session session description
@param task task description
@param error error description
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:self.data options:NSJSONReadingAllowFragments error:NULL];
CYLOG(@"---%@",error);
}
利用token保持登錄狀態(tài)
有時(shí)候項(xiàng)目里面需要在客戶端保持登錄狀態(tài),使用的不是存儲(chǔ)的用戶名和密碼,每次去模擬登錄。登錄成功,從服務(wù)器收到token,token是服務(wù)器生存的一個(gè)字符串,唯一標(biāo)識(shí)一個(gè)用戶,并且會(huì)在一段時(shí)間后銷毀,所以app會(huì)要求重新登錄。
利用一個(gè)工具類進(jìn)行token的存儲(chǔ)、刪除和讀取。登錄成功進(jìn)行存儲(chǔ),下一次打開(kāi)app進(jìn)行讀取、退出進(jìn)行刪除。如果有refreshtoken,可以進(jìn)行刷新??的token,就不用再次登錄。
tokenManager相關(guān)代碼
#import "XDTokenManager.h"
#import "XDToken.h"
NSString *const TOKEN_KEY = @"token";
@implementation XDTokenManager
// 存儲(chǔ)token
+ (void)saveToken:(XDToken *)token {
NSUserDefaults *userDefaults=[NSUserDefaults standardUserDefaults];
NSData *tokenData = [NSKeyedArchiver archivedDataWithRootObject:token];
[userDefaults setObject:tokenData forKey:TOKEN_KEY];
[userDefaults synchronize];
}
// 讀取token
+ (XDToken *)getToken {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSData *tokenData = [userDefaults objectForKey:TOKEN_KEY];
XDToken *token = [NSKeyedUnarchiver unarchiveObjectWithData:tokenData];
[userDefaults synchronize];
return token;
}
// 清空token
+ (void)cleanToken {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults removeObjectForKey:TOKEN_KEY];
[userDefaults synchronize];
}