I have an application that I wrote that uses an external unix executable file. It needs to run this file in order to get some data needed for further processes.
Right now this executable is located in my project folder and in order to use it in my app I have hardcoded paths to it (which is bad).
I've heard that to avoid this hardcoded paths issue it's possible to use bundles.
Can anyone explain me if this is the best way to achieve what I want, and direct me how to do it if so?!
I already looked through similar questions on stackoverflow and went through this:
https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFBundles/Introduction/Introduction.html#//apple_ref/doc/uid/10000123i
it didn't really help me so far...
You use the NSBundle object to locate your executable. You start by getting your application's bundle using [NSBundle mainBundle]. Depending on where you've placed your Unix tool, you can use NSFundle's pathForAuxiliaryExecutable: or pathForResource:ofType: to locate your executable.
For example, if your Unix tool is in your Application bundle's Resources folder, you could do the following:
NSString* toolPath = [[NSBundle mainBunble] pathForResource:#"toolname" ofType:nil]
Related
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];
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.
I'm trying to obtain the path for a java file which I want to load into an NSString.
Currently this line of code is returning nil.
[[NSBundle mainBundle] pathForResource:#"LockDialog" ofType:#"java"]];
I added my file "LockDialog.java" to the project via the menu, File>New>New File. The pathForResource method seems fine for returning the path of txt files or html files but completely fails when I'm trying to get the path of a java file.
Any help or insight massively appreciated,
Thanks,
James
File type should not matter, but chances are the file is not actually being copied to your application bundle. Check your Target>Build Phases>Copy Bundle Resources settings to ensure it's there, and if not, drag it over to this list.
In addition to adding the file to the project, you need to make sure that it gets added to the output bundle.
Open the project in Xcode, navigate to your target, switch to the "Build Phases" tab, and add "LockDialog.java" to the "Copy Bundle Resources" list.
I am writing a program in Objective-C using Xcode. My program creates a file as follows:
[#"" writeToFile:fileName atomically:YES encoding:NSUTF8StringEncoding error:NULL];
I would like the file to be created in the same directory as the executable. When I run the program from Xcode, the file is created in the debug directory as expected.
However, when I run the .app file, the file is created in the root directory. How can I get the program to create a file in the directory where the .app file is located.
Thanks a lot.
EDIT: This is a MacOS application
EDIT2: Well, it seems that I shouldn't be writing to the .app directory. Thanks bbum and Paul R. What is the proper way to do it? To be more concrete, here's what I am doing: each time the user clicks a button in the application, a piece of hardware connected to a serial port will send a bunch data which will be written to a new file. This can happen any number of times while the application is running, so numerous files may be created. I would like them all created in the same folder.
You must never make any assumptions about the initial working directory for your application, as this will depend on what method was used to launch it (e.g. Finder, Terminal (via open), Xcode, gdb, third party utility, etc). You should use an appropriate API to find a suitable directory to store temporary files or user-specific files or whatever it is you need to do. This should never be within the app's bundle and never at a path that is relative to the initial working directory.
You do not want the file to be created inside the .app wrapper. That is never the right answer; your application may easily be installed somewhere where the current user does not have write access to the YourApp.app wrapper.
(For example, my main user account is non-admin and all applications are installed admin-write-only. If an app ever fails to work because it can't write to its app wrapper, the app goes in the trash.)
See this question for an outline of where files should be stored. Depends on the role of the file.
This is a very simple question. I have a script in the same folder as the Cocoa app. I can't seem to set the path to it properly for setLaunchPath for NSTask. Help please.
I have a folder called Project. Inside of it, exist multiple folders but only two we care about: Classes (the source files for the Cocoa app are here) and Ruby (which is a ruby server folder). I am trying to call Ruby/script/server. I assumed it would be something like ./Ruby/script/server or Ruby/script/server but both are wrong.
Thanks.
EDIT: I guess what I'm actually asking is if there is a way to access the folder where the source files or the project is by using a special character or shortcut because by default it goes to the /tmp folder.
The current directory (in the unix sense) in an app is not guaranteed to be anything. The path to the app itself can be obtained by getting the main app bundle by
NSBundle*mainBundle=[NSBundle mainBundle];
and then getting its path
NSString*path=[mainBundle bundlePath];
However please don't do that; you won't be able to distribute your app without extra instructions of putting files here and there.
Instead, put your Ruby code inside yourApp.app/Contents/Resources/. This can be done by including the Ruby code in the XCode, and making sure it's set to be copied into the app. The files inside this Resources directory can be obtained as follows:
NSString*path=[mainBundle pathForResource:#"rubyServer" ofType:#"rb"];
To learn more about the bundle structure, read Bundle Programming Guide.