Get image paths from NSBundle in Objective C?

22,188

Solution 1

The correct way to get the full path to a resource in the main bundle is:

[[NSBundle mainBundle] pathForResource:@"avt_filename_00X" ofType:@"png"]

(or you can supply the empty string for 'ofType' if you prefer to include the extension in the resource name)

But nowhere in the docs is the path guaranteed to remain the same across devices, operating system iterations, etc. It's the path to that file from the application bundle in the current environment, guaranteed to remain valid for the duration of this run of the application only.

Because the path to the application, and hence to its resources, isn't guaranteed to stay the same, I think it's explicitly unsafe to put it in an SQL database by any means.

Could you perhaps adopt a scheme whereby a filename starting in / is a complete path, one without a / at the start is assumed to be in the bundle, meaning that you can apply the logic on the outside of the database?

Solution 2

How can I be sure that the path will work when the app is on a device?

Therein lies the rub: you can't. You would be best to let the paths be handled on-the-fly, and perhaps just store the file names instead.

Share:
22,188

Related videos on Youtube

zardon
Author by

zardon

Updated on October 29, 2020

Comments

  • zardon
    zardon over 3 years

    I have about 60 images I want to store in Core Data, 30 of which are avatars and have the prefix of avt_filename_00X.png and 30 of them are smaller and have a different prefix.

    Rather than storing all the images as BLOBs in Core Data/SQLite, I want to store the paths for each image found (in the same way you would store image paths for a MySQL database).

    However I am not sure how to grab the path of the image as found in NSBundle.

    I can get the path to the NSDocumentDirectory via:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager fileExistsAtPath:documentsDirectory];
    
    NSLog(@"documentsDirectory = %@", documentsDirectory);
    

    And I can load the image and add it to an array.

    if (qty == 0)
    {
        //NSLog(@"fileToLoad = %@", fileToLoad);
    
        UIImage *img = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fileToLoad ofType:fileExt]];
    
        [self.avtList addObject:img];
    
        [img release];
    
    } else {
    
        // load multiple image into an array
        // not coded yet
    }
    

    But, what I'm unsure of is:

    1. How do I grab the path where the computer found the image once its inside the NSBundle?

    2. How can I be sure that the path will work when the app is on a device?

    The idea would be to get all the images stored in an array and then push them to Core Data/SQLite at a later time.

  • zardon
    zardon over 13 years
    Oh I didn't know that. I thought you could use store the full path and then use that. If I write it to store the filename and the filepath, would I need to check that it exists before doing anything with it?
  • zardon
    zardon over 13 years
    Yeah, that makes sense. I think I will just store the filename in a database and then use your NSBundle code at a later stage to grab the image back.
  • Philip Regan
    Philip Regan over 13 years
    Absolutely, because the chances of that working properly anywhere else other than your own computer is very slim. For example, if a user places the application in their /Users/username/Applications folder, then change in the username will render the stored path useless.

Related