Last active
September 14, 2024 16:40
-
-
Save matiaskorhonen/69cb9239bb3f78cdb4d062b88d19d33d to your computer and use it in GitHub Desktop.
Custom image import into Photos.app using PhotoKit. Import an original JPEG plus an edited version of it. Proof of concept.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Cocoa | |
import Photos | |
let original = URL(fileURLWithPath: "/Users/matt/Code/personal/PhotoKitPlayground/Test/DSC_6326.jpg") | |
let edited = URL(fileURLWithPath: "/Users/matt/Code/personal/PhotoKitPlayground/Test/DSC_6326-edit.jpg") | |
let status = PHPhotoLibrary.authorizationStatus(for: .readWrite) | |
if status != .authorized { | |
PHPhotoLibrary.requestAuthorization(for: .readWrite) { status in | |
if status == .denied { | |
assertionFailure("Photo access is required") | |
} | |
} | |
} | |
func addAsset(image: URL, editedImage: URL, to album: PHAssetCollection) { | |
PHPhotoLibrary.shared().performChanges { | |
// Request creating an asset from the image | |
guard let creationRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(atFileURL: image) else { return } | |
// Request editing the album | |
guard let addAssetRequest = PHAssetCollectionChangeRequest(for: album) else { return } | |
// Get a placeholder for the new asset | |
guard let placeholder = creationRequest.placeholderForCreatedAsset else { return } | |
// Set the edited photo as an adjustment | |
let output = PHContentEditingOutput(placeholderForCreatedAsset: placeholder) | |
let editedData = try! Data(contentsOf: editedImage) | |
try! editedData.write(to: output.renderedContentURL, options: .atomic) | |
output.adjustmentData = PHAdjustmentData( | |
formatIdentifier: "customImport", | |
formatVersion: "1", | |
data: "📸".data(using: .utf8)! | |
) | |
output.renderedContentURL | |
creationRequest.contentEditingOutput = output | |
// Add the placeholder to the album editing request | |
addAssetRequest.addAssets([placeholder as Any] as NSArray) | |
} completionHandler: { success, error in | |
if !success, let error = error { | |
error | |
print("error creating asset: \(error.localizedDescription)") | |
} | |
} | |
} | |
let collectionOptions = PHFetchOptions() | |
collectionOptions.predicate = NSPredicate.init(format: "title = %@", "Import") | |
let assetCollections = PHAssetCollection.fetchAssetCollections(with: .album, subtype: .any, options: collectionOptions) | |
let importAlbum = assetCollections.firstObject! | |
importAlbum.localizedTitle | |
addAsset(image: original, editedImage: edited, to: importAlbum) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment