You have added a resource (such as an image) to your Xcode project and now, at runtime, you would like to access that resource.
Use the mainBundle
class method
of the NSBundle
class in order to retrieve your main bundle. Once that is done,
use the pathForResource:ofType:
method of your main bundle to retrieve the path for that specific
resource. Once the path is detected, depending on the type of resource,
you can either pass the path to your file to a class such as UIImage
or NSData
, or you can manually access the file
using NSFileManager
.
Note
It is required that you give a unique name to each resource inside your main bundle. For instance, it is not good practice to have a file named Default.png in more than one place inside your main bundle. Different ways of loading a resource from a bundle could then yield different results. As a result, make sure you give unique names to your files inside any bundle, regardless of whether it is the main bundle or a custom bundle that you’ve created (see Recipe 1.26).
To access the main bundle, we can use the mainBundle
class method of the NSBundle
class. Bundles are all of type
NSBundle
and once you have an
instance of a bundle, you can load resources from that bundle.
Note
Every app’s main bundle has a flat hierarchy on disk when it is compiled for submission to App Store. That means all the files that get wrapped up in your app bundle will be placed on the root folder of the main bundle. In other words, the main bundle has only one folder, the root folder, and all files and resources are stored in that folder. Even if you have a folder on disk with a few files in it and drag and drop it into Xcode, only the files in that folder will be placed in the main bundle’s file hierarchy, not the folder itself.
For instance, let’s say that you have an image called AlanSugar.png sitting on your desktop. Simply drag and drop it into Xcode. At this point, Xcode will display a dialog to you, asking you which project this file has to be added to and whether you want this file to be copied over to the project’s folder, if need be. This dialog will look similar to that shown in Figure 1-34.
In this dialog, make sure that the “Copy items into destination group’s folder (if needed)” item is selected. This will copy the file that you drop into Xcode to the target app’s folder. Now, if you delete the file on your desktop, it won’t get deleted from your project because your project has its own copy. It’s generally good practice to do this unless, for specific reasons, you decide not to (and I’ve experienced many of these reasons myself). After you drag and drop the file, the file AlanSugar.png is in the project’s main bundle and you can retrieve its path in this way:
-
(
BOOL
)
application:
(
UIApplication
*
)
application
didFinishLaunchingWithOptions:
(
NSDictionary
*
)
launchOptions
{
NSString
*
alanSugarFilePath
=
[[
NSBundle
mainBundle
]
pathForResource:
@"AlanSugar"
ofType:
@"png"
];
if
([
alanSugarFilePath
length
]
>
0
){
UIImage
*
image
=
[
UIImage
imageWithContentsOfFile:
alanSugarFilePath
];
if
(
image
!=
nil
){
NSLog
(
@"Successfully loaded the file as an image."
);
}
else
{
NSLog
(
@"Failed to load the file as an image."
);
}
}
else
{
NSLog
(
@"Could not find this file in the main bundle."
);
}
self
.
window
=
[[
UIWindow
alloc
]
initWithFrame:
[[
UIScreen
mainScreen
]
bounds
]];
self
.
window
.
backgroundColor
=
[
UIColor
whiteColor
];
[
self
.
window
makeKeyAndVisible
];
return
YES
;
}
The output of the pathForResource:ofType:
method of NSBundle
will be
either a valid path or nil if the specified resource cannot be found in
the target bundle. So after you call this method, it is best to check
whether the path could actually be retrieved. If so, the code shown
passes the path of the file to the UIImage
class in order to load the AlanSugar.png file into memory as an
image.
Similarly, if you wanted to load the data of that file into
memory, instead of retrieving this image as an image object, you could
use the NSData
class:
-
(
BOOL
)
application:
(
UIApplication
*
)
application
didFinishLaunchingWithOptions:
(
NSDictionary
*
)
launchOptions
{
NSString
*
alanSugarFilePath
=
[[
NSBundle
mainBundle
]
pathForResource:
@"AlanSugar"
ofType:
@"png"
];
if
([
alanSugarFilePath
length
]
>
0
){
NSError
*
readError
=
nil
;
NSData
*
dataForFile
=
[[
NSData
alloc
]
initWithContentsOfFile:
alanSugarFilePath
options:
NSMappedRead
error:
&
readError
];
if
(
readError
==
nil
&&
dataForFile
!=
nil
){
NSLog
(
@"Successfully loaded the data."
);
}
else
if
(
readError
==
nil
&&
dataForFile
==
nil
){
NSLog
(
@"No data could be loaded."
);
}
else
{
NSLog
(
@"An error occured while loading data. Error = %@"
,
readError
);
}
}
else
{
NSLog
(
@"Could not find this file in the main bundle."
);
}
self
.
window
=
[[
UIWindow
alloc
]
initWithFrame:
[[
UIScreen
mainScreen
]
bounds
]];
self
.
window
.
backgroundColor
=
[
UIColor
whiteColor
];
[
self
.
window
makeKeyAndVisible
];
return
YES
;
}
Get iOS 6 Programming Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.