I would like to programmatically add/delete keywords from Photos in the Photos Library in an iOS app. I have written and tested the code below to toggle the favorite setting on a given photo but I have not been able to find anything in the documentation about the keywords. Photos clearly have metadata that contains keywords.
Here's the simple function to toggle "favorite" on the latest photo in the library and this code does complete as expected.
class ViewController: UIViewController {
@IBOutlet weak var myImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
photoAuthorization()
toggleFavorite()
}
private func loadImage() -> UIImage? {
let manager = PHImageManager.default()
let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions())
var image: UIImage? = nil
manager.requestImage(for: fetchResult.object(at: 0), targetSize: CGSize(width: 800, height: 600), contentMode: .aspectFill, options: requestOptions() ) {img, err in
guard let img = img else { return }
image = img
}
return image
}//load Image
private func fetchOptions() -> PHFetchOptions {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
return fetchOptions
}//fetch options
private func requestOptions() -> PHImageRequestOptions {
let requestOptions = PHImageRequestOptions()
requestOptions.isSynchronous = true
requestOptions.deliveryMode = .highQualityFormat
return requestOptions
}//request options
private func photoAuthorization() {
let status = PHPhotoLibrary.authorizationStatus()
switch status {
case .authorized:
myImageView.image = loadImage()
case .restricted, .denied:
print("put up alert for auth restricted or denied")
case .notDetermined:
PHPhotoLibrary.requestAuthorization { (status) in
switch status {
case .authorized:
DispatchQueue.main.async {
self.myImageView.image = self.loadImage()
}
case .restricted, .denied:
print("in notDetermined put up alert for auth restricted or denied")
case .notDetermined:
break
@unknown default:
fatalError("fatal error inside request authorization (inner loop)")
}
}
@unknown default:
fatalError("fatal error authorized switch (outer loop)")
}
}//photo authorization
private func toggleFavorite() {
let fetchResult: PHFetchResult = PHAsset.fetchAssets(with: fetchOptions())
guard let firstAsset = fetchResult.firstObject else { return }
PHPhotoLibrary.shared().performChanges({
let changeRequest = PHAssetChangeRequest(for: firstAsset)
changeRequest.isFavorite = !firstAsset.isFavorite
//want to add keyword instead of toggling favorite
//changeRequest.setValue("jumping", forKey: "keywords")
//
}) { (success, error) in
print(success ? "Successfully updated favorite" : "\(error ?? "error did not work either" as! Error)")
}
}//toggle favorite
}//class
Any guidance would be appreciated. Xcode 11.4.1