AFN\HTTPS\UIWebView
生活随笔
收集整理的這篇文章主要介紹了
AFN\HTTPS\UIWebView
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1.AFN使用技巧
1.在開發(fā)的時候可以創(chuàng)建一個工具類,繼承自我們的AFN中的請求管理者,再控制器中真正發(fā)請求的代碼使用自己封裝的工具類。 2.這樣做的優(yōu)點(diǎn)是以后如果修改了底層依賴的框架,那么我們修改這個工具類就可以了,而不用再一個一個的去修改。 3.該工具類一般提供一個單例方法,在該方法中會設(shè)置一個基本的請求路徑。 4.該方法通常還會提供對GET或POST請求的封裝。 5.在外面的時候通過該工具類來發(fā)送請求 6.單例方法: + (instancetype)shareNetworkTools { static TCJNetworkTools *instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // 注意: BaseURL中一定要以/結(jié)尾 instance = [[self alloc] initWithBaseURL:[NSURL URLWithString:@"http://120.25.226.186:32812/"]]; }); return instance; }2.AFN文件上傳
1.文件上傳拼接數(shù)據(jù)的第一種方式 [formData appendPartWithFileData:data name:@"file" fileName:@"xxoo.png" mimeType:@"application/octet-stream"]; 2.文件上傳拼接數(shù)據(jù)的第二種方式 [formData appendPartWithFileURL:fileUrl name:@"file" fileName:@"xx.png" mimeType:@"application/octet-stream" error:nil]; 3.文件上傳拼接數(shù)據(jù)的第三種方式 [formData appendPartWithFileURL:fileUrl name:@"file" error:nil]; 4.【注】在資料中已經(jīng)提供了一個用于文件上傳的分類。 /*文件上傳相關(guān)的代碼如下*/ -(void)upload { //1.創(chuàng)建一個請求管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //2.發(fā)送POST請求上傳數(shù)據(jù) /* 第一個參數(shù):請求路徑:NSString類型 第二個參數(shù):要上傳的非文件參數(shù) 第三個參數(shù):block回調(diào) 在該回調(diào)中,需要利用formData拼接即將上傳的二進(jìn)制數(shù)據(jù) 第三個參數(shù):上傳成功的block回調(diào) task:dataTask(任務(wù)) responseObject:服務(wù)器返回的數(shù)據(jù) 第四個參數(shù):上傳失敗的block回調(diào) error:錯誤信息,如果上傳文件失敗,那么error里面包含了錯誤的描述信息 */ NSDictionary *dict = @{ @"username":@"123" }; [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { //把本地的圖片轉(zhuǎn)換為NSData類型的數(shù)據(jù) UIImage *image = [UIImage imageNamed:@"123"]; NSData *data = UIImagePNGRepresentation(image); /* //拼接二進(jìn)制文件數(shù)據(jù) 第一個參數(shù):要上傳的文件的二進(jìn)制數(shù)據(jù) 第二個參數(shù):服務(wù)器接口規(guī)定的名稱 第三個參數(shù):這個參數(shù)上傳到服務(wù)器之后用什么名字來進(jìn)行保存 第四個參數(shù):上傳文件的MIMEType類型 */ [formData appendPartWithFileData:data name:@"file" fileName:@"xxoo.png" mimeType:@"application/octet-stream"]; } success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { NSLog(@"請求成功---%@",responseObject); } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) { NSLog(@"請求失敗--%@",error); }]; } -(void)upload2 { NSLog(@"%s",__func__); //1.創(chuàng)建一個請求管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //2.發(fā)送POST請求上傳數(shù)據(jù) /* 第一個參數(shù):請求路徑:NSString類型 第二個參數(shù):要上傳的非文件參數(shù) 第三個參數(shù):block回調(diào) 在該回調(diào)中,需要利用formData拼接即將上傳的二進(jìn)制數(shù)據(jù) 第三個參數(shù):上傳成功的block回調(diào) task:dataTask(任務(wù)) responseObject:服務(wù)器返回的數(shù)據(jù) 第四個參數(shù):上傳失敗的block回調(diào) error:錯誤信息,如果上傳文件失敗,那么error里面包含了錯誤的描述信息 */ NSDictionary *dict = @{ @"username":@"123" }; [manager POST:@"http://120.25.226.186:32812/upload" parameters:dict constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { //本地文件的url NSURL *fileUrl = [NSURL fileURLWithPath:@"/Users/changjiang/Desktop/KF[WTI`AQ3T`A@3R(B96D89.gif"]; /* //拼接二進(jìn)制文件數(shù)據(jù) 第一個參數(shù):要上傳文件的url路徑 第二個參數(shù):服務(wù)器要求的參數(shù)名稱 第三個參數(shù):這個文件上傳到服務(wù)器之后叫什么名稱 第四個參數(shù):文件的mimetype類型 第五個參數(shù):錯誤信息 */ // [formData appendPartWithFileURL:fileUrl name:@"file" fileName:@"xx.png" mimeType:@"application/octet-stream" error:nil]; //另外一種上傳文件的方式 /* 說明:該方法和上面的方法等價,不過該方法更加簡單其內(nèi)部會自動的的根據(jù)url路徑確定文件保存名稱,并通過內(nèi)部方法獲取上傳文件的mimetype類型 */ [formData appendPartWithFileURL:fileUrl name:@"file" error:nil]; } success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { NSLog(@"請求成功---%@",responseObject); } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) { NSLog(@"請求失敗--%@",error); }]; }3.使用AFN進(jìn)行序列化處理
/* 1.AFN它內(nèi)部默認(rèn)把服務(wù)器響應(yīng)的數(shù)據(jù)當(dāng)做json來進(jìn)行解析,所以如果服務(wù)器返回給我的不是JSON數(shù)據(jù)那么請求報錯,這個時候需要設(shè)置AFN對響應(yīng)信息的解析方式。AFN提供了三種解析響應(yīng)信息的方式,分別是: 1)AFXMLParserResponseSerializer----XML 2) AFHTTPResponseSerializer---------默認(rèn)二進(jìn)制響應(yīng)數(shù)據(jù) 3)AFJSONResponseSerializer---------JSON2.還有一種情況就是服務(wù)器返回給我們的數(shù)據(jù)格式不太一致(開發(fā)者工具Content-Type:text/xml),那么這種情況也有可能請求不成功。解決方法: 1) 直接在源代碼中修改,添加相應(yīng)的Content-Type 2) 拿到這個屬性,添加到它的集合中3.相關(guān)代碼 -(void)srializer {//1.創(chuàng)建請求管理者,內(nèi)部基于NSURLSessionAFHTTPSessionManager *manager = [AFHTTPSessionManager manager];/* 知識點(diǎn)1:設(shè)置AFN采用什么樣的方式來解析服務(wù)器返回的數(shù)據(jù)*///如果返回的是XML,那么告訴AFN,響應(yīng)的時候使用XML的方式解析manager.responseSerializer = [AFXMLParserResponseSerializer serializer];//如果返回的就是二進(jìn)制數(shù)據(jù),那么采用默認(rèn)二進(jìn)制的方式來解析數(shù)據(jù)//manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //采用JSON的方式來解析數(shù)據(jù) //manager.responseSerializer = [AFJSONResponseSerializer serializer]; /*知識點(diǎn)2: 告訴AFN服務(wù)器返回的數(shù)據(jù)內(nèi)容是什么類型的 Content-Type*/ manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/xml"]; //2.把所有的請求參數(shù)通過字典的方式來裝載,GET方法內(nèi)部會自動把所有的鍵值對取出以&符號拼接并最后用?符號連接在請求路徑后面 NSDictionary *dict = @{ @"username":@"223", @"pwd":@"ewr", @"type":@"XML" }; //3.發(fā)送GET請求 [manager GET:@"http://120.25.226.186:32812/login" parameters:dict success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { //4.請求成功的回調(diào)block NSLog(@"%@",[responseObject class]); } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) { //5.請求失敗的回調(diào),可以打印error的值查看錯誤信息 NSLog(@"%@",error); }]; }4.使用AFN來檢測網(wǎng)絡(luò)狀態(tài)
/* 說明:可以使用AFN框架中的AFNetworkReachabilityManager來監(jiān)聽網(wǎng)絡(luò)狀態(tài)的改變,也可以利用蘋果提供的Reachability來監(jiān)聽。建議在開發(fā)中直接使用AFN框架處理。*/ //使用AFN框架來檢測網(wǎng)絡(luò)狀態(tài)的改變 -(void)AFNReachability {//1.創(chuàng)建網(wǎng)絡(luò)監(jiān)聽管理者 AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager]; //2.監(jiān)聽網(wǎng)絡(luò)狀態(tài)的改變 /* AFNetworkReachabilityStatusUnknown = 未知 AFNetworkReachabilityStatusNotReachable = 沒有網(wǎng)絡(luò) AFNetworkReachabilityStatusReachableViaWWAN = 3G AFNetworkReachabilityStatusReachableViaWiFi = WIFI */ [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { switch (status) { case AFNetworkReachabilityStatusUnknown: NSLog(@"未知"); break; case AFNetworkReachabilityStatusNotReachable: NSLog(@"沒有網(wǎng)絡(luò)"); break; case AFNetworkReachabilityStatusReachableViaWWAN: NSLog(@"3G"); break; case AFNetworkReachabilityStatusReachableViaWiFi: NSLog(@"WIFI"); break; default: break; } }]; //3.開始監(jiān)聽 [manager startMonitoring]; } ------------------------------------------------------------ //使用蘋果提供的Reachability來檢測網(wǎng)絡(luò)狀態(tài),如果要持續(xù)監(jiān)聽網(wǎng)絡(luò)狀態(tài)的概念,需要結(jié)合通知一起使用。 //提供下載地址:https://developer.apple.com/library/ios/samplecode/Reachability/Reachability.zip -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //1.注冊一個通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkChange) name:kReachabilityChangedNotification object:nil]; //2.拿到一個對象,然后調(diào)用開始監(jiān)聽方法 Reachability *r = [Reachability reachabilityForInternetConnection]; [r startNotifier]; //持有該對象,不要讓該對象釋放掉 self.r = r; } //當(dāng)控制器釋放的時候,移除通知的監(jiān)聽 -(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } -(void)networkChange { //獲取當(dāng)前網(wǎng)絡(luò)的狀態(tài) if([Reachability reachabilityForLocalWiFi].currentReachabilityStatus != NotReachable) { NSLog(@"當(dāng)前網(wǎng)絡(luò)為WIFI"); }else if ([Reachability reachabilityForInternetConnection].currentReachabilityStatus != NotReachable) { NSLog(@"當(dāng)前網(wǎng)絡(luò)為手機(jī)自帶網(wǎng)絡(luò)"); }else { NSLog(@"當(dāng)前沒有網(wǎng)絡(luò)"); } }5.數(shù)據(jù)安全
01 攻城利器:Charles(公司中一般都使用該工具來抓包,并做網(wǎng)絡(luò)測試) 注意:Charles在使用中的亂碼問題,可以顯示包內(nèi)容,然后打開info.plist文件,找到j(luò)ava目錄下面的VMOptions,在后面添加一項:-Dfile.encoding=UTF-8 02 MD5消息摘要算法是不可逆的。 03 數(shù)據(jù)加密的方式和規(guī)范一般公司會有具體的規(guī)定,不必多花時間。6.HTTPS的基本使用
1.https簡單說明HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全為目標(biāo)的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎(chǔ)是SSL,因此加密的詳細(xì)內(nèi)容就需要SSL。 它是一個URI scheme(抽象標(biāo)識符體系),句法類同http:體系。用于安全的HTTP數(shù)據(jù)傳輸。https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默認(rèn)端口及一個加密/身份驗證層(在HTTP與TCP之間)。2.HTTPS和HTTP的區(qū)別主要為以下四點(diǎn):一、https協(xié)議需要到ca申請證書,一般免費(fèi)證書很少,需要交費(fèi)。二、http是超文本傳輸協(xié)議,信息是明文傳輸,https 則是具有安全性的ssl加密傳輸協(xié)議。三、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。 四、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。 3.對開發(fā)的影響。 3.1 如果是自己使用NSURLSession來封裝網(wǎng)絡(luò)請求,涉及代碼如下。 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]]; NSURLSessionDataTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.apple.com"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); }]; [task resume]; } /* 只要請求的地址是HTTPS的, 就會調(diào)用這個代理方法 我們需要在該方法中告訴系統(tǒng), 是否信任服務(wù)器返回的證書 Challenge: 挑戰(zhàn) 質(zhì)問 (包含了受保護(hù)的區(qū)域) protectionSpace : 受保護(hù)區(qū)域 NSURLAuthenticationMethodServerTrust : 證書的類型是 服務(wù)器信任 了解:證書有好幾種,一種是被認(rèn)證過的一種是沒有被認(rèn)證過的,如果證書是被認(rèn)證過的,那么只需要信任一次就可以了,如果是沒有被認(rèn)證過的,那么每次都需要重新認(rèn)證 */ - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler { // NSLog(@"didReceiveChallenge %@", challenge.protectionSpace); NSLog(@"調(diào)用了最外層"); // 1.判斷服務(wù)器返回的證書類型, 是否是服務(wù)器信任 if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { NSLog(@"調(diào)用了里面這一層是服務(wù)器信任的證書"); /* NSURLSessionAuthChallengeUseCredential = 0, 使用證書 NSURLSessionAuthChallengePerformDefaultHandling = 1, 忽略證書(默認(rèn)的處理方式) NSURLSessionAuthChallengeCancelAuthenticationChallenge = 2, 忽略書證, 并取消這次請求 NSURLSessionAuthChallengeRejectProtectionSpace = 3, 忽略當(dāng)前這一次, 下一次再詢問 */ // NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential , card); } } 3.2 如果是使用AFN框架,那么我們不需要做任何額外的操作,AFN內(nèi)部已經(jīng)做了處理。7 WebView的基本使用
1 概念性知識01 webView是有缺點(diǎn)的,會導(dǎo)致內(nèi)存泄露,而且這個問題是它系統(tǒng)本身的問題。02 手機(jī)上面的safai其實就是用webView來實現(xiàn)的03 現(xiàn)在的開發(fā)并不完全是原生的開發(fā),而更加傾向于原生+Html5的方式 04 webView是OC代碼和html代碼之間進(jìn)行交互的橋梁 2 代碼相關(guān) /*A*網(wǎng)頁操控相關(guān)方法**/ [self.webView goBack]; 回退 [self.webView goForward]; 前進(jìn) [self.webView reload]; 刷新 //設(shè)置是否能夠前進(jìn)和回退 self.goBackBtn.enabled = webView.canGoBack; self.fowardBtn.enabled = webView.canGoForward; /*B*常用的屬性設(shè)置**/ self.webView.scalesPageToFit = YES; 設(shè)置網(wǎng)頁自動適應(yīng) self.webView.dataDetectorTypes = UIDataDetectorTypeAll; 設(shè)置檢測網(wǎng)頁中的格式類型,all表示檢測所有類型包括超鏈接、電話號碼、地址等。 self.webView.scrollView.contentInset = UIEdgeInsetsMake(50, 0, 0, 0); /*C*相關(guān)代理方法**/ //每當(dāng)將加載請求的時候調(diào)用該方法,返回YES 表示加載該請求,返回NO 表示不加載該請求 //可以在該方法中攔截請求 -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { return ![request.URL.absoluteString containsString:@"dushu"]; } //開始加載網(wǎng)頁,不僅監(jiān)聽我們指定的請求,還會監(jiān)聽內(nèi)部發(fā)送的請求 -(void)webViewDidStartLoad:(UIWebView *)webView //網(wǎng)頁加載完畢之后會調(diào)用該方法 -(void)webViewDidFinishLoad:(UIWebView *)webView //網(wǎng)頁加載失敗調(diào)用該方法 -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error /*D*其它知識點(diǎn)-加載本地資源**/ NSURL *url = [[NSBundle mainBundle] URLForResource:@"text.html" withExtension:nil]; [self.webView loadRequest:[NSURLRequest requestWithURL:url]];8 HTML
1.Html決定網(wǎng)頁的內(nèi)容,css決定網(wǎng)頁的樣式,js決定網(wǎng)頁的事件 2.html學(xué)習(xí)網(wǎng)站:http://www.w3school.com.cn9 OC和JS代碼的互調(diào)
01 OC調(diào)用JS的代碼NSString *str = [self.webView stringByEvaluatingJavaScriptFromString:@"sum()"]; 02 JS怎么調(diào)用OC的說明 新的需求:點(diǎn)擊按鈕的時候撥打電話 但是我在點(diǎn)擊按鈕的時候,用戶是不知道的,我們怎么能夠知道用戶點(diǎn)擊了網(wǎng)頁上面的一個按鈕,只能通過一個技巧,那就是自己搞一個特定的協(xié)議頭比如說cj://,當(dāng)我攔截到你的網(wǎng)絡(luò)請求的時候,只需要判斷一下當(dāng)前的協(xié)議頭是不是這個就能判斷你現(xiàn)在是否是JS調(diào)用。 OC里面有通過字符串生成SEL類型的方法,所以當(dāng)拿到數(shù)據(jù)之后做下面的事情 1)截取方法的名稱 2)將截取出來的字符串轉(zhuǎn)換為SEL 3)利用performSelect方法來調(diào)用SEL 03 涉及到的相關(guān)方法 [@"abc" hasPrefix:@"A"] //判斷字符串是否以一個固定的字符開頭,這里為A //截串操作 - (NSString *)substringFromIndex:(NSUInteger)from; //切割字符串,返回一個數(shù)組 - (NSArray<NSString *> *)componentsSeparatedByString:(NSString *)separator; //替換操作 - (NSString *)stringByReplacingOccurrencesOfString:(NSString *)target withString:(NSString *)replacement //把string包裝成SEL SEL selector = NSSelectorFromString(sel); 04 如何屏蔽警告9 NSInvocation的基本使用
//封裝invacation可以調(diào)用多個參數(shù)的方法 -(void)invacation {//1.創(chuàng)建一個MethodSignature,簽名中保存了方法的名稱,參數(shù)和返回值//這個方法屬于誰,那么就用誰來進(jìn)行創(chuàng)建 //注意:簽名一般是用來設(shè)置參數(shù)和獲得返回值的,和方法的調(diào)用沒有太大的關(guān)系 NSMethodSignature *signature = [ViewController instanceMethodSignatureForSelector:@selector(callWithNumber:andContext:withStatus:)]; /*注意不要寫錯了方法名稱 // NSMethodSignature *signature = [ViewController methodSignatureForSelector:@selector(call)]; */ //2.通過MethodSignature來創(chuàng)建一個NSInvocation //NSInvocation中保存了方法所屬于的對象|方法名稱|參數(shù)|返回值等等 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; /*2.1 設(shè)置invocation,來調(diào)用方法*/ invocation.target = self; // invocation.selector = @selector(call); // invocation.selector = @selector(callWithNumber:); // invocation.selector = @selector(callWithNumber:andContext:); invocation.selector = @selector(callWithNumber:andContext:withStatus:); NSString *number = @"10086"; NSString *context = @"下課了"; NSString *status = @"睡覺的時候"; //注意: //1.自定義的參數(shù)索引從2開始,0和1已經(jīng)被self and _cmd占用了 //2.方法簽名中保存的方法名稱必須和調(diào)用的名稱一致 [invocation setArgument:&number atIndex:2]; [invocation setArgument:&context atIndex:3]; [invocation setArgument:&status atIndex:4]; /*3.調(diào)用invok方法來執(zhí)行*/ [invocation invoke]; }10 異常處理
01 一般處理方式:a.app異常閃退,那么捕獲crash信息,并記錄在本地沙盒中。b.當(dāng)下次用戶重新打開app的時候,檢查沙盒中是否保存有上次捕獲到的crash信息。c.如果有那么利用專門的接口發(fā)送給服務(wù)器,以求在后期版本中修復(fù)。02 如何拋出異常//拋出異常的兩種方式// @throw [NSException exceptionWithName:@"好大一個bug" reason:@"異常原因:我也不知道" userInfo:nil]; //方式二 NSString *info = [NSString stringWithFormat:@"%@方法找不到",NSStringFromSelector(aSelector)]; //下面這種方法是自動拋出的 [NSException raise:@"這是一個異常" format:info,nil]; 03 如何捕獲異常 NSSetUncaughtExceptionHandler (&UncaughtExceptionHandler); void UncaughtExceptionHandler(NSException *exception) { NSArray *arr = [exception callStackSymbols];//得到當(dāng)前調(diào)用棧信息 NSString *reason = [exception reason];//非常重要,就是崩潰的原因 NSString *name = [exception name];//異常類型 NSString *errorMsg = [NSString stringWithFormat:@"當(dāng)前調(diào)用棧的信息:%@\nCrash的原因:%@\n異常類型:%@\n",arr,reason,name]; //把該信息保存到本地沙盒,下次回傳給服務(wù)器。 }轉(zhuǎn)載于:https://www.cnblogs.com/chenweb/p/9003377.html
總結(jié)
以上是生活随笔為你收集整理的AFN\HTTPS\UIWebView的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ansible: hosts文件拆分为i
- 下一篇: 【从入门到放弃】23种设计模式(1):设