IOS网络开发实战(二)

1 飞机航班查询软件

1.1 问题

NSURLConnection是IOS提供的用于处理Http协议的网络请求的类,可以实现同步请求也可以实现异步请求,本案例使用NSURLConnection类实现一个飞机航班查询的工具软件,采用GET的同步请求方式访问网络数据,如图-1所示:

图-1

1.2 方案

首先创建一个SingleViewApplication应用,在Storyboard文件中搭建查询界面,上方的三个Textfield控件分别用于接受用户输入的出发城市、到达城市和触发日期,界面中间有一个查询按钮,当用户点击该按钮则发送网络请求,根据用户输入的信息获取飞机航班信息。将三个Textfield控件分别关联成ViewController的输出口属性departCity、arriveCity、departDate。

界面的下半部分是一个TableView控件,用于展示网络返回的数据结果,将TableView控件的dataSource和delegate设置为ViewController,并关联成ViewController的输出口属性resultTV。

其次需要确定一个能够提供数据的公共网络平台,本案例使用http://webservice.webxml.com.cn网络平台,该平台能够提供多种类型的服务例如火车时刻查询、天气预报查询等。

本案例使用飞机航班查询,该服务的名称是getDomesticAirlinesTime,进入该服务界面可以看到除了提供参数使用说明还有测试窗口,如图-2所示:

图-2

这里可以使用测试功能进行测试,查看返回的XML文件的内容,出发城市输入上海,到达城市输入北京,日期输出2015-3-8,这里输入的信息必须符合参数要求不可以随意修改,如图-3所示:

图-3

点击调用按钮发出请求,可以在弹出的新页面中查看返回的XML文件的内容,如图-4所示:

图-4

然后根据应用的需要在返回的XML文件中获取需要的信息,将相关的航班信息保存在ScheduledFlight类中,该类继承至NSObject,根据所需定义如下属性:

NSString类型的属性company,记录航空公司名称;

NSString类型的属性airlineCode,记录航班号;

NSString类型的属性startDrome,记录起飞机场;

NSString类型的属性arriveDrome,记录到达机场;

NSString类型的属性startTime,记录起飞时间;

NSString类型的属性arriveTime,记录到达时间;

NSString类型的属性mode,记录飞机机型。

接下来需要创建一个Parse类型用于解析XML文件,从中获取需要的航班信息,并将信息存入ScheduledFlight类型的实例中。Parse类有一个公开的静态方法getFlightsByData:,该方法返回一个NSMutableArray类型的数组,该数组的每一个元素都是一个ScheduledFlight类型的实例,即航班信息。

然后将查询按钮关联成ViewController的动作方法search:,该方法中根据用户输入的查询条件得到NSString类型的路径path,由于含有中文因此需要进行编码,然后通过path创建NSURL对象和NSMutableURLRequest对象,最后通过NSURLConnection类的工厂方法sendSynchronousRequest:returningResponse:发送同步请求,得到返回的NSData类型的数据。

最后通过Parse类的getFlightsByData:方法解析数据得到一组航班信息,将其存放在ViewController的NSMutableArray类型的属性flights中,根据flights存放的航班数据更新表视图resultTV的显示内容。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:搭建查询界面

首先创建一个SingleViewApplication应用,在Storyboard文件中搭建查询界面,上方的三个Textfield控件分别用于接受用户输入的出发城市、到达城市和触发日期,界面中间有一个查询按钮,当用户点击该按钮则发送网络请求,根据用户输入的信息获取飞机航班信息。将三个Textfield控件分别关联成ViewController的输出口属性departCity、arriveCity、departDate。

界面的下半部分是一个TableView控件,用于展示网络返回的数据结果,将TableView控件的dataSource和delegate设置为ViewController,并关联成ViewController的输出口属性resultTV,代码如下所示:

  1. @interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
  2. @property (weak, nonatomic) IBOutlet UITextField *departCity;
  3. @property (weak, nonatomic) IBOutlet UITextField *arriveCity;
  4. @property (weak, nonatomic) IBOutlet UITextField *departDate;
  5. @property (weak, nonatomic) IBOutlet UITableView *resultTV;
  6. @end

在Storyboard中完成的界面如图-5所示:

