I found that it performs normal when not passing the alterPhoto. This is my code
let options = PHAssetResourceCreationOptions()
options.shouldMoveFile = true
PHPhotoLibrary.shared().performChanges{
let creationRequest = PHAssetCreationRequest.forAsset()
let options = PHAssetResourceCreationOptions()
options.shouldMoveFile = true
creationRequest.addResource(with: .photo, fileURL: self.rawFileURL!, options: options)
if let a = alterPhoto{
creationRequest.addResource(with: .alternatePhoto, data: a, options: nil)
}
}completionHandler: { s, e in
print(e)
}
This is the code from apple's own document in this address,which is not a full project but an article with code pieces: https://developer.apple.com/documentation/avfoundation/photo_capture/capturing_photos_in_raw_and_apple_proraw_formats
PHPhotoLibrary.shared().performChanges {
// Save the RAW (DNG) file as the main resource for the Photos asset.
let options = PHAssetResourceCreationOptions()
options.shouldMoveFile = true
creationRequest.addResource(with: .photo,
fileURL: rawFileURL,
options: options)
// Add the compressed (HEIF) data as an alternative resource.
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .alternatePhoto,
data: compressedData,
options: nil)
} completionHandler: { success, error in
// Process the Photos library error.
}
}
I really don't know why.
I ran into the same issue but was able to get it working by switching the order of the HEIF and RAW: set the HEIF as the primary and the RAW as the alternate:
PHPhotoLibrary.shared().performChanges {
// Add the compressed (HEIF) data as the main resource for the Photos asset.
let creationRequest = PHAssetCreationRequest.forAsset()
creationRequest.addResource(with: .photo,
data: compressedData,
options: nil)
// Save the RAW (DNG) file an alternate resource for the Photos asset.
let options = PHAssetResourceCreationOptions()
options.shouldMoveFile = true
creationRequest.addResource(with: .alternatePhoto,
fileURL: rawFileURL,
options: options)
} completionHandler: { success, error in
// Process the Photos library error.
}
}
Update (2023-10-22): I also ran into an issue where the thumbnail displayed by Photos would be in the camera's native orientation (but opening up the full-size image was fine). I tested combinations of RAW/HEIF first, and using addResource
as either data
or fileURL
.
TL;DR: use addResource(with: .photo, data: heicData, options: options)
and addResource(with: .alternatePhoto, fileURL: rawURL, options: options)
.
Where H = HEIF and R = RAW, I came up with the following results:
Primary | Alternate | Result |
---|---|---|
H/Data | R/Data | Error 3300 |
H/URL | R/Data | Error 3300 |
H/Data | R/URL | Good |
H/URL | R/URL | Thumbnail not rotated |
R/URL | H/Data | Error 3300 |
R/Data | H/Data | Error 3300 |
R/Data | H/URL | Displayed as 'RAW' instead of 'JPEG + RAW' in Photos |
R/URL | H/URL | Displayed as 'RAW' instead of 'JPEG + RAW' in Photos |
Summarized:
addResource(with:data:options:)
instead of addResource(with:fileURL:options:)
..alternatePhoto
or Photos will not (at least not in the UI) recognize the HEIF.addResource(with:data:options:)
, it does not correctly read orientation metadata when generating the thumbnail.