多线程与网络 - 概况

多线程

  • NSThread
  • GCD
    • 队列
      • 并发队列
        • 全局队列
        • 自己创建
      • 串行队列
        • 主队列
        • 自己创建
    • 任务:block
    • 函数
      • sync:同步函数
      • async:异步函数
    • 单例模式
  • NSOperation & NSOperationQueue
  • RunLoop
    • 同一时间只能选择一个模式运行
    • 常用模式
      • Default:默认
      • Tacking:拖拽UIScrollView

网络

HTTP请求

  • GET请求
// url转码:
NSString *urlStr = @"http://可能有中文.com";
// stringByAddingPercentEscapesUsingEncoding方法在iOS9中已被弃用
// urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// 改用:
urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
// URL
NSURL *url = [NSURL URLWithString:urlStr];
    
// 请求
NSURLRequest *request = [NSURLRequest requestWithURL:url];
  • POST请求
// url转码:
NSString *urlStr = @"http://可能有中文.com";
urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

// URL
NSURL *url = [NSURL URLWithString:urlStr];
    
// 请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = [@"username=123&pwd=456" dataUsingEncoding:NSUTF8StringEncoding];

NSURLConnection(iOS9之后已经过期)

NSURLSession

发送一般的GET/POST请求
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            
}];

[task resume];
下载文件 - 不需要离线断点(小文件下载)
NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
}];
    
[task resume];
下载文件 - 需要离线断点(大文件下载)
  • 开启任务
// 创建session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration ] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
    
// 设置请求头(告诉服务器从哪个字节开始下载)
[request setValue:@"bytes=1024-" forHTTPHeaderField:@"Range"];
    
// 创建任务
NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
    
// 开启任务
[task resume];
  • 实现代理方法
// 1.接收到响应
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSHTTPURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    // 打开 NSOutputStream
    // 获得文件的总长度
    // 存储文件的总长度
    // 回调返回的 block(允许接收数据)
    completionHandler(NSURLSessionResponseAllow);
}

// 2.接收到服务器返回的数据(这个方法可能会被调用多次)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    // 利用NSOutputStream写入数据
    // 计算下载进度
}

// 3.请求完毕
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    // 关闭并清空NSOutputStream
    // 清空任务task
}
文件上传
  • 设置请求头
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", JPBoundary] forHTTPHeaderField:@"Content-Type"];
  • 拼接请求体
    • 文件参数
    • 其他参数(非文件参数)
  • 开启任务
//创建session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration ] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];

// NSURLSessionUploadTask继承于NSURLSessionDataTask,所以是遵守NSURLSessionDataDelegate
NSURLSessionUploadTask *task = [self.session uploadTaskWithRequest:request fromData:[self body] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

}];

[task resume];
  • 实现代理方法
//上传数据
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
    // 计算上传进度
    NSLog(@"didSendBodyData %lf", 1.0 * totalBytesSent / totalBytesExpectedToSend);
}

// 请求结束(根据error判断是否成功)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"didCompleteWithError");
}

AFNetworking

  • GET
// AFHTTPSessionManager:专门管理http请求操作(内部包装了NSURLSession)
AFHTTPSessionManager *manger = [AFHTTPSessionManager manager];

NSDictionary *parame = @{@"username": @"123", @"pwd": @"456"};

[manger GET:BaseURL parameters:parame success:^(NSURLSessionDataTask *task, id responseObject) {
    NSLog(@"%@", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    NSLog(@"%@", error);
}];
  • POST
AFHTTPRequestOperationManager *manger = [AFHTTPRequestOperationManager manager];

NSDictionary *parame = @{@"username": @"123", @"pwd": @"456"};

[manger POST:BaseURL parameters:parame success:^(AFHTTPRequestOperation *operation, id responseObject) {
        
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        
}];
  • 文件上传
AFHTTPSessionManager *manger = [AFHTTPSessionManager manager];
    
[manger POST:@"http://120.25.226.186:32812/upload" parameters:nil constructingBodyWithBlock:^(id formData) {
        
    NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"minion_15" ofType:@"png"]];
        
    // 在block中设置需要上传的文件
    // name:请求参数名,服务器给的参数名称接口
    // fileName:上传的文件名
        
    // 方法一(需要自己定义mimeType)
    [formData appendPartWithFileData:data name:@"file" fileName:@"minion_15.png" mimeType:@"image/png"];
        
    // 方法二(根据文件后缀名获取mimeType)
    // [formData appendPartWithFileURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"minion_15" ofType:@"png"]] name:@"file" fileName:@"minion_15.png" mimeType:@"image/png" error:nil];
        
    // 方法三(使用上传文件名当作fileName)
    // [formData appendPartWithFileURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"minion_15" ofType:@"png"]] name:@"file" error:nil];
        
} success:^(NSURLSessionDataTask *task, id responseObject) {
    NSLog(@"%@", responseObject);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    NSLog(@"%@", error);
}];

// 上传进度
[manger setTaskDidSendBodyDataBlock:^(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) {
    NSLog(@"DidSendBodyDataBlock %lf", 1.0 * totalBytesSent / totalBytesExpectedToSend);
}];

UIWebView

UIWebView是iOS内置的浏览器控件,系统自带Safari浏览器就是通过UIWebView实现的
UIWebView不但能加载远程的网页资源,还能加载绝大部分的常见文件
  • html\htm
  • pdf、doc、ppt、txt
  • mp4
  • ...
加载方式
  • 加载本地html文件
[self.webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"]]];
  • 加载网络url
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]];
  • 加载本地文件
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"泡沫.mp4" ofType:nil]]]];
  • 加载data
self.webView loadData:<#(nonnull NSData *)#> MIMEType:<#(nonnull NSString *)#> textEncodingName:<#(nonnull NSString *)#> baseURL:<#(nonnull NSURL *)#>
  • 加载html
[self.webView loadHTMLString:@"
爽爽爽爽爽
" baseURL:nil];

你可能感兴趣的:(多线程与网络 - 概况)