图-5

步骤二:创建航班类ScheduledFlight

本案例使用http://webservice.webxml.com.cn公共网络平台获取飞机航班信息,然后通过XML解析将信息展示在界面上。

首先创建一个航班类ScheduledFlight,该类继承至NSObject,根据所需定义如下公开属性:

NSString类型的属性company,记录航空公司名称;

NSString类型的属性airlineCode,记录航班号;

NSString类型的属性startDrome,记录起飞机场;

NSString类型的属性arriveDrome,记录到达机场;

NSString类型的属性startTime,记录起飞时间;

NSString类型的属性arriveTime,记录到达时间;

NSString类型的属性mode,记录飞机机型,代码如下所示:

  1. @interface ScheduledFlight : NSObject
  2. @property (nonatomic,copy) NSString *company;
  3. @property (nonatomic,copy) NSString *airlineCode;
  4. @property (nonatomic,copy) NSString *startDrome;
  5. @property (nonatomic,copy) NSString *arriveDrome;
  6. @property (nonatomic,copy) NSString *startTime;
  7. @property (nonatomic,copy) NSString *arriveTime;
  8. @property (nonatomic,copy) NSString *mode;
  9. @end

步骤三:创建XML解析类Parse

接下来需要创建一个Parse类型用于解析XML文件,从中获取需要的航班信息,并将信息存入ScheduledFlight类型的实例中。首先在该类中定义三个私有属性NSMutableArray类型的flights用于记录最终获得的一组航班信息,ScheduledFlight类型的currentFlight用于记录当前正在解析的航班,NSString类型的currentString用于记录当前正在读取的字符串,代码如下所示:

  1. @interface Parser ()<NSXMLParserDelegate>
  2. @property (nonatomic,strong) NSMutableArray *flights;
  3. @property (nonatomic,strong) ScheduledFlight *currentFlight;
  4. @property (nonatomic,copy) NSString *currentString;
  5. @end

Parse类有一个公开的静态方法getFlightsByData:,该方法返回一个NSMutableArray类型的数组,记录着最终解析出来的所有航班信息,即self.flights,代码如下所示:

  1. -(NSMutableArray *)getFlightsByData:(NSData *)data{
  2. self.flights = [NSMutableArray array];
  3. NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
  4. parser.delegate = self;
  5. [parser parse];
  6. return self.flights;
  7. }

然后通过实现NSXMLParserDelegate协议中的相关方法进行XML数据解析,得到所有的航班信息,代码如下所示:

  1. - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
  2. if ([elementName isEqualToString:@"AirlinesTime"]) {
  3. //创建ScheduledFlight实例
  4. self.currentFlight = [[ScheduledFlight alloc]init];
  5. }
  6. }
  7. -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
  8. self.currentString = string;
  9. }
  10. -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
  11. if ([elementName isEqualToString:@"Company"]) {
  12. self.currentFlight.company = self.currentString;
  13. }else if ([elementName isEqualToString:@"AirlineCode"]) {
  14. self.currentFlight.airlineCode = self.currentString;
  15. }else if ([elementName isEqualToString:@"StartDrome"]) {
  16. self.currentFlight.startDrome = self.currentString;
  17. }else if ([elementName isEqualToString:@"ArriveDrome"]) {
  18. self.currentFlight.arriveDrome = self.currentString;
  19. }else if ([elementName isEqualToString:@"StartTime"]) {
  20. self.currentFlight.startTime = self.currentString;
  21. }else if ([elementName isEqualToString:@"ArriveTime"]) {
  22. self.currentFlight.arriveTime = self.currentString;
  23. }else if ([elementName isEqualToString:@"Mode"]) {
  24. self.currentFlight.mode = self.currentString;
  25. }else if ([elementName isEqualToString:@"AirlinesTime"]){
  26. //解析完成将当前的航班放入self.flights数组中保存
  27. [self.flights addObject:self.currentFlight];
  28. }
  29. }

步骤四:发送网络请求,展示航班信息

