Archive for the 'Apple' Category

Review: Apple Time Capsule

I usually do not do reviews of hardware, but in this case, I feel the urge to.

For my apartment, I purchased the Apple Time Capsule, which is an Airport Extreme Base Station (wireless router) with a 500 GB for backing up. So, let’s start with the wireless router. Setting it all up was a cinch. I plugged it in, and all my computers were on. One of the great things about this router is that it broadcasts at 802.11n, so all of you with 802.11n cards in your laptop would love the transfer speed we get. Also, the back of the router has 3 additional Ethernet jacks, so you can run any other computers and what not off Ethernet. And it works like a charm.

The second main feature I love about the Time Capsule is the hard drive. Not only is it a shared hard drive (so anyone I give access to can see it and put files on it), but I can use it as my Time Machine volume (a back up disk that is). I can do wireless backup seamlessly whenever I am in the apartment. That is terrific considering the drive doesn’t have to be hooked up to my machine, etc. And because the router is 802.11n, it’s pretty darn fast too.

And finally, the Time Capsule also has a USB port, so you can plug in a printer or extra hard drive, or both (given you plug in a hub). Setting up the printer to work with my Macbook Pro was literally as easy as plugging in the printer.

I can be sitting in my living room, surfing the net, printing out pictures from a weekend adventure, and backing up my computer, all at the same time, wirelessly. And given the fact the cost is pretty good and the device looks pretty, I would say that is a tremendous deal.

If you’re thinking of getting a wireless router, get the Time Capsule.

Back in the Bay

Last Sunday, I arrived back in Cupertino, CA, for another summer internship at Apple. Since arriving, it has been quite the whirlwind of activity (hence the fact that I have been unable to put up a blog post).

This summer, I am working on the same team at Apple, Interface Builder, which is a specific team of about 6 people in the Development Technologies group. I love what I am doing, and am really excited to be back again with the same people and such. I am living in some apartments across the street from the Apple campus (not the same place as last year) with my roommates Justin, Mike, and Elliot.

I will certainly try to get posts up as much as I can, but no promises given the insane amount of work to be done for some releases coming up.

A tale of two developer sites

The other day, I wanted to look at how to write applications for Windows for a class I am in. Where is the logical place to look? The manufacturer’s developer website would be a good place to start. Upon arriving at Microsoft’s Developer Network homepage, suddenly everything got really confusing.

I have a theory about developer home pages, whether they be from Microsoft, Apple, ARM, or Intel: they should be extremely simple and geared mainly towards beginners who know nothing about the technology they want to write software for. I feel that Microsoft fell far short of that. Their MSDN homepage is cluttered, hard to pinpoint where to go if you want to write Windows applications, depends on you knowing about existing Microsoft technologies, and even has ads for their developer products (making people pay for Developer tools is another whole issue).

MSDN home page

Now on the other side of this spectrum is Apple’s developer homepage, which is simple, clean, and extremely informative about where you should go next: “Are you developing for the Mac or the iPhone?”

Apple home page

Matters get worse with the Mac and Windows Dev Center. If I am developer wanting to write an application, I want something that tells me where to go, that explains things simply, and walks me through getting started. Once again, Apple gets it, and even after trying to get through Microsoft’s developer site for about a half-hour, I couldn’t figure it out. Apple’s seemed to take about 2 seconds (or maybe like a minute).

Microsoft’s Windows Dev Center:

Windows Dev Center page

Apple’s Mac Dev Center:

Apple's Dev Center page

So I guess my question is: what’s so wrong with making things simple? Is it just a personal thing?

Granted, all this said, neither of these two developer sites is perfect, in any regard. Both sites place a huge emphasis on their products, versus the actual development on said products. Secondly, anyone who wambles onto their site should be able to write a 5-minute “Hello world!” application with no hassle. Apple and Microsoft both need to simplify, swallow the fact that people do not care to see ads for their products, and then provide a handy guide for how to write applications for their platforms.

Detecting conflicting Objective-C category methods

Objective-C categories are an extremely powerful way to add functionality to an existing class. Take for example, the category below that adds some stack-like methods to NSMutableArray:

@interface NSMutableArray (StackAdditions)
- (id)pop;
- (void)push:(id)object;
@end

