Showing posts with label Cocoa. Show all posts
Showing posts with label Cocoa. Show all posts

Thursday, December 18, 2008

When too much is too much ... #2

I'm finally putting the final touches to my NSKeyedArchiver/NSKeyedUnarchiver replacement. It's not that it's a complex things to do really, it's just that finding the time to do it with a 4 weeks old baby around is I found, a major challenge. Overall, I'm satisfied by how my archiver is doing since it's packing that simple object (1 uint + 1 float) I was talking about in my previous post into 44 bytes instead of the wasteful 232 bytes of NSKeyedArchiver (while still supporting keyed encoding, of course). That 44 bytes include a preamble which ,when needed, could be skipped, for example when storing a collection of objects into a same file, so the archived object really only take 35 bytes, which isn't bad all considered :-)

Wednesday, December 10, 2008

When too much is too much ...

To store the data generated with my iPhone application, I have been using the facilities provided by the NSCoding protocol in cooperation with a NSKeyedArchiver, and it works quiet well even if it is likely not what I should be using since it force all my data to be saved or loaded all at once. Nevertheless at this stage in the development process, this is a good enough solution since my data-set is relatively small (less than 30 items). The whole concept of archiving object isn't new to me since I was using it back in my BeOS days (BMessage with the BArchivable class), however the NeXT's take on this old favorite is a little much more handy to use, thanks to Objective-C dynamic nature (compared to C++ more rigid nature) . Since the name of the class is archived at the same time than the object data, it can be later used to recreate the object automatically (granted that the executable unarchiving your object knows about that particular class).

Unfortunately, there is (of course) a price to paid for using NSKeyedArchiver. The end result bytes consumption is criminally high. For example a simple NSObject derived class, encoding a uint and a float, requires a 232 bytes long buffer. 8 bytes of real data (not counting the class name), flattened into 232 bytes ... So obviously, lots of the overhead won't be duplicated if I was encoding more than a single object, but if you want to archive a single object for transmission or storage (bytes oriented kind of storage), the cost is a little too high.

Hopefuly, since the NSCoding protocol is based on using the abstract class NSCoder, one could create its own archiver, with hopefully similar capabilities, but lower memory footprint. I know, I shouldn't waste my (limited) time making my own, and instead focus on the app, but I can't help ...

Wednesday, November 12, 2008

Kind of done ...

I sort of completed my first iPhone app yesterday. It's nothing fancy, really, but it's something we were in imminent need for. Since I only applied for enrollment in the iPhone developer program back on October 29th, I have yet to put the app on my iPod touch for testing. I sure hope we get accepted ASAP so that we can do a real life test ...

The experience has been very fun, so far. For a mobile device, the IDE (Xcode) and the API (Cocoa Touch) are pretty good in comparison to what I was used on Symbian (CodeWarrior). Now, to be fair I should mention that the last time I had to use Symbian stuff was back in 2005. Since I haven't followed-up on it since, I shouldn't really compare both experiences ... yet, coding for the iPhone as so far be a real pleasure where Symbian was a major pain (lacking documentation, constant need for tricks & hacks ...). I have yet to explore the whole touch API, but right now it appears to be consistent and well though-out.

I'm not going to disclose just yet what sort of application we are working on. But I believe it should be fairly easy to guess at it. Post your guesses as comments if you'd like, the winner will get a free version (if and whenever it get released) ;-)

Saturday, October 11, 2008

@superfluous #2

While I'm in whining mood these days (so it seems), let's me talk about a part of Objective-C which I don't like too much: the lack of namespace. This has a unfortunate effect on the way Cocoa can be confusing at time simply because in order to avoid name collision, everyone is prefixing his stuff with some kind of 2 to 3 letters abbreviation. For example, Apple have been using NS since back in the NeXTSTEP days and thus everything in Cocoa is prefixed as such (e.g NSApplication, NSController ...). And this is the problem since at first glance, there is no easy way to tell what a particular keyword is, unless you already know about it. For example, is NSPoint a class? No, it's a structure. NSNumber? a class, NSInteger? a type ... 9_9

Since namespaces are a relatively recent addition to C++, the fact that is missing from Objective-C isn't much of a surprise. However, one may wonders why it has still not been added. In any case, this is somewhat irrelevant, since it is unlikely that Apple will go over Cocoa (and other framework such as Foundation) and make use of some Cocoa namespace; braking everyone code in the process. Alas, something like NS::TInteger, NS::CNumber will have make the developers life a little easier ...

Like our Hungarian friends like to said: A little prefixing can go a long way ...

Friday, October 10, 2008

@superfluous

