Friday, August 24, 2007

Need to make a correction

Okay, if you look backwards in the history of this blog, I've said before that when you use the '*' before the variable name, that tells the compiler to create it in memory. I was a little off by that. What that '*' means is simply reference the pointer in memory. Using this prevents the computer from lugging around a variable from method to method so it can be used. By referencing the pointer, you are essentially lugging around a simple memory address that the method will use to get the value of that variable.

This essentially is saying (Figuratively of course):
I have a car but it's in the garage. If you want to see my car, lets go out to the garage, but I don't personally carry my car with me at all times.

Just thought I would clarify this Objective-C/C++ thing.
Happy Coding :-)

Tuesday, August 14, 2007

Running an application as root in Objective-C

Okay, so if you look back into the past a bit on the Blog history, I was having problems with this type of thing. I had an application that needed to access files belonging to root. Anyway, after 2 1/2 hours reading documentation, I found this code snippet.

AuthorizationRef authorizationRef;

AuthorizationExecuteWithPrivileges(authorizationRef, "/Path/To/", kAuthorizationFlagDefaults, nil, nil);

Now, this will run any application as a root user so use it wisely. Just make sure, if you are trying to run a .app file, you need to continue into it's contents and run the actual application. That's represented above. Just replace both "Application" instances with your application's name.

After the call is made, the OS will launch the application specified with root user privileges. It will require that you authenticate as an admin before the application is launched.

Killing a process by name in Objective-C

Okay, so one thing that really frustrated me was that in objective-c, there wasn't a way to kill a process by name. Well, I found the way to do it. There is a command line application that you can use to kill a process by its name. To use this in Objective-C, you just need to use the following.

system("usr/bin/killall processName");

If you want to make this dynamic created using a NSString, just make sure you call the cString function on the NSString object.

Thursday, August 9, 2007

I need some help!

Okay. So, if you are a UNIX genius, you might be able to help me with this.

I have an application that uses the system() command to send a command to the terminal. I'm using sudo to allow the user to delete files that belong to root.

so an example will be something like this
system("sudo rm /file/to/delete.txt");

But, as soon as this runs, it asks in terminal for a password.

Here's the thing. I need it so that all authentication is done without the terminal. It all needs to be handled in the objective-c application.

Is there a way to pre-authenticate the user so that sudo will work without asking for a password in terminal? Is there another way to delete files that belong to root in objective-c? If you can answer this, please help me out. That would be great!

Saturday, August 4, 2007

What to do next!

So, I think I answered, for the most part, everyone's questions I've received. Now, what else is there that you are having problems with? (Objective-C problems, not life problems)

I'm thinking about placing a post up about Localization. Would anyone be interested in that? It's really hard to explain in the blog so it will be a download the source kind of thing. But, if you are working with a big company that does business around the world, then localization will be something you will have to deal with. 

I'm can't really think of anything else right now to create or talk about so if y'all have any questions about objective, make a comment to this post. I'll receive an email and respond to the comment ASAP.

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.
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!)

Tuesday, June 5, 2007

Pulling in RTF Information in Objective-C


So, a view pointed out that you can't pull in an RTF file because it's in binary.

I did some playing around and found a class derived from a string class called NSAttributedString.

If you want to pull in RTF information, this string does it. I successfully used this to pull in every line from an RTF in the application I posted to the demo server. I still haven't fixed it yet. But hey, RTF's are a possibility! :-)

To get the string data, I just created a new NSAttributedString and called the following init method.
  • [[NSAttributedString alloc] initWithPath:@"location.rtf" documentAttributes:nil];
Then I called the string property and returned a standard string.

The rest I solved using the way I demonstrated before.

Happy Coding :-)

Sunday, June 3, 2007

Reading in individual lines from a file in Objective-C

Okay, I had someone comment on the blog saying that they can get in the string information, they just need to filter out each line. This can be done easily. I also have an application up on the demo server so you can download the source.

It took me a little bit to figure out what the key was to symbolize a new line but it turns out to be a simple \n. So, this is what you have to do:

Read in your text to an NSString object, like so:
  • NSString *info = [NSString stringWithContentsOfFile:@"FilePath.txt"];
