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

Cách tải ảnh từ URL trong iOS bằng Swift (URLSession)

Để tải ảnh từ URL trong iOS, chúng ta dùng URLSession với dataTask để tải ở background, tránh chặn luồng chính (main thread).

Ví dụ cơ bản

Bước 1: Tạo dự án và thêm Image View

Tạo project mới → Thêm UIImageView vào Storyboard → Tạo @IBOutlet tên imgView.

Cách tải ảnh từ URL trong iOS bằng Swift (URLSession)

Bước 2: Code tải ảnh cơ bản

func getData(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
    URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
}

func downloadImage(from url: URL) {
    getData(from: url) { data, response, error in
        guard let data = data, error == nil else { return }
        DispatchQueue.main.async {
            self.imgView.image = UIImage(data: data)
        }
    }
}

Bước 3: Gọi trong viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    let url = URL(string: "https://example.com/image.jpg")!
    downloadImage(from: url)
}

Cách tốt hơn: Extension cho UIImageView

Tạo extension để tái sử dụng dễ dàng:

extension UIImageView {
    func loadImage(from url: URL, placeholder: UIImage? = nil, completion: ((UIImage?) -> Void)? = nil) {
        // Hiển thị placeholder ngay lập tức
        if let placeholder = placeholder {
            self.image = placeholder
        }
        
        URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
            guard let self = self,
                  let data = data,
                  error == nil,
                  let image = UIImage(data: data) else {
                DispatchQueue.main.async {
                    completion?(nil)
                }
                return
            }
            
            DispatchQueue.main.async {
                self.image = image
                completion?(image)
            }
        }.resume()
    }
}

Sử dụng extension

override func viewDidLoad() {
    super.viewDidLoad()
    let url = URL(string: "https://static.independent.co.uk/s3fs-public/thumbnails/image/2017/09/12/11/naturo-monkey-selfie.jpg?w968h681")!
    imgView.loadImage(from: url, placeholder: UIImage(named: "placeholder")) { image in
        if image != nil {
            print("Tải ảnh thành công")
        }
    }
}

Cách tải ảnh từ URL trong iOS bằng Swift (URLSession)

Thư viện bên thứ 3 khuyến nghị (Production)

Để production, nên dùng thư viện đã tối ưu caching, memory management:

  • Kingfisher: pod 'Kingfisher' → imageView.kf.setImage(with: url)
  • SDWebImage: pod 'SDWebImage' → imageView.sd_setImage(with: url)
  • Nuke: Hiệu năng cao, API hiện đại

Lưu ý quan trọng

  • App Transport Security (ATS): iOS 9+ yêu cầu HTTPS. Nếu dùng HTTP, cần thêm exception vào Info.plist
  • Memory: Ảnh lớn có thể gây crash do OOM. Nên resize ảnh server-side hoặc dùng downsampling
  • Cancellation: Hủy task khi view controller bị dismiss (dùng weak self như ví dụ)
  • Caching: URLCache tự động cache response, có thể cấu hình dung lượng

Info.plist cho HTTP (nếu bắt buộc)

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