@implementation NSMutableArray (StackAdditions)
- (id)pop
{
    id lastObject = [[[self lastObject] retain] autorelease];
    [self removeLastObject];
    return lastObject;
}

- (void)push:(id)object
{
    [self addObject:object];
}
@end

Now let’s say that I was writing a plugin for any app in Mac OS X that had a plugin architecture, such as IB, Aperture, Address Book, etc. Now, let’s also say that these apps had the same category methods on NSMutableArray, but they were slightly different, maybe they didn’t retain the object because of a special need they had. Well, when my plugin gets loaded into the app, the Objective-C runtime will auto-magically replace their category with mine because they have methods with the same name.

Obviously, this presents a problem. Now whenever their code calls -[NSMutableArray pop] or -[NSMutableArray push:], then the runtime will use my implementation instead. And if their category relied on some special happenings in their implementation, then the entire app could quickly fall into an unstable and fatal state.

So what’s to be done? If you are writing an application that has a plugin architecture or you are writing a plugin for an app, you should run the application during testing with the environment variable OBJC_PRINT_REPLACED_METHODS set to YES. What this does is it tells the Objective-C runtime to print out any methods it replaces when loading in a plugin. If you see that your implementation is being overwritten or you are overriding someone else’s, then you know that you will need to change the name of your method to something else, such as -[NSMutableArray myPop] instead of the original method -[NSMutableArray pop].

Leaving me wanting

The SDK is downloaded, I wrote my first iPhone app, but…

I can’t test it on the iPhone.

Unfortunately, in order to be an iPhone developer, you have to have a certificate that code-signs your software. In order to obtain this certificate, it is necessary to enroll in the iPhone Developer Program, which costs anywhere from $99 to $299. At this point, that isn’t worth it for me.

Conclusion: iPhone development to be continued at a later time.

iPhone SDK on the way

A beta of the iPhone SDK was released this afternoon at about 1 CST. I immediately tried to get on the site, only to be greeted by a friendly page that said:

Safari can’t open the page “http://developer.apple.com/iphone/program/” because the server unexpectedly dropped the connection, which sometimes occurs when the server is busy. You might be able to open the page later.

This continued all afternoon until just about 10 minutes, when I was finally able to get through!
My downloads window

Using counting semaphores on Mac OS X

The POSIX runtime extension includes counting semaphores, specified by functions such as sem_wait, sem_post, and sem_create. Unfortunately, OS X does not implement sem_create for counting (unnamed) semaphores, only implementing it for named semaphores. This certainly creates quite an issue if you want the ease of use (or power in some cases), of a counting semaphore.

I thought I was at a loss for using them until I stumbled upon the Mach kernel primitive semaphores, which happen to be, thank goodness, counting semaphores. The Mach kernel specifies the following functions for using semaphores, as defined by <mach/semaphore.h> and <mach/task.h> (Note: I have only listed the important ones that have POSIX relatives):

kern_return_t semaphore_create(task_t task, semaphore_t *semaphore,
    int policy, int value)
kern_return_t semaphore_signal(semaphore_t semaphore)
kern_return_t semaphore_signal_all(semaphore_t semaphore)
kern_return_t semaphore_wait(semaphore_t semaphore)
kern_return_t semaphore_destroy(task_t task, semaphore_t semaphore)
kern_return_t semaphore_signal_thread(semaphore_t semaphore,
    thread_act_t thread_act)

By looking at them, you can probably guess what they do, and if you don’t, you can always look it up in the documentation, or click here to view it on Apple’s developer website.

You may however, be wondering what the task_t type is, and how you might possibly retrieve the correct task_t struct. But never fear, in <mach/task.h>, there are two methods for getting the current task: current_task and mach_task_self, which both return the current task, but in different forms. For user space programming, you should use mach_task_self, which returns a pointer to the kernel’s virtual memory map. If you are doing kernel programming, however, you would not want to use mach_task_self, and instead you want to use current_task. Do not attempt to use current_task in user-space programming, since linking of your code will fail since the symbol is only available to Kernel extensions.

Below is an example using the counting semaphore primitives. Basically, we are counting up and counting down a static variable by the same amount on two separate threads. With the semaphores, the final value should be zero. If you remove the semaphores, you will not get zero, and you will get some arbitrary value.

#include <stdio.h>
#include <pthread.h>

#include <mach/semaphore.h>
#include <mach/task.h>

