官术网_书友最值得收藏!

Parsing responses with Decodable

A Decodable object is an object that can be transformed from Data to a pure Swift object or struct, through Decoder. This section will not provide a full coverage of codables, but rather, a quick example that shows how you can leverage this when communicating with a server in a generic way.

Let's re-work the previous example a bit and improve the code; instead of returning data, we want to return a pure Swift object:

func get<T>(url: URL, callback: @escaping (T?, Error?) -> Void) -> URLSessionTask where T: Decodable {
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
callback(nil, error)
return
}
// Very simple handling of errors, you may wanna
// have a more in depth implementation
if let data = data {
do {
let result = try JSONDecoder().decode(T.self, from: data)
callback(result, nil)
} catch let error {
callback(nil, error)
}
} else {
callback(nil, nil)
}
}
task.resume()
return task
}

The preceding get method will fetch the contents of a URL, and then try to parse the received data into the expected type. You can use it the following way:

struct MyResult: Decodable {
/*
you can put anything decodable here
the compiler will generate the decodable implementation
*/
}

func handle(result: MyResult) {
print(result)
}

func handle(handle: Error) {
print(handle)
}

_ = get(url: URL(string: "http://example.com")!) { (result: MyResult?, error) in
switch (result, error) {
case (.some(let result), _):
handle(result: result)
case (_, .some(let error)):
handle(handle: error)
default: // both are nil :/
break;

}
}

In the preceding example, we'll get the contents of http://example.com, and the get<T> function will automatically try to map the contents of the response body into the expected MyResult. This gives you a compile time guarantee that only valid response bodies will be processed further down your application, which is very interesting when building robust clients.

Now that we have implemented a simple get method and a parser, let's look at how we can tie the loop with another method.

主站蜘蛛池模板: 遂昌县| 隆昌县| 同江市| 巴林右旗| 广河县| 巴彦县| 丽水市| 明溪县| 巴林左旗| 江华| 留坝县| 台北市| 东光县| 延寿县| 本溪| 蓬安县| 将乐县| 维西| 高要市| 金堂县| 金乡县| 昌邑市| 沈阳市| 安徽省| 九台市| 都兰县| 洪江市| 当涂县| 上林县| 伊金霍洛旗| 丰原市| 东至县| 桂林市| 新平| 奉新县| 井研县| 莎车县| 大名县| 万山特区| 大石桥市| 庆安县|