程序的实现需要借助几个对象:
NSURLRequest:建立了一个请求,可以指定缓存策略、超时时间。和NSURLRequest对应的还有一个NSMutableURLRequest,如果请求定义为NSMutableURLRequest则可以指定请求方法(GET或POST)等信息。
NSURLConnection:用于发送请求,可以指定请求和代理。当前调用NSURLConnection的start方法后开始发送异步请求。
当然了这种方法比较原始。。。
//
// ViewController.m
// xiazai
//
// Copyright © 2016年 asamu. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()<NSURLConnectionDataDelegate>
{
NSMutableData *_data;//响应数据
UITextField *_textField;
UIButton *_button;
UIProgressView *_progressView;
UILabel *_label;
long long _totalLength;
NSDictionary *_musicDic;
}
@end
@implementation ViewController
#pragma mark -- UI方法
- (void)viewDidLoad {
[super viewDidLoad];
[self analysisJson];
[self layoutUI];
}
#pragma mark -- 私有方法
#pragma mark 解析 JSON
-(void)analysisJson{
NSError *error;
NSString *str = @"http://douban.fm/j/mine/playlist?channel=3";
NSURL *url = [NSURL URLWithString:str];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSDictionary *musicDic = [[NSDictionary alloc]init];
//遍历字典 取出 key - @"song"
for (musicDic in dic[@"song"]) {
_musicDic = musicDic;
}
}
#pragma mark 界面布局
-(void)layoutUI{
//地址栏
_textField = [[UITextField alloc]initWithFrame:CGRectMake(10, 50, 300, 25)];
//加圆角和边框
_textField.layer.cornerRadius = 3.0f;
_textField.layer.borderWidth = 0.5f;
_textField.textColor = [UIColor redColor];
/*
解析的 JOSN 中的 歌曲名加上 .mp3 的后缀
这个名字就是存储在沙盒中的名字,所以要加 .mp3
由于名称不一样,所以不会覆盖
*/
NSString *musicName = [_musicDic[@"title"] stringByAppendingString:@".mp3"];
_textField.text = musicName;
[_textField sizeToFit];
[self.view addSubview:_textField];
//进度条
_progressView = [[UIProgressView alloc]initWithFrame:CGRectMake(10, 100, 300, 25)];
[self.view addSubview:_progressView];
//状态显示
_label = [[UILabel alloc]initWithFrame:CGRectMake(10, 130, 300, 25)];
_label.textColor = [UIColor colorWithRed:0 green:146/255.0 blue:1.0 alpha:1.0];
[self.view addSubview:_label];
//下载按钮
_button = [[UIButton alloc]initWithFrame:CGRectMake(10, 500, 300, 25)];
[_button setTitle:@"下载" forState:UIControlStateNormal];
[_button setTitleColor:[UIColor colorWithRed:0 green:146/255.0 blue:1.0 alpha:1.0] forState:UIControlStateNormal];
[_button addTarget:self action:@selector(sendRequest) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_button];
}
#pragma mark -- 更新进度
-(void)updateProgress{
if (_data.length == _totalLength) {
_label.text = @"Finish downloaded";
}else{
_label.text = @"downing...";
[_progressView setProgress:(float)_data.length/_totalLength];
}
}
#pragma mark -- 发送请求
-(void)sendRequest{
NSLog(@"begin");
NSString *urlStr = [NSString stringWithFormat:_musicDic[@"url"],_textField.text];
//解码
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// 创建 URL 链接
NSURL *url = [NSURL URLWithString:urlStr];
//创建请求
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0f];
//创建连接
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
//启动连接
[connection start];
}
#pragma mark -- 连接代理方法
#pragma mark 开始响应
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(@"receive response");
_data = [[NSMutableData alloc]init];
_progressView.progress = 0;
//通过响应头中的 Content-Length 取得整个响应的长度
NSHTTPURLResponse *httpRespose = (NSHTTPURLResponse *)response;
NSDictionary *httpResponseHeaderFields = [httpRespose allHeaderFields];
_totalLength = [[httpResponseHeaderFields objectForKey:@"Content-Length"]longLongValue];
}
#pragma mark 接收响应数据,(根据响应内容的大小此方法会被重复调用)
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(@"Receive data");
//连续接收数据
[_data appendData:data];
//更新进度
[self updateProgress];
}
#pragma mark 接收数据完成
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(@"loading finish");
//数据接收完保存文集(注意苹果官方要求:下载数据只能保存在缓存目录)
NSString *savePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
savePath = [savePath stringByAppendingPathComponent:_textField.text];
[_data writeToFile:savePath atomically:YES];
NSLog(@"path:%@",savePath);
}
#pragma mark 请求失败
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"connection error,error detail is:%@",error.localizedDescription);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
随笔 10()部分,都来自 KenshinCui,后系列就不一一列出,估计大神的 url 没用了,所以我换了个音乐的 url,可以用。初学者,若有错误,敬请指出,不甚感激。