Search code examples
iosuiimagensurlnsfilemanagerfile-uri

save image to subfolder of /library/Application Support/bundleID_name/... iOS


The following code works without error or exception - but still, it does not do what it should ! I wanted to save an image into the iOS library/Application Support folder. More precisely, the image should be placed into a /library/Application Support/bundleID_name/subfolder/ (and the subfolder being called "location1").

If I check the functionality with the iOS-Simulator, I can see the creation of the subfolder (i.e. .../library/Application Support/bundleID_name/location1/). Also the function "saveImage" works without exception. But there is no image being saved !!!! (i.e.the image-file is missing and the folder remains empty) !!

What could be the mistake ??

Here is my code with the call of two functions (see code below):

UIImage *in_image = [UIImage imageNamed:@"template009c.jpg"];

NSString *locDirectoryName = @"location1";
NSURL *LocationDirectory = [self appendLocationToApplicationDirectory:locDirectoryName];

[self saveImage:in_image :@"image1" :LocationDirectory];

With the corresponding function-Nr1:

- (NSURL*)appendLocationToApplicationDirectory:(NSString*)locationDirName
{
    NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier];
    NSFileManager*fm = [NSFileManager defaultManager];
    NSURL*    dirPath = nil;

    // Find the application support directory in the home directory.
    NSArray* appSupportDir = [fm URLsForDirectory:NSApplicationSupportDirectory
                                    inDomains:NSUserDomainMask];
    if ([appSupportDir count] > 0) {
        // Append the bundle ID and the location-Foldername to the URL for the Application Support directory
        dirPath = [[[appSupportDir objectAtIndex:0] URLByAppendingPathComponent:appBundleID] URLByAppendingPathComponent:locationDirName];

        // If the directory does not exist, this method creates it.
        // This method call works in OS X 10.7 and later only.
        NSError*    theError = nil;
        if (![fm createDirectoryAtURL:dirPath withIntermediateDirectories:YES attributes:nil error:&theError]) {
            // Handle the error.
            NSLog(@"%@", theError.localizedDescription);
            return nil;
        }
        else {
            // Mark the directory as excluded from iCloud backups
            if (![dirPath setResourceValue:@YES
                            forKey:NSURLIsExcludedFromBackupKey
                             error:&theError]) {
                NSLog(@"Error excluding %@ from iCloud backup %@", [dirPath lastPathComponent], theError.localizedDescription);
            }
            else {
                NSLog(@"Location Directory excluded from iClud backups");
            }
        }
    }
    return dirPath;
}

And function Nr2:

//saving an image
- (void)saveImage:(UIImage*)image :(NSString*)imageName :(NSURL*)pathName {
    NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
    NSFileManager *fileManager = [NSFileManager defaultManager];
    // NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    // NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *LocationDirectory = [pathName absoluteString];
    NSString *fullPath = [LocationDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", imageName]];

    /***** THE FOLLOWING LINE DOES NOT SEEM TO DO WHAT IT IS SUPPOSED TO *******/
    [fileManager createFileAtPath:fullPath contents:imageData attributes:nil];

    /**** I also tried without the FileManager, but same problem - no file written...  ***/
    // [imageData writeToFile:fullPath atomically:NO];
    NSLog(@"image saved");
}

By the way, getting the "fullPath" with the XCode-Debugger, I get:

"fullPath   NSPathStore2 *  @"file:/Users/username/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/2BCC3345-9M55F-4580-A1E7-6694E33456777/Library/Application%20Support/bundleID_name/image1.png" 0x09d50950

Doesn't that also seem correct ?? But why is [fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; not performing ???


Solution

  • This:

    "fullPath   NSPathStore2 *  @"file:/Users/username/Library/Application%20Support/iPhone%20Simulator/7.1/Applications/2BCC3345-9M55F-4580-A1E7-6694E33456777/Library/Application%20Support/bundleID_name/image1.png" 0x09d50950
    

    is not a valid path, it's a URL path but stored in a string. If you are going to use URL's then use ULRs rather than trying to convert to a string:

    [imageData writeToURL:pathName atomically:YES];
    

    (preferably naming the parameter as pathURL) and if you want to use paths then don't use a URL at any stage.

    Also, where an API method returns an error or status flag, check it in the code as standard.