static int x = 0;
semaphore_t sem = 0;

void * countUp(void *param)
{
    semaphore_wait(sem);

    unsigned i = 0;
    for (i = 0; i < 100000000; i++)
        x++;

    semaphore_signal(sem);
    return NULL;
}

void * countDown(void * param)
{
    semaphore_wait(sem);
    unsigned i = 0;
    for (i = 0; i < 100000000; i++)
        x--;

    semaphore_signal(sem);
    return NULL;
}

int main (int argc, const char * argv[])
{
    // Create our semaphore. SYNC_POLICY_FIFO is how we handle threads that are
    // waiting on the semaphore. I am pretty sure that POSIX uses FIFO, so I
    // think it is best to use that here, though there are other options defined
    // in .
    int initialValue = 1;
    semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, initialValue);

    pthread_t up, down;
    pthread_create(&up, NULL, countUp, NULL);
    pthread_create(&down, NULL, countDown, NULL);

    pthread_join(up, NULL);
    pthread_join(down, NULL);

    printf(”%d\n”, x);  // Should print 0.

    return 0;
}

Now the only problem with this code is that it is not platform independent, and will not compile on Linux. If you wanted, you could make platform independent versions of semaphore creating, posting, and waiting functions, as implemented in the example below:

#ifdef __APPLE__
#include <mach/semaphore.h>
#include <mach/task.h>
#else
#include <semaphore.h>
#endif

void platform_sem_create(void * semStructure, int initialValue)
{
    #ifdef __APPLE__
    semaphore_create(mach_task_self(), (semaphore_t *)semStructure, SYNC_POLICY_FIFO, initialValue);
    #else
    int pshared = 0;
    sem_init((sem_t *)semStructure, pshared, initialValue);
    #endif
}

void platform_sem_signal(void * semStructure)
{
    #ifdef __APPLE__
    semaphore_signal(*((semaphore_t *)semStructure));
    #else
    sem_post((sem_t *)semStructure);
    #endif
}

void platform_sem_wait(void * semStructure)
{
    #ifdef __APPLE__
    semaphore_wait(*((semaphore_t *)semStructure));
    #else
    sem_wait((sem_t *)semStructure);
    #endif
}

Then in your code, just use platform_sem_create, platform_sem_signal, and platform_sem_wait instead of functions like sem_wait, semaphore_create, etc.

And that’s the magic to using counting semaphores on Mac OS X.

Subclassing in Interface Builder 3

Probably the most common question asked about IB 3 is: how do you subclass something? In IB 2, it was easy, right? You could just go to the class browser, find the class you wanted to subclass (typically NSObject), subclass it with a name, and then instantiate an instance of that subclass. But, what happened to the class browser in IB 3? Interface Builder 3 goes back to the idea of M-V-C: model, view, controller. For those of you familiar with this concept, you can ignore this next sentence: model is where you write code pertaining to data, view is where you write code or make graphics for what users see, and then finally, controller is where you write code relating to the response of user events. Thanks to Cocoa, the interface code is all written for us, and we can benefit from just dragging objects out of a library in IB. Our typical use to subclass an object in IB is to create a controller object or something similar that our interface talks to.

Note: Interface Builder is not the place to write code, that is the role of Xcode. IB has the ability to generate code, but more for a traditional sense. So the idea is to create a class in Xcode, and then bring the knowledge of that class into IB. Thanks to the smarts of IB, you don’t have to do any work for this, since IB is in constant communication with the pieces of your project. If you create a class, IB knows about it the next time you switch to IB from Xcode.OK, enough talk, how do I do this? Here is a step-by-step guide to subclassing something to use in IB (the example below is creating a subclass of NSObject called AppController)

  1. Create your class in Xcode
    In your Xcode project, add a new Objective-C class file by choosing New File… from the File menu. Name the file AppController.m.
  2. Instantiate your class in IB
    The instantiation process is two-fold. First, switch over to IB, and from the Library, drag an instance of NSObject (which you can find using the filter text-field) into your Document Window.
    Library

    And your Document Window should look something like this now:

    So now you have just instantiated NSObject, but what about your subclass? To make the instance you just created descend from your subclass, select in the Document Window, and then open the Identity Inspector (you can do this from the Tools menu, or if you have the inspector open, it is the sixth segment with the little “i”). Once the identity inspector is open, at the top of inspector, there is a slice called “Class Identity”, and under that is a text-field labeled “Class”. In that text-field, start typing the name of your subclass. As you are typing, by the time you get to “App”, it should have auto-completed the text-field with the name of your subclass. Again, please understand here, you no longer have to tell IB about classes in your project because IB has automatic integration with your project.

    Identity Inspector

    And your document window should now look something like this, with the “Object” replaced by “App Controller”.
    New Document Window

    At this point you are done, but if you would like to add connectivity to your class, proceed to step 3.

  3. Add actions and outlets
    Now that you have an instance of your subclass to work with in IB, you may very well want to add some connectivity between it and the interface. To do so, you can add outlets(IBOutlet) and actions (IBAction) to your class’s header file. To do so, go back to Xcode, and enter them where desired. If you need more help on this, please see the Cocoa tutorials on connections. Once you have created your outlets and actions in Xcode, switch back to IB, and by the time you do so, IB already has parsed your source code and found all of the outlets and actions, and they are now readily available for you to use.

