网络

基础知识

  1. 两种数据交换格式:XML、JSON(JavaScript Object Notation)
  2. 调试器:

处理 HTTP/HTTPS 请求

NSURLSession

什么是 NSURLSession

  • 本身是一个类,同时也代指一套用于处理 HTTP/HTTPS 请求的类。

关于类 NSURLSession

  • 负责管理发送和接收 HTTP 请求;
  • 通过获取单例或传入 NSURLSessionConfiguration 创建实例;
  • 可以通过 Blockdelegate 接收回调;

主要有以下三种方法创建获取一个 session:

1
2
3
4
5
6
7
8
+ (NSURLSession *)sharedSession;
// 使用全局的 Cache、Cookie、证书,获取一个共享的会话。

+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
// 通过传入一个 NSURLSessioinConfiguration(用于设置相关的参数)配置来创建相关会话。

+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id <NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue;
// 根据 NSURLSessionConfiguration、NSURLSessionDelegate、NSOperationQueue 三个参数创建会话。

NSURLSessionConfiguration

上面创建方法中已经提及了这个类,它有三种类型的配置:

  • default:默认配置,使用全局的 Cache、Cookie、证书;
  • ephemeral:与默认配置类似,所有与会话相关的数据都存储在内存中;
  • background:会话在后台上执行上传下载任务,即使应用程序本身被系统暂定或终止,传输仍然会继续。

NSURLSessionTask

系统为不同的上传下载类型封装了不同的类,其中 NSURLSessionTask 是这些类的基类:

  • NSURLSessionTask:一个抽象基类需要实现三个方法(cancelsuspendresume

下面我们分别介绍这个基类派生出来的几个类:

  • NSURLSessionDataTask

    1
    2
    3
    4
    5
    6
    7
    8
    
    NSString *dataUrl = @"your_data_url";
    NSURL *url = [NSURL URLWithString:dataUrl];
    
    NSURLSessionTask *downloadTask = [[NSURLSession sharedSession] // 创建一个NSURLSession对象
                                      dataTaskWithURL:url // 指定一个NSURL对象
                                      compeletionHandler:^(NSData *data, NSURLResponse *reponse, NSError *error){}]; // 通过Block指定回调方法
    
    [downloadTask resume];
    
  • NSURLSessionDownloadTask:下面是创建一个下载任务的示例代码:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    NSURL *url = [NSURL URLWithString:@"blabla"];
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
    [req setHTTPMethod:@"GET"];
    
    NSURLSession *sharedSession = ;
    NSURLSessionDownloadTask *task = [[NSURLSession sharedSession]
                                     downloadTaskWithRequest:req
                                     completionHandler:^(NSURL *_Nullable location, NSURLResponse *_Nullable response, NSError *_Nullable error){
                                       if(!error && response && location) // 检查是否下载成功
                                         [self handleDownloadFile:location];
                                     }];
    

    另外,下载任务一个常见的需求就是获取下载进度,这个如何实现呢?

    • 使用代理,比如对于 NSURLSessionDownloadTask 可以实现 NSURLDownloadDelegate 协议。
  • NSURLSessionUploadTask:这个方法继承自 NSURLSessionDataTask

JSON 编码解码

在 Objetive-C 中,主要使用 NSJsonSerialization 这个类对进行字符串与 json 之间的转换:

1
2
3
4
5
// JsonData ==> FoundationObjects
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;

// FoundationObjects ==> JsonData
+ (NSData *)dataWithJSONObjects:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;

其中的基类需要满足以下的要求:

  • 顶层对象必须是 NSArrayNSDictionary
  • 所有对象必须是 NSStringNSNumberNSArrayNSDictionary 或者 NULL
  • 所有字典的键值都是字符串类型的;
  • 数值类型变量不能是非数值或者无穷大;

文件操作

Bundle

什么是 bundle?Apple document

  • bundle 是操作系统将可执行代码与相关资源整合起来,存储在文件系统中的一个文件夹;
  • 在 iOS 或 OS X 中,应用、框架或其他软件都是 bundle。
  • Objective-C 中常见的 Foundation 与 Core Foundation 关键词就是用语定位和加载 bundle 资源的。

在 Objetive-C 中,通过下面的方法即可获取一个资源文件的绝对路径:

1
2
NSBundle *main = [NSBundle mainBundle];
NSString *resourcePath = [main pathForResource:@"Seagull" ofType:@"jpg"];

读取文件

iOS 中将文件分为四种文件类型,分别对应着四个不同的目录:

  1. Home 目录:NSHomeDirectory()

  2. Document 目录:用于保存用户生成的数据:

    1
    2
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [paths objectAtIndex:0];
    
  3. Library 目录:除 caches 之外的非用户数据:

    1
    2
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSString *path = [paths objectAtIndex:0];
    
  4. Cache 目录:临时文件,这个文件夹中的文件 App 应该临时清理,存储空间不足时主动清理:

    1
    2
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,  NSUserDomainMask, YES);
    NSString *path = [paths objectAtIndex:0];
    

文件操作

比如我们通过以下的代码得到了一个 FileManager:

1
NSFileManager *fileManager = [NSFileManager defaultManager];

之后我们通过以下的这些方法进行文件相关操作:

  1. 判断文件是否存在:

    1
    
    BOOL fileExists = [fileManager fileExistsAtPath:[fileURL path]];
    
  2. 读取文件信息:

    1
    
    NSDictionary *attr = [fileManager attributesOfItemAtPath:[fileURL path] error:&error];
    
  3. 遍历目录下的所有文件:

    1
    
    [fileManager contentsOfDirectoryAtURL:bundleURL includingPropertesForKeys:@[] options:NSDirectoryEnumerationSkipsHiddenFiles error:nil];
    
  4. 创建目录:

    1
    
    [fileManager createDirectoryAtPath:imagesPath withIntermediateDirectories:NO attribute:nil error:&error];
    
  5. 移动文件:

    1
    
    [[NSFileManager defaultManager] moveItemAtURL:source toURL:destination error:&err];
    
  6. 删除文件/目录:

    1
    
    [fileManager removeItemAtPath:filePath error:&error];