Or like this:
  • NSString *info = [[NSString alloc] initWithContentsOfFile:@"FilePath.txt"];
Then you split the string into an array list by doing the following.
  • NSArray *arrayOfLines = [info componentsSeparatedByString:@"\n"];
Now, you will have an array of all the lines in the file. This might actually be one of the slowest means of doing things, since the file has to be read into memory, but it works. And if you have some settings that need to be loaded in through a file, this might just be your thing.

The only bug I had with this was reading in a rich text file. A standard text file works fine doing this method. I hope this helps out. :-)

Saturday, June 2, 2007

Interacting with the command line in Objective-C


Before, I thought that you could interact with the command line only through Apple Script. I found a different way of doing it. If you have a script file for command line, you can access it and utilize it by using one of the following methods in Objective-C (Note, These are C functions)
  • int result = system("Your Command Here");
If you want to get the output from this call, you will have to pipe the output to a file and read it in using Objective-C. You can pipe the output like this:
  • int result = system("Your Command Here > File.txt");
I'm going to try and get a demo up for this to better understand this sometime this weekend.

The result contains from my understanding a 1 if it completed without error or a 0 if it had an error, I could be wrong. All I know is if you handle the result like this.
  • if (!result) {}
Your code will fall through to this method if it had an error.

Now, if you have a script that can run in the background, you can use the following C command
  • FILE *fileObject = popen("Your Command Here");
As shown above, this will return a FILE Object. This is a C object. This contains all the information being sent to and returned from the console, so if you need to get back information, you will have to use some C functions to print it out.

Saturday, May 26, 2007

The Demo Server

The demo server is almost up and ready to go! I'm using Google Pages to create it. I would highly recommend anyone to it. It's freaking awesome!

Anyway, here is the website.


Tuesday, May 22, 2007

CoreData and Objective-C


Here was my problem. I was trying to figure out the best way to store data in Objective-C. I know that Objective-C provides many ways to write text to a file, but handling relational structures can get tricky using this method. This is when I remembered CoreData. This was a little tricky to me at first but after thinking about it in a dumb way, I was able to figure it out. I guess I was looking at it way to much in detail, making it harder than it seemed. I have created an application that uses several features of Objective-C that I just barely figured out like the Alert Panel that is relative to the window that called it as well as getting data out of the array controller when you need it.

To download the application and source, click here and your browser will begin to download it from my iDisk.

Now, if you haven't used CoreData before, I suggest the apple developers website since they have videos :-)

When you have completed the video series (I think there are 14 two to three minute videos), you can then use my information to go in deeper with the CoreData stuff.

This is what I show you in my demonstration application:
  • How to access an array of information that is stored in the NSArrayController Object.

  • How to use the NSRunAlertPanel so that it drops down out of the window (The cool alert panel, I think ;-))
CoreData does all the hard work for you when it comes down to saving and loading information, but you can't do everything in the interface designer. Accessing the data in the ArrayController allows you to branch off and get even more creative with your applications without you having to manage data files.

I hope this makes someones day a little easier! It did mine... :-)

Thursday, May 10, 2007

Interface in Objective-C


I'm placing this post up because I just had an interview with Apple and I couldn't for the life of me remember what the definition to a interface was. I feel dumb because I talked to my roommate and described it perfectly. I hate it when I'm nervous.

An interface in Objective-C is like in the .h file. You have the interface that describes what the class looks like and provides the interaction with the class. Essentially, it is the interaction layer between two classes. Of course, when you think of it on a different scale, an interface could be anything that provides an interaction. Like the UI, it is an interface. It provides interaction. API (Application Programming Interface), It's another interface.

I have to remember this so if I get another interview I won't embarrass myself!

Monday, May 7, 2007

Key Press and Mouse Events in Objective-C

Okay, here is another situation that a programmer might have. Lets say, you are creating a drawing application that requires you to click and hold the mouse and drag it around the screen to draw a line. You can change the color by pressing a button on the keyboard, like b for black, r for red, g for green, etc... How would you go about doing that if the standard events in XCode don't allow for this...

This application is coming up next! I'm excited about this one simply because it will provide more control for you application.

