URL Loading System 之 NSURLRequest/URLRequest

NSURLRequest

NSURLRequest /URLRequest 封装了请求的两个基本属性:要加载的URL和用于加载该请求的策略。通常用于 HTTP 和 HTTPS 请求,包括 HTTP 方法(GETPOST等)和 HTTP 标头。可变子类型是 NSMutableURLRequest 。

一个平平无奇的 GET 请求

网络请求的测试,我们访问 httpbin 来进行,方便对比请求的响应

官网:https://httpbin.org/

httpbin 可以把我们请求时的信息,返回给我们

PS: 在swift 中没有细分可变子类型了,let 声明的对象就是不可变,var 声明就是可变,那我们手动添加一个头部信息,看看效果。

url

allHTTPHeaderFields

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let url = URL.init(string: "https://httpbin.org/get")
var request = URLRequest.init(url: url!)
request.setValue("Tiantian", forHTTPHeaderField: "Tommy-Girl")
print(request.allHTTPHeaderFields ?? [:])
//请求怎么发出去呢?我们先使用苹果提供的单例尝试一下
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
//查看 response,我们打印出来可以看到一个 NSHTTPURLResponse 对象,以及部分头部信息
print("Response:")
print(response as Any)

let statusCode = (response as? HTTPURLResponse)?.statusCode ?? -1
if statusCode == 200 {
guard let data = data else { return }
do {
let object = try JSONSerialization.jsonObject(with: data, options: [])
print(object)
} catch let error {
print(error)
}
} else {

}
}
task.resume()

返回结果:

我们刚刚添加了一个 名为 Tommy-Girl 值为 Tiantian 的头部信息,服务器已经收到,并且原封不动帮我们返回了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
GET: 
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-us",
"Host": "httpbin.org",
"Tommy-Girl": "Tiantian",
"User-Agent": "URLLoadingSystem/1 CFNetwork/1220.1 Darwin/19.6.0",
"X-Amzn-Trace-Id": "Root=1-6094ffc6-18f7b8391c8bcc4049bc6beb"
},
"origin": "*.*.*.*",
"url": "https://httpbin.org/get"
}

一个略显英俊的 POST 请求

PS: GET 和 POST 请求的区别,以及各Status Code 的含义见另一篇文章HTTP 的一点儿小知识

如果上面的代码,我们直接把 URL 替换为只允许 POST 请求的服务,我们会收到一个 405 的code 码,405 一般表示请求方法不允许。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Response:
Optional(<NSHTTPURLResponse: 0x6000026150e0> { URL: https://httpbin.org/post }
{ Status Code: 405, Headers {
"Access-Control-Allow-Origin" = (
"*"
);
"Content-Length" = (
178
);
"Content-Type" = (
"text/html"
);
Date = (
"Fri, 07 May 2018 08:22:31 GMT"
);
Server = (
"gunicorn/19.9.0"
);
"access-control-allow-credentials" = (
true
);
allow = (
"POST, OPTIONS"
);
} })

httpMethod

那怎么发送一个 POST 请求呢?很简单,URLRequest 有一个 httpMethod 属性,指定对应的方法名即可

1
request.httpMethod = "POST"

httpBody

一个 NSData/Data 类型的属性,用于添加参数,可以但不限于:

1
2
3
4
let parameter = ["a" : "1",
"b" : "2"]
let data = try? JSONSerialization.data(withJSONObject: parameter, options: [])
request.httpBody = data

timeoutInterval

超时时间

httpShouldHandleCookies

决定这个请求是否要使用cookie,默认为YES。

常用到的就上面这几个属性,真实开发中我们很少会直接使用 Request 发送请求,往往依赖于三方框架,像 OC 的 AFNetworking 、swift 的 Alamofire 等等。

系列:

URL Loading System[译]

NSURLRequest

NSURLResponse