HTTP定义了一种在服务器和客户端之间传递数据的途径。
URL定义了一种唯一标示资源在网络中位置的途径。
REQUESTS 和 RESPONSES:
客户端先建立一个TCP连接,然后发送一个请求。服务器受到请求处理后发送一个响应向客户端传递数据。然后客户端可以继续发送请求或者关闭这个TCP连接。
HTTPS:
在TCP连接建立后,发送请求之前,需要建立一个一个SSL会话。
request方法和它们的用途
注意:想server发送大量数据需要用POST,因为GET仅支持发送少量数据(8KB)。
iOS的NSURLRequest和它的子类NSMutableURLRequest提供了建立HTTP请求的方法。
NSURLResponse 和 它的子类NSHTTPURLResponse 处理返回的数据。
URL:
Protocol包括HTTP、FTP和file。
URL编码:
NSString *urlString = @"http://myhost.com?query=This is a question";
NSString *encoded = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL用来管理URL。
IOS HTTP APIS:
涉及到下面一些类:
NSURL, NSURLRequest, NSURLConnection, 和 NSURLResponse.
1、NSURL
NSURL可以定义本地文件和网络文件
NSURL *url = [NSURL urlWithString:@"http://www.google.com"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSURL定义了很多访问器:
if (url.port == nil) {
NSLog(@"Port is nil");
} else {
NSLog(@"Port is not nil");
}
2、NSURLRequest
创建了NSURL后,就可以用NSURLRequest建立请求了:
NSURL *url = [NSURL URLWithString: @"https://gdata.youtube.com/feeds/api/standardfeeds/top_rated"];
if (url == nil) {
NSLog(@"Invalid URL");
return;
}
NSURLRequest *request = [NSURLRequest requestWithURL:url];
if (request == nil) {
NSLog(@"Invalid Request");
return;
}
NSMutableURLRequest是NSURLRequest 的子类,提供了改变请求的属性的方法:
NSURL *url = [NSURL urlWithString@"http://server.com/postme"];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req setHTTPMethod:@"POST"];
[req setHTTPBody:[@"Post body" dataUsingEncoding:NSUTF8StringEncoding]];
如果你要发送一个图片或者视频,那么用需要用NSInputStream,它没有把数据全部加在到内存。
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSInputStream *inStream = [NSInputStream inputStreamWithFileAtPath:srcFilePath];
[request setHTTPBodyStream:inStream];
[request setHTTPMethod:@"POST"];
3、NSURLResponse
4、NSURLConnection
提供了初始化、开始、和取消一个连接。
发送同步请求:
- (NSArray *) doSyncRequest:(NSString *)urlString {
// make the NSURL object from the string
NSURL *url = [NSURL URLWithString:urlString];
// Create the request object with a 30 second timeout and a cache policy to always retrieve the
// feed regardless of cachability.
NSURLRequest *request =
[NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:30.0];
// Send the request and wait for a response
NSHTTPURLResponse *response;
NSError *error;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
// check for an error
if (error != nil) {
NSLog(@"Error on load = %@", [error localizedDescription]);
return nil;
}
// check the HTTP status
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode != 200) {
return nil;
}
NSLog(@"Headers: %@", [httpResponse allHeaderFields]);
}
// Parse the data returned into an NSDictionary
NSDictionary *dictionary =
[XMLReader dictionaryForXMLData:data
error:&error];
// Dump the dictionary to the log file
NSLog(@"feed = %@", dictionary);
NSArray *entries =[self getEntriesArray:dictionary];
// return the list if items from the feed.
return entries;
}
Queued Asynchronous Requests:
- (void) doQueuedRequest:(NSString *)urlString delegate:(id)delegate {
// make the NSURL object
NSURL *url = [NSURL URLWithString:urlString];
// create the request object with a no cache policy and a 30 second timeout.
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:30.0];
// If the queue doesn't exist, create one.
if (queue == nil) {
queue = [[NSOperationQueue alloc] init];
}
// send the request and specify the code to execute when the request completes or fails.
[NSURLConnection sendAsynchronousRequest:request
queue:queue
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error) {
if (error != nil) {
NSLog(@"Error on load = %@", [error localizedDescription]);
} else {
// check the HTTP status
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode != 200) {
return;
}
NSLog(@"Headers: %@", [httpResponse allHeaderFields]);
}
// parse the results and make a dictionary
NSDictionary *dictionary =
[XMLReader dictionaryForXMLData:data
error:&error];
NSLog(@"feed = %@", dictionary);
// get the dictionary entries.
NSArray *entries =[self getEntriesArray:dictionary];
// call the delegate
if ([delegate respondsToSelector:@selector(setVideos:)]) {
[delegate performSelectorOnMainThread:@selector(setVideos:)
withObject:entries
waitUntilDone:YES];
}
}
}];
}
NSURLConnection start方法和Delegate:
GET:
NSURL *url=[[ NSURL alloc ] initWithString :urlString];
NSMutableURLRequest *request=[[NSMutableURLRequest alloc ] init ];
NSURLConnection *connection = [[ NSURLConnection alloc ] initWithRequest :request delegate : self ];
if (connection)
{
[connection start];
}
else
{
NSLog ( @"sorry" );
}
/*
* NSURLConnectionDataDelegate
*/
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse *)response
{
[activityIndicator startAnimating]; //UIActivityIndicatorView
NSLog(@"Did Receive Response %@", response);
responseData = [[NSMutableData alloc]init];
}
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
//NSLog(@"Did Receive Data %@", data);
[responseData appendData:data]; //NSMutableData
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
NSLog(@"Did Fail");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[activityIndicator stopAnimating];
NSLog(@"Did Finish");
// Do something with responseData
}
POST:
//initialize new mutable data
NSMutableData *data = [[NSMutableData alloc] init];
self.receivedData = data;
//initialize url that is going to be fetched.
NSURL *url = [NSURL URLWithString:@"http://www.snee.com/xml/crud/posttest.cgi"];
//initialize a request from url
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[url standardizedURL]];
//set http method
[request setHTTPMethod:@"POST"];
//initialize a post data
NSString *postData = [[NSString alloc] initWithString:@"fname=example&lname=example"];
//set request content type we MUST set this value.
[request setValue:@"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
//set post data of request
[request setHTTPBody:[postData dataUsingEncoding:NSUTF8StringEncoding]];
//initialize a connection from request
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
self.connection = connection;
//start the connection
[connection start];
异步请求:
异步请求需要一个run loop来操作代理对象,GCD和NSOperationQueue默认并没有run loop,所以如果你想在后台发起一个HTTP请求,必须确保有run loop。
NSURLConnection connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self startImmediately:NO];
[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
[connection start];
上面的代码是在主线程运行,如果想在其他线程运行,可以在其他线程新建一个run loop,并绑定到connection。