Sunday, May 6, 2007

Recognizing a voice command (NSSpeechRecognizer) in Objective-C

Okay, Lets say you have a complicated application and you know you can do something in it but you cant remember how to get there. Standard UI rules state that you shouldn't overwhelm the user with controls and options. So, how do you help out the user? What about voice activated controls. Objective-C provides access to an object (NSSpeechRecognizer) that works with the computers voice recognizer to help you out. Just getting it to work is tricky.

So, here is the source code for the application. You can download it from my iDisk by clicking here.

I don't know how long this will be up. It all depends on when I get the actual server running. This is just a temporary thing.

For those who don't want to open the source code, here is how you get a NSSpeechRecognizer Object to work.

  • Instantiate your object
  • Set the Delegate to "self" in the INIT method of your control, like so:
    • [speechRecognizerObject setDelegate:SELF];
  • Create a delegate method (Essential, just put in this method header in your controls .m file)
    • - (void)speechRecognizer:(NSSpeechRecognizer *)sender didRecognizeCommand:(id)command{}
    • Fill in the blanks between the {}'s
  • As long as you have the delegate set to self, the object will look in the class where it is instantiate for that method. When a command is recognized, it will send it back in (id)command object.
    • Just so you know, it will only recognize a given set of commands. To set these commands, you will need to pass in a array of commands. I use a NSMutableArray to handle this. You can send in the commands using the [speechRecognizerObject setCommands:arrayOfCommands];
I know I'm going to have fun with this one.

I think I figured out through this demo app how to figure out if the mouse moves or not. It took me this application to fully realize how delegates worked in Objective-C.

Saturday, May 5, 2007

Demo Application Server

Would anyone like a demo application server? I'm going to be creating a web site here pretty quick (In about 2 months) and when I get it created, I can post up some zip files on the server with the source to the examples I post. I will also post the source to the examples I have now.

So, would anyone be interested? If so, comment on this with your thoughts.

I've been really busy this last week with LANDesk so I haven't had all the time I needed to get these demo apps created. I'm tring to get the time to continue working on them because it helps me out a lot. So, if y'all are still interested in my blog and my help with Objective-C, just subscribe to the RSS feed and it will notify you when a demo app is ready.

Wednesday, March 7, 2007

What do you want to know?

Tell me what you want to know.

Comment on this with something you would like to know better and I will try my best to answer your question.

Thursday, February 15, 2007

Using custom panels in Objective-C

Okay, so here was a problem that was presented to my by the Objective-C Language. Lets say in my .nib file, I have a custom panel to create a new person and add them to the database. In C#, I just call the name of the file to instantiate it. I tried to do the same in Objective-C. Well, there is a problem, a .nib file isn't really a class. It is a resource that contains GUI information. So, I had to sit down and figure out how to make my custom panel display on demand. After an hour, I figured out how.

To use a custom panel in Objective-C, you need to create it in your .nib file. After you do so, you need to create a handler for it and your main window. The easiest way to bypass this problem is to just create a reference (An Outlet with NSPanel or NSWindow for its type) to the window and the custom panel in the handlers. So then, if you want to make them appear all you have to do is call the method [panelName makeKeyAndOrderFront];

That's about it. A simple solution to the problem. Now I am sure that there is another way that is probably easier to work with, but this is a quick and pretty easy solution to my problem.

Hope this helps!

Tuesday, February 13, 2007

Classes in Objective-C

Something that confused me about Objective-C was how classes worked. I couldn't really find any good examples on it neither. So I sat down and played with it for a day and figured it out.

I will break down the structure for you and give you an example on how to create a working class in Objective-C.

  • In your XCode project, select File > New File
  • Scroll down to the Cocoa section and add a New Objective-C Class.
  • Change the name of the class to what ever you want, for this example, I will use ExampleClass.
  • Click create.
  • Now, in your project screen you will see two files called ExampleClass.h and ExampleClass.m
  • .h is your interface class. Providing the compiler with a brief overview of what your class has.
  • .m is your implementation class. This is where you will put your init and dealloc method as long as any methods you define in your interface class.
  • Within in your interface class (.h file) you will have the following:



  • Anything placed inside the interface tag becomes attributes to the class. You can only put variables in here. Like an NSString, etc....
  • Methods are declared outside the interface brakets just right before the @end. These are just the method stubs without the { }'s

