从这篇文章开始将会对iOS中的网络部分进行重新的认识,其中大部分为基础知识,将常见的和不常见的全部列举出来,供以后复习使用。

URL

在www上,每一信息资源都有统一的且在网上唯一的地址,该地址就叫URL(Uniform Resource Locator,统一资源定位符),它是www的统一资源定位标志,就是指网络地址。

URL的编码

URL 采用 ASCII 编码格式,所以不支持如中文等非 ASCII 码字符,另外 URL 中保留的分隔符号(?、&、=等)也无法作为内容,否则会引起歧义。这就需要通过编码,用安全的字符来表示这些不符合要求的字符,格式是%加两位安全字符,所以 URL 编码也称为百分号编码。在 iOS 中的相关操作分别为:

Encode

NSString *encodedString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

@interface NSCharacterSet (NSURLUtilities)
+ (NSCharacterSet *)URLUserAllowedCharacterSet;  //"#%<>[\]^`{|}
+ (NSCharacterSet *)URLPasswordAllowedCharacterSet;  //"#%/<>?@\^`{|}
+ (NSCharacterSet *)URLHostAllowedCharacterSet;  //"#%/:<>?@[\]^`{|}
+ (NSCharacterSet *)URLPathAllowedCharacterSet; //"#%;<>?[\]^`{|}
+ (NSCharacterSet *)URLQueryAllowedCharacterSet;  //"#%<>[\]^`{|}
+ (NSCharacterSet *)URLFragmentAllowedCharacterSet;  //"#%/:<>?@[\]^`
@end

Decode

+ (NSString *)decodeURLString:(NSString *)URLString {
    // 有时从服务端获取的 URL 中,空格被编码为+, 
    // 而方法- stringByRemovingPercentEncoding只替换百分号编码,
    // 所以要在执行该方法前,先将`+`替换掉(真正的加号字符是被百分号编码的)
    NSString *result = [URLString stringByReplacingOccurrencesOfString:@"+" withString:@" "];
    result = [result stringByRemovingPercentEncoding];

    return result;
}

注意

在编码的时候同样会将“+”替换为“ ”,为了保证特殊字符不被替换我们需要自定义字符集:

