Retrieve info.plist file from command-line tool - objective-c

Using the following steps, I'm able to embed an info.plist into a command-line tool.
http://developer.apple.com/library/mac/#documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html
I know how to retrieve the plist file from a .bundle, but I'm not sure how to do the same in a single-file tool like I've got.
I've embedded the info.plist into the command-line tool so that I can store the version in it. Does anyone know how I can retrieve it at run-time so I can determine what version is running?
Thanks

__info_plist is a "magic" section name that makes the following Just Work:
NSBundle *bundle = [NSBundle mainBundle];
id version = [bundle objectForInfoDictionaryKey: (NSString*) kCFBundleVersionKey];
NSLog(#"mainBundle.version = %#", version);
If you need to read a bundle embedded in a different executable than the one currently running, this answer by Bavarious from the comments has a more comprehensive list of approaches.

Related

Objective C - How to determine if a folder is a package?

App Packages are basically folders and you can read their contents just like any folders. I understood this.
My question is:
If I have a folder called folderA which has files and a package called PackageA which has files, how can I programmatically tell what is a normal folder and what is a package ?
In my application I need to exclude any packages but process any normal folders.
Any advise would be appreciated.
I have tried to check via NSBundle but both normal folder as well as package folder is an NSBundle. I was hoping one is not. I am sure there is a property that will tell me that?
I solved it as:
NSNumber *isPackage;
NSError *error = nil;
[filePath getResourceValue:&isPackage forKey:NSURLIsPackageKey error:&error];
if( [isPackage integerValue] == 1)
{
// treat as package
}
There are multiple ways to do this, the "modern" way is to use NSURL's getResourceValue:forKey:error: method (or one of its siblings). The key for determining whether the NSURL instance references a package is NSURLIsPackageKey.

Obj-C OS X Delete application from /Applications

I am writing an application to remove a piece of software and its files from OS X. I can delete everything else except the .app and a folder in /Applications. I am using AuthetificationExecuteWithPriviledges, I know that it is deprecated, so could that be giving me admin issues when attempting to move the .app to the trash bin? When I step through the process I see an NSCocoaErrorDomain, with code 513. I did a quick search for it, and saw it is related to a permissions error. My other theory is that my path to the application is incorrect. I am using:
NSString *ibmNotesApplication = #"/Applications/IBM Notes.app";
If you are wondering why I am trying to delete Lotus Notes, it is because the Notes uninstaller provided by IBM doesn't have all of the functionality I would like. So, I am writing one that removes notes and all files related to it so we can have a fresh install.
Here is a snippet of code where I move an item in the array to the trash bin.
if ([filemanager fileExistsAtPath:object])
{
NSURL *objectURL = [NSURL fileURLWithPath:object];
NSURL *trashedObject;
NSError *error;
//Moves item to trash bin and update log
if([filemanager trashItemAtURL:objectURL resultingItemURL:&trashedObject error:&error])
{
NSLog(#"Trashed %# to %#",objectURL, trashedObject);
self.textfield.stringValue = [NSString stringWithFormat:#"%#%#%#%#%#%#", self.textfield.stringValue, #"Trashed ", objectURL, #" to ", trashedObject, #"\n"];
}
As you mentioned in the question, the function AuthorizationExecuteWithPrivileges is a deprecated function and has been for quite a while now. I suggest you start by following Apple's advice of factoring out the privileged process into a separate privileged helper tool, which is launched with the help of launchd.
You can follow the example code here.
If the permission problem still exists, then at least you've gone about refactoring your code to the right way of doing things, knowing that it will be supported for future versions of the OS.

Core data creates an sqlite file with no tables

I am creating an ios application with xcode 4.6.1 which uses core data to save data in the database, i have provided the deployment target as ios 4.3 and the base sdk is set to latest 6.1.
The place where i am stuck is when i run the application on ios 4.3 i see that my sqlite file is created but contains no tables in it. I have wrote no special code here and every thing is by default taken care in the app delegate, i came across few post where other developers have said to
NSURL *modelURL =[[NSBundle mainBundle] URLForResource:#"StudentData" withExtension:#"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
use "mom" above but i even did that and it seems that every time in ios 4.3 this issue pops up, i have also tried and reset my simulator lots of time but nothing seems to be working and i do require ios4.3 support so please let me know what's going on here and what do i need to do.
I also tried printing
NSLog(#"%#",[self managedObjectModel]);
but it's not nil
Please note their is no mistake in the name of the files here.
Thanks
NSBundle *modelWrapper = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:#"StudentData" ofType:#"momd"]];
NSString *modelPath = [modelWrapper pathForResource:#"StudentData" ofType:#"mom"];
managedObjectModel = [[NSManagedObjectModel alloc]initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]];
By default in Mac OS you don't have write permission.
From terminal go to the path where you have stored your StudentData file and then write this command chmod 777.
It will allow you to write data in files.
Well, i got this working what i did was ran the application and saw that it created the sqlite file but with no tables but when i tried to insert the data in the database with ios 4.3 then the data got inserted and tables were created surprisingly it did not make any sense to me but i got this working without changing anything in the code.

ios read content from private network address

I need to read a file that come for example:
\\192.168.0.1\Folder\Readme.txt
how can I read this file from my app into the iPhone
NSString *pathToTextFile;
NSError *readError;
NSString *fileData = [NSString stringWithContentsOfFile:pathToTextFile
encoding:NSUTF8StringEncoding
error:*readError]
NSLog(#"here is your file as string = %#",fileData);
I think in this case you can use a library like ASIHTTP. Link
It should be possible to download the file into a NSString object, and then store this object into a file.
[nsStringObject writeToFile:pathToFile atomically:YES encoding:stringEncoding error:errorHandler];
As you suggest in your question, you need to access your file over SMB protocol (samba or windows share). I don't think iOS supports smb out of the box, however, i stumbled across tango library on github some time ago. The library claims to be a SMB/CIFS implementation for iOS, so i guess you might give it a try.

Launching App using 'launchedTaskWithLaunchPath' Cocoa/objective-c API

I need to launch 'TextMate' from an App, and I used the following code.
[NSTask launchedTaskWithLaunchPath:#"/Applications/TextMate.app" arguments:[NSArray arrayWithObjects:#"hello.txt", nil]];
But, I got the following error return.
*** NSTask: Task create for path '/Applications/TextMate.app' failed: 22, "Invalid argument". Terminating temporary process.
What's wrong with my code? I just tried to run "TextMate hello.txt".
ADDED
I could make it run as follows.
[NSTask launchedTaskWithLaunchPath:#"/Applications/TextMate.app/Contents/MacOS/TextMate" arguments:[NSArray arrayWithObjects:#"hello.txt", nil]];
And I asked another question to see how many other ways available.
In this case, the invalid parameter is the application's name.
If you check the documentation for NSTask you'll see that the method you're using is basically a wrapper for the low-level exec() system call. This means you need to provide the name of an actual executable or binary file for it to be able to create the process. In your case, you're giving it a directory (use a terminal to confirm that most app bundles in /Applications are directories). That's why it barfs.
You could look inside TextMate's bundle directory to find the actual executable (should be somewhere in /Applications/TextMate.app/Contents/MacOS). You could then modify your code to call the actual executable.
However, it would seem that the correct, Cocoa-ish way to do it is by using NSWorkspace, you might look into its openFile:withApplication: method, which seems to do what you need, and in this case you DO specify the application bundle directory as a parameter, the way you were originally doing it.
Official documentation is here.
By the way, I can't fully take credit for it; see this StackOverflow answer to learn more about this topic.
You're trying to launch a directory, not a binary.
With the onset of sandboxing this does not work anymore and fails with "forbidden-sandbox-reinit" if you try to launch yourself.