IOS開發網路資料---- AFNetworking的使用

來源:互聯網
上載者:User

標籤:

http網路程式庫是集XML解析,Json解析,網狀圖片下載,plist解析,資料流請求操作,上傳,下載,緩衝等網路眾多功能於一身的強大的類庫。最新版本支援session,xctool單元測試。網路擷取資料一直是手機軟體的重中之重,如果處理的不好,會造成很差的使用者體驗。隨著ASIHTTPRequest的停止更新,更換網路程式庫是必然的事情,AFNetworking就是很好的替代品。而且都是輕量級,不要擔心加入太多庫會多軟體效能有影響。1.為什麼用第三方網路程式庫?先說如果不用網路程式庫,我曾有一次覺得什麼都用蘋果原生的好,XML解析用蘋果內建的委託,下載圖片自己寫,如果你也有跟我一樣的經曆,那你會發現自己管理起來很複雜,很容易出錯。而且效能不好。如果你是一個追求完美的人,那就放下你的固執,就如當初的我一樣,嘗試一下網路程式庫吧。2.為什麼要用AFNetworking?第一點,它有人更新和維護,而且目前使用者很多,第二點,還是使用者很多,那麼他的資料,文檔,demo就多,很好找遇到問題好解決。如果不用AFNetworking,還有一種MKNetworkKit也不錯,不妨一試。 如何選擇AFNetworking版本

首先得下載AFNetworking庫檔案,下載時得首先弄清楚,你將要開發的軟體相容的最低版本是多少。AFNetworking 2.0或者之後的版本需要xcode5.0版本並且只能為IOS6或更高的手機系統上運行,如果開發MAC程式,那麼2.0版本只能在MAC OS X 10.8或者更高的版本上運行。

AFNetworking 2.0的https://github.com/AFNetworking/AFNetworking如果你想要相容IOS5或MAC OS X 10.7,那你需要用最新發行的1.x版本AFNetworking 1.x的https://github.com/AFNetworking/AFNetworking/tree/1.x如果要相容4.3或者MAC OS X 10.6,需要用最新發行的0.10.x版本AFNetworking 0.10.xhttps://github.com/AFNetworking/AFNetworking/tree/0.10.x 2013年大多數軟體相容的最低版本為4.3,而2014年,估計大多數軟體相容的最低版本將會是5.0甚至6.0;所以,目前最好的選擇還是1.x版本,相容到IOS5.0。 如何通過URL擷取json資料第一種,利用AFJSONRequestOperation,官方網站上給的例子:

    NSString *str=[NSString stringWithFormat:@"https://alpha-api.app.net/stream/0/posts/stream/global"];

    NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    //    從URL擷取json資料

    AFJSONRequestOperation *operation1 = [AFJSONRequestOperation JSONRequestOperationWithRequest:requestsuccess:^(NSURLRequest *request, NSHTTPURLResponse *response, NSDictionary* JSON) {

                NSLog(@"擷取到的資料為:%@",JSON);

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id data) {

        NSLog(@"發生錯誤!%@",error);

    }];

    [operation1 start];

 

第二種方法,利用AFHTTPRequestOperation 先擷取到字串形式的資料,然後轉換成json格式,將NSString格式的資料轉換成json資料,利用IOS5內建的json解析方法:

   NSString *str=[NSString stringWithFormat:@"https://alpha-api.app.net/stream/0/posts/stream/global"];

    NSURL *url = [NSURL URLWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

   AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSString *html = operation.responseString;

             NSData* data=[html dataUsingEncoding:NSUTF8StringEncoding];

             id dict=[NSJSONSerialization  JSONObjectWithData:data options:0 error:nil];

        NSLog(@"擷取到的資料為:%@",dict);

    }failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSLog(@"發生錯誤!%@",error);

    }];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    [queue addOperation:operation];

 

 

如果發生Error Domain=NSURLErrorDomain Code=-1000 "bad URL" UserInfo=0x14defc80 {NSUnderlyingError=0x14deea10 "bad URL", NSLocalizedDescription=bad URL這個錯誤,請檢查URL編碼格式。有沒有進行stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding

 

 

如何通過URL擷取圖片

非同步擷取圖片,通過隊列實現,而且圖片會有緩衝,在下次請求相同的連結時,系統會自動調用緩衝,而不從網上請求資料。


UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 100.0f, 100.0f, 100.0f)]; 
    [imageView setImageWithURL:[NSURL URLWithString:@"http://i./r4uwx.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder-avatar"]]; 
    [self.view addSubview:imageView];

