Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> iOS

Cách truy cập RESTful API từ iOS/iPhone bằng Swift

Để gọi REST API trong Swift, cách native là dùng URLSession với DataTask. REST (Representational State Transfer) định nghĩa các ràng buộc cho web service. Dưới đây là quy trình cơ bản.

Các bước gọi API (GET example)

  1. Tạo URLSessionConfiguration & Session

let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
  1. Tạo URLRequest

let urlString = "https://api.example.com/users"
guard let url = URL(string: urlString) else { return }

var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
// Thêm header auth nếu cần:
// request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
  1. Tạo DataTask & Resume

let task = session.dataTask(with: request) { data, response, error in
    // 1. Kiểm tra error network
    if let error = error {
        print("Network error: \(error)")
        return
    }
    
    // 2. Kiểm tra HTTP response
    guard let httpResponse = response as? HTTPURLResponse else {
        print("Invalid response")
        return
    }
    
    print("Status code: \(httpResponse.statusCode)")
    
    // 3. Xử lý data
    guard let data = data else { return }
    
    do {
        // Parse JSON
        if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
            print("Response JSON: \(json)")
            // Cập nhật UI trên main thread
            DispatchQueue.main.async {
                // self.updateUI(with: json)
            }
        }
    } catch {
        print("JSON parse error: \(error)")
    }
}

task.resume()  // Quan trọng: bắt đầu task

Gói thành hàm tái sử dụng


func callAPI(_ urlString: String, 
                           method: String = "GET",
                           body: Data? = nil,
                           completion: @escaping (Result) -> Void) {
    
    guard let url = URL(string: urlString) else {
        completion(.failure(URLError(.badURL)))
        return
    }
    
    var request = URLRequest(url: url)
    request.httpMethod = method
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.httpBody = body
    
    URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            completion(.failure(error))
            return
        }
        
        guard let httpResponse = response as? HTTPURLResponse,
              (200...299).contains(httpResponse.statusCode),
              let data = data else {
            let status = (response as? HTTPURLResponse)?.statusCode ?? -1
            completion(.failure(NSError(domain: "APIError", code: status, userInfo: nil)))
            return
        }
        
        do {
            let decoded = try JSONDecoder().decode(T.self, from: data)
            completion(.success(decoded))
        } catch {
            completion(.failure(error))
        }
    }.resume()
}

// Sử dụng với Codable model:
struct User: Codable { let id: Int; let name: String; let email: String }

callAPI("https://jsonplaceholder.typicode.com/users/1") { (result: Result) in
    switch result {
    case .success(let user): print("User: \(user.name)")
    case .failure(let err): print("Error: \(err)")
    }
}

Lưu ý quan trọng

  • App Transport Security (ATS): iOS mặc định chặn HTTP không mã hóa. Cần thêm NSAppTransportSecurity trong Info.plist cho HTTP hoặc domain exception.
  • JSONDecoder/Encoder: Dùng Codable protocol cho type-safe parsing thay vì JSONSerialization.
  • Background thread: dataTask chạy trên background, cập nhật UI phải dispatch về main.
  • Thư viện phổ biến: Alamofire (wrapper URLSession), Moya (network abstraction), Apollo (GraphQL).