NSString *personName;
NSString *personAddress;
NSString *personPhone;
- (NSString *)PersonName;
- (NSString *)PersonAddress;
- (NSString *)PersonPhone;
- (void)setPersonName:(NSString *)value;
- (void)setPersonAddress:(NSString *)value;
- (void)setPersonPhone:(NSString *)value;

  • Now to explain the code above: personName, personAddress, personPhone are only to the class. Nothing outside the class can access them. So to solve this problem and allow outside classes to communicate with these variables, you create Accessor methods. If you want a variable to be readable and writable from other classes, you need 2 methods, if you want a variable to be readable only, you need 1. Makes sense really.
  • As you can see, I didn't fill out the methods in this file. That is because it is a interface class and it can't do any work. It only tells the compiler what the class looks like.
  • To fill out the methods, you need to put them into the .m file and fill them out there.
  • In the .m file, add in the method stubs you created in the .h file.
  • After you do so, the .m file should look like this.
- (NSString *)PersonName
- (NSString *)PersonAddress
- (NSString *)PersonPhone
- (void)setPersonName:(NSString *)value
- (void)setPersonAddress:(NSString *)value
- (void)setPersonPhone:(NSString *)value
  • Now you need to fill them out. It should look like this when you are finished
- (NSString *)PersonName
return personName;
- (NSString *)PersonAddress
return personAddress;
- (NSString *)PersonPhone
return personPhone;
- (void)setPersonName:(NSString *)value
personName = value;
- (void)setPersonAddress:(NSString *)value
personAddress = value;
- (void)setPersonPhone:(NSString *)value
personPhone = value;
  • Now you need to add in your init and dealloc method. I can't remember what all is in these methods because XCode's CodeSense will plot it down for you if you type init and press return or dealloc and press return.
  • All you have to do is replace the <# Add Code Here #> tag here to have the compiler perform the the code on method when the class is loaded or thrown away.
That's it. All classes are made this way. It was confusing for me since C# classes just had a single file. Hope this helps!

Reading and Writing Data using Objective-C

Okay, Reading and writing data was something I made a big deal out of. Mainly because I started out with C# two years ago. In C#, you have to declare a StreamReader or a StreamWriter. After which, you then give it a location of a file and it returns a string based on the current line you are on. This made since once I figured it out. Then I got a mac a year back and wanted to figure out how to do the same in Objective-C. I tried the hardest method first thinking it was the easiest. You would think that you would do the same in Objective-C that you do in C#. Not so! All the work has been done for you!
Most objects which contain a NS at the beginning of the name have a method called writeToFile:(NSString *)aLocation.

And if they contain a writeToFile, they also contain a initWithContentsOfFile:(NSString *)aLocation.

So, with that said, this is how you will read in a file to a String.
NSString *filesContent = [[NSString alloc] initWithContentsOfFile:@"file.txt"];

To write a string to a file, well, That's easy too.

[yourDataString writeToFile:@"file.txt"];

Another thing I found to be the most useful in Objective-C is that when you write an array to a file, it converts it over to XML. If you have an array of objects, it will convert those objects to XML and put them in the list as well. This is great especially if you are creating a Mac and Windows app that you need to have working together. You can have your windows app conform to the mac's xml standard for writing arrays and you have two applications working on two systems that work off the same file format.

It is also wonderful because there is hardly any code needed to make it read and write data.

Apple has done it better again! :-)

NSTableView in Objective-C Explained


Lets explain a bit on the NSTextView in Objective-C Example.

The Table view basically contains a dataSource method and a Delegate Method. It looks in the code you associate with it for that tableView Method and the numberOfRowsInTableView Method. It uses this to figure out what to display and how much to display. That's it. That's all it truly does. You need those to methods and provide the code to extract your information.

Unlike Objective-C, C# does all the work for you. All you have to do in C# is put the following to show a single item:
  • listView.Items.Add(aObject);
