iOS圖片瘦身總結

前言html

最近在公司寫了個小程序來爲iOS應用中的圖片瘦身,進而減少APP大小,減小用戶下載時的流量。json

瘦身是在一個專門爲圖片瘦身的網站進行的。小程序

地址:https://tinypng.com安全

這個網站提供的接口是基於https協議的,以前沒有怎麼用過https協議,如今一併總結一下。服務器

 

關於HTTPS多線程

https協議基礎請參考參考:app

HTTPS的七個誤解異步

其實HTTPS就是安全版本的http協議,async

他採用了RSA非對稱加密公私鑰對,使用SSL證書驗證保證了用戶數據在傳輸時的安全行。網站

下面簡單看一下http和https請求過程的異同

咱們按個看下流程

1.客戶端向服務端發送基於https的請求。

2.服務端建立公私鑰對。

3.服務端把共鑰綁定在證書上面返回給客戶端。

4.客戶端驗證證書是否可靠(驗證方式有兩種,分別針對CA機構辦法的證書和本身建立的證書:1.是向頒發證書的CA機構發送請求來驗證。2.是在客戶端保存一個證書副本,來對比兩個證書,同時還會驗證是否被中間人進行了攻擊,驗證方式就是用證書的pubkey去解證書的上密文,若是和證書上的明文一直就能夠肯定沒有被攻擊)。

5.客戶端生成一個隨機數並用公鑰加密傳遞給服務器。

6.服務器用私鑰解密獲得隨機數,根據隨機數產生對稱加密祕鑰並用私鑰對祕鑰進行加密。

7.傳遞對稱祕鑰給客戶端。

8.客戶端用公鑰解密獲得對稱加密祕鑰。

之後的通訊就會使用對稱加密的祕鑰來進行了,因此https其實也就第一次請求會比較慢,由於要生成通訊對稱祕鑰,之後再進行通訊就和http不會差不少了。

 

iOS對於HTTPS的支持

在說這點以前,先說說tinypng這個網站的接口。

註冊新用戶後會返回給你一串key,咱們要針對這串key作https請求

該站採用的是HTTP Basic Auth認證方式(關於Basic Auth認證方式詳情參看維基百科)。

因此咱們作請求的時候就須要使用添加headerfield。

返回的時候會把咱們上傳圖片處理後的下載路徑傳回來,比較奇葩的是,路徑並不在響應體而是在響應頭中的Location字段內...(難道圖片就不須要保密了麼...)。

下面說說iOS該怎麼作,

iOS的NSURLConnection和NSURLSession的API都提供了很方便的API來支持https請求。

我在實際操做的時候使用的是NSURLConnection。

首先建立請求:

 1 NSURL *url = [NSURL URLWithString:REQUEST_URL];
 2 
 3 NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
 4 
 5 NSString *basicAuthUsername = BASIC_AUTH_USERNAME;
 6 NSString *basicAuthPassword = BASIC_AUTH_PASSWORD;
 7 NSData *authorizationData = [[NSString stringWithFormat:@"%@:%@",basicAuthUsername,basicAuthPassword] dataUsingEncoding:NSASCIIStringEncoding];
 8 NSString *authorizationStr = [NSString stringWithFormat:@"Basic %@",[authorizationData base64EncodedStringWithOptions:0]];
 9 NSLog(@"%@",authorizationStr);
10 [request setHTTPMethod:@"POST"];
11 [request addValue:authorizationStr forHTTPHeaderField:@"Authorization"];
12 [request addValue:@"*/*" forHTTPHeaderField:@"Accept"];

 

URL在API中提供的有,只是協議咱們寫爲HTTPS,而後進行Authorization頭字段的拼接,實際上就是Basic base64(用戶名:密碼)。

Accept這裏設置爲了*/*,其實若是知道服務器返回類型能夠直接指定application/json或者text/json之類的就行。

 

下面看看鏈接:

1 -(BOOL)connection:(NSURLConnection*)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace*)protectionSpace
2 {
3     return[protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
4 }
5 
6 -(void)connection:(NSURLConnection*)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)challenge
7 {
8     [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
9 }

 

咱們須要實現NSURLConnectionDelegate,而後實現上面的兩個方法。

第一個方法是判斷須要響應哪一類的安全問題,

  NSString *NSURLAuthenticationMethodDefault;

  NSString*NSURLAuthenticationMethodHTTPBasic;

  NSString*NSURLAuthenticationMethodHTTPDigest;

  NSString*NSURLAuthenticationMethodHTMLForm;

  NSString*NSURLAuthenticationMethodNegotiate;

  NSString*NSURLAuthenticationMethodNTLM;

  NSString*NSURLAuthenticationMethodClientCertificate;

  NSString*NSURLAuthenticationMethodServerTrust;

能夠響應的安全問題有不少,這裏咱們只響應HTTPS相關的就行,所以選擇NSURLAuthenticationMethodServerTrust。

第二個方法是處理驗證結果的,這裏我這樣寫會直接忽略證書驗證,這裏咱們能夠處理證書的驗證策略邏輯。

咱們start connection後就會發現能夠成功的調用接口了。

 

關於一些其餘細節

寫這個小玩意仍是用到了一些沒有接觸過的東西的。

下面總結一下。

1.文件實例類NSFileHandle,這個類能夠拿到文件實例,好比咱們想去控制文件讀寫細節就須要用到這個類,這裏使用是爲了保存沒有成功請求的圖片名稱。

2.connection的異步請求作的很是好了,使用多線程請求,具體的請求線程個數由系統來判斷。

3.多線程讀寫文件使用dispatch_barrier_async方法避免資源競爭。

 

不足

1.寫的時候是全部上傳請求所有結束後纔開始下載的,這樣效率很低,能夠修改成成功上傳後就直接下載不用等待其餘的文件上傳,不過這樣多線程處理會稍微麻煩一些。

相關文章
相關標籤/搜索