Category Archive: Source

NSCoder + NSKeyedArchiver

This post is a simple example of NSCoder and NSKeyedArchiver to save and restore the data of an instance.

First of all we need to create our object, in this case an object “Person” with three properties (name, surname, age). The interface looks like normally.

#import <Foundation/Foundation.h>
@interface Person : NSObject { }
@property (retain) NSString *firstName;
@property (retain) NSString *lastName;
@property int age;
@end

The implementation needs some additional code. We need to implement the NSCoding protocol, which means two additional methods. (initWithCoder: and encodeWithCoder:)

#import "Person.h"
@implementation Person
@synthesize age,firstName,lastName;
-(id)initWithCoder:(NSCoder*)decoder{
    if ((self = [super init])) {
        firstName = [decoder decodeObjectForKey:@"firstName"];
        lastName  = [decoder decodeObjectForKey:@"lastName"];
        age           = [decoder decodeIntForKey:@"age"];
    }
    return self;
}
-(void)encodeWithCoder:(NSCoder*)encoder{
    [encoder encodeObject:firstName forKey:@"firstName"];
    [encoder encodeObject:lastName forKey:@"lastName"];
    [encoder encodeInt:age forKey:@"age"];
}
@end

Once we implement the protocol, saving will look like this:

// Save method
// We initialise our object and set the values
Person* p1 = [[[Person alloc] init] autorelease];
p1.firstName = [firstNameTextField stringValue];
p1.lastName  = [lastNameTextField stringValue];
p1.age       = [ageTextField intValue];
 
// We initialise our NSMutableData
NSMutableData *sData = [[NSMutableData alloc] init];
/*And our NSKeyedArchiver initialised to encode stream and version 
information into a given mutable data object.*/
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] 
                      initForWritingWithMutableData:sData];
// Then we encode our object for a key of our choice
[archiver encodeObject:p1 forKey:@"person"];
[archiver finishEncoding];
 
// Finally we can write out the data      
[sData writeToURL:fileURL atomically:YES];

Restoring is the other way around:

// Restore method
NSMutableData *rData = [[NSMutableData alloc]
                         initWithContentsOfURL:locationOfTheFile];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
                         initForReadingWithData:rData];
 
// Initialise the object and use the unarchiver to set the values
Person* p1 = [[[Person alloc] init] autorelease];
p1 =  [unarchiver decodeObjectForKey:@"person"];
 
// set the value on the textfields
[firstNameTextField setStringValue:p1.firstName];
[lastNameTextField setStringValue:p1.lastName];
[ageTextField setStringValue:
                 [NSString stringWithFormat:@"%i",p1.age]];

Here is the source code of the above example with NSSavePanel and NSOpenPanel.

Bandwidth Limiter

Hi everyone…

This post it won’t be very helpful for most of you, but it is extremely useful for me. :)
Currently I live in accommodation flat in London and for some annoying reason every room has a weekly cap of 14Gb… Therefore, I usually reach the limit quite fast so I had to do something!!!

Solution: A Bandwidth limiter that limits my connection to 64kbit/s.

Grab the application from here and the source code here.

Click here to read more »

Textfield validation


The following example is the simplest way to validate a textfield. In this case we have a textfield and the only characters allowed are:

[0123456789QWERTYUIOPLKJHGFDSAZXCVBNMqwertyuioplkjhgfdsazxcvbnm ];

I think in any application with user input you will need some sort of validation :)

You can grab the code TextFormatter

Infix to Postfix in Cocoa

Hi, recently I have been working on this infix to postfix notation converter in C++ for my data structures module at the university. I also discovered that Objective-C does not have templates like C++ to create an abstract data type.

Anyway, the infix to postfix requires the use of a Stack and as you can see here there is a way to implement this behaviour using a NSMutableArray.

Grab the source code - InfixToPostfix – The code is based on this java implementation. Click here to read more »

Preferences window paradigm

In this post I will introduce you my preferences window approach :) For sure is not the only one you will come across, but is definitely one of the easiest ways. In this case the toolbar is created with Interface Builder so is compatible only with 10.5 or later. (less code)

So let’s start…

STEP #1 Preferences window controller

Click here to read more »

Separate nibs/xibs Part 2

Following the previous post that I explained you why you are encouraged to separate your nib/xib files now I am going to explain you how to do it.

STEP #1 The window controller

First we need to create the window controller (NSWindowController) :)  The header file AboutWindowController.h

#import <cocoa /Cocoa.h>
@interface AboutWindowController : NSWindowController { }
@end</cocoa>

And the implementation file AboutWindowController.m

#import "AboutWindowController.h"
@implementation AboutWindowController
- (id)init {
	if ((self = [super initWithWindow:NULL]) != NULL) {}
	return self;
}
- (NSString *)windowNibName {
	return NSStringFromClass([self class]);
// This determines the name of the Xib file, In this case the name
// of the class, so we need to create the AboutWindowController.xib
}
@end

STEP #2 Create the Xib

Now, with Interface Builder we need to add a new Application Xib and name it “AboutWindowController”. Step 1 Step 2

Click here to read more »

Track Spaces changes [Source Code]

Have you ever wonder how to track space changes in Cocoa?

Yes??? Then you were like me, before few months hunting for an answer! I was using a different approach in DockSpaces based on applescript but it was a bit slow and annoying. The solution came from an email <which I manage to lose> and someone explained me how to use CGSPrivate and track the space changes.

So in case you are interested grab a sample project here