Reveal bundle contents in Mountain Lion using ObjC - objective-c

How can I reveal a bundle contents in Mountain Lion using [NSWorkspace selectFile:nil inFileViewerRootedAtPath:pathEndingWithDotBundle]? I mean: pathEndingWithDotBundle is a path whose basename is something like "folder.bundle". If I call this method this way, the Terminal opens up and I don't know why...

It opens Terminal because it thinks you want to launch the bundle, and that's the default application. I would open a bugreport against this, because the documentation does not say that it will open the path. It says it that it will display it in a file viewer. It would be reasonable for this to be an error (since a bundle is not logically a directory; it's just phyiscally a directory). But it makes no sense for it to do something random like try to launch another program.
That said, it's fairly easy to work around. Just select the Contents folder, which is required to be within the bundle:
[[NSWorkspace sharedWorkspace] selectFile:[pathEndingWithDotBundle stringByAppendingPathComponent:#"Contents"]
inFileViewerRootedAtPath:pathEndingWithDotBundle];
In 10.6+, you can use activateFileViewerSelectingURLs:
NSURL *URL = [NSURL fileURLWithPath:[pathEndingWithDotBundle stringByAppendingPathComponent:#"Contents"]];
[[NSWorkspace sharedWorkspace] activateFileViewerSelectingURLs:#[URL]];

Related

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"];

Programmatically discover the name of the .DMG

say I have a .DMG
I click it to open it
there's an app inside.
I run the app (which I develop)
Is there a programatic way for the executable to find out the name of the .DMG it's running from at runtime (if any)? perhaps a "Get full path" which will include the name of that DMG? There are certain keywords on that .DMG name that may exist and if they do, I need to act upon them.
[[NSBundle mainBundle] bundlePath]; //Or Bundle URL, depends if you prefer NSString or NSURL.

data file location on iPad

I've been teaching myself over the last couple of weeks by typing in programs from the iPad books I bought (Backlin's, SAM's, Apps for Dummies, etc.) and YouTube tutorials. Still, there are a couple of things I haven't grasped intuitively. Do you mind helping me out?
I got a program working that saves and retrieves names and phone numbers from pList files. I looked on the Mac's HD and couldn't find the file (Contacts.plist), even though the program was working. I finally discovered it at
~/Library/Application Support/iPhone Simulator
I'm not sure why Finder didn't locate it. My own app needs to load a data file when it starts (questions and answers, for example). Do I write a program to create the Q & A file, (I could modify that phone program to do that) then copy the file into the simulator's virtual directory for my own app? Or do I copy that file into the XCODE Resources folder? Would the data files then travel with the finished executable program?
Sorry to sound so clueless. Thanks for any info. -Rob
If you want to deliver a file with your finished application, you must add it to your Xcode project. It doesn't matter whether you place it under Resources or in another group in Xcode as Xcode will by default copy all non-code files that are in your project into your finished app bundle.
To access this file from your code, you need to retrieve its path:
NSString *fullPathToContactsFile = [[NSBundle mainBundle] pathForResource:#"Contacts" ofType:#"plist"];
Note that unlike on the iOS Simulator, your app bundle on the device is read only, so if you want your app to make changes to the file, you cannot save it in the bundle itself. In that case, your app should copy the file from your bundle to your app's Documents or Library directory on first launch and then open/save it from/to that location.

NSBundle folder not found on device, but works in simulator

I'm having a really weird problem with the iPad app I'm writing. On startup I want to copy a folder containing a few other folders (that are empty) from the application bundle to the Documents directory. The folder to be copied, called 'flds' (all lowercase), was added to the Xcode 4 project using 'Create folder references for any added folders', and I have checked that it is actually part of the .app file after compiling. (And that it doesn't exist already when attempting to copy.)
I've tried getting to the 'flds' folder using either one of these calls (they all work):
[[[NSBundle mainBundle] bundleURL] URLByAppendingPathComponent:#"flds"]
[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"flds"]
[[NSBundle mainBundle] pathForResource:#"flds" ofType:#""]
Then copying using NSFileManager's copyItemAtPath:toPath:error: method (or the URL equivalent when using URL instead of path string).
All of these strategies work perfectly in the iPad Simulator and on the iPad device, with the following exception: When I (successfully) build for Ad Hoc distribution, drag the .app and the .mobileprovision into iTunes, sync and then run the app on the device, the system no longer thinks the 'flds' folder exists! I've been trying to examine this for many hours, with no luck. Again, I'm perfectly sure it works both in the simulator and on the device running from Xcode, but not when synced via iTunes.
Ideas?
I discovered that the following call gets the folder path successfully also after syncing the iPad app via iTunes:
[[NSBundle mainBundle] pathForResource:#"flds" ofType:nil inDirectory:nil]
However, when I use this path to copy the folder to its new location in the Documents directory, only the folder itself and the .txt file in it (which I put in there as a test, it's not really supposed to be there) gets copied, and not the 6-7 empty subfolders. Again, the same pattern shows itself: Works as expected both on simulator and device running from Xcode ('flds' folder with 'test.txt' and empty subfolders are copied successfully), but not when synced via iTunes (only 'flds' folder with 'test.txt' are copied, not subfolders). Is this really the intended behaviour of copyItemAtPath:toPath:error:? And why would it behave differently after syncing via iTunes?
In the end I figured out that copyItemAtPath:toPath:error: wouldn't copy empty folders, even though I think it's supposed to. And again, this behaviour only occured after syncing the app to the iPad via iTunes (when running from Xcode it did copy empty folders). My solution for the time being is to simply put a dummy text file in each subfolder, so that they're not empty anymore.

Why currentDirectoryPath return different result under IDE and without it?

I have a strange trouble using below code
NSString * pth = [[[NSFileManager defaultManager] currentDirectoryPath] copy];
If that code runs under IDE it works fine, and i have pth like that
/Users/user/Desktop/iShutdown/build/Release
But if i run that code without IDE simply launching my standalone app
i see in log that pth is only contains "/"
Why? how to get same result in standalone mode?
The initial working directory will depend on how the application is launched and you should never make any assumptions about what this will be. For Finder launches it will typically be / as you have seen, while for Xcode launches it will usually be the same directory as the executable (although you can change this in the settings for the executable). There are various other ways of launching an app though, e.g. from the command line, so the initial working directory can be pretty much anything the user wants it to be.
If you just want to find some specific file which resides at a specific location relative to your app, e.g. a data file that your app needs, then you should just get the path to your application bundle and use that, not the working directory.