首先在ViewController类中定义一个NSMutableArray类型的属性flights,用于记录需要展示的航班信息,然后实现表视图的协议方法展示数据,代码如下所示:

  1. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  2. return self.flights.count;
  3. }
  4. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  5. return 100;
  6. }
  7. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  8. static NSString *identifier = @"Cell";
  9. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
  10. if (!cell) {
  11. cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
  12. }
  13. ScheduledFlight *flight = [self.flights objectAtIndex:indexPath.row];
  14. // NSLog(@"%@",flight.company);
  15. cell.textLabel.numberOfLines = 0;
  16. cell.textLabel.text = [NSString stringWithFormat:@"航空公司:%@\n航班号:%@\n起飞机场:%@\n到达机场:%@\n起飞时间:%@\n到达时间:%@\n机型:%@",flight.company,flight.airlineCode,flight.startDrome,flight.arriveDrome,flight.startTime,flight.arriveTime,flight.mode];
  17. [cell.textLabel setFont:[UIFont systemFontOfSize:10]];
  18. cell.backgroundColor = [UIColor clearColor];
  19. return cell;
  20. }

然后将查询按钮关联成ViewController的动作方法search:,该方法中根据用户输入的查询条件得到NSString类型的路径path,由于含有中文因此需要进行编码,然后通过path创建NSURL对象和NSMutableURLRequest对象,最后通过NSURLConnection类的工厂方法sendSynchronousRequest:returningResponse:发送同步请求,得到返回的NSData类型的数据,代码如下所示:

  1. - (IBAction)search:(UIButton *)sender {
  2. [self.departDate resignFirstResponder];
  3. //根据用户输入的信息得到路径
  4. NSString *path = [NSString stringWithFormat:@"http://webservice.webxml.com.cn/webservices/DomesticAirline.asmx/getDomesticAirlinesTime?startCity=%@&lastCity=%@&theDate=%@&userID=",self.departCity.text,self.arriveCity.text,self.departDate.text];
  5. //由于含有中文需要进行编码
  6. path = (NSString*)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)path, NULL, NULL, kCFStringEncodingUTF8));
  7. //创建url路径
  8. NSURL *url = [NSURL URLWithString:path];
  9. NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
  10. [request setHTTPMethod:@"GET"];
  11. NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
  12. // NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
  13. }

最后在ViewController类中导入头文件"ScheduledFlight.h"和"Parser.h",在search:方法中通过Parse类的getFlightsByData:方法解析数据得到一组航班信息,将其存放在ViewController的NSMutableArray类型的属性flights中,根据flights存放的航班数据更新表视图resultTV的显示内容,代码如下所示:

  1. - (IBAction)search:(UIButton *)sender {
  2. [self.departDate resignFirstResponder];
  3. //根据用户输入的信息得到路径
  4. NSString *path = [NSString stringWithFormat:@"http://webservice.webxml.com.cn/webservices/DomesticAirline.asmx/getDomesticAirlinesTime?startCity=%@&lastCity=%@&theDate=%@&userID=",self.departCity.text,self.arriveCity.text,self.departDate.text];
  5. //由于含有中文需要进行编码
  6. path = (NSString*)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)path, NULL, NULL, kCFStringEncodingUTF8));
  7. //创建url路径
  8. NSURL *url = [NSURL URLWithString:path];
  9. NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
  10. [request setHTTPMethod:@"GET"];
  11. NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
  12. // NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
  13. Parser *parser = [[Parser alloc]init];
  14. self.flights = [parser getFlightsByData:data];
  15. [self.resultTV reloadData];
  16. }

1.4 完整代码