上面的方法是官方提供的,還有一種方法,

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.scott-sherwood.com/wp-content/uploads/2013/01/scene.png"]];

    AFImageRequestOperation *operation = [AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response,UIImage *image) {

        self.backgroundImageView.image = image;

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {

        NSLog(@"Error %@",error);

    }];

 

    [operation start];

 

如果使用第一種URLWithString:  placeholderImage:會有更多的細節處理,其實實現還是通過AFImageRequestOperation處理,可以點擊URLWithString:  placeholderImage:方法進去看一下就一目瞭然了。所以我覺得還是用第一種好。

 

如何通過URL擷取plist檔案

通過url擷取plist檔案的內容,用的很少,這個方法在官方提供的方法裡面沒有

    NSString *weatherUrl = @"http://www.calinks.com.cn/buick/kls/Buickhousekeeper.plist";

    NSURL *url = [NSURL URLWithString:[weatherUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    [AFPropertyListRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/plain"]];

    AFPropertyListRequestOperation *operation = [AFPropertyListRequestOperation propertyListRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id propertyList) {

        NSLog(@"%@",(NSDictionary *)propertyList);

        

    }failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id propertyList) {

        NSLog(@"%@",error);

    }];

 

    [operation start];

如果稍不留神,可能就出現Error Domain=AFNetworkingErrorDomain Code=-1016 "Expected content type {(

    "application/x-plist"

)}, got text/plain" UserInfo=0x16e91ce0 {NSLocalizedRecoverySuggestion=

 

...

...

, AFNetworkingOperationFailingURLRequestErrorKey= { }, NSErrorFailingURLKey=, NSLocalizedDescription=Expected content type {(

    "application/x-plist"

)}, got text/plain, AFNetworkingOperationFailinponseErrorKey= { URL:  } { status code: 200, headers {

    "Accept-Ranges" = bytes;

    Connection = "keep-alive";

    "Content-Length" = 974;

    "Content-Type" = "text/plain";

    Date = "Sat, 25 Jan 2014 07:29:26 GMT";

    Etag = ""1014c2-3ce-4ee63e1c80e00"";

    "Last-Modified" = "Wed, 25 Dec 2013 23:04:24 GMT";

    Server = "nginx/1.4.2";

 

} }}

可能還會出現亂碼,解決辦法就是[AFPropertyListRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/plain"]];

 

 

如何通過URL擷取XML資料

xml解析使用AFXMLRequestOperation,需要實現蘋果內建的NSXMLParserDelegate委託方法,XML中有一些不需要的協議格式內容,所以就不能像json那樣解析,還得實現委託。我之前有想過能否所有的XML連結用一個類處理,而且跟服務端做了溝通,結果很不方便,效果不好。XML大多標籤不同,格式也不固定,所以就有問題,使用json就要方便的多。

第一步;在.h檔案中加入委託NSXMLParserDelegate

第二步;在.m檔案方法中加入代碼

    NSURL *url = [NSURL URLWithString:@"http://113.106.90.22:5244/sshopinfo"];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    AFXMLRequestOperation *operation =

    [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request,NSHTTPURLResponse *response, NSXMLParser *XMLParser) {

        XMLParser.delegate = self;

        [XMLParser setShouldProcessNamespaces:YES];

        [XMLParser parse];

    }failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser*XMLParser) {

        NSLog(@"%@",error);

    }];

    [operation start];

第三步;在.m檔案中實現委託方法

    //在文檔開始的時候觸發

-(void)parserDidStartDocument:(NSXMLParser *)parser{

    NSLog(@"解析開始!");

}

//解析起始標記

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{

    NSLog(@"標記:%@",elementName);

    

}

//解析文本節點

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

    NSLog(@"值:%@",string);

}

//解析結束標記

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString *)qName{

    NSLog(@"結束標記:%@",elementName);

}

//文檔結束時觸發

-(void) parserDidEndDocument:(NSXMLParser *)parser{

    NSLog(@"解析結束!");

}

啟動並執行結果:


