iOS学习笔记-----URLSession的使用

1.GET请求

(1)

 //1 构造URL网络地址
    NSURL *url = [NSURL URLWithString:@"http://www.weather.com.cn/data/sk/101010300.html"];

    //2 构造网络请求对象  NSURLRequest
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    //设置请求方式 GET
    request.HTTPMethod = @"GET";
    //设置请求的超时时间
    request.timeoutInterval = 60;
    //请求头
    //[request setValue:<#(nullable NSString *)#> forHTTPHeaderField:<#(nonnull NSString *)#>];
    //请求体
    //request.HTTPBody
    //3 通过配置对象构造网络会话 NSURLSession
    //使用系统默认的会话对象
    NSURLSession *session = [NSURLSession sharedSession];
    //4 创建网络任务 NSURLSessionTask
    //通过网络会话 来创建数据任务
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"网络请求完成");

        //获取响应头
        //将响应对象 转化为NSHTTPURLResponse对象
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
        //获取网络连接的状态码
        //  200 成功  404 网页未找到
        NSLog(@"状态码:%li", httpResponse.statusCode);
        if (httpResponse.statusCode == 200) {
            NSLog(@"请求成功");
        }
        //响应头
        NSLog(@"响应头:%@", httpResponse.allHeaderFields);
        //获取响应体
        //对响应体进行JSON解析
        if (data) {

            NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil][@"weatherinfo"];
//            NSLog(@"响应体数据:%@", dic);
            NSArray *array = dic.allKeys;
            for (NSString *key in array) {
                NSLog(@"%@:%@", key, dic[key]);
            }
        }


    }];
    //5 发起网络任务
    [dataTask resume];

(2)使用configuration配置属性,并用NSURLSessionDataDelegate代理监听数据接收

构建任务:

//构建URL
    NSURL *url = [NSURL URLWithString:@"http://218.76.27.57:8080/chinaschool_rs02/135275/153903/160861/160867/1370744550357.mp3"];
    //构建configuration
    /*
     defaultSessionConfiguration;       默认会话类型,能够进行磁盘缓存
     ephemeralSessionConfiguration;     临时会话类型,不进行任何的磁盘缓存
     backgroundSessionConfigurationWithIdentifier:(NSString *)identifier 后台类型,用于后台下载上传
     */
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];

    //设置配置文件
    //设置缓存策略
    //config.requestCachePolicy = NSURLRequestUseProtocolCachePolicy;
    //设置网络服务类型 决定了网络请求的形式
    config.networkServiceType = NSURLNetworkServiceTypeDefault;
    //设置请求超时时间
    config.timeoutIntervalForRequest = 15;
    //设置请求头
    //config.HTTPAdditionalHeaders
    //网络属性  是否使用移动流量
    config.allowsCellularAccess = YES;

    //创建会话对象
    //delegateQueue 网络请求都是在后台进行,但是当网络请求完成后,可能会需要回到主线程进行刷新界面操作。所以此时可以设置代理回调方法所执行的队列。
    //NSURLSessionDataDelegate -> NSURLSessionTaskDelegate -> NSURLSessionDelegate
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    //创建网络任务
    NSURLSessionDataTask *task = [session dataTaskWithURL:url];
    [task resume];

代理代码:

//已经接受到响应头
- (void)URLSession:(NSURLSession *)session
          dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
 completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {

    //通过状态码来判断石是否成功
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
    if (httpResponse.statusCode == 200) {
        NSLog(@"请求成功");

        NSLog(@"%@", httpResponse.allHeaderFields);

        //初始化接受数据的NSData变量
        _data = [[NSMutableData alloc] init];

        //执行Block回调 来继续接收响应体数据
        //执行completionHandler 用于使网络连接继续接受数据
        /*
         NSURLSessionResponseCancel 取消接受
         NSURLSessionResponseAllow  继续接受
         NSURLSessionResponseBecomeDownload 将当前任务 转化为一个下载任务
         NSURLSessionResponseBecomeStream   将当前任务 转化为流任务
         */
        completionHandler(NSURLSessionResponseAllow);

    } else {
        NSLog(@"请求失败");
    }

}

//接受到数据包时调用的代理方法
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
//    NSLog(@"收到了一个数据包");

    //拼接完整数据
    [_data appendData:data];
    NSLog(@"接受到了%li字节的数据", data.length);
}

//数据接收完毕时调用的代理方法
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"数据接收完成");

    if (error) {
        NSLog(@"数据接收出错!");
        //清空出错的数据
        _data = nil;
    } else {
        //数据传输成功无误,JSON解析数据
//        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:_data options:NSJSONReadingMutableLeaves error:nil];
//        NSLog(@"%@", dic);
    }
}

