Launch application from application bundle - objective-c

I have a helper application, which is within my main application's application bundle (in the Resources). I'm not sure how to get the path of the application from inside the bundle and launch it.

I'm not sure I fully understand the question. I think you're saying you have an application (let's call it PrimaryApplication.app) and inside it's Resources directory there is an application you need to launch (let's call it Helper.app). In that case you use NSBundle's -bundlePath to get the path to the currently running application, then you append the path to your helper from there. You can use NSWorkspace to launch the application once you know the path to it.
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *helperAppPath = [[mainBundle bundlePath]
stringByAppendingString:#"/Contents/Resources/Helper.app"];
[[NSWorkspace sharedWorkspace] launchApplication:helperAppPath];

In Core Foundation, CFBundleCopyResourceURL should get you the application's url.
In Cocoa, NSBundle has equivalent pathForResource:ofType: and URLForResource:withExtension: methods.

Related

How to access resources during app testing

Newbie questions.
I am aware that during testing my iPhone app in the Simulator, not all resource files are available in the [NSBundle mainBundle]. I understand that the solution is to refer to [NSBundle bundleForClass:[self class]] rather than to the mainBundle.
Questions I have:
Is refering to [NSBundle bundleForClass:[self class]] valid when the app is deployed and is it good practice?
Is it good practice to define in the app delegate...
NSBundle *appBundle = [NSBundle bundleForClass:[self class]];
// or, for in final app
// NSBundle *appBundle = [NSBundle mainBundle];
... and use appBundle throughout the code? Otherwise there are too many places where I refer to [NSBundle mainBundle] that I would have to change to the bundleForClass:[self Class].
If I go with this appBundle definition, should I be doing anything else? Perhaps release the appBundle before the app delegate terminates?
Thank you!
Sleiman
mainBundle contains everything inside a bundle, the resources for your target (app). XCode tries to add all the assets into the bundle but sometimes misses or other times you may have inadvertently told XCode not to copy it into the bundle. It's important to remember to only put into the bundle what the app needs before release -- if you have test files, remove them -- because they make your app larger which eats up users storage and bandwidth.
To add/remove/inspect what is in the bundle go to the file/group inspector, the little folder icon at the top-left of XCode. Choose the project, the very top-most entry. Select a target if you have more than one. Click Build Phases and scroll down to Copy Bundle Resources. That is where you manage what gets copied into the bundle.

Resources folder path in cocoa app

I am working on Mac OS X app which using some c files, and i have a configuration file i add it to the app resources.
My question is "What is the relative path of resources folder?"
I tried
"[MyAppName].app/Contents/Resources/config.cfg"
and it works fine only when I run my app from xCode, otherwise it's doesn't work!
I thought the app starts from "MacOS" folder, so i used this path:
"../Resources/config.cfg"
but it also didn't work :(
any help please
Using relative paths is asking for trouble. Fortunately Cocoa will give you an absolute path:
NSBundle *myBundle = [NSBundle mainBundle];
NSString *absPath= [myBundle pathForResource:#"config" ofType:#"cfg"];

How to get the correct bundle instance if multiple bundles with same ID exist?

I am writing a plugin for a host application (Aperture). The plugin is deployed as a bundle and within this bundle there are frameworks needed by this plugin e.g. Sparkle.
The problem is that it is now possible that another plugin is loaded within Aperture, which also has the Sparkle framework embedded. In the Sparkle code the following preprocessor directive is defined, which is used to retrieve Sparkle's NSBundle instance:
#define SPARKLE_BUNDLE [NSBundle bundleWithIdentifier:#"org.andymatuschak.Sparkle"]
However if two plugins have their instance of Sparkle each, two bundles with the same identifier exist and of course in my case the wrong one is loaded. Anyhow I would not like to rely on chance here.
My Question
Is there a way to load the correct Sparkle bundle, the one which is embedded in my plugin?
I thought about this alternative:
#define SPARKLE_BUNDLE [NSBundle bundleForClass:[self class]]
I am not sure but I think this would break if the class is subclassed by a file located outside the bundle (like it's done in AppKit, too). Am I correct here?
if you embedded it, load it via its path not via its identifier
myPluginBundle = [NSBundle bundleForClass:self.class];
bundlePath = [myPluginBundle pathForResource:#"Sparkle"type:#"bundle"];
bundle = [NSBundle bundleAtPath:bundlePath];

Using NSBundle to load my resources

I wanted to separate my resources, nib files and localization files into a common reusable bundle. And so I created a bundle for my ios application and specified resources to be included inside the bundle using build phases, copy bundle resources. But, now if I try to load the bundle, I am not able to load the bundle. I try using [NSBundle allBundles] and the array shows only the main apps bundle.
I also tried to enumerate the directory for NSApplicationPath but again the only bundle available is my application default bundle. I wanted to learn this technique and make use of it to separate my resources. Any help and suggestions would be greatly appreciated. Thank you
[NSBundle bundleWithPath:[NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] bundlePath], pathToYourBundleWithinTheDotAppDirectory];
Let me know how you get on.
Try something like this:
NSBundle* bundle=[NSBundle bundleWithIdentifier: #"bundle name"];
And make sure that you have selected these options when you have dragged the bundle to the project:
For projects with one bundle, I use:
// in this example, we load test.png from the bundle
NSString *pathToResource = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"png"];
What makes this so convenient is that when you have localized files, this provides the path the the file for the current user locale. This is handy since localized files are not in the main directory, but are rather in their own subfolders (for example, English localized files are in the #"en.lproj" subfolder), and calling them by name is a hassle because you need the full path. This method gets the path for you.

How do I determine which path my application is run from?

I'm creating a little program to copy the Domain file for iWeb over to a USB stick or external harddrive or such. The program is meant to be run from that USB stick or external harddrive, and then create a directory where the application is run from. E.g. the application is run from ~/Documents, the application should create a folder at ~/Documents/(account name)'s website, and then copy the Domain file to that folder. But when I try to run the application from a USB stick, it creates a folder under /, called /(account name)'s website. How do I fix this?
If you want the current working directory of your app then use NSFileManager's currentDirectoryPath.
NSString *currentPath = [[NSFileManager defaultManager] currentDirectoryPath];
NSBundle has an instance method called bundlePath which will almost get you what you want.
NSString *bundleParentPath = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
This should return the directory that the application is being run from.