+ (NSString *)urlEncodeForStr:(NSString *)str {
    NSString *charactersToEscape = @"?!@#$^&%*+,:;='\"`<>()[]{}/\\| ";
    NSCharacterSet *allowedCharacters = [[NSCharacterSet characterSetWithCharactersInString:charactersToEscape] invertedSet];
    return [str stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
}

URL的组成

URL的一般语法格式为(带方括号[]的为可选项):
protocol://hostname[:port]/path/[;parameters][?query]#fragment
完整的、带有授权部分的普通统一资源标志符语法格式为:
协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值#标志

URL的格式说明

  1. 协议(protocol):指定使用的传输协议,下表列出 protocol 属性的有效方案名称。 最常用的是 HTTP协议,它也是目前www中应用最广的协议。
    • http 通过 HTTP 访问该资源。 格式 http://
    • https 通过安全的 HTTPS 访问该资源。 格式 https://
    • file 资源是本地计算机上的文件。 格式 file:///(注意后边应是三个斜杠)
    • ftp 通过 FTP 访问该资源。 格式 ftp://
    • mailto 资源为电子邮件地址,通过 SMTP 访问。 格式 mailto:
    • MMS 通过支持 MMS(流媒体)协议的播放该资源。(代表软件:Windows Media Player) 格式 MMS://
    • ed2k 通过支持 ed2k(专用下载链接)协议的 P2P 软件访问该资源。(代表软件:电驴) 格式 ed2k://
    • 等;
  2. 主机名(hostname):是指存放资源的服务器的域名系统(DNS) 主机名或 IP 地址。有时,在主机名前也可以包含连接到服务器所需的用户名和密码(格式:username:password@hostname)。
  3. 端口号(port):整数,可选,省略时使用方案的默认端口,各种传输协议都有默认的端口号,如http的默认端口为80。如果输入时省略,则使用默认端口号。有时候出于安全或其他考虑,可以在服务器上对端口进行重定义,即采用非标准端口号,此时,URL中就不能省略端口号这一项。
  4. 路径(path):由零或多个“/”符号隔开的字符串,一般用来表示主机上的一个目录或文件地址。
  5. 参数:这是用于指定特殊参数的可选项。
  6. 查询:可选,用于给动态网页(如使用CGI、ISAPI、PHP/JSP/ASP/ASP.NET等技术制作的网页)传递参数,可有多个参数,用“&”符号隔开,每个参数的名和值用“=”符号隔开。
  7. 信息片断:字符串,用于指定网络资源中的片断。例如一个网页中有多个名词解释,可使用fragment直接定位到某一名词解释。

而在 Objective-C 中,这些组成部分可以用系统提供的方法可以很方便的获取到,而不用麻烦的处理一堆字符串,下面给大家举个栗子🌰。

    NSString *urlStr = @"https://www.testurl.com:8080/path/subpath;parms=test_parms?uid=123&gid=45#fragment=009&fragment";
    NSURL    *URL = [NSURL URLWithString:urlStr];
    NSString *absoluteString = URL.absoluteString;
    NSString *baseURL = URL.baseURL.absoluteString;
    NSString *scheme = URL.scheme;
    NSString *host = URL.host;
    NSString *path = URL.path;
    NSArray  *pathComponents = URL.pathComponents;
    NSString *lastPathComponent = URL.lastPathComponent;
    NSString *pathExtension = URL.pathExtension;
    NSString *query = URL.query;
    NSString *fragment = URL.fragment;
    NSString *parameterString = URL.parameterString;
    NSString *relativePath = URL.relativePath;
    NSString *port = [URL.port stringValue];
    NSString *user = URL.user;
    NSString *password = URL.password;
// absoluteString = https://www.testurl.com:8080/path/subpath;parms=test_parms?uid=123&gid=45#fragment=009&fragment
    NSLog(@"absoluteString = %@", absoluteString);
    // baseURL = (null)
    NSLog(@"baseURL = %@", baseURL);
    // scheme = https
    NSLog(@"scheme = %@", scheme);
    // host = www.testurl.com
    NSLog(@"host = %@", host);
    // port = 8080
    NSLog(@"port = %@", port);
    // path = /path/subpath
    NSLog(@"path = %@", path);
    // pathComponents = ("/", path, subpath)
    NSLog(@"pathComponents = %@", pathComponents);
    // lastPathComponent = subpath
    NSLog(@"lastPathComponent = %@", lastPathComponent);
    // pathExtension = @""  //<object returned empty description>
    NSLog(@"pathExtension = %@", pathExtension);
    // query = uid=123&gid=45
    NSLog(@"query = %@", query);
    // fragment = fragment=009&fragment
    NSLog(@"fragment = %@", fragment);
    // relativePath = /path/subpath (The same as path if baseURL is nil)
    NSLog(@"relativePath = %@", relativePath);
    // parameterString = parms=test_parms
    NSLog(@"parameterString = %@", parameterString);
    // user = (null)
    NSLog(@"user = %@", user);
    // password = (null)
    NSLog(@"password = %@", password);

NSURL

一个 NSURL 对象代表了一个表示远程服务器资源或者本地文件的 URL。所以在 iOS 的网络请求和操作文件系统的 API 中,很多都需要 NSURL 类型的参数。

创建 NSURL 对象

1.传入的字符串类型的 URL 参数要求是经过编码后的,如果该参数不符合规范或者传入了 nil,那么上述方法会返回 nil。

+ URLWithString:
- initWithString:

2.除了字符串类型的 URL 参数,还需要一个 NSURL 类型的 Base URL 参数,字符串类型的 URL 将作为 Base URL 的相对路径。同样字符串类型的 URL 参数要求是经过编码后的,如果不符合规范或者传入了 nil,那么也会返回 nil。

+ URLWithString:relativeToURL:
- initWithString:relativeToURL:

3.创建一个 file URL (协议为file:///),参数 Path 需要传入一个系统路径,如果路径中包含~,那么需要先调用 NSString 的stringByExpandingTildeInPath方法解析~,如果传入的路径是相对路径,那么生成的 URL 将相对于当前路径。当没有 isDirectory 参数时,如果路径以/结束,则认为路径是一个目录,若不是以/结束,则系统会先检查路径是否存在,若路径存在且是一个目录,则系统会在路径后添加/,若路径不存在,系统则认为路径代表一个文件。而 isDirectory 参数则明确指明路径是否代表一个目录。

+ fileURLWithPath:
- initFileURLWithPath:
+ fileURLWithPath:isDirectory:
- initFileURLWithPath:isDirectory:

NSURL拼接

- URLByAppendingPathComponent:  //返回一个新的 file path URL,这个 URL 在原 URL 对象后添加了传入的一段路径参数。该方法会自动在原 URL 对象和新的 path 间加入'/',如果 path 参数最后没有以/结尾,那么该方法会同步检测新 URL 对象指向的资源是否存在且是一个目录,如果路径指向网络挂载卷,这将会造成严重的性能损耗。
- URLByAppendingPathComponent:isDirectory: //功能同上一个方法,不过可以通过 isDirectory 参数具体指明新的 file URL 是否为一个目录,从而避免系统的同步检测。
- URLByAppendingPathExtension:  //返回一个添加扩展名的 URL 对象,该方法会自动去掉原 URL 对象最后的/并添加.
- URLByDeletingLastPathComponent  //去掉最后一段 path 的 URL 对象
- URLByDeletingPathExtension  //去掉最后一段文件扩展名的 URL 对象
- URLByResolvingSymlinksInPath  //一个解析了 symbolic link 后的 URL
- URLByStandardizingPath  //一个解析了 symbolic link 后的 URL

file URL 检测

  • fileURL,布尔值,指明 URL 是否使用file:///协议,无论是 file path URL 还是 file reference URL
  • isFileReferenceURL,返回布尔值,说明 URL 对象是否为 file reference URL
  • checkResourceIsReachableAndReturnError:,返回布尔值,说明 file URL 指向的文件资源是否可获取,若返回 NO,通过 error 参数可以获取更多信息

你远道而来这人世间,想必也是因为热爱吧 ||