如何使用AFHTTPClient進行web service操作AFHTTPClient處理GET 和 POST請求.做網頁的朋友們這個方法用的比較多。在要經常調用某個請求時,可以封裝,節省資源。

   BaseURLString = @"http://www.raywenderlich.com/downloads/weather_sample/";

    NSURL *baseURL = [NSURL URLWithString:[NSString stringWithFormat:BaseURLString]];

    NSDictionary *parameters = [NSDictionary dictionaryWithObject:@"json" forKey:@"format"];

    AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:baseURL];

    

    [client registerHTTPOperationClass:[AFJSONRequestOperation class]];

    [client setDefaultHeader:@"Accept" value:@"text/html"];

    [client postPath:@"weather.php" parameters:parameters success:^(AFHTTPRequestOperation *operation,id responseObject) {

        NSString* newStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];

        NSLog(@"POST請求:%@",newStr);

    }failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSLog(@"%@",error);

    }];

    

    [client getPath:@"weather.php" parameters:parameters success:^(AFHTTPRequestOperation *operation, idresponseObject) {

        NSString* newStr = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];

        NSLog(@"GET請求:%@",newStr);

    }failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSLog(@"%@",error);

    }];

 

運行結果:

如果需要顯示網路活動指標,可以用下面方法:[AFNetworkActivityIndicatorManager sharedManager].enabled = YES;

 

Error: Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo=0x16774de0 {NSErrorFailingURLKey=http://192.168.2.2:8181/ecar/tsp/uploadLocation?CID=781666&serviceType=1, AFNetworkingOperationFailinponseErrorKey= { URL: http://192.168.2.2:8181/ecar/tsp/uploadLocation?CID=781666&serviceType=1 } { status code: 200, headers {

    XXX

 

} }, NSLocalizedDescription=Request failed: unacceptable content-type: text/html}

返回資料格式不對。登出這句話: op.responseSerializer = [AFJSONResponseSerializerserializer];然後將返回的資料自己轉換。

 

 

 

error = Error Domain=com.alamofire.error.serialization.response Code=-1016 "Request failed: unacceptable content-type: text/html" UserInfo=0x1740f2c00 {com.alamofire.serialization.response.error.response= { URL: http://192.168.5.132/api/cats?type=apps } { status code: 200, headers {

    Connection = "keep-alive";

    "Content-Type" = "text/html; charset=utf-8";

    Date = "Thu, 05 Nov 2015 10:27:42 GMT";

    Server = nginx;

    "Transfer-Encoding" = Identity;

} }

 

 

AF可以接受json以外的資料    自己隨意定義的格式都可以    只不過要使用AFNetwork提供的解析方法的話   它只對通用的格式做處理    你返回的資料不是那種格式   他就無法解析出來     那要你自己處理    改變AFNetWork的庫檔案     找到他判斷錯誤的那個函數    讓他從正確的方法返回     如果你不會的話  就在返回錯誤的方法處理也可以   反正資料已經到了       網路的目的   是為了得到資料    你的資料已經到了   只不過AFNetwork認定你的資料不符合常用的格式      確實也不符合   因為你的資料是加密的東西  而且是對整個json格式加密   而不是只對值加密    所以要實現這種格式的傳輸    只能修改AFNetwork的庫    而你不會    那就先這麼用著

 

 

舉個例子    你們現在的做法是對整個字串加密    如果你不這麼做    只將值部分加密  而不對鍵加密    就是{“message”:“值的密文”}   那麼這個資料仍然符合json格式   AFNetwork依然能解析出來       你們對整個json字串都加密了  那密文就不是json格式了       所以你們可以按我說的改  僅加密值部分     也就按照現在的方法    在錯誤的返回方法裡面處理資料    但是你自己知道資料是正確的   只不過AFNetwork誤判了而已        這個屬於原理上東西    改不了     要麼就是不讓AFNetwork解析      他只透傳    你自己解析    如果讓他幫你解析   你就要指定一個格式給他    指定了格式  而你的資料不符合格式   那就是按錯誤的方法返回   

AFNetworking關於HTTP認證的問題

 

AFNetwork實現basic認證的方法很簡單

http://stackoverflow.com/questions/12440059/using-afnetworking-and-http-basic-authentication

AFNetwork實現digest認證

建立一個NSURLCredential對象,然後將對象賦值到請求

https://github.com/AFNetworking/AFNetworking/issues/551 http://stackoverflow.com/questions/31784319/digest-access-authentication-for-afnetworking
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:@"Username" password:@"Password" persistence:NSURLCredentialPersistenceForSession]; [manager setCredential:credential]; 

IOS開發網路資料---- AFNetworking的使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.