A week or so ago, I decided to stop my Cocoa musing and focus instead on properly following Aaron Hillegass' Cocoa Programming for Mac OS X. The idea being that this will give me a more proper initiation to Cocoa, especially on the subject of KVC, KVO and the famous bindings. I started Chapter 8 last night and went through the implementation of the first version of the RaiseMan tutorial. This chapter also introduce the usage of the new Objective-C 2.0 @property, which can be use to automatically create setter and getter methods. Now, it's all good, I don't mind saving some time by writing less code, however I'm running into a bit of a personal conflict with this.

Like many other developers that have been around for sometime, I've grow over the years my own coding style, made up of all the things I have encountered and came to appreciate. One of the thing I find necessary is the prefixing of any variable by a lower case single character which give some clear hint on the origin of the variable (e.g iSomeNumber, aObject, lCount ...). In case you are wondering, I got into that habit from my time on Symbian. Now, there's no problem with using such notation with Cocoa unless you happened to want to define an instance variable as property.

What @synthesize do behind the scene is to generate the setter/getter methods using the name of the instance variable. So far so good. Now, if you happens to name your instance variable something like iSomeSumber, the setter will end up being -setISomeNumber: and the getting -iSomeNumber ... Not very elegant, right? (What I want really is the methods to -setSomeNumber: and -someNumber ... well really, I'd like the getter to be -getSomeNumber ... but that's another issue ...)

Since there is a refactoring tool in Xcode which will generate the setter and getter of a given instance variable, I do find the @property somewhat superfluous (Yes, I do know that the property allow for more than what the current refactoring tool does).

Thursday, September 25, 2008

The Dark Side (TM) clouds everything ...

I have been observing for a while now how things are panning out with Apple and the App Store. Since I haven't started developing for the iPhone yet (but soon! I'm starting a new full time job doing just that in 6 days!!, I can't add anything of value to the on-going discussions, except joining the group of bystanders and shaking my head in disbelieve at each moves Apple made. Even thought I always had a soft spot for Apple since my days on an Apple IIc, I'm not naive enough to believe they can do no evil ... especially since they sort of have a proven track record of not always playing fair and square. Lots of fore front bloggers have commented about the whole situation (e.g Daring Fireball, Wil Shipley ...), including the still standing NDA, which have already caused the publishing of a programming book to be canceled. Now, as long as you can stay anonymous (does that really mean anything on Internet these days?), it is not impossible to post details (including tutorials) on Cocoa Touch. It is a bit of a risky endeavour I must said, but very much appreciated by newbies iPhone devs like myself ;-)

On another subject, but still related ... The Technologizer.com web site has an interesting post with a bunch of old to recent Apple's TV ads, make sure to check it out for a bit of nostalgia.

Wednesday, September 24, 2008

Toying around ... #2

A few pointless posts ago, I was talking about Nibless Cocoa applications, and how Jeff Johnson, had a ready to use solution for us, Interface Builder cheaters. Jeff's elegant solution is build around using Cocoa NSObject's ability to have a class pose as another class (but it must be a parent class). The trick been to make sure that when the application is starting, the NSBundle created to load the main NIB file does not load it, and instead just pretend to have done so. The method works like a charm (granted that the entry NSMainNibFile in info.plist has been removed), however there is just a little problem: the class method poseAsClass has been deprecated in OS X 10.5 and is not even present in 64-bit Cocoa. I have no idea whatsoever this is been phased-out by Apple. Since a similar facility exists in Objective-C and GNUStep, it's not clear at all why this have to go ... Security concern maybe? Whatever the explanation, I'd like to know ...

So ... since I'm interested in a solution that can work from 10.4 and beyond on PowerPC and Intel, 32-bit as well as 64-bit, I had to go back to the drawing board and come-up with an alternative solution, likely something not as elegant. Hopefully, thanks to Objective-C's dynamic abilities, it is possible to replace on-the-fly a method implementation by another function (as long as it have a compatible signature). Scott Stevenson have made a an excellent post on this, which I used as the base of my solution.

The idea is relatively simple: replace the NSBundle's class method loadNibNamed:owner: by my own implementation function and call the original method only in when necessary. Since I wanted to have this automatically done as part of a special type of application, I derived NSApplication in HZNiblessApplication, implementing its object method init to do the dirty work:


- (id) init {
if ((self = [super init]))
{
Method lMethod = class_getClassMethod([NSBundle class],@selector(loadNibNamed:owner:));
if(!lMethod)
NSLog(@"NSBundle+loadNibNamed:owner: not found!");
else
{
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4
gDefaultNSBundleLoadNibNamed = method_setImplementation(lMethod,(IMP)loadNibNamed);
#else
gDefaultNSBundleLoadNibNamed = lMethod->method_imp;
lMethod->method_imp = (IMP)loadNibNamed;
#endif
}
}
return self;
}
view rawThis Gist brought to you by GitHub.

