- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSLog(@"We are here...");
NSString *urlAsString = @"http://www.yahoo.com";
NSLog(@"Firing synchronous url connection...");
dispatch_queue_t dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(dispatchQueue, ^(void) {
NSURL *url = [NSURL URLWithString:urlAsString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response
error:&error];
if ([data length] > 0 && error == nil){
NSLog(@"%lu bytes of data was returned.", (unsigned long)[data length]); }
else if ([data length] == 0 && error == nil){
NSLog(@"No data was returned."); }
else if (error != nil){
NSLog(@"Error happened = %@", error);
} });
NSLog(@"We are done.");
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible];
return YES;
}
昨天在公司接到的任务是获取指定URL返回的数据,由于返回值简单,我就简单使用NSString类的获取URL初始化的方法获取。但正规的还是的使用NSURLConnection累的方法获取网络数据,今天就单独学习了下NSURLConnection的几种发送请求的方法。
先说明下参考的书《iOS 5 Programming Cookbook》作者Vandad Nahavandipoor,以下摘抄的代码均来自于此书。
1.用NSURLConnection进行异步下载并保存在本地
NSString *urlAsString = @"http://www.apple.com";
NSURL *url = [NSURL URLWithString:urlAsString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response,
NSData *data, NSError *error) {
if ([data length] >0 && error == nil){
/* Get the documents directory */
NSString *documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask,
YES) objectAtIndex:0];
/* Append the file name to the documents directory */
NSString *filePath = [documentsDir stringByAppendingPathComponent:@"apple.html"];
/* Write the data to the file */ [data writeToFile:filePath
atomically:YES];
NSLog(@"Successfully saved the file to %@", filePath);
}
else if ([data length] == 0 &&
error == nil){ NSLog(@"Nothing was downloaded.");
}
else if (error != nil){
NSLog(@"Error happened = %@", error); }
}];
对于自己有几个知识点需要注意:一是发送异步请求方法时需要的参数;二是对于代码快^(){}的理解,像匿名函数,我先这么记着,但肯定没有这么简单,将来在接触到了再做补充;三是将数据保存在本地的方法,如何获取document目录的方法,追加上文件名,数据集合对象应该有写入文件的方法。
2.用NSURLConnection进行同步下载并保存在本地
我边查字典边看说明应该说是同步下载网络数据会阻塞主进程,作者解释说是会阻塞“当前”进程,如果把访问的网络的进程另开辟新的进程中执行的话,不会阻塞主进程的,与异步的差异不是很大,什么差异我的英语能力实在有限没法翻译,先亮出会阻塞主进程的方式:
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSLog(@"We are here...");
NSString *urlAsString = @"http://www.yahoo.com"; NSURL *url = [NSURL URLWithString:urlAsString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil; NSError *error = nil;
NSLog(@"Firing synchronous url connection...");
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response error:&error];
if ([data length] > 0 && error == nil){
NSLog(@"%lu bytes of data was returned.", (unsigned long)[data length]); }
else if ([data length] == 0 && error == nil){
NSLog(@"No data was returned."); }
else if (error != nil){
NSLog(@"Error happened = %@", error);
}
NSLog(@"We are done.");
self.window = [[UIWindow alloc] initWithFrame:
[[UIScreen mainScreen] bounds]]; self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES; }
预计结果如下:
We are here...
Firing synchronous url connection...
194472 bytes of data was returned.
We are done.
再亮出不会阻塞主进程的:
- (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSLog(@"We are here...");
NSString *urlAsString = @"http://www.yahoo.com";
NSLog(@"Firing synchronous url connection...");
dispatch_queue_t dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(dispatchQueue, ^(void) {
NSURL *url = [NSURL URLWithString:urlAsString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response
error:&error];
if ([data length] > 0 && error == nil){
NSLog(@"%lu bytes of data was returned.", (unsigned long)[data length]); }
else if ([data length] == 0 && error == nil){
NSLog(@"No data was returned."); }
else if (error != nil){
NSLog(@"Error happened = %@", error);
} });
NSLog(@"We are done.");
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible];
return YES;
}
预计结果如下:
We are here...
Firing synchronous url connection...
We are done.
194326 bytes of data was returned.
分析一下,第一段代码因为网络访问就在主进程中,所以知道下完数据才执行的最后一句话:We are done.但是第二段将网络访问进程分发到其他进程中,这个是我的盲区,我还不会多线程开发,记得高中数学老师说过,弄不懂的先承认它!总之是与主进程分开了,结果就是We are done.这句话不用等数据下完就直接打出来了,可见并没有被阻塞。今天的主题不是多线程开发,所以我就不会深究那几个应该是C函数吧,总之是会学习他们的,你给我等着!!~~
3.get和post方式请求数据,基本的访问框架也就是上面的,变化就是NSMutableURLRequest实例的参数设置问题,如:[urlRequest setHTTPMethod:@"POST"];和[urlRequest setHTTPMethod:@"GET"];post方法再多个这个设置NSString *body = @"bodyParam1=BodyValue1&bodyParam2=BodyValue2"; [urlRequest setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];这样就把数据带上。
总结:今天算是将网络访问入个小门,书是越读越厚,期待读薄的时候。