2.POST请求

 //构建URL
    NSURL *url = [NSURL URLWithString:@"http://piao.163.com/m/cinema/schedule.html?app_id=1&mobileType=iPhone&ver=2.6&channel=appstore&deviceId=9E89CB6D-A62F-438C-8010-19278D46A8A6&apiVer=6&city=110000"];

    //创建请求对象
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    //设置请求方式
    request.HTTPMethod = @"POST";
    //超时时间
    request.timeoutInterval = 60;
    //设置请求体
    NSString *bodyString = @"cinema_id=1533";
    //将字符串 转化为NSData
    request.HTTPBody = [bodyString dataUsingEncoding:NSUTF8StringEncoding];

    //创建会话
    NSURLSession *session = [NSURLSession sharedSession];

    //创建任务
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

        //JSON解析
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
        NSLog(@"%@", dic);
    }];

    [dataTask resume];

3.下载任务


#define kResumeDataPath [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/resumeData.plist"]


@interface ViewController () <NSURLSessionDownloadDelegate>
{
    NSURLSession *_session;
    NSURLSessionDownloadTask *_downLoadTask;

}

@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (weak, nonatomic) IBOutlet UILabel *progressLabel;

@end

@implementation ViewController


#pragma mark - NSURLSessionDownloadDelegate


//下载完成 必须实现的方法
/**
 *  文件下载完成
 *
 *  @param session      网络会话
 *  @param downloadTask 下载任务
 *  @param location     下载完成的文件,在本地磁盘中的位置  临时文件
 */
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    NSLog(@"下载完成");


    //将临时文件,移动到沙盒路径中
    //拼接文件的目标路径
    NSString *targetPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/菊花台.mp3"];
    //移动文件
    NSFileManager *manager = [NSFileManager defaultManager];
    [manager moveItemAtURL:location toURL:[NSURL fileURLWithPath:targetPath] error:nil];

    NSLog(@"%@", targetPath);

}

//下载过程中调用的方法

/**
 *  接受到一部分数据后 调用的方法
 *
 *  @param session                   网络会话对象
 *  @param downloadTask              下载任务对象
 *  @param bytesWritten              当前数据包写入的数据字节数
 *  @param totalBytesWritten         当前总共写入的数据字节数
 *  @param totalBytesExpectedToWrite 完整的文章总大小字节数
 */
- (void)URLSession:(NSURLSession *)session
      downloadTask:(NSURLSessionDownloadTask *)downloadTask
      didWriteData:(int64_t)bytesWritten
 totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {

//    NSLog(@"获取到一个数据包:%lli", bytesWritten);
//    NSLog(@"已经写入的数据包大小:%lli", totalBytesWritten);
//    NSLog(@"总文件大小:%lli", totalBytesExpectedToWrite);

    //计算当前任务进度
    CGFloat progress = (CGFloat)totalBytesWritten / totalBytesExpectedToWrite;

    //更新界面数据
    _progressView.progress = progress;
    _progressLabel.text = [NSString stringWithFormat:@"%.2f%%", progress * 100];


}

#pragma mark -

- (void)viewDidLoad {
    [super viewDidLoad];

    //初始化网络会话
    //Configuration
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    _session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];

}

- (IBAction)startDownLoad:(id)sender {

    //构建URL
    NSURL *url = [NSURL URLWithString:@"http://218.76.27.57:8080/chinaschool_rs02/135275/153903/160861/160867/1370744550357.mp3"];

    //创建下载任务
    _downLoadTask = [_session downloadTaskWithURL:url];
    //开始下载
    [_downLoadTask resume];

}

//暂停下载
- (IBAction)pauseDownLoad:(id)sender {

    //判断当前的下载状态
    if (_downLoadTask && _downLoadTask.state == NSURLSessionTaskStateRunning) {


        //取消当前任务,将任务的信息保存的文件中
        [_downLoadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {

            //将数据写入到文件,方便下次读取
            //下载链接,已下载的数据大小,已下载的临时文件文件名
            [resumeData writeToFile:kResumeDataPath atomically:YES];
            NSLog(@"%@", kResumeDataPath);
        }];

        _downLoadTask = nil;
    }
}

