Http requests on iOS: get, post, and synchronous and asynchronous
There is a public weather interface on the Internet: weather, click the getSupportCityDataset interface in it, and use this interface as an example to write the HTTP request Writing Method on iOS. The format requirements of get and post requests are provided.
1. get:
NSString * URLString = @ "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx/getSupportCityDataset? TheRegionCode = Guangdong "; NSURL * URL = [NSURL URLWithString: [URLString encoding: NSUTF8StringEncoding]; NSURLRequest * request = [[NSURLRequest alloc] initWithURL: URL]; NSURLResponse * response = nil; NSError * error = nil; NSData * data = [NSURLConnection sendSynchronousRequest: request returningResponse: & response error: & error]; if (error) {NSLog (@ "error: % @", [error localizedDescription]);} else {NSLog (@ "response: % @", response); NSLog (@ "backData: % @ ", [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]);}
The request parameter of the get method is placed in a long URL string. Here, only one parameter is required, that is, the Region ID or name. Through this parameter, the server returns the list of cities that support weather searches in this region. If more parameters are included in the URL string, the parameter organization method depends on the server requirements.
To construct an NSURL with a string, we recommend that you perform UTF8 transcoding for the original string when using URLWithString. For more information about transcoding, see the first part. Then, the NSURL object constructs the NSURLRequest and uses the NSURLConnection synchronization method to pass in the request object to obtain data through the get method.
Here, an NSError object address is passed in for error judgment. The actual situation of the network is changeable and the request error must be considered; otherwise, the program may crash.
2. post:
NSString * URLString = @ "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx/getSupportCityString"; NSURL * URL = [NSURL URLWithString: [URLString encoding: NSUTF8StringEncoding]; NSString * postString = @ "theRegionCode = Guangdong "; NSData * postData = [postString dataUsingEncoding: NSUTF8StringEncoding]; // convert the request parameter string to NSData-type NSMutableURLRequest * request = [[NSMutableURLRequest alloc] init]; [request setHTTPMethod: @ "post"]; // specify the request method [request setURL: URL]; // set the request address [request setHTTPBody: postData]; // set the request parameter NSURLResponse * response; NSError * error; NSData * backData = [NSURLConnection sendSynchronousRequest: request returningResponse: & response error: & error]; if (error) {NSLog (@ "error: % @", [error localizedDescription]);} else {NSLog (@ "response: % @", response); NSLog (@ "backData: % @ ", [[NSString alloc] initWithData: backData encoding: NSUTF8StringEncoding]);}
In post mode, parameters are placed in HTTPBody, and the string needs to be transcoded to the NSData type of the response. Generally, the transcoding method is specified in the interface documentation, UTF8 here, there are also gb2312. After the request is built, use NSURLConnection to request data like the get method.
3. synchronous and asynchronous requests:
Generally, network requests take some time, even if there is less data and the network is good, it will take some time. In many cases, you must consider the app status when the network is poor. To use a synchronous request, you only need to wait for the data with peace of mind. No additional operations are required. The two examples above are synchronous requests. After the connection calls the method, the data returned for the request is not required. However, synchronization will block the thread. If a request is initiated by clicking the button, the button will stay in the highLight State until the request ends. This will cause the app to get stuck and crashed, which is not good.
Asynchronous get:
NSString * URLString = @ "http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx/getSupportCityDataset? TheRegionCode = Guangdong "; NSURL * URL = [NSURL URLWithString: [URLString encoding: NSUTF8StringEncoding]; NSURLRequest * request = [[NSURLRequest alloc] initWithURL: URL]; _ connection = [[NSURLConnection alloc] initWithRequest: request delegate: self]; (1)
Asynchronous post is similar. Instead of using NSURLConnection to call the method to directly obtain data, instead of using (1) the position method to construct an NSURLConnection object. This method starts to request data by default. The next step is to rely on delegation. Because the request time is unknown, the callback function of the delegate mode is used. When the data is returned, the Protocol method is called. The post and get delegate methods are the same.
Protocol method:
Note that there are two delegates: NSURLConnectionDataDelegate and NSURLConnectionDelegate. The first one inherits from the last one. The method for obtaining data is defined in the previous delegate. Therefore, you only need to follow NSURLConnectionDataDelegate.
Generally, four delegate methods are used:
// Receives respone, which contains the HTTP Request status code and data header information, including the data length and encoding format-(void) connection :( NSURLConnection *) connection didReceiveResponse :( NSURLResponse *) response {NSLog (@ "response = % @", response); _ backData = [[NSMutableData alloc] init];} // called when data is received, the complete data may be split into multiple packages and sent. This method is called every time a data segment is received. Therefore, a global NSData object is required to splice the data together-(void) connection :( NSURLConnection *) connection didReceiveData :( NSData *) data {[_ backData appendData: data];} // this method is called at the end of data acceptance, at this time, the data is the complete data obtained. You can use the data for subsequent processing-(void) connectionDidFinishLoading :( NSURLConnection *) connection {NSLog (@ "% @", [[NSString alloc] initWithData: _ backData encoding: NSUTF8StringEncoding]);} // This is a request error and is called. error handling cannot be ignored-(void) connection :( NSURLConnection *) connection didFailWithError :( NSError *) error {if (error. code = NSURLErrorTimedOut) {NSLog (@ "request timeout");} NSLog (@ "% @", [error localizedDescription]);}
Finally, you can set the timeout value for the request:NSURLRequest * request = [[NSURLRequest alloc]initWithURL:URL cachePolicy:0 timeoutInterval:8.0];
Or:NSMutableURLRequest * request = [[NSMutableURLRequest alloc]initWithURL:URL]; [request setTimeoutInterval:8.0];
If the request time exceeds the set timeout time, it is automatically called.-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
However, the problem is how to determine whether the request fails due to timeout. The above example has already been written and can be determined based on the returned error code. You can better notify users of request failures in different situations.