So to quickly recap:

  1. Create your class in Xcode
  2. Switch to IB and add an instance of NSObject from the Library
  3. Change the instances class name to your subclass using the Identity Inspector
  4. Add actions and outlets
  5. Realize that subclassing in IB 3 is a lot easier than in IB 2

WWDC Keynote Review

On Monday morning, Steve Jobs gave his keynote at the World Wide Developer’s Conference, most commonly known as WWDC. There is a common saying, at Apple at least, where we call this keynote the Stevenote. There are a few reasons why this event has been tagged as such. First off, what is always included in the Stevenote is flashy stuff. The fluff of software is what Steve Jobs loves to show off. In the hallways of the Apple Campus, you hear engineers talk about how they spent one hour adding some flashy animation to an interface or changed the look of a button just so that Steve would like it, and want to show it at his keynote. The second characteristic of the Stevenote is that he always shows off something secret that no one else, except the engineers who worked on it, know about. And finally, the Stevenote is usually really good, and has you leaving the room excited and ready to go innovate.I regret to say that this year’s WWDC keynote may have hinted on the first two, but certainly fell short of the third one. The keynote was indeed flashy, as Steve demoed the latest features of the Mac OS called Leopard. The announcement of Safari on Windows was certainly surprising. But after the hour and half, I was bored, and ready for it to be done. Here are the things I liked and didn’t like about Steve Jobs keynote.

  • The new desktop?: One extremely misleading feature of Leopard is the “new” desktop. OK, maybe in terms of code a lot of new things are happening, but it was hardly worth the number one feature. There is a new silver dock, which I like, a deeper drop shadow on the active window, which I like, a unified UI, which I like, but the new menu bar? I loathe the new menu bar. It supposed to adapt to your background picture, but it ends up just totally being unreadable. In earlier versions of Leopard, they had a great menu bar, and two or three days we sent off Leopard to be duplicated for the developers, they changed it. And everyone hated it, and they ignored us. Now everyone at Apple and everyone at WWDC hates it.
  • Spaces: I actually love Spaces. There are a lot of people who don’t, but I do. It is an extremely useful way of getting rid of windows that you don’t want to see at the current time. It’s like having as many monitors as you want, only you don’t have to strain your neck to look at them. It’s just a keystroke, and your there. Great! There are currently two other ways to hide windows: minimize them or hide the entire application. Personally, I think minimizing windows is one of the dumbest ideas ever. Maybe that is one of the reasons why I hate Windows so much is because they hinge on that. I don’t want my window to go somewhere where I have to bring my mouse down and retrieve it. No. I want a keystroke to get it back. Hiding the entire application is a good start, because it can be done with a keystroke and retrieved with a keystroke, and it does not clutter up my Dock or anything. Of course, if I need these windows open so I can do a copy and then paste or drag and drop, the screen gets cluttered. Spaces opens up a lot of space, and its sweet.
  • CoverFlow in the Finder: I was watching the keynote in one of the employee rooms, and when Steve Jobs said that CoverFlow in the Finder was useful, our whole room burst in laughter. That’s because we had been trying to use it for the past month (for me) or months (for everyone else), and we could not find any use for it. Again, to be perfectly honest, I just don’t like the finder. I am perfectly content with cd, ls, cp, and mv.
  • Dashboard: When Steve Jobs needs five minutes to show off a movie widget, you know that he has absolutely nothing better to say. Dashboard is a memory sucking camel, and extremely over-hyped. Yeah, WebClip is cool. But I still do not think that he had to spend so much time on a Javascript widget that most developers could have written quite easily
  • Safari on Windows: This is a great strategy. Combined with the release of the iPhone, I think that lots of people, mainly iPhone developers, will use Safari in order to test their sites. I don’t mind Apple products on the Windows platform, especially when they run faster than their competitors.
  • A “sweet” way to make iPhone applications: Here at Apple, we have created a sweet way to create applications on the iPhone, they are called websites. Come on! Are we stupid? I do not think that dwelling on this sweet way of making applications was necessary or beneficial. I think anyone who has written a line of HTML would be offended by that. I know a lot of people who were.

