Để 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.

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")
}
}
}

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:
URLCachetự độ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>