本案例中,ViewController.m文件中的完整代码如下所示:

  1. #import "ViewController.h"
  2. #import "ScheduledFlight.h"
  3. #import "Parser.h"
  4. @interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
  5. @property (weak, nonatomic) IBOutlet UITextField *departCity;
  6. @property (weak, nonatomic) IBOutlet UITextField *arriveCity;
  7. @property (weak, nonatomic) IBOutlet UITextField *departDate;
  8. @property (weak, nonatomic) IBOutlet UITableView *resultTV;
  9. @property (nonatomic,strong) NSMutableArray *flights;
  10. @end
  11. @implementation ViewController
  12. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  13. return self.flights.count;
  14. }
  15. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  16. return 100;
  17. }
  18. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  19. static NSString *identifier = @"Cell";
  20. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
  21. if (!cell) {
  22. cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
  23. }
  24. ScheduledFlight *flight = [self.flights objectAtIndex:indexPath.row];
  25. // NSLog(@"%@",flight.company);
  26. cell.textLabel.numberOfLines = 0;
  27. cell.textLabel.text = [NSString stringWithFormat:@"航空公司:%@\n航班号:%@\n起飞机场:%@\n到达机场:%@\n起飞时间:%@\n到达时间:%@\n机型:%@",flight.company,flight.airlineCode,flight.startDrome,flight.arriveDrome,flight.startTime,flight.arriveTime,flight.mode];
  28. [cell.textLabel setFont:[UIFont systemFontOfSize:10]];
  29. cell.backgroundColor = [UIColor clearColor];
  30. return cell;
  31. }
  32. - (IBAction)search:(UIButton *)sender {
  33. [self.departDate resignFirstResponder];
  34. //根据用户输入的信息得到路径
  35. NSString *path = [NSString stringWithFormat:@"http://webservice.webxml.com.cn/webservices/DomesticAirline.asmx/getDomesticAirlinesTime?startCity=%@&lastCity=%@&theDate=%@&userID=",self.departCity.text,self.arriveCity.text,self.departDate.text];
  36. //由于含有中文需要进行编码
  37. path = (NSString*)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)path, NULL, NULL, kCFStringEncodingUTF8));
  38. //创建url路径
  39. NSURL *url = [NSURL URLWithString:path];
  40. NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
  41. [request setHTTPMethod:@"GET"];
  42. NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
  43. Parser *parser = [[Parser alloc]init];
  44. self.flights = [parser getFlightsByData:data];
  45. [self.resultTV reloadData];
  46. }
  47. @end

本案例中,ScheduledFlight.h文件中的完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface ScheduledFlight : NSObject
  3. @property (nonatomic,copy) NSString *company;
  4. @property (nonatomic,copy) NSString *airlineCode;
  5. @property (nonatomic,copy) NSString *startDrome;
  6. @property (nonatomic,copy) NSString *arriveDrome;
  7. @property (nonatomic,copy) NSString *startTime;
  8. @property (nonatomic,copy) NSString *arriveTime;
  9. @property (nonatomic,copy) NSString *mode;
  10. @end

本案例中,Parser.h文件中的完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. #import "ScheduledFlight.h"
  3. @interface Parser : NSObject
  4. -(NSMutableArray *)getFlightsByData:(NSData *)data;
  5. @end

本案例中,Parser.m文件中的完整代码如下所示:

  1. #import "Parser.h"
  2. @interface Parser ()<NSXMLParserDelegate>
  3. @property (nonatomic,strong) NSMutableArray *flights;
  4. @property (nonatomic,strong) ScheduledFlight *currentFlight;
  5. @property (nonatomic,copy) NSString *currentString;
  6. @end
  7. @implementation Parser
  8. -(NSMutableArray *)getFlightsByData:(NSData *)data{
  9. self.flights = [NSMutableArray array];
  10. NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
  11. parser.delegate = self;
  12. [parser parse];
  13. return self.flights;
  14. }
  15. - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
  16. if ([elementName isEqualToString:@"AirlinesTime"]) {
  17. //创建ScheduledFlight实例
  18. self.currentFlight = [[ScheduledFlight alloc]init];
  19. }
  20. }
  21. -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
  22. self.currentString = string;
  23. }
  24. -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
  25. if ([elementName isEqualToString:@"Company"]) {
  26. self.currentFlight.company = self.currentString;
  27. }else if ([elementName isEqualToString:@"AirlineCode"]) {
  28. self.currentFlight.airlineCode = self.currentString;
  29. }else if ([elementName isEqualToString:@"StartDrome"]) {
  30. self.currentFlight.startDrome = self.currentString;
  31. }else if ([elementName isEqualToString:@"ArriveDrome"]) {
  32. self.currentFlight.arriveDrome = self.currentString;
  33. }else if ([elementName isEqualToString:@"StartTime"]) {
  34. self.currentFlight.startTime = self.currentString;
  35. }else if ([elementName isEqualToString:@"ArriveTime"]) {
  36. self.currentFlight.arriveTime = self.currentString;
  37. }else if ([elementName isEqualToString:@"Mode"]) {
  38. self.currentFlight.mode = self.currentString;
  39. }else if ([elementName isEqualToString:@"AirlinesTime"]){
  40. //解析完成将当前的航班放入self.flights数组中保存
  41. [self.flights addObject:self.currentFlight];
  42. }
  43. }
  44. @end

