Thursday, July 26, 2007

Saving data using NSDictionaries

Okay, I had a blog viewer inquire about this problem. They were wanting to save information about people in a single XML file but didn't know how to do it. 

If you want to save information about people, the easiest way to do that is by using nested dictionaries where a single root dictionary contains dictionaries with your data. 

When you store all your dictionaries in a root dictionary, you can just write the root dictionary to file and and you will get an XML file representation of you data. 

I have a demonstration app up on the server, you just can't find it from the first page. 

Here is the link to the dictionary example to demonstrate how you do this. 
maccoder.server.googlepages.com/DictionaryExample.zip
Make sure you build it in XCode first before you run it. The current built file doesn't reflect a change I made in code to keep it from locking up your computer. 

I hope this helps!
Happy coding! :-)

Monday, July 16, 2007

Authenticating Users in Objective-C

Okay, so here is another solution. Let say you are creating an application that makes changes to your computer. You only want administrators to have the right to use your application. How do you go about doing this you might ask... Well, it is actually really simple. Here is how you access the built in authentication framework in Mac OS X in Objective-C.

First, you need to import some libraries. In the header file, import the following files:
  • Security/Authorization.h
  • Security/AuthorizationTags.h
Make sure you use the angle brackets instead of quotations.

This will give you access to the built in authentication and some variables to use for basic authentication.

Second, you need to declare some variables, you need the following:
  • OSStatus
  • AuthorizationRef
  • AuthorizationItem
  • AuthorizationRights
  • AuthorizationFlags
This is how I declared them in the demo app on the demo server. 

OSStatus status;
AuthorizationRef authorizationRef;
AuthorizationItem right = {kAuthorizationRightExecute, 0, NULL, 0);
AuthorizationRights rightSet = { 1, &right };
AuthorizationFlags flags = kAuthorizationFlagExtendRights | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagDefaults;

Now, you have declared all the variables you will need. Notice that you don't have the '*' next to the variable name. This is because you are leaving the realm of Objective-C and going into C/C++ and Objective-C will try to create id variables for all the items with the '*'. This will cause the application to stop responding.

To check authorization, you need to do the two methods. 

First, call this method:

status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);

This calls the dialog to open if you aren't already authenticated. 
After this method call, call this

status = AuthorizationCopyRights(authorizationRef, &rightSet, kAuthorizationEmptyEnvironment, flags, NULL);

This will extract the actual authorization for the user entered and set it to the status variable.

Now, you do a check.

if (status == errAuthorizationSuccess){ 
//do something 
}

That's it! If the user is authenticated, then the method body will be executed, else, it is left alone. Now, in the demo app, I had problems getting the application to keep working after the user closed the dialog, or put in bad information. So, I just surrounded the code with a @try @catch block.

Happy coding! :-)

Saturday, July 14, 2007

Accessing bundled files in Objective-C : NSBundle class

Okay, this is something new that I learned to do recently.

Lets say you have an application that has users. You want to give users the ability to set a picture to represent their account. Well, it's easier if you just have a default picture at first and allow them to change it later. The question is, how will you access that default picture in the application bundle. 
There is a class designed especially to allow us to do this type of thing. It is called NSBundle. 

So, now, you have a user set up a new account, you now need to access that default picture within the application bundle. This is how you will utilize the NSBundle class. 
  • NSImage *defaultImage = [[NSImage alloc] initWithFile:[[NSBundle mainBundle] pathForResource:@"default_image" ofType:@"png"]];
That's all there really is to do to access a bundled file. This opens up the door to many possibilities really. You can include in data files, defaults (like an image, default settings, etc...) and not really let the user have access to it. It also makes it easy for you to distribute any necessary files, in a user friendly way, for your application to work. 

I'm going to play with this some more but I think you can also write to your bundled file (like if you have a bundled database file or something). I'll check it out over the next couple of days and post about my findings. 

Happy Coding! :-)

Back from break!

Hey everyone, I'm back from break now. I had a little time off from school so I went back to my home to visit family. I'm now working with the Mac Team at LANDesk so now, I'm learning even more about how Cocoa and Objective-C work in the real world. I'm still willing to help you all out with problems with Objective-C so saying that, if there is anything that is challenging that you are having problems with in Objective-C, just post a comment to this post and I'll respond back ASAP! 

Happy Coding! :-) (That's now my new saying!)