Objective C: How to get another application's bundle identifier - objective-c

I would like to get the bundle identifier of an application, given it's path.
eg:
NSString* vlcFilePath = #"/Applications/VLC.app"
I know how to get the bundle identifier using NSWorkspace if it is the active application, but in this case it is not necessarily the active application.

NSBundle has a bundleIdentifier method. This won't run or load the application if it is not already loaded/running:
NSString *vlcFilePath = #"/Applications/VLC.app";
NSBundle *bundle = [NSBundle bundleWithPath:vlcFilePath];
NSLog (#"%#", [bundle bundleIdentifier]);

Open the application bundle's plist file and read it from there:
NSDictionary *plistInfo = [NSDictionary dictionaryWithContentsOfFile:[vlcPath stringByAppendingPathComponent:#"Contents/Info.plist"]];
NSLog(#"VLC bundle identifier = %#", [plistInfo objectForKey:#"CFBundleIdentifier"]);

Related

How would I get the other app's version from mac app

How would I get the other app's version.
I can use [NSWorkspace fullPathForApplication:(NSString *)appName] to get app's path, can I get the app's info?
There's several ways you can accomplish this — I usually take the shortest route using NSBundle in addition to CFBundleversion:
NSBundle *appBundle = [NSBundle bundleWithPath:appPath];
NSString *bundleVersion = [appBundle objectForInfoDictionaryKey:#"CFBundleVersion"];
Once you have the full path to the Application, you can read the Contents/Info.plist file and look at the CFBundleShortVersionString value.
Something like this:
NSString *appPath = [NSWorkspace fullPathForApplication:appName];
NSString *plistPath = [appPath stringByAppendingPathComponent:#"Contents/Info.plist"];
NSDictionary *plist = [NSDictionary dictionaryWithContentsOfFile:plistPath];
NSString *version = plist[#"CFBundleShortVersionString"];

pathForResource ofType returns nil

here is the code i am working with.
NSString* path = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"plist"];
if(path == nil)
{
NSLog(#"file not found");
}
when i run this it prints file not found in the console.
my file.plist is in the supporting files folder in my cocoa project. where does mainBundle look for files at exactly. this is stumping me quite a bit. i get that it looks for the .app file, but when developing the app where doe mainBundle look?
pathForResource:ofType: only looks in the Resources folder (and localised folders). If you are placing files into dedicated folders in the bundle then you need to use pathForResource:ofType:inDirectory: and supply the directory name.
If the NSBundle you found is what you wanted through :
NSBundle *yourTargetBundle = [NSBundle mainBundle];
or
NSBundle *yourTargetBundle = [NSBundle bundleWithURL:[[NSBundle mainBundle]
URLForResource:#"YourCustomBundleName" withExtension:#"bundle"]];
And get the nil result use function: pathForResource: ofType:. Then you can log the paths of resource under yourTargetBundle:
// Given that your resource type is .png and have no sub dir
NSArray *resoursePaths = [yourTargetBundle pathsForResourcesOfType:#"png" inDirectory:nil];
NSLog(#"resoursePaths == %#",resoursePaths);
it will log all the resources path of type png. You can get the image object use:
targetImg = [[UIImage alloc] initWithContentsOfFile:#"OnePngPathYouChose"];
I think the above approach is one way to resolve the return nil situation.

Program directory in Objective-C (OSX)

I'm developing an OSX-application and in it, I'd like to know what the current directory is (i.e. the directory which holds .app-file).
At the moment, I'm using the following code:
NSString *dir=[[NSFileManager defaultManager] currentDirectoryPath];
[[NSAlert alertWithMessageText:#"dir"
defaultButton:#"OK"
alternateButton:nil
otherButton:nil
informativeTextWithFormat:dir] runModal];
When running from Xcode (Run-button), this gives me the debug directory (which is what I'm looking for), but when double-clicking the app in Finder (so, in the debug directory), it's giving me / which puzzles me.
Why does this happen and how can I get the current directory reliably?
That is the bundle folder:
NSString *appPath = [[NSBundle mainBundle] bundlePath];
(reference).
When programming in Apple Swift you will get the application path with:
let pathtoapplication: String = NSBundle.mainBundle().bundlePath

How do I copy a directory that is inside of my main bundle to an NSPasteBoard?

I have been tearing my hair trying different combinations of file paths and different types but basically what I am trying to do is copy a folder called "test" that is inside of my resources folder.
Copying folders onto the NSPasteBoard works when I give an absolute path (ex: /Users/dw/src/Menulet) but it doesn't work when I try using my mainBundle's resource path.
Here is the code I currently have:
NSString *resourceFolder = [[NSURL fileURLWithPath:[[NSBundle mainBundle]
resourcePath]] absoluteString];
NSPasteboard *pboard = [NSPasteboard pasteboardWithName:NSDragPboard];
[pboard declareTypes:[NSArray arrayWithObject:NSURLPboardType] owner:nil];
NSString *SDKPathString = [[NSString alloc] initWithFormat:#"%#test/",
resourceFolder];
NSURL *SDKPathURL = [[NSURL alloc] initWithString:SDKPathString];
[pboard writeObjects:[NSArray arrayWithObject:SDKPathURL]];
The result is that it can't find the file:
__CFPasteboardIssueSandboxExtensionForPath: error for [/Users/dw/Library/Developer/Xcode/DerivedData/Menulet-bvwpfkjlcufhxubvaxubgnubtfgi/Build/Products/Debug/Menulet.app/Contents/Resources/test]
How can I copy the directory?
Edit:
My guess is that you're missing a '/' character when you do this:
NSString *SDKPathString = [[NSString alloc] initWithFormat:#"%#test/",
resourceFolder];
Indeed resourceFolder is a path, I usually use something like this instead:
NSString* SDKPathString= [resourceFolder stringByAppendingPathComponent: #"test"];
Even if in your case you could simply correct the error by putting a '/' character before "test".But I think this is more mnemonic.
Update
Isn't said that if you create a group Xcode also creates a folder. If you want to be sure that Xcode does so, create a folder with finder and drag it to the project. Check these options:
This way the folder is actually created, and also added to the bundle.
Update 2
You shouldn't try to move your directory inside the project folder to put into the right place, instead put it wherever you want in the bundle, provided that the directory is copied in the bundle.
Once did so, the bundle will manage everything for you. So just search the directory using:
- (NSString *)pathForResource:(NSString *)name ofType:(NSString *)extension;
So in your case:
NSBundle* bundle= [NSBundle mainBundle];
NSString *SDKPathString = [ bundle pathForResource: #"test" ofType: #""];

NSWorkspace vs NSTask to start iTunes from a sandboxed app

I'm trying to run iTunes from my ObjectiveC app that runs in a sandbox.
Apple documentation mentions that 'child processes created with the NSTask class inherit the sandbox of the parent app'. The result is that when running iTunes, some permission error pops up and iTunes is closed.
When running it using NSWorkspace methods it does not crash and seems it's running outside any sandbox. Does that mean that i have permission to insert some dynamic library at launch time using DYLD_INSERT_LIBRARIES ?
Here's some code:
NSString* appPath = #"/Applications/iTunes.app";
// Get application URL
NSBundle *targetBundle = [NSBundle bundleWithPath:appPath];
NSURL *applicationURL = [targetBundle executableURL];
NSString* libPath = [NSHomeDirectory() stringByAppendingPathComponent:#"myLib.dylib"];
// Environment setup
NSDictionary *config = nil;
NSDictionary *env = [NSDictionary dictionaryWithObject:libPath forKey:#"DYLD_INSERT_LIBRARIES"];
NSNumber *arch = [NSNumber numberWithInt:(int)NSBundleExecutableArchitectureI386];
config = [[NSDictionary alloc] initWithObjectsAndKeys:env, NSWorkspaceLaunchConfigurationEnvironment,
arch, NSWorkspaceLaunchConfigurationArchitecture, nil];
// Launch application
[[NSWorkspace sharedWorkspace] launchApplicationAtURL:applicationURL
options:0
configuration:config
error:nil];
[config release];
When the above code runs in a sandbox iTunes starts without any lib. Any suggestion?
Thanks,
Vlad.