2 歌曲下载

2.1 问题

通常同步请求的用户体验不是很好,因此很多情况下会采用异步请求,异步请求是使用NSURLConnection的委托协议NSURLConnectionDelegate来实现的,本案例使用NSURLConnection类的异步请求实现网路歌曲的下载。

2.2 方案

首先创建一个SingleViewApplication应用,在ViewDidLoad方法中定义三个私有属性,NSData类型的fileData,用于存储接受文件的数据,NSString类型的fileName用于记录接受文件的名称,NSUInteger类型的length用于记录接受文件的长度。

在viewDidLoad方法中通过歌曲的网路路径path创建NSURL对象url和NSMutableURLRequest对象request,通过request创建一个NSURLConnection类型的对象connection,将delegate设置为ViewController,如果connection创建成功则表示异步请求发送成功。

当连接成功则会接收到响应,是一个NSURLResponse类型的实例response,通过response的属性allHeaderFields获取到下载文件的头文件,头文件里面包含文件的类型、长度、名称等信息。

最后通过实现NSURLConnectionDelegate协议和NSURLConnectionDataDelegate协议的相关方法接受网路数据响应,接受网络数据,完成数据下载并存入本地。

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建NSURLConnection连接

首先创建一个SingleViewApplication应用,在ViewDidLoad方法中定义三个私有属性,NSData类型的fileData,用于存储接受文件的数据,NSString类型的fileName用于记录接受文件的名称,NSUInteger类型的length用于记录接受文件的长度,代码如下所示:

  1. @interface ViewController ()<NSURLConnectionDelegate,NSURLConnectionDataDelegate>
  2. @property (nonatomic, strong)NSMutableData *fileData;
  3. @property (nonatomic,copy)NSString *fileName;
  4. @property (nonatomic,assign) NSUInteger length;
  5. @end

在viewDidLoad方法中通过歌曲的网路路径path创建NSURL对象url和NSMutableURLRequest对象request,通过request创建一个NSURLConnection类型的对象connection,将delegate设置为ViewController,如果connection创建成功则表示异步请求发送成功,代码如下所示:

  1. - (void)viewDidLoad
  2. {
  3. self.fileData = [NSMutableData data];
  4. [super viewDidLoad];
  5. NSString *path = @"http://music.baidu.com/data/music/file?link=http://zhangmenshiting.baidu.com/data2/music/65371921/401533401375268461128.mp3?xcode=c318182b0f97938776659f1fd7cf3f72f84b7d701136b422";
  6. NSURL *url = [NSURL URLWithString:path];
  7. NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
  8. NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
  9. if (connection) {
  10. NSLog(@"连接成功");
  11. }
  12. }

步骤二:实现协议方法,完成数据下载

当连接成功则会接收到响应,是一个NSURLResponse类型的实例response,通过response的属性allHeaderFields获取到下载文件的头文件,头文件里面包含文件的类型、长度、名称等信息。

最后通过实现NSURLConnectionDelegate协议和NSURLConnectionDataDelegate协议的相关方法接受网路数据响应,接受网络数据,完成数据下载并存入本地,代码如下所示:

  1. //接受到相响应时调用
  2. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
  3. NSLog(@"接收到响应!!");
  4. NSHTTPURLResponse *resp = (NSHTTPURLResponse*)response;
  5. //获取头文件,头文件里面包含文件的类型,长度,名称等信息
  6. NSDictionary *dic = resp.allHeaderFields;
  7. NSLog(@"%@",dic);
  8. self.length = [[dic objectForKey:@"Content-Length"] intValue];
  9. self.fileName = [dic objectForKey:@"Content-Disposition"];
  10. NSLog(@"length:%lu,filename:%@",self.length,self.fileName);
  11. }
  12. //接受数据时调用
  13. -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
  14. //已经接受的数据长度
  15. NSLog(@"data length = %lu",(unsigned long)data.length);
  16. //将持续接受的数据存入self.fileData
  17. [self.fileData appendData:data];
  18. }
  19. //下载完成时调用
  20. -(void)connectionDidFinishLoading:(NSURLConnection *)connection{
  21. //当接受完成将文件存入本地
  22. NSFileManager *fm = [NSFileManager defaultManager];
  23. NSString *filePath = @"/Users/Vivian/Desktop/songs";
  24. [fm createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
  25. [self.fileData writeToFile:[filePath stringByAppendingPathComponent:self.fileName] atomically:YES];
  26. NSLog(@"完成");
  27. }
  28. -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
  29. NSLog(@"error");
  30. }

