Xây Dựng Thư Viện HTTP Request đơn Giản Sử Dụng UrlSession - Viblo
Có thể bạn quan tâm
Phần lớn các ưng dụng iOS hiện nay đều cần giao tiếp Server-Client thông qua giao thức HTTP, nhằm mục đích giao tiếp với một JSON API.
Trong bài viết này sẽ từng bước xây dựng một thư viện HTTP request đơn giản sử dụng URLSession, protocol Codable và Protocol oriented programming.
Luồng hoạt động của một request
Theo mô hình trên, khi thực hiện một HTTP request, thông tin trao đổi giữa ứng dụng và server có thể chia thành hai loại:
- Request: Cung cấp các thông tin cần thiết để có thể gửi yêu cầu tới server
- Response: Kết quả trả về từ server sau khi gửi request.
Để gửi một Request tới server ta cần cung cấp các thông tin sau:
- Địa chỉ URL của API cần gửi
- Phương thức HTTP sẽ sử dụng (get, post, put, patch, delete..,)
- Dữ liệu sẽ gửi đi
- Request header
Ta sẽ định nghĩa thông tin này thông qua cấu trúc RequestData
public struct RequestData { public let path: String public let method: HTTPMethod public let params: [String: Any?]? public let headers: [String: String]? public init ( path: String, method: HTTPMethod = .get, params: [String: Any?]? = nil, headers: [String: String]? = nil ) { self.path = path self.method = method self.params = params self.headers = headers } } Xây dựng ResponseResponse là kết quả trả về backend API (thường dưới định dạng JSON), nên ta cần phải định nghĩa cấu trúc dữ liệu ta sẽ nhận được là gì. Để dễ dàng chuyển đổi qua lại giữa JSON object và struct dữ liệu nhận được ta sẽ sử dụng protocol Codable
struct ResponseType: Codable { let dataField1: Int let dataField2: String } Kết hợp Request và ResposneNhư đã giải thích ở trên Response là kết quả trả về của Request sau khi được sử lý. Ta sử dụng Protocol oriented programming để thể hiện mối quan hệ này. Ta sẽ tạo một protocol RequestType để kết nối Request và Response
public protocol RequestType { associatedtype ResponseType: Codable var data: RequestData { get } } Xây dựng DispatcherGiao thức RequestType (ở trên) kết nối giữa dữ liệu request và dữ liệu response. Ta cần xây dựng một protocol cho phép người dùng sử dụng request data là dữ liệu đầu vào và response data là dữ liệu đầu ra của kết quả request.
public protocol NetworkDispatcher { func dispatch(request: RequestData, onSuccess: @escaping (Data) -> Void, onError: @escaping (Error) -> Void) }Protocol trên có thể thực thi một cách đơn giản thông qua thư viện UrlSession.
public enum ConnError: Swift.Error { case invalidURL case noData } public struct URLSessionNetworkDispatcher: NetworkDispatcher { public static let instance = URLSessionNetworkDispatcher() private init() {} public func dispatch(request: RequestData, onSuccess: @escaping (Data) -> Void, onError: @escaping (Error) -> Void) { guard let url = URL(string: request.path) else { onError(ConnError.invalidURL) return } var urlRequest = URLRequest(url: url) urlRequest.httpMethod = request.method.rawValue do { if let params = request.params { urlRequest.httpBody = try JSONSerialization.data(withJSONObject: params, options: []) } } catch let error { onError(error) return } URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in if let error = error { onError(error) return } guard let _data = data else { onError(ConnError.noData) return } onSuccess(_data) }.resume() } }Ta sẽ cần phải thực thi protocol RequestType để thực hiện một request, và gọi các phương thức của protocol NetworkDispatcher để trả về kết quả của request.
public extension RequestType { public func execute ( dispatcher: NetworkDispatcher = URLSessionNetworkDispatcher.instance, onSuccess: @escaping (ResponseType) -> Void, onError: @escaping (Error) -> Void ) { dispatcher.dispatch( request: self.data, onSuccess: { (responseData: Data) in do { let jsonDecoder = JSONDecoder() let result = try jsonDecoder.decode(ResponseType.self, from: responseData) DispatchQueue.main.async { onSuccess(result) } } catch let error { DispatchQueue.main.async { onError(error) } } }, onError: { (error: Error) in DispatchQueue.main.async { onError(error) } } ) } } Ví dụTrong bài viết này, ta có một Web API tại địa chỉ htt://127.0.0.1:3000/test trả về dữ liệu có dạng
[{ "dataField1": "1", "dataField2": "1", }, { "dataField1": "2", "dataField2": "2", }, { "dataField1": "3", "dataField2": "3", }]Để dụng API ở trên ta cần thực hiện các bước sau:
- Bước 1: Định nghĩa struct/class sử dụng protocol Codablestruct SampleData: Codable { let dataField1: String let dataField2: String }
- Bước 2: Định nghĩa struct/class/enum sử dụng protocol RequestType
- Bước 3: Gọi hàm execute để thực thi
- Nguồn tham khảo: https://medium.com/ios-os-x-development/minimal-networking-layer-from-scratch-in-swift-4-a151af786dc5
- Mã nguồn
Từ khóa » Thư Viện Http
-
Unirest – Thư Viện Http Request Gọn Nhẹ Dành Cho Nhiều Ngôn Ngữ
-
THƯ VIỆN PHÁP LUẬT _ Tra Cứu, Nắm Bắt Pháp Luật Việt Nam
-
THƯ VIỆN QUỐC GIA VIỆT NAM
-
Trung Tâm Thông Tin Thư Viện - Đại Học Thương Mại
-
Thư Viện HTTP Client Dựa Trên Promise Dành Cho Trình Duyệt Và ...
-
Thư Viện Java Tốt Nhất để Sử Dụng Cho HTTP POST, GET, V.v. Là Gì ...
-
Python: Thư Viện Requests Của Python | V1Study
-
Python An Ninh Mạng - Bài 2: Thư Viện Requests - AnonyViet
-
Hỏi Về Http Request Và Cách Thêm Thư Viện Curl Vào Project
-
Request Cơ Bản Trong Python - Làm Việc Thông Thái
-
Địa Chỉ Website Các Thư Viện
-
Thư Viện - Trường Đại Học Mở Hà Nội