//继续下载
- (IBAction)resumeDownLoad:(id)sender {

    //获取已经保存的数据
    NSData *data = [NSData dataWithContentsOfFile:kResumeDataPath];
    if (data) {
        //重建下载任务 继续下载
        _downLoadTask = [_session downloadTaskWithResumeData:data];

        //继续任务
        [_downLoadTask resume];
        //移除文件
        [[NSFileManager defaultManager] removeItemAtPath:kResumeDataPath error:nil];
    }

}

4.上传任务,multipart/form-data POST文件上传

#define kBoundary @"ABC"



@interface ViewController ()

@end

@implementation ViewController



/*

 multipart/form-data 上传数据时 所需要的数据格式

 HTTP请求头:
 ....
 multipart/form-data; charset=utf-8;boundary=AaB03x
 ....

 HTTP请求体:
 --AaB03x
 Content-Disposition: form-data; name="key1"

 value1
 --AaB03x
 Content-Disposition: form-data; name="key2"

 value2
 --AaB03x
 Content-Disposition: form-data; name="key3"; filename="file"
 Content-Type: application/octet-stream

 图片数据...
 --AaB03x--

 */


/**
*  包装请求体
*
*  @param token 用户密钥
*  @param text  微博正文
*  @param image 上传的图片
*
*  @return multipart/form-data
*/
- (NSData *)bodyDataWithToken:(NSString *)token
                    text:(NSString *)text
                   image:(UIImage *)image {

    //key1 = @"access_token"    vlaue1 = 2.00hd363CtKpsnBedca9b3f35tBYiPD
    //key2 = @"status"          value2 = text
    //key3 = @"pic"             value3 = image;

    //包装数据到请求体中
    NSMutableString *mString = [[NSMutableString alloc] init];

    //token
    [mString appendFormat:@"--%@\r\n", kBoundary];
    //拼接带有双引号的字符串 需要添加\在双引号之前
    [mString appendFormat:@"Content-Disposition: form-data; name=\"access_token\"\r\n\r\n"];
    //拼接value1
    [mString appendFormat:@"%@\r\n", token];
    [mString appendFormat:@"--%@\r\n", kBoundary];


    //微博正文
    //key2
    [mString appendFormat:@"Content-Disposition: form-data; name=\"status\"\r\n\r\n"];
    //拼接value2
    [mString appendFormat:@"%@\r\n", text];
    [mString appendFormat:@"--%@\r\n", kBoundary];


    //图片
    [mString appendFormat:@"Content-Disposition: form-data; name=\"pic\"; filename=\"file\"\r\n"];
    [mString appendFormat:@"Content-Type: application/octet-stream\r\n\r\n"];

    NSLog(@"%@", mString);
    //将字符串  转化为NSData
    NSMutableData *bodyData = [[mString dataUsingEncoding:NSUTF8StringEncoding] mutableCopy];

    //拼接图片数据
    //将图片转化为数据
    NSData *imageData = UIImageJPEGRepresentation(image, 1);
    [bodyData appendData:imageData];

    //结尾字符串  结束符
    NSString *endString = [NSString stringWithFormat:@"\r\n--%@--\r\n", kBoundary];
    NSData *endData = [endString dataUsingEncoding:NSUTF8StringEncoding];

    [bodyData appendData:endData];

    return [bodyData copy];
}


- (IBAction)uploadImage:(id)sender {

    //构建URL
    NSURL *url = [NSURL URLWithString:@"https://upload.api.weibo.com/2/statuses/upload.json"];
    //构建请求对象
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

    //设置请求对象
    request.URL = url;
    request.HTTPMethod = @"POST";
    //请求头
    //格式: multipart/form-data; charset=utf-8;boundary=AaB03x
    //拼接请求头字符串
    NSString *string = [NSString stringWithFormat:@"multipart/form-data; charset=utf-8; boundary=%@", kBoundary];
    //设置请求头
    [request setValue:string forHTTPHeaderField:@"Content-Type"];

    //图片和文本
    UIImage *ali = [UIImage imageNamed:@"ali.jpg"];
    NSString *text = @"发送微博";
    NSString *token = @"2.00hd363CtKpsnBedca9b3f35tBYiP";
    //创建bodyData
    NSData *bodyData = [self bodyDataWithToken:token text:text image:ali];


    //创建会话
    NSURLSession *session = [NSURLSession sharedSession];
    //创建上传任务
    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:bodyData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

        NSHTTPURLResponse *httpRes = (NSHTTPURLResponse *)response;
        NSLog(@"状态码:%li", httpRes.statusCode);
        if (error) {
            NSLog(@"上传出错");
        } else {
            NSLog(@"上传成功");
        }
    }];

    //开始任务
    [uploadTask resume];

}

你可能感兴趣的:(iOS学习笔记)