2.4 完整代码

本案例中,ViewController.m文件中的完整代码如下所示:

  1. #import "ViewController.h"
  2. @interface ViewController ()<NSURLConnectionDelegate,NSURLConnectionDataDelegate>
  3. @property (nonatomic, strong)NSMutableData *fileData;
  4. @property (nonatomic,copy)NSString *fileName;
  5. @property (nonatomic,assign) NSUInteger length;
  6. @end
  7. @implementation ViewController
  8. - (void)viewDidLoad
  9. {
  10. self.fileData = [NSMutableData data];
  11. [super viewDidLoad];
  12. NSString *path = @"http://music.baidu.com/data/music/file?link=http://zhangmenshiting.baidu.com/data2/music/65371921/401533401375268461128.mp3?xcode=c318182b0f97938776659f1fd7cf3f72f84b7d701136b422";
  13. NSURL *url = [NSURL URLWithString:path];
  14. NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
  15. NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
  16. if (connection) {
  17. NSLog(@"连接成功");
  18. }
  19. }
  20. //接受到相响应时调用
  21. - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
  22. NSLog(@"接收到响应!!");
  23. NSHTTPURLResponse *resp = (NSHTTPURLResponse*)response;
  24. //获取头文件,头文件里面包含文件的类型,长度,名称等信息
  25. NSDictionary *dic = resp.allHeaderFields;
  26. NSLog(@"%@",dic);
  27. self.length = [[dic objectForKey:@"Content-Length"] intValue];
  28. self.fileName = [dic objectForKey:@"Content-Disposition"];
  29. NSLog(@"length:%lu,filename:%@",self.length,self.fileName);
  30. }
  31. //接受数据时调用
  32. -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
  33. //已经接受的数据长度
  34. NSLog(@"data length = %lu",(unsigned long)data.length);
  35. //将持续接受的数据存入self.fileData
  36. [self.fileData appendData:data];
  37. }
  38. //下载完成时调用
  39. -(void)connectionDidFinishLoading:(NSURLConnection *)connection{
  40. //当接受完成将文件存入本地
  41. NSFileManager *fm = [NSFileManager defaultManager];
  42. NSString *filePath = @"/Users/Vivian/Desktop/songs";
  43. [fm createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
  44. [self.fileData writeToFile:[filePath stringByAppendingPathComponent:self.fileName] atomically:YES];
  45. NSLog(@"完成");
  46. }
  47. -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
  48. NSLog(@"error");
  49. }
  50. @end
时间: 2024-07-28 23:11:07

IOS网络开发实战(二)的相关文章

IOS网络开发(二)

1 局域网群聊软件 1.1 问题 UDP协议将独立的数据包从一台计算机传输到另外一台计算机,但是并不保证接受方能够接收到该数据包,也不保证接收方所接收到的数据和发送方所发送的数据在内容和顺序上是完全一致的. UDP广播就是建立于UDP协议上的数据传输,当网络中的某一台计算机向交换机或路由发送一个广播数据时,交换机或路由则会将此广播数据发送到其节点下的所有接收者.本案例使用第三方Socket编程框架AsyncUdpSocket框架,基于UDP广播实现一个局域网群聊软件,一个基于UD广播的聊天室程序

iOS项目开发实战——获取网页源代码的二进制数据