Basically, Microsoft did all the background work for you. You have to do the background work in Objective-C.

The benefits to the Objective-C form of doing a list or table are:
  • You get more control
  • Formatting is easier
  • Don't have to fool around with a dataset to display multiple items like in Objective-C
  • You can do some pretty neat things, like add images into the table with ease.
The Downside to this is:
  • It requires some setup and prior knowledge of Objective-C or a C Based computer language.
I hope that this has helped out you mac programmers out there who are interested in writing programs in Objective-C with tables!

Monday, February 12, 2007

NSTableView in Objective-C

Okay, lets go through a little example to help you understand just what a NSTableView is doing.

A NSTableView contains two layers, It contains a Data Layer and a Presentation Layer (The Actual TableView)

The datalayer is comprised of two methods that is in any of your classes. I will discuss this later in the example.

An example of this is:
Your monitor will visualize the data but it won't store it. The data is in the computer and is sent to your monitor for visualization.

Now to set this up, you need 3 steps. Step 1 is setting up you .nib file. Step 2 is setting up your data. Step 3 is creating your datasource for the table.

This is going to guide you through the steps to set up a new project that works with a NSTableView.

NOTE:You need to know how to work with XCode and Interface Builder to do this, if you don't know how, you might want to get a visual resouce to explain some of the stuff mentioned here.

