PhotoKit là framework của Apple để làm việc với thư viện phương tiện trên iOS và macOS, cung cấp quyền truy cập trực tiếp vào ảnh, video và Live Photos trên thiết bị. Theo tài liệu của Apple, framework này thay thế AssetsLibrary cũ và hỗ trợ iCloud, album, chỉnh sửa và Change Tracking. PhotoKit cung cấp API thống nhất cho truy vấn, bộ nhớ đệm và thay đổi thư viện phương tiện với đồng bộ tự động qua iCloud.
Các điểm chính
PhotoKit là framework của Apple (được giới thiệu trong iOS 8, macOS 10.11) cung cấp API hướng đối tượng để làm việc với thư viện phương tiện hệ thống. Không giống AssetsLibrary, PhotoKit coi thư viện phương tiện như một cơ sở dữ liệu: các truy vấn trả về các đối tượng PHAsset, PHCollection và PHCollectionList đại diện cho nội dung và cấu trúc lưu trữ.
PhotoKit hỗ trợ tất cả các loại phương tiện: ảnh (JPEG, HEIF, RAW), video (MOV, MP4), Live Photos và ảnh chụp liên tiếp. Framework tự động quản lý đồng bộ iCloud: nếu ảnh được lưu trữ trong iCloud, PhotoKit sẽ yêu cầu nó qua mạng và báo cáo tiến trình qua PHImageRequestOptions.progressHandler.
Một tính năng chính của PhotoKit là mô hình dữ liệu dựa trên PHObject với định danh cục bộ (localIdentifier) ổn định giữa các phiên. Điều này cho phép bạn lưu tham chiếu đến các đối tượng phương tiện và khôi phục chúng sau khi khởi động lại ứng dụng mà không cần truy vấn lại.
PhotoKit được xây dựng trên ba cấp độ: mô hình dữ liệu (PHObject), truy vấn (PHFetchResult) và thay đổi (PHPhotoLibrary.performChanges). Mô hình dữ liệu có thứ bậc: PHAsset (ảnh/video) nằm trong PHAssetCollection (album) và các album được nhóm trong PHCollectionList (thư mục).
Các truy vấn được thực hiện qua PHAsset.fetchAssets và PHAssetCollection.fetchAssetCollections. Tất cả các phương thức fetch đều đồng bộ và trả về PHFetchResult, nó thực hiện ngay lập tức truy vấn vào cơ sở dữ liệu thư viện phương tiện. PHFetchResult hỗ trợ truy cập nhanh theo chỉ mục (object(at:)) và liệt kê qua enumerateObjects.
PHFetchOptions là đối tượng để cấu hình truy vấn: sắp xếp (sortDescriptors), vị từ (predicate), bao gồm phương tiện ẩn và đã xóa (includeHiddenAssets, includeAllBurstAssets). Các tùy chọn fetch cho phép lọc theo loại phương tiện: PHAssetMediaType.image, .video, .audio.
PhotoKit bao gồm một tập hợp các lớp để truy cập, truy vấn và sửa đổi thư viện phương tiện. Hiểu từng lớp là điều cần thiết để làm việc hiệu quả với framework.
PHAsset là một đối tượng bất biến đại diện cho một mục phương tiện. Nó chứa siêu dữ liệu: mediaType, mediaSubtypes, creationDate, location, pixelWidth, pixelHeight, duration (cho video), isFavorite, burstIdentifier. LocalIdentifier là khóa chuỗi ổn định có thể truy cập ngay cả sau khi khởi động lại ứng dụng.
PHAssetCollection là một nhóm phương tiện: album hệ thống (Recents, Favorites, Selfies, Screenshots), album người dùng hoặc Moments (được nhóm tự động theo thời gian và địa điểm). Thuộc tính: localizedTitle, assetCollectionType, assetCollectionSubtype, startDate, endDate.
PHCollectionList là một thư mục chứa các album (PHAssetCollection) hoặc các thư mục khác. Nó ít khi được sử dụng, chủ yếu để hiển thị hệ thống phân cấp trong giao diện người dùng.
PhotoKit không trả về UIImage trực tiếp từ PHAsset — bạn cần yêu cầu ảnh qua PHImageManager. Điều này đảm bảo ảnh được tải với hỗ trợ iCloud, bộ nhớ đệm và kích thước cần thiết.
| Thành phần | Mục đích | Tính năng |
|---|---|---|
| PHImageManager.default() | Trình quản lý tiêu chuẩn cho các yêu cầu một lần | Không có bộ nhớ đệm giữa các yêu cầu |
| PHCachingImageManager | Trình quản lý với tải trước cho bộ sưu tập | startCachingImages để cuộn mượt |
| PHImageRequestOptions | Cài đặt yêu cầu: kích thước, chế độ, phân phối | synchronous, deliveryMode, progressHandler |
| PHImageRequestID | Định danh yêu cầu để hủy | cancelImageRequest(PHImageRequestID) |
PHImageManager hỗ trợ ba chế độ phân phối: opportunistic (đầu tiên là phiên bản thu nhỏ, sau đó là đầy đủ), highQualityFormat (chỉ chất lượng đầy đủ) và fastFormat (phiên bản nhanh nhất có sẵn). Đối với bộ sưu tập, luôn sử dụng PHCachingImageManager với tải trước ảnh cho các ô hiện thị.
PhotoKit được sử dụng để tạo các thư viện ảnh tùy chỉnh, trình chỉnh sửa và ứng dụng phương tiện. Hãy xem xét ba kịch bản chính.
PHAsset.fetchAssets với PHFetchOptions được sắp xếp theo ngày tạo là truy vấn cơ bản để xây dựng thư viện ảnh tùy chỉnh. PHFetchResult hỗ trợ tải chậm và truy cập trực tuyến.
let options = PHFetchOptions()
options.sortDescriptors = [NSSortDescriptor(
key: "creationDate",
ascending: .false
)]
options.predicate = NSPredicate(
format: "mediaType == %d",
PHAssetMediaType.image.rawValue
)
let allPhotos = PHAsset.fetchAssets(with: options)
print("Đã tìm thấy \(allPhotos.count) ảnh")
allPhotos.enumerateObjects { asset, index, stop in
print("Ảnh \(index): \(asset.localIdentifier)")
}
PHFetchResult là vùng chứa an toàn luồng. Truy cập các đối tượng theo chỉ mục qua object(at:) không chặn giao diện người dùng, nhưng yêu cầu ảnh qua PHImageManager phải được thực hiện không đồng bộ.
PHCachingImageManager là một lớp con của PHImageManager với các phương thức startCachingImages và stopCachingImages để tải trước. Nó được sử dụng trong UICollectionView để cuộn mượt.
let cachingManager = PHCachingImageManager()
let targetSize = CGSize(width: 200, height: 200)
// Tải trước cho các ô hiện thị
cachingManager.startCachingImages(
for: visibleAssets,
targetSize: targetSize,
contentMode: .aspectFill,
options: nil
)
// Yêu cầu ảnh qua PHImageRequestOptions với dự phòng iCloud
let requestOptions = PHImageRequestOptions()
requestOptions.deliveryMode = .opportunistic
requestOptions.isNetworkAccessAllowed = .true
requestOptions.progressHandler = { progress, error, stop, info in
DispatchQueue.main.async {
print("Đang tải xuống từ iCloud: \(progress * 100)%")
}
}
let requestID = cachingManager.requestImage(
for: asset,
targetSize: targetSize,
contentMode: .aspectFill,
options: requestOptions
) { image, info in
print("Đã lấy được ảnh: \(image?.size ?? .zero)")
}
Các thay đổi trong thư viện phương tiện được thực hiện qua PHPhotoLibrary.shared().performChanges bên trong khối changeRequest. Tất cả các thao tác được xử lý hàng loạt và áp dụng theo giao dịch.
PHPhotoLibrary.shared().performChanges {
let changeRequest = PHAssetChangeRequest(for: asset)
changeRequest.isFavorite = .true
} completionHandler: { success, error in
if success {
print("Đã thêm vào yêu thích")
}
}
PhotoKit cung cấp cơ chế quan sát các thay đổi trong thư viện phương tiện thông qua giao thức PHPhotoLibraryChangeObserver. Khi có bất kỳ thay đổi nào (tạo, xóa, chỉnh sửa), phương thức photoLibraryDidChange được gọi với một đối tượng PHChange.
PHChange chứa changeDetails cho mỗi loại truy vấn: PHFetchResultChangeDetails với removedIndexes, insertedIndexes, changedIndexes. Điều này cho phép áp dụng các thay đổi vào giao diện người dùng với hoạt ảnh: performBatchUpdates với move, insert, delete cho UICollectionView.
class PhotosViewController: UIViewController {
var fetchResult: PHFetchResult>PHAsset>?
override func viewDidLoad() {
super.viewDidLoad()
PHPhotoLibrary.shared().register(self)
}
deinit {
PHPhotoLibrary.shared().unregisterChangeObserver(self)
}
}
extension PhotosViewController: PHPhotoLibraryChangeObserver {
func photoLibraryDidChange(_ changeInstance: PHChange) {
guard let fetchResult,
let details = changeInstance.changeDetails(for: fetchResult)
else { return }
DispatchQueue.main.async {
self.fetchResult = details.fetchResultAfterChanges
// Áp dụng các thay đổi cho collectionView
}
}
}
PhotoKit hỗ trợ chỉnh sửa phương tiện thông qua cơ chế PHContentEditingInput và PHContentEditingOutput. Ứng dụng yêu cầu editingInput với dữ liệu gốc, áp dụng các thay đổi và lưu kết quả qua editingOutput. Framework tự động giữ lại bản gốc, cho phép người dùng hoàn tác các thay đổi bằng cách đặt lại về bản gốc.
Ảnh RAW (DNG, CR2, NEF) được hỗ trợ qua PHAssetResourceManager, cung cấp quyền truy cập vào tệp RAW gốc. Để xử lý RAW, bạn nên sử dụng CoreImage với bộ lọc CIRAWFilter, hỗ trợ điều chỉnh nhiệt độ, độ phơi sáng và độ sắc nét. PhotoKit cũng hỗ trợ các tiện ích mở rộng trình chỉnh sửa qua Photo Editing Extension (iOS) — một ứng dụng có thể được gọi từ trình chỉnh sửa hệ thống để xử lý ảnh hoặc video được chọn.
PhotoKit là một framework mạnh mẽ nhưng tốn nhiều tài nguyên. Sử dụng không đúng cách có thể dẫn đến độ trễ khi cuộn và tiêu thụ bộ nhớ quá mức. Hãy làm theo các khuyến nghị sau để có hiệu suất tối ưu.
PHLivePhoto yêu cầu một yêu cầu riêng qua PHLivePhoto.request(with:targetSize:contentMode:options:resultHandler:). Không yêu cầu Live Photo cho các ô chỉ hiển thị ảnh — sử dụng PHLivePhotoBadge làm chỉ báo.
Câu hỏi thường gặp
PhotoKit là framework hiện đại của Apple để làm việc với thư viện phương tiện, được giới thiệu trong iOS 8. Không giống AssetsLibrary cũ, PhotoKit cung cấp mô hình đối tượng PHAsset, PHFetchResult với tìm kiếm nhanh, hỗ trợ iCloud và Change Tracking để quan sát các thay đổi.
Gọi PHPhotoLibrary.requestAuthorization(for: .readWrite) với một trình xử lý callback. Sau khi nhận được trạng thái .authorized, bạn có thể thực hiện các truy vấn PHAsset.fetchAssets. Quyền truy cập ghi yêu cầu quyền .readWrite. Chỉ đọc — .addOnly.
Sử dụng PHImageManager.default().requestImage với các tham số: asset, targetSize, contentMode và PHImageRequestOptions. Phương thức không đồng bộ trả về PHImageRequestID, cho phép bạn hủy yêu cầu. Đối với bộ sưu tập, hãy sử dụng PHCachingImageManager với tải trước.
Đăng ký một người quan sát qua PHPhotoLibrary.shared().register(self) và triển khai giao thức PHPhotoLibraryChangeObserver. Trong phương thức photoLibraryDidChange, nhận PHChange với changeDetails cho mỗi fetchResult và áp dụng các thay đổi vào giao diện người dùng với hoạt ảnh.
Trong PHImageRequestOptions, đặt isNetworkAccessAllowed = true và progressHandler để theo dõi tiến trình tải xuống iCloud. Trong khi cuộn nhanh, tắt quyền truy cập mạng và chỉ tải các phiên bản cục bộ để tránh độ trễ khi cuộn.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm