Referencing a nib file in a subfolder of an Xcode compiled Cocoa app bundle
-
05-09-2019 - |
Question
If I have a directory in my Xcode project (not a Group), which is added to the main target, and compile it, how do I instruct an NSViewController to initWithNibName:bundle:
a nib file inside that directory?
I've tried [viewController initWithNibName:@"FolderName/NibName" bundle:nil]
, but that doesn't work. Neither does without the folder name, nor setting the bundle parameter to [NSBundle mainBundle]
. I've even tried setting the bundle to [NSBundle bundleWithPath:pathToFolderName]
to no avail.
Solution
You're best off not using folders like this. Many Cocoa conveniences like -[NSImage imageNamed:], or the view controller init method expect to find a file in the Resources folder of the bundle.
If you'd really like to keep a folder of NIB files anyway, you can, but you won't be able to use the convenience methods. You can override -[NSViewController loadView] method of your view controller to invoke -[NSBundle loadNibFile:externalNameTable:withZone:]. You would pass the path to the NIB file, a name table with NSNibOwner set to the view controller, and a NULL zone. You'll also need to take care of releasing the top level objects from the NIB file.
Things will go a lot smoother if you abandon the sub directories in Resources.
OTHER TIPS
Another option would be to create a 'Run Script' to be executed at the end of your 'Build Phases' that could copy your *.xib files from the non-group directory into the main bundle. You will not only need to copy the xib files but you will need to compile them into *.nib files using the ibtool
command. Below is an example of my script that I am using:
# For some reason the tilde is causing problems with find
# so I am replacing the tilde with /Users/whoami
user=`whoami`
# We will find all non-nib files in this directory and copy them into the main bundle
find -L ${LW_ISHARE_PLATFORM_SRC/\~/\/Users\/$user}/lw-ishare-platform-nibs -type f -not -name ".*" -not -name "*.xib" | xargs -t -I {} cp {} ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/
export IBC_MINIMUM_COMPATIBILITY_VERSION=${IPHONEOS_DEPLOYMENT_TARGET}
#setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
export XCODE_DEVELOPER_USR_PATH="/Developer/usr/bin/"
# Now compile all xib files into nib files
for each in `find -L ${LW_ISHARE_PLATFORM_SRC/\~/\/Users\/$user}/lw-ishare-platform-nibs -type f -name "*.xib"`
do
prefix=`basename "${each}" .xib`
${XCODE_DEVELOPER_USR_PATH}/ibtool --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/${prefix}.nib ${each} --sdk ${SDKROOT}
done
exit 0
$LW_ISHARE_PLATFORM_SRC
is a global XCode variable for me and I am placing all my *.xib and related resource in the $LW_ISHARE_PLATFORM_SRC/lw-ishare-platform-nibs
directory.
${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}
is the path to your "main bundle".