0

I am Writing an app which has share extension to save selected photo to my app' local storage from iphone photo gallery. NSData WriteToFile returns YES but I couldn't find the stored file into the directory in of which I gave path while writing. So, in short NSData WriteToFile fails to save a photo at given path.

Below is my code.

   - (IBAction)acceptButtonTapped:(id)sender
{
    __block UIImage *photo;
    for (NSExtensionItem *item in self.extensionContext.inputItems)
    {
        for (NSItemProvider *itemProvider in item.attachments)
        {
            if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage])
            {
                [itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(UIImage *image, NSError *error) {
                    if(image)
                    {
                        dispatch_async(dispatch_get_main_queue(), ^{
                            photo = image;

                            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

                            [formatter setDateFormat:@"yyyy_MM_dd_hh_mm_ss"];

                            NSString *fileName;

                            fileName = [NSString stringWithFormat:@"%@.jpeg",[formatter stringFromDate:[NSDate date]]];

                            dataPath = [dataPath stringByAppendingPathComponent:fileName];
                            NSData * imageData = [NSData dataWithData:UIImageJPEGRepresentation(image, 1.0)];
                            BOOL isdone = [imageData writeToFile:dataPath atomically:NO];
                            NSLog(@"%u", isdone);
                        });
                    }
                }];
                break;
            }
        }
    }

    [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];
}

Any Help would be much appreciable.

Thank you.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
Paras Gorasiya
  • 1,295
  • 2
  • 13
  • 33
  • Please verify 'dataPath' i.e. does it contains the path of your local storage like DocumentDirectory ? – Mahendra Mar 30 '16 at 11:19
  • it is in DocumentDirectory, i have created a folder inside DocumentDirectory and into it I am storing the photo. Does it have any problem with that ? – Paras Gorasiya Mar 30 '16 at 11:22
  • Log your path to the debug console on the simulator, then copy everything but the filename into the clipboard, go to the finder, press command shift G, and paste the path into the "Go to folder" dialog box. See what happens. Also log the path to the documents directory in `applicationDidFinishLaunching` and make sure your path points to a file in that directory. – Duncan C Mar 30 '16 at 11:25

2 Answers2

1

If you're trying to access the Document directory from the share extension, NO you can't do that. Share extension or other widgets are separate application from their containing app and therefore have their own sandbox. So you will need to use App Groups to share files.

Application groups are primarily targeted for extensions, more specifically, for widgets.

NSFileManager has a method on it containerURLForSecurityApplicationGroupIdentifier: where you can pass in the identifier you created when turning on App Groups for your apps

NSURL *containerURL = [[NSFileManager defaultManager] 
           containerURLForSecurityApplicationGroupIdentifier:@"group.com.company.app"];

You can save the files to this location, because you can access the shared application groups from both extension and host app.

Surya Subenthiran
  • 2,217
  • 1
  • 15
  • 22
  • Yes you are right about the container URL, but when I store any file at that url, it fails every time. Do I need to make any directory and then try to store ? It shows me the error that no such file or directory – Paras Gorasiya Mar 30 '16 at 15:34
  • You have to create the App group in Project capabilities tab, which must be common for both widget and host app. And change the created app group identifier name in the above code. Then it should work. – Surya Subenthiran Mar 30 '16 at 16:59
0

You're modifying dataPath on each pass through the loop, appending another filename to it. That will create an ever-growing series of badly formed paths that contain all the filenames.

Don't do that. Create a new local variable filePath, and construct a filename into filePath using

filePath = [docsPath stringByAppendingPathComponent: filename];

Log your path and LOOK AT IT. When your program doesn't behave as expected, don't trust any of your assumptions, because one or more of them may be wrong.

Duncan C
  • 128,072
  • 22
  • 173
  • 272