So I have been pretty harsh on Apple, but I think we should. Apple is the leader of innovation, and they have extremely high standards around the globe. I think that the display that Steve Jobs put on was not on par with where it should be. I am looking forward to how Steve is going to dig himself out of this one.

Why is my blog so boring?

I think at this point a lot of people are probably wondering: “Why is Kevin’s blog so boring.” Well, I will give you an honest answer: my life outside of work is not too exciting. I would love to tell you about work, but then I would have to kill you. So, I will tell you what I can about my typical day.7:20: Good morningIt’s usually up pretty early, about 7:20, which means I don’t get out of bed until 7:30. Then I do the typical morning get ready deal to prepare myself for the day.7:40: DevosI can’t start my day without some time in the Word. Right now I am reading Jeremiah, after just completing a cover-to-cover reading of the entire Bible (which I would recommend to everyone, even if you don’t believe what it says). Devos also encompasses some time reading a devotional by Frederick Buechner called “Listening to Your Life.” I would say that it certainly has its gems.8:15: BreakfastBy now my roommates Dax Norman and Matt Pizzimenti are up, so we will eat breakfast together. I am a big fan of Fruit Loops cereal. Hey, it’s better than pop-tarts!8:30: Off to workI like getting out the door relatively early. The Apple Campus really doesn’t start until 11, so I have about 2 hours of solid quiet time to work on my projects. The walk to work only takes 5 minutes, but it is 5 minutes along a busy road and over a major highway, not the most serene walk. When I get to work, I usually will set up my workstation by wiring in my laptop to my iMac, read some emails, get some ice tea, and then get on with the work for the day.8:45 - 12:30: WorkAs with most people, I do work best in the morning. So I work hard until lunch. There’s not much else I can say here, except that I love what I do. For those of you who still don’t know exactly what I do, don’t fret, no one does. But I can tell you that I work on the Interface Builder Team for the Runtime Technologies Group, which is part of the Developer Technologies Department. I work with some great people, and the floor seems to glow with bright people.12:30 - 1:30: Lunch at Caffe MacsCaffe Macs is the place to go for lunch, and pretty much everyone ends up there between 11 and 2. They have quite the variety of food: a burrito bar, salad bar, sandwich bar, grill, Sushi bar, Asian salad bar, cooked pasta goods, pizza bar, gelato and dessert bar, and of course all of the other fruit and vegetable and bread tables. Great food, and very reasonably priced. Yeah so it’s not Google, but its still good food that I haven’t gotten sick of eating yet.1:30 - 6:00: Work time!As with the morning, this is just more work. By the now most of the office has woken up, so there is the steady hum of people milling about and asking question and running into bugs.6:00: Dinner or home, dependingBecause we are closing in on the conference (WWDC), there is a lot of work still to be done. So, a lot of people stay to do work all night. In fact, most engineers are on the noon to midnight work flow, or lunch to 3 in the morning work flow. So usually our whole department will go down to Caffe Macs where we get served dinner for free because we are working so hard for the conference.7:00 - 8:00: HomeI hardly ever stay past 7 or 8. I like to have a little time back at the apartment to read, relax, code, and organize photos. Other books I am reading right now are: Code Complete by Steve McConnell, and Mere Christianity by C.S. Lewis. I am still working hard on MacQuill, as I move closer to a beta release sometime soon.10:30: BedI don’t stay up late. By this time I am wiped, and I need to go to bed to get up and do it all over again in the morning.So is that still boring you?