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

Cách ping kiểm tra host bên ngoài trong iOS bằng Swift

Đô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"

Cách ping kiểm tra host bên ngoài trong iOS bằng Swift

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)