8

My photo extension app has access to both Camera and Photos. All is ok, but when pressing Done, it can not save image.

Code of standard completion handler:

- (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 is not nil,
error is nil, thus function [NSData writeToURL] was successful,
written_well is YES,

when debugging line-by-line, after block finishes, an alert appears: enter image description here

output.renderedContentURL is /private/var/mobile/Containers/Data/PluginKitPlugin/509C1A04-D414-4DB7-B1E6-83C47FC88BC9/tmp/blah_blah_name.JPG

So, I have permissions, debug shows no errors, what can I try to detect the cause of problem?

olha
  • 2,132
  • 1
  • 18
  • 39

2 Answers2

7

As of iOS 10, the adjustment data must have at least one byte. This is a breaking change from iOS 9, where the adjustment data can be nil. I've tested this on both iOS 9 and iOS 10 to confirm.

Additional documentation: 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];
jjxtra
  • 20,415
  • 16
  • 100
  • 140
  • This isn't working for me. I get the error for some images only, always the same images, every time. Other images save without problem. Can not pin point what is the difference between the images that save and those that don't... – Nicolas Miari Sep 15 '18 at 04:17
1

Even though the header implies that adjustmentData can be nil, the documentation states:

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.

So do something like this before calling the completion handler:

output.adjustmentData = [[PHAdjustmentData alloc] initWithFormatIdentifier:@"com.whatever.app" formatVersion:@"1.0" data:[NSData data]];
chockenberry
  • 7,811
  • 5
  • 32
  • 41