'Show Package Contents' through objective C code - objective-c

We can right click an .app file and see its package contents. To open a file programmatically, we can use NSWorkspace but how to open the app's package contents?
I have searched a lot but seems there is no solution. Please help if I am missing something.

Per the comment it seems the OP want to open the contents directory of an app in the finder from code. The following line will accomplish that:
Swift:
let appName = "Safari";
let command:NSString = String(format:"open '/Applications/%#.app/Contents'", appName);
system(command.cStringUsingEncoding(NSUTF8StringEncoding))
Objective-C:
NSString *appName = #"Safari";
NSString *command = [NSString stringWithFormat:#"open '/Applications/%#.app/Contents'", appName];
system([command cStringUsingEncoding:NSUTF8StringEncoding]);
Alternate:
NSString *appPath = #"/Applications/Safari";
NSString *command = [NSString stringWithFormat:#"open '/%#.app/Contents'", appPath];
system([command cStringUsingEncoding:NSUTF8StringEncoding]);

This seems to work:
NSString* contentsPath = [appPath stringByAppendingPathComponent:#"Contents"];
[[NSWorkspace sharedWorkspace] selectFile: contentsPath
inFileViewerRootedAtPath: appPath];

An application is just a directory, show package contents just allows you to access the application as a directory rather than executing it. So you can access a file within an application such as
/Applications/Safari.app/Contents/Info.plist

Related

how to get version of default browser on my mac os x

I want to get system information in mac using objective C.
I am searching a lot but did not got single line of code for
my use.They provided solutions via javascript but i want them in
objective C.
Provide me some help to go ahead.
You can use launch services to get the path to the default browser as below
LSGetApplicationForURL((CFURLRef)[NSURL URLWithString: #"http:"],
kLSRolesAll, NULL, (CFURLRef *)&appURL);
NSString *infoPlistPath = [[appURL path] stringByAppendingPathComponent:#"Contents/info.plist"];
Now read the CFBundleShortVersionString from the info.plist.
Here you go :
NSString *userName=NSUserName();
NSLog(#"UserName: %#",userName);
NSArray *ipAddress=[[NSHost currentHost] addresses];
NSLog(#"IP Address=%#",ipAddress[0]);
Updating my answer
This is tested and works well
NSWorkspace *nsSharedWorkspace = [NSWorkspace sharedWorkspace];
NSString *nsAppPath = [nsSharedWorkspace fullPathForApplication:appName];
NSBundle *nsAppBundle = [NSBundle bundleWithPath: nsAppPath];
NSDictionary *nsAppInfo = [nsAppBundle infoDictionary];
//Now you can print all dictionary to view all its contents and pick which you want
NSLog(#"%#",nsAppInfo);
//or you can get directly using following methods
NSLog(#"%#",[nsAppInfo objectForKey:#"CFBundleShortVersionString"]);
NSLog(#"%#",[nsAppInfo objectForKey:#"CFBundleVersion"]);
Dont forget to add AppKit framework

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

Saving attachments from Mail.app through ScriptingBridge (Objective C)

I'm trying to retrieve attachments from Mail.app through scriptingbridge. I'm using the following code to get access to my inbox messages.
MailApplication *mailApp = [SBApplication applicationWithBundleIdentifier:#"com.apple.mail"];
MailMailbox *inbox = [mailApp inbox];
SBElementArray *messages = [inbox messages];
By iterating over the SBElementArray, I can access an individual MailMessage object.
Each MailMessage object has a getter that retrieves another SBElementArray, this time filled with MailMailAttachment objects.
It's working, because if I put a NSLog(#"count:%lu",mailitem.attachments.count); it will print the correct amount of attachments. File name and size are also correct printed.
But when I iterate over the attachments array and save it, nothing happens.
NSURL *url = [[NSURL new] initFileURLWithPath:#"/Users/usr/Documents/tmp/"];
NSLog(#"count:%lu",mailitem.attachments.count);
for (MailMailAttachment *attachment in mailitem.attachments) {
NSLog(#"name:%#",attachment.name);
NSLog(#"size:%ld",attachment.fileSize);
[attachment saveIn:url as:MailSaveableFileFormatNativeFormat];
}
I didn't found any documentation about this method. From header file, it says:
- (void) saveIn:(NSURL *)in_ as:(MailSaveableFileFormat)as; // Save a document.
I'm assuming that the NSURL is the place in which I want to store the file, but I have no idea about MailSaveableFileFormat. I'm passing MailSaveableFileFormatNativeFormat, that I found on header file, but as I said, nothing happens. Not even a simple error message.
I also tried to initialize the NSURL with a directory and a complete filepath (path + filename). Same result.
Does anyone has an example? How do I save it?
TIA,
Bob
I managed to solve the problem. I was initializing NSURL wrong... The code that worked is:
for (MailMailAttachment *attachment in mailitem.attachments) {
NSString *filePath = [NSString stringWithFormat:#"%#%#",#"/Users/usr/Documents/tmp/",attachment.name];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
[attachment saveIn:fileUrl as:MailSaveableFileFormatNativeFormat];
}
On my old system, I use a file path and nil like this [attachment saveIn:file_Path as:nil];
In my "Mail.h" : saveIn:(NSString *)in_ as:(NSString *)as;.
I know it changed on Lion NSURL instead of NSString) , but not in AppleScript script, you must specify the file path without suffering any other parameter --> save thisAttachment in filePath -- Applescript
So I think the complete file path + as:nil should work.

Embedding XML to iOS application

I'm making my first game in iOS and I need to load some levels that are stored as XML. Level files are stored locally and everything works fine from emulator. However, since XML is loaded in the runtime when i try to test my game on an actual device it can't find the XML files since they are not actually part of the app.
I'm coming from Flash background so I might have a wrong idea how this is done on iOS but I need to somehow bundle those XML files with the app, or embed it in the code somehow? Is this possible?
Thanks a lot :)
Well The code to look up your app bundle for the specified file is
NSString *path = [[NSBundle mainBundle] pathForResource:#"fileName.xml" ofType:nil]
NSURL *xmlURL = [NSURL fileURLWithPath:path];
[[NSXMLParser alloc] initWithContentsOfURL: xmlURL]
Hope this helps you...
You could add the XML file to your project and run time read it up with something like this
NSArray *myPathList = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *myPath = [myPathList objectAtIndex:0];
NSError **err;
myPath = [myPath stringByAppendingPathComponent:fileName];
if([[NSFileManager defaultManager] fileExistsAtPath:myPath])
text = [NSString stringWithContentsOfFile:myPath encoding:NSUTF8StringEncoding error:err];
You could consider using JSON in instead of XML. At least to my knowledge the available XML parsers are not nearly as simply to use as SBJson for instance (https://github.com/stig/json-framework/)
Here is my solution in Swift 3.0. In addition to the code, you'll need to add your xml file as a data set in your Assets.xcassets. Do this by creating a new Data Set, giving it any name, and then dragging the xml file from the finder to your newly created data set. When you reference the file in your code, you'll use the file name of the file, and not the name of the data set.
var parseResults = false
if let path = Bundle.main.path(forResource: fileName, ofType: ".xml") {
let url = URL(fileURLWithPath: path)
if let xmlParser = XMLParser(contentsOf: urlToFile) {
xmlParser.delegate = self
parseResults = xmlParser.parse()
}
}

NSFileManager works when built in Xcode as release, but not when ran as standalone OS X Cocoa app

I have the following function written to randomly pick a file from a directory. It works totally fine when I build the project in Xcode for release with the application that automatically opens. However, if I open the application from finder, pressing the button that triggers this function will cause my program to freeze then crash. The only thing I could think of was changing the argument to contentsOfDirectoryAtPath: to not have the ./, but either version has the same exact issue.
Looking at Console tells me that my program exited abnormally with a Floating Point Exception, but I have no idea what's causing it. Is there something jumping out to you guys that I'm not seeing? I only started learning/using objective-C and cocoa about a week ago, so this is all fairly new to me.
Thanks for taking a look at this...
- (NSMutableString*)setFilePathRandom{
NSArray* files;
NSFileManager* fileManager;
fileManager = [[NSFileManager alloc] init];
files = [fileManager contentsOfDirectoryAtPath:#"./Random Trippy Pics" error:NULL];
NSString* directoryPath = (NSMutableString*)[fileManager currentDirectoryPath];
NSString* fileName;
do{
fileName = [files objectAtIndex:(arc4random()%[files count])];
}while([fileName isEqualToString:#".DS_Store"]);
filePath = [NSString stringWithFormat:#"%#/Random Trippy Pics/%#",directoryPath,fileName];
[fileManager release];
return filePath;
}
When an OS X application is run from Xcode, its current directory is the path to the build folder. When run "normally", the current directory is /. So your program is looking for a directory at /Random Trippy Pics, which almost certainly doesn't exist. Where is that directory normally?
Edit:
You could get the directory in which the application is currently stored with this bit of code:
NSString *currentStoragePath = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
However, if the Random Trippy Pics directory is required by the application, you should store it in a known location -- preferably the application's Resource directory. Then you can get the contents with:
NSArray *files = [[NSBundle mainBundle] pathsForResourceOfType:nil inDirectory:#"Random Trippy Pics"];