Step 1.
  • Create a new NSDocument Based Cocoa App in XCode.
  • When your project is created, double-click the MyDocuments.nib file.
  • When Interface Builder loads you need to do the following:
  1. Remove the "This is a document" lable.
  2. Add a NSTableView Controller.
  3. Open the Inspector and set the columns field to be equal to 1
  4. Double-click in the table view to select the table view and not its NSScrollView Container
  5. Double-Click on the Column's Header to select the NSDataColumn
  6. In the inspector, change the Header to be "Text in Array" and set the identifier to be "text"
  7. Resize the column to look good.
  8. Add a Editable NSTextField (The Text Box)
  9. Add a NSButton and change its text to be something like "Add"
  10. Subclass the NSObject and create a new object called "TableViewController"
  11. Add 3 outlets named "tvTable" with type "NSTableView", "btnAdd" with type "NSButton", "txtTextToAdd" with type "NSTextField"; (You could keep the type as id, it really doesn't matter, this is just the way I like to do it)
  12. Add 1 action called "btnAdd_Click:"
  13. Instantiate and make your connections.After you have made all your connections, create your files.
  • Now you have created your .nib file and your class files. You now need to create your logic
  • Open up the newly created TableViewController.m file
  • You should see a method similar to this
- (IBAction)btnAdd_Click:(id)sender
  • If you don't see this, you will need to start over with the .nib creation.
  • Now, open up the TableViewController.h file
  • In the @interface section, you need to add the following.
NSMutableArray *arrayOfText;
  • Outside the @interface tags, add the following
- (int)numberOfRowsInTableView:(NSTableView *)tableView;
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex;
  • Build your project and close the .h file.
  • Now change your method stubs to look like this:
- (IBAction)btnAdd_Click:(id)sender
NSString *textToAdd = [txtTextToAdd stringValue];
[arrayOfText addObject:textToAdd];
[tvTable reloadData];

- (int)numberOfRowsInTableView:(NSTableView *)tableView
return [arrayOfText count];
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
NSString *valueToDisplay = [[arrayOfText objectAtIndex:rowIndex] string];
return valueToDisplay;
  • Now you need to add in 2 new methods (a init and a dealloc method)
  1. In the .m file, all you have to do is start typing init and wait for codesence to popup. It will too say init. Press enter and it will create your init method. The same will go with dealloc.
  2. Replace the <#Add Code Here#> text in the init method with this: arrayOfText = [[NSMutableArray alloc] init];
  3. Replace the <#Add Code Here#> text in the dealloc method with this: [arrayOfText release];
  • run the project and Wa La! You should now be able to type text into the text box, press the add button and everytime you do that, the text will then appear in the NSTextView.

Now you have finished the construction of the class, It seems like a lot of information but it is just hard to explain with short words. All table views work this way. If you wish, you can check the column's identifier and specifiy information to add based on the column, this makes your table more complex and in some way more beautiful because you can add in a image for a cell or even sliders, radio buttons, etc...

To keep this blog short, I will create another blog called NSTextView in Objective-C Explained.

Friday, February 9, 2007

NSSavePanel in Objective-C

Here is the code to use a basic NSOpenPanel.

1. NSSavePanel *save = [NSSavePanel savePanel];
3. //Optional : Add Code here to change NSSavePanel basic configuration
5. int result = [save runModal];
7. if (result == NSOKButton){
8. NSString *selectedFile = [save filename];
9. //Add Additional code to handle the save;
10. }

Code Explained:
Line 1: When you declare a NSSavePanel, you need to make sure you put a *. Now to retrieve a basic save panel, you just need to use [NSSavePanel savePanel] and place it to the right of the =.

Line 3: You would replace this comment with additional configuration code. These are properties within the panel class like setRequiredFileType:NSString or setCanCreateDirectories:BOOL.

Line 5: When you are ready to present the panel, you will create a integer (int) called anything really, I am just using results since that is what it is storing. When the runModal method is called for the panel, it will return a int based on what the user did in the panel. Typically the user will press the OK Button or the Cancel Button.

Line 7: This is the check to see if the user clicked OK. NSOKButton is an enumeration (enum) that contains the int representation of a Dialog Result equal to OK. If the result is equal to this, then the user pressed okay and you can proceed with your code to handle the save. Now notice the = and the ==. They are used differently! The = means your are setting a value. The == means your are comparing values.

Thursday, February 8, 2007

NSOpenPanel in Objective-C

Here is the code to use a basic NSOpenPanel.

1. NSOpenPanel *open = [NSOpenPanel openPanel];
3. //Optional : Add Code here to change NSOpenPanel basic configuration
5. int result = [open runModal];
7. if (result == NSOKButton){
8. NSString *selectedFile = [open filename];
9. //Add Additional code to handle the open;
10. }

Code Explained:
Line 1: When you declare a NSOpenPanel, you need to make sure you put a *. Now to retrieve a basic open panel, you just need to use [NSOpenPanel openPanel] and place it to the right of the =.

Line 3: You would replace this comment with additional configuration code. These are properties within the panel class like setCanChooseDirectories:BOOL or setAllowedFileTypes:NSArray

Line 5: When you are ready to present the panel, you will create a integer (int) called anything really, I am just using results since that is what it is storing. When the runModal method is called for the panel, it will return a int based on what the user did in the panel. Typically the user will press the OK Button or the Cancel Button.

Line 7: This is the check to see if the user clicked OK. NSOKButton is an enumeration (enum) that contains the int representation of a Dialog Result equal to OK. If the result is equal to this, then the user pressed okay and you can proceed with your code to handle the open. Now notice the = and the ==. They are used differently! The = means your are setting a value. The == means your are comparing values.

Using Objects in Objective-C

As you know, the mac programming language, Objective-C, handles things differently than C# for windows or Java. It took me a little time to understand how all this really works. Here is the syntax for using objects.

When you declare a object, you will need to use this following pattern:

NameOfObject *objectTitle;
- The * tells the compiler that you are creating a variable and not using one.

Accessing an object is differently than other languages too.
When you access an object, it is this following pattern:

[objectTitle methodName];
[objectTitle propertyName];

This essentially replaces the C# way of doing things, which is:

Now when you declare something that is native to Objective-C's mother language C then you don't need the *.

For example:
double objectTitle;

Putting the * before the objectTitle will cause the compiler to freak out. It took me a couple of days to get this straight. Every time I used a double, I would do the * and wonder why it didn't work.

Hope this helps out the New-To-Mac Programmer's.

The Start


I am here to introduce my first blog! I am creating this because I am a Mac Programmer, A new one at that, and I had problems trying to find out information about Cocoa, XCode, and Objective-C. Maybe someone trying to find answers might find them here on my blog.

I will make periodic posts with some information that I found out about Objective-C and Cocoa that I had a hard time understanding or even finding information on. I may even need some help with something. So, if you see this, check back soon and help me and others become a better Mac Programmer.