iOS 照片扩展 finishContentEditing WithCompletionHandler:无法保存更改
iOS photo extension finishContentEditingWithCompletionHandler: Unable to Save Changes
我的照片扩展应用程序可以访问相机和照片。
一切正常,但按完成时,无法保存图像。
标准完成处理程序代码:
- (void)finishContentEditingWithCompletionHandler:(void (^)(PHContentEditingOutput *))completionHandler {
// Update UI to reflect that editing has finished and output is being rendered.
// Render and provide output on a background queue.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
PHContentEditingOutput *output = [[PHContentEditingOutput alloc] initWithContentEditingInput:self.input];
NSError* error = nil;
NSData *renderedJPEGData = UIImageJPEGRepresentation(filtered_ui_image, 1.0);
assert(renderedJPEGData != nil);
//BOOL written_well = [renderedJPEGData writeToURL:output.renderedContentURL atomically:YES];
BOOL written_well = [renderedJPEGData writeToURL:output.renderedContentURL options:NSDataWritingAtomic error:&error];
assert(written_well);
// Call completion handler to commit edit to Photos.
completionHandler(output);
});
}
renderedJPEGData
不是 nil
,
error
是 nil
,因此函数 [NSData writeToURL]
成功,
written_well
是 YES
,
逐行调试时,块完成后,出现警告:
output.renderedContentURL
是 /private/var/mobile/Containers/Data/PluginKitPlugin/509C1A04-D414-4DB7-B1E6-83C47FC88BC9/tmp/blah_blah_name.JPG
所以,我有权限,调试显示没有错误,我可以尝试检测问题的原因是什么?
尽管 header 暗示 adjustmentData 可以为零,但文档指出:
If you write new asset content to the URL specified by the renderedContentURL property, you must also provide a new, distinct PHAdjustmentData object describing your edit. Passing a preexisting adjustment data object (that describes an earlier edit) results in undefined behavior.
所以在调用完成处理程序之前做这样的事情:
output.adjustmentData = [[PHAdjustmentData alloc] initWithFormatIdentifier:@"com.whatever.app" formatVersion:@"1.0" data:[NSData data]];
从iOS10开始,调整数据必须至少有一个字节。这是 iOS 9 的重大变化,其中调整数据可以为零。我已经在 iOS 9 和 iOS 10 上进行了测试以确认。
其他文档:https://developer.apple.com/reference/photos/phcontenteditingoutput/1518684-adjustmentdata
PHContentEditingOutput* output = [[PHContentEditingOutput alloc] initWithContentEditingInput:self.input];
NSMutableData* adjustmentData = [NSMutableData data];
uint8_t byte = 1;
[adjustmentData appendBytes:&byte length:1];
output.adjustmentData = [[PHAdjustmentData alloc] initWithFormatIdentifier:@"com.yourcompany.yourapp" formatVersion:@"1.0f" data:adjustmentData];
我的照片扩展应用程序可以访问相机和照片。 一切正常,但按完成时,无法保存图像。
标准完成处理程序代码:
- (void)finishContentEditingWithCompletionHandler:(void (^)(PHContentEditingOutput *))completionHandler {
// Update UI to reflect that editing has finished and output is being rendered.
// Render and provide output on a background queue.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
PHContentEditingOutput *output = [[PHContentEditingOutput alloc] initWithContentEditingInput:self.input];
NSError* error = nil;
NSData *renderedJPEGData = UIImageJPEGRepresentation(filtered_ui_image, 1.0);
assert(renderedJPEGData != nil);
//BOOL written_well = [renderedJPEGData writeToURL:output.renderedContentURL atomically:YES];
BOOL written_well = [renderedJPEGData writeToURL:output.renderedContentURL options:NSDataWritingAtomic error:&error];
assert(written_well);
// Call completion handler to commit edit to Photos.
completionHandler(output);
});
}
renderedJPEGData
不是 nil
,
error
是 nil
,因此函数 [NSData writeToURL]
成功,
written_well
是 YES
,
逐行调试时,块完成后,出现警告:
output.renderedContentURL
是 /private/var/mobile/Containers/Data/PluginKitPlugin/509C1A04-D414-4DB7-B1E6-83C47FC88BC9/tmp/blah_blah_name.JPG
所以,我有权限,调试显示没有错误,我可以尝试检测问题的原因是什么?
尽管 header 暗示 adjustmentData 可以为零,但文档指出:
If you write new asset content to the URL specified by the renderedContentURL property, you must also provide a new, distinct PHAdjustmentData object describing your edit. Passing a preexisting adjustment data object (that describes an earlier edit) results in undefined behavior.
所以在调用完成处理程序之前做这样的事情:
output.adjustmentData = [[PHAdjustmentData alloc] initWithFormatIdentifier:@"com.whatever.app" formatVersion:@"1.0" data:[NSData data]];
从iOS10开始,调整数据必须至少有一个字节。这是 iOS 9 的重大变化,其中调整数据可以为零。我已经在 iOS 9 和 iOS 10 上进行了测试以确认。
其他文档:https://developer.apple.com/reference/photos/phcontenteditingoutput/1518684-adjustmentdata
PHContentEditingOutput* output = [[PHContentEditingOutput alloc] initWithContentEditingInput:self.input];
NSMutableData* adjustmentData = [NSMutableData data];
uint8_t byte = 1;
[adjustmentData appendBytes:&byte length:1];
output.adjustmentData = [[PHAdjustmentData alloc] initWithFormatIdentifier:@"com.yourcompany.yourapp" formatVersion:@"1.0f" data:adjustmentData];