Đôi khi cần kiểm tra một website/server có đang hoạt động (up) trước khi gửi request xử lý chính. Bài viết hướng dẫn dùng HTTP HEAD request để "ping" nhẹ nhàng, không tải toàn bộ nội dung.
Cách thực hiện với URLSession
Bước 1: Tạo dự án
Xcode → Single View App → Tên: "PingMe".
Bước 2: Hàm kiểm tra kết nối
Mở ViewController.swift, thêm hàm checkIsConnectedToNetwork():
func checkIsConnectedToNetwork() {
let hostUrl = "https://google.com"
guard let url = URL(string: hostUrl) else { return }
var request = URLRequest(url: url)
request.httpMethod = "HEAD" // Chỉ lấy header, không tải body
request.timeoutInterval = 10 // Timeout 10 giây
URLSession(configuration: .default)
.dataTask(with: request) { _, response, error in
// 1. Kiểm tra lỗi network
if let error = error {
print("Lỗi kết nối: \(error.localizedDescription)")
return
}
// 2. Kiểm tra HTTP status code
guard let httpResponse = response as? HTTPURLResponse else {
print("Không phải HTTP response")
return
}
if httpResponse.statusCode == 200 {
print("✅ Host đang hoạt động (UP)")
} else {
print("❌ Host trả về status: \(httpResponse.statusCode)")
}
}
.resume()
}
Bước 3: Gọi trong viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
checkIsConnectedToNetwork()
}
Mã hoàn chỉnh
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
checkIsConnectedToNetwork()
}
func checkIsConnectedToNetwork() {
let hostUrl = "https://google.com"
guard let url = URL(string: hostUrl) else { return }
var request = URLRequest(url: url)
request.httpMethod = "HEAD"
request.timeoutInterval = 10
URLSession(configuration: .default)
.dataTask(with: request) { _, response, error in
if let error = error {
print("Lỗi: \(error.localizedDescription)")
return
}
guard let httpResponse = response as? HTTPURLResponse else {
print("Invalid response")
return
}
if httpResponse.statusCode == 200 {
print("✅ Host is up and running")
} else {
print("❌ Host status: \(httpResponse.statusCode)")
}
}
.resume()
}
}
Kết quả chạy
Console in ra: "✅ Host is up and running"

Mở rộng: Tích hợp vào UI
Thêm button trên màn hình, khi tap mới ping và hiển thị kết quả lên label:
@IBOutlet weak var statusLabel: UILabel!
@IBAction func pingButtonTapped(_ sender: UIButton) {
statusLabel.text = "Đang kiểm tra..."
checkIsConnectedToNetwork { isUp in
DispatchQueue.main.async {
self.statusLabel.text = isUp ? "🟢 Online" : "🔴 Offline"
}
}
}
// Cập nhật hàm để có completion handler
func checkIsConnectedToNetwork(completion: @escaping (Bool) -> Void) {
// ... code như trên ...
if httpResponse.statusCode == 200 {
completion(true)
} else {
completion(false)
}
}
Lưu ý quan trọng
- HEAD request nhẹ hơn GET (không tải body), phù hợp cho health check
- Một số server chặn HEAD → có thể fallback sang GET với
Range: bytes=0-0 - Khác với ICMP ping (ping lệnh terminal) - iOS không cho phép raw socket ICMP
- Chỉ kiểm tra được HTTP/HTTPS endpoint, không ping IP thuần túy
- Cần xử lý App Transport Security (ATS) cho HTTP non-secure
Thư viện network monitoring hiện đại
iOS 12+: Nên dùng NWPathMonitor (Network framework) để theo dõi trạng thái mạng real-time:
import Network
let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
if path.status == .satisfied {
print("Có kết nối mạng")
} else {
print("Mất kết nối mạng")
}
}
let queue = DispatchQueue(label: "NetworkMonitor")
monitor.start(queue: queue)