As your can see, the method basically retrieve the method within the NSBundle class, and swap its implementation with a function called loadNibNamed. Since we need to call the original method to perform its duty when there is a need to load a bundle, we save the pointer to the function in a global variable named gDefaultNSBundleLoadNibNamed. Let's have a look now on how that replacement function is implemented:


BOOL loadNibNamed(id aObject,SEL aSelector,NSString *aNibNamed,id aOwner)
{
if (!aNibNamed && aOwner == NSApp)
return true;
else
return (BOOL)(*gDefaultNSBundleLoadNibNamed)(aObject,aSelector,aNibNamed,aOwner);
}
view rawThis Gist brought to you by GitHub.

From there, all that is needed is to replace the value of the NSPrincipalClass key in the application's info.plist by HZNiblessApplication and get your application delegate to fill in the Application menu from -applicationWillFinishLaunching: ... Okay, yeah I'm simplifying a bit here, but you get the point I'm sure :-P

As you have noticed, I finally figured a way of putting neatly formatted code (hmm ... at least on Firefox) on this blog, courtesy of github.com.

Friday, August 22, 2008

Toying around ...

I purchased on the App Store the game Toy Bot Diaries from local company (Vancouver!) IUGO, after reading the review posted on touchArcade. I can only agree with the author, it's a very sweet deal (nice gaming, low price). Best of all, the game take advantage of the controls native to the platform, and it work out pretty well, except if you are trying to play while lying down ... In this setup, I found the control to not work too well. No big deal really, I shouldn't be playing right before sleeping anyway ... ;-)

Meanwhile, I have been continuing my Cocoa musing without Interface Builder, and banging my head on the (one will think) simple issue of filling the application menu. Hopefully for ma sanity, I came accross Jeff Johnson's blog which have a serie of great posts (and a sample XCode project), on how to create a Nibless application. Turns out it's not as simple as it should be. It's also more akin to hacking the framework than using it ... anyhow it does work.

Before I sign-out, I will like to point to a video from the lastest iPhoneDevCamp, which feature Neil Young's (no, not the singer) keynote on the iPhone as a gaming platform.

Saturday, August 16, 2008

NSApplication and delegate #2

The only reason for that yucky thing I could think off, is that they wanted to save people from having to define and implement all 14 methods each time a NSApplication delegate was needed, even if only one of them was needed. Since the concept of optional method in a Protocol was only introduced recently in Objective-C 2.0, using a protocol for the NSApplicationDelegate (or for NSApplicationNotifications) was I guess not a solution back when NeXTSTEP was been designed and implemented. Still, having to define and implements a bunch of methods isn't much of a huge burden (copy&paste), likely only a couple of them are going to have a real implementation, and the number of application delegate class per application is mainly, well ... one.

I'm aware that adding methods in Objective-C isn't as costly as adding a virtual method to a C++ class, but still ... this is not a very elegant solution. As this thing used all over the place? I'm a little scare to find out ...

BTW, sorry for the sloppy code formatting on my previous posts. I still haven't figured a nice way to present it with proper indentation. Syntax highlighting will be nice too.

Friday, August 15, 2008

NSApplication and delegate

Last night, I finally restarted my Cocoa learning effort, by looking at how I could write an application without using Interface Builder. IB is so vastly used that there isn't as much details available on the web on how to go about with it, nevertheless, there is enough to get started. And in fact, it is relatively easy, at first.

A Cocoa application, in its simplest expression, is composed of a single NSApplication object and one (or more) NSWindow object(s). Overall, it doesn't take much boiler code to get something going, which is good:
int main(int argc, char *argv[])
{
NSWindow *lWindow;
// create an auto-release pool
NSAutoreleasePool *lPool = [[NSAutoreleasePool alloc] init];

// initializes the display environment and connects to the window server
// and display server
[NSApplication sharedApplication];

// create a window
lWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(10,10,320,240)
styleMask:kStyle
backing:NSBackingStoreBuffered
defer:NO];
// set the window's title
[lWindow setTitle:@"Hello world!"];
// show the window and move it foreground
[lWindow makeKeyAndOrderFront:nil];

// start the application run loop
[NSApp run];

// release the window
[lWindow release];

// release the pool
[lPool release];
}

The Application object gets a bunch of notification from the system during its life-time. If I wanted to perform some actions in some of them, there is two ways of doing it: I could subclass NSApplication and implement the corresponding methods, which is the usual way of doing it in 99% of the toolkits out there ... or, I could follow the Cocoa way and use a delegate instead. Since the later is what Apple encourage developers to do, the NSApplication class is built to support the addition of a delegate by sending it a setDelegate message.

