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

Cách tạo HTTP POST request trong iOS bằng Swift (URLSession)

Để thực hiện HTTP request trong iOS, chúng ta sử dụng URLSession với dataTask. Bài viết này hướng dẫn tạo POST request hoàn chỉnh với JSON.

Các bước tạo POST Request

1. Tạo URLSessionConfiguration và Session

let configuration = URLSessionConfiguration.default
let session = URLSession(configuration: configuration)

2. Tạo URLRequest với method POST

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

var request = URLRequest(url: url)
request.httpMethod = "POST"
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")

// Body JSON
let parameters = ["name": "John", "email": "john@example.com"]
request.httpBody = try? JSONSerialization.data(withJSONObject: parameters)

3. Thực hiện dataTask và xử lý response

let dataTask = session.dataTask(with: request) { data, response, error in
    // 1. Kiểm tra lỗi network
    if let error = error {
        print("Network error: \(error.localizedDescription)")
        return
    }
    
    // 2. Kiểm tra HTTP response
    guard let httpResponse = response as? HTTPURLResponse,
          let receivedData = data else {
        print("Invalid HTTP response")
        return
    }
    
    // 3. Xử lý status code
    switch httpResponse.statusCode {
    case 200...299:
        print("Success: \(httpResponse.statusCode)")
        // Parse JSON response
        if let json = try? JSONSerialization.jsonObject(with: receivedData) {
            print("Response: \(json)")
        }
    case 400...499:
        print("Client error: \(httpResponse.statusCode)")
    case 500...599:
        print("Server error: \(httpResponse.statusCode)")
    default:
        print("Unexpected status: \(httpResponse.statusCode)")
    }
}

dataTask.resume() // Quan trọng: phải gọi resume() để bắt đầu task

Hàm hoàn chỉnh tái sử dụng

func postRequest(to urlString: String, 
                 parameters: [String: Any],
                 completion: @escaping (Result<[String: Any], Error>) -> Void) {
    
    guard let url = URL(string: urlString) else {
        completion(.failure(NSError(domain: "Invalid URL", code: -1)))
        return
    }
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    request.httpBody = try? JSONSerialization.data(withJSONObject: parameters)
    
    URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            completion(.failure(error))
            return
        }
        
        guard let httpResponse = response as? HTTPURLResponse,
              let data = data else {
            completion(.failure(NSError(domain: "Invalid response", code: -2)))
            return
        }
        
        switch httpResponse.statusCode {
        case 200...299:
            if let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
                completion(.success(json ?? [:]))
            } else {
                completion(.failure(NSError(domain: "Parse error", code: -3)))
            }
        default:
            let errorMsg = String(data: data, encoding: .utf8) ?? "Unknown error"
            completion(.failure(NSError(domain: errorMsg, code: httpResponse.statusCode)))
        }
    }.resume()
}

// Sử dụng
postRequest(to: "https://api.example.com/users", 
            parameters: ["name": "John", "age": 30]) { result in
    switch result {
    case .success(let json):
        print("Thành công: \(json)")
    case .failure(let error):
        print("Lỗi: \(error.localizedDescription)")
    }
}

Lưu ý quan trọng

  • App Transport Security (ATS): Mặc định yêu cầu HTTPS. Cần cấu hình Info.plist nếu gọi HTTP
  • Timeout: Cấu hình configuration.timeoutIntervalForRequest = 30
  • Background session: Dùng URLSessionConfiguration.background cho upload/download lớn
  • Codable: Nên dùng JSONEncoder/Decoder với struct conform Codable thay vì JSONSerialization
  • Authentication: Thêm header Authorization: request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")

Info.plist cho HTTP (nếu cần)

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

Lưu ý: Ví dụ này không có output thực tế vì cần API server thật để test.