我在上一篇博客<iOS项目开发实战--iOS网络编程获取网页Html源代码>中讲述了如何获取一个网页的HTML源代码,可以满足一定的需求.但是由于特殊原因,我们想获取的是一个网页的二进制数据,那么应该怎么办呢? 具体实现如下: (1)创建一个iOS项目,Language选择Swift,然后在ViewController.swift 中写入如下代码: override func viewDidLoad() { super.viewDidLoad() var data = NSData(conte

IOS网络开发NSURLSession详解(一)概述

原创blog,转载请注明出处blog.csdn.net/hello_hwc 我的IOS-SDK详解专栏,欢迎关注 http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html 前言: 这个IOS网络编程的系列计划6篇文章,NSURLSession3篇(一篇概述,一篇详细阐述三种task和delegate的使用,一篇阐述授权,证书等内容),网络的基础知识两篇(一篇REST API讲解已经写完了,一篇我会把写博客的过程中遇到的概念总结出来

iOS项目开发实战——学会使用TableView列表控件(四)plist读取与Section显示

文本将会实现把数据存储到plist文件里.然后在程序中进行读取.在TableView控件中依据不同的类别显示Section. 有关TableView 的其它实现,请參考<iOS项目开发实战--学会使用TableView列表控件(一)><iOS项目开发实战--学会使用TableView列表控件(二)><iOS项目开发实战--学会使用TableView列表控件(三)了解Section>. (1)新建一个Property List文件,这个也就是plist文件.我取名为dat

iOS项目开发实战——storyboard设置界面技巧与注意事项

在iOS开发中,使用Main.storyboard来设计界面是每一个iOS开发人员需要面对的问题,使用storyboard相比较Android中使用XML来设置布局,有优点也有缺陷,现在我们来谈谈storyboard的设计技巧. (1)直接使用鼠标右键可以直接缩放storyboard的缩放比例.当然你也可以用触摸板使用2根手指缩放. . (2)拖拽控件绑定到代码中,不一定要从设计界面的控件中进行拖拽,也可以直接从左侧的列表中拖拽,这样会更加清晰方便. . (3)如何添加修改超过一屏的控件.我们把

iOS项目开发实战——设置视图的透明度改变动画

在iOS中 ,透明度的改变可以让View视图以一种渐变的效果动态的出现或者消退,非常有意思.这里我们将会对一个View控件的色块执行透明度改变的动画.关于其他的动画效果可以参考我的其他几篇博客<iOS项目开发实战--制作视图的平移动画以及解决移动异常问题>,<iOS项目开发实战--多个视图的平移动画与闭包函数的声明与调用>. (1)在Main.storyboard中拖入一个View,并且绑定到代码中. (2)实现代码如下: import UIKit class OpacityVie

iOS项目开发实战——配置自定义动画

动画很多的属性,如位置,透明度等,开发者可以根据这些属性来自定义自己需要的动画.现在我们来简单实现如何自定义动画,以视图的透明度的变化为例.其他的动画效果可以参考我的其他两篇博客<iOS项目开发实战--视图动画效果><iOS项目开发实战--实现视图切换动画>. (1)同样也在Images.xcassets中拖入一张图片,然后在 Main.storyboard中使用一个ImageView控件来包含这张图片.并且绑定控件到代码中. (2)然后在ViewController中实现代码如下

iOS动画开发之二——UIView动画执行的另一种方式

iOS动画开发之二--UIView动画执行的另一种方式 上一篇博客中介绍了UIView的一些常用动画,通过block块,我们可以很方便简洁的创建出动画效果:http://my.oschina.net/u/2340880/blog/484457,这篇博客再介绍一种更加传统的执行UIView的动画的方法. 这种方式相比如block的方式,显得要麻烦一些,apple官方也推荐我们使用带block的创建动画的方式,我们可以将编程重心更多的放在动画逻辑的实现上.使用begin和commit方式主要分为三个

聚合数据 iOS 项目开发实战:条码查询器

记录下,聚合数据 iOS 项目开发实战:条码查询器:视频地址:http://www.jikexueyuan.com/course/324.html 条码查询API:https://www.juhe.cn/docs/api/id/52 核心内容: 1.条码查询器结构分析.2.如何将聚合数据 SDK 添加到工程中.3.模型以及业务类的封装.4.控制器间的数据传递.5.tableView 以及 webView 的使用. 具体课时 1.条码查询器界面搭建 12:53 本课时通过分析条码查询的UI结构和业