Now, as expected, this message take as single argument: the object to be the delegate. So far so good. However, instead of defining the argument with a specific class, for example something like said NSApplicationDelegate, it is defined as an id (meaning any kind of object). Since I'm still more of a C++ kind of guy than an Objective-C dude, I found myself a little puzzled by this but still decide to move forward by searching in NSApplication.h (since I didn't see anything in the class documentation) for the delegate class I am expecting to have to subclass, or some sort of protocol definition.

In the header file, I was nicely surprised to see that NSApplicationDelegate does exists, but in a way I was not expecting, at all: @interface NSObject(NSApplicationDelegate). Yep, that's right. A category ... meaning that any object with NSObject for root parent, can be the application delegate ... Since 99% of all Cocoa's classes have NSObject as root, any objects can be the delegate .... including widgets! If this isn't yucky, I don't know what is! Why on earth didn't they use a protocol!??

Tuesday, July 1, 2008

Happy Cocoa Day! ... err Canada day ...

Not since my early days as a Symbian developer, have I spent so many days just reading documents without doing much coding. Since today is an holiday in Canada, I'm sizing the opportunity to finish reading Memory Management Programming Guide for Cocoa, and then hopefully start reading the Cocoa Fundamentals Guide. Early last week, I had finished reading the Objective-C 2.0 document from Apple, which (big surprise) is based on the original NeXT document I had read before, so yeah you can save yourself sometime by skipping that old document ... 9_9 Since I'm going over the memory management rules in use for Cocoa programming, I now realize (with some embarrassment) that my mistake with the exception from a couple of blog entries ago, was due to my ignorance of the common rule that a convenience constructor (such as +exceptionWith...) must autorelease the object that it creates.

Rogers have announced last week the pricing of the plans to go with the iPhone 3G in Canada. We were going to get an iPhone 3G (for my wife), but since, this is definitely way over-priced, we simply won't as she doesn't really need a cell phone. It's nice that the phone by it-self is much cheaper than a year ago, but the total cost of ownership is insane ... too bad for Rogers & Apple, since it looks like lots of people won't get it for the same reason.

We went to see Wall-E last night and really enjoyed it. I don't think it's the best ever Pixar movie in my book, but it is definitely a good one. The usual short movie, Presto, that is shown before the main attraction is most excellent :-) After the show, we were wondering what is the next movie to be released next year, and I though it will be Toy Story 3, but it turns out that it's one called Up ... and yes, there was no trailer for this up-coming movie before Wall-E :-(

Last but not least, Scott Stevenson has recently posted an article on Thinking like a Cocoa programmer, which is a good read for all Cocoa wannabee like myself :-)

Monday, June 16, 2008

Bandwith stealer (casual)

Since I was in Victoria all week-end, I didn't manage to continue learning the way of the OS-X platform. However, since I had my iTouch with me, I was able to "steal" a bit of bandwidth from various location ... enough to check a couple of web sites (e.g Slashdot). I don't know if you have travelled to Victoria, but in order to get there you need to take a ferry (1.5 hours) on a very scenic trip. This is usually a good occasion to check out what kind of electronic toys are popular these days. During past trips, I had very often saw many Apple laptops (in majority at time!), but yesterday, oddly enough, I didn't see a single one, only PC laptops and a couple of iPhone and iPod touch and "older" iPods. I think that it will be nice if a wireless Internet access was provided on-board the ferry, however one should really be enjoying the trip from the promenade decks and not be plowing away on a laptop (albeit it should be possible to geek from the deck).

In the past, when confronting with the need to learn a new platform, I have in most case been subject to hard time constraints (e.g day job) forcing me to get up to speed as quickly as possible. However, since my current Cocoa endeavor isn't bound to any particular project (at the moment) I have been taking my time, leisurely (some may said lazily) reading the various documents I have printed-out (sorry, I'm not much for ready PDF on a screen). The thing with Apple documentation, is that it is usually filled with good content, while being also pleasant to the eyes. True be told, I haven't really started reading a document authored by Apple, since I have been reading and older document published by NeXT: Object-Oriented Programming and the Objective-C language. But, I can said that the layout and content are definitly very much akin to Apple's documents (e.g The Objective-C 2.0 Programming Language). Since I'm not even half-way trough the document, and that so far it have only covered the basic OO concepts, which which I'm already familiar, I can't (yet) tell if it is a recommended reading when getting started with MacOS programming. Likely it's an interesting read from an historical standpoint, but likely not a mandatory one since it's a little bit outdated (I believe it is from 1997).