Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

Tag: mac

Protocol Buffers on iOS – Source Code

For those of you who have been asking for the source code to the sample I wrote some time ago illustrating how to serialize and de-serialize protocol buffer messages on the iPhone, then you can download a fully functioning sample project from here:


This contains the Xcode project file as well as all of the source code, which should hopefully get you started.

Note that this sample is really just a serialization and de-serialization sample. The code expects for there to be some socket server listening on localhost, so you will have to modify it to no longer expect that (or write your own server that receives ZombieSightinmessages).


Google Protocol Buffers on iOS and Mac – Redux

In a previous blog post, I talked about how I used the C++ stock Google Protocol Buffers generated code and the native C++ library in my iOS application. It involved some trickery of creating a wrapper Objective-C++ class to keep the C++ from bleeding into my Cocoa project, I had to link a static library, and it actually bloated my application quite a bit.

Since then, I have found a great native Objective-C protobuf implementation that not only plugs into the regular protoc compiler, but it generates ARC-friendly code. Check out this library on Github for the Objective-C protobuf code.

Now, rather than fussing with creating a C++ object (which requires me to manually malloc and free!), I can just create a new protobuf object that feels natural and native to my iOS and Mac code:

ZombieSighting *sighting =
        [[[[[[[ZombieSighting builder] setDescription:@"This is a zombie"]
                setName:@"Lord Kevin of the Undead"] build];

With this implementation of protobufs, I can just do [sighting data] to get the NSData for the object, and I can de-serialize a protobuf object that I plucked off the wire far more easily than before:

DirectMessage *dm = [DirectMessage parseFromData:data];

See how much easier and cleaner everything is? The moral of the story here is good enough isn’t good enough. Just because you find one solution doesn’t mean it’s the best one. I am constantly in search of simpler, easier, more elegant ways of doing things and I think I’ve finally found a decent way of dealing with protobufs in Objective-C.

Using Google Protocol Buffers in Objective-C on iOS and the Mac

For all the hype and buzz surrounding web services and SOAP and JSON these days, sometimes we still need to deal with sending and receiving binary messages. In fact, we need to do this far more often than you might think. When we think about sending and receiving messages via TCP socket streams or storing information in binary format, one option that has become increasingly popular lately is Google’s Protocol Buffers, Google’s standard data interchange format.

Firstly, why do we need to use a different interchange format? With Cocoa, we have serialization with the NSCoding protocol. Well, the NSCoding protocol only really works best when both sides of the data interchange are Cocoa applications. If you want to exchange messages from C# to Java or from iOS to C++ and so on, and you want to describe this interchange pattern in a platform agnostic IDL, then this is where protobufs really start to shine and you can see their real value.

Feel free to go read the documentation on protobufs, but the cliff notes are as follows: By creating .proto IDL files (simple text describing message schemas) you can use the protoc compiler to generate code in C++, Java, or Python. The generated code contains simple classes representing the messages described in your IDL, as well as methods that allow you to dump the messages to a string and read and write the messages from various formats, including raw binary.

In terms of utilizing protobufs in iOS/Mac OS X there are a couple of options. There is an open-source extension to the protobuf compiler that produces Objective-C code, but it’s newest release is three years old and I couldn’t get it to compile. I would much rather use the protobuf trunk so my code is up to date. So the rest of this blog post is devoted to showing you how to use the C++ generated protobuf classes in either your iOS or your Mac application code without any hackery, shennanigans, or reliance on stale OSS projects.

First, you’ll need to download the source code for protoc, the protocol buffer compiler. You can get this from the link earlier in the blog. Follow the instructions on your Mac to autogen, configure, and make the compiler (you’ll need the command-line developer tools turned on, not just the stock Xcode install). Once you’ve got the compiler on your machine, you can create a sample message.

Here’s some IDL for a message that will send indications of zombie sightings during the apocalypse:

package kotancode;

enum ZombieType {
    SLOW = 0;
    FAST = 1;

message ZombieSighting {
    required string name = 1;
    required double longitude = 2;
    required double latitude = 3;
    optional string description = 4;
    required ZombieType zombieType = 5 [default = SLOW];

Now that you have a protobuf IDL file, you can run the protoc compiler (see protoc –help for syntax) to generate the C++ classes. In this case, it produces a zombie.pb.h and a zombie.pb.cc (I renamed it to zombie.pb.cpp since I’m more familiar with that extension).

Next there’s a bit of manual mucking around but you only have to do it once. In the source code directory you downloaded from Google, delete all of the files related to unit testing, delete the compiler source, and I actually got rid of the gzip sources as well because I had linker issues with those. Add this google directory (e.g. ~/Downloads/protobuf-2.4.1/src/google) to your Xcode project (iOS or Mac, doesn’t matter.. isn’t cross-platform awesome?). You’ll also need to modify config.h so that it doesn’t include the “tr1” namespace prefix. You may not need to do this, but on my Mac I had to. For example, you’ll need to change the HASH_NAMESPACE #define to just std instead of std::tr1 and you’ll need to change the HASH_MAP_CLASS from tr1::unordered_map to just unordered_map. Again, this is a pain but you only have to do this once and then never again for all of your subsequent protobuf projects.

Next, add the config.h file to your Xcode project (this is in the root of the protobuf source dir). Now add the source root (one level above the google directory) to your Xcode project’s header search paths (e.g. mine was ~/Downloads/protobuf-2.4.1/src). You do not need to statically link the protobuf library because you have all of the source code directly in your project, which comes in really handy when you get EXC_BAD_ACCESS errors in your messaging layer.

Now we can get down to business. You have a couple options in terms of how far you allow the C++ stuff to leak into your application. I prefer to write a single wrapper object around the C++ stuff so that the rest of my application can be written in Objective-C and I can minimize the syntax blending. While this blending makes cross-platform stuff on the Mac easy, it can also get confusing when you start bleeding C++ memory management into your UIKit view controllers.

So, here’s the .h and .mm (note the extension!) of my ZombieSightingMessage Objective-C class. Right now it just has a method called doSomething that lets me verify that I can construct, serialize, dump, and de-serialize protobuf messages but you should be able to extrapolate from this how you might wrap your messaging layer behind a small number of Objective-C++ classes.

// -- ZombieSightingMessage.h - note my C++ object is not in the public interface.
#import <Foundation/Foundation.h>

@interface ZombieSightingMessage : NSObject
- (void)doSomething;

// -- ZombieSightingMessage.mm
#import <UIKit/UIKit.h>
#import "ZombieSightingMessage.h"
#import "zombie.pb.h"

@implementation ZombieSightingMessage

- (void)doSomething {
    // Doing random stuff with a UIView here to show the mixing
    // of C++ and Objective-C/Cocoa syntax in the same file...
    UIView *uiView = [[UIView alloc] init];
    [uiView setCenter:CGPointMake(20, 10)];

    // instantiate my protobuf-generated C++ class.
    kotancode::ZombieSighting *zombieSighting = new kotancode::ZombieSighting();
    zombieSighting->set_description("This is a zombie");

    // Some small tomfoolery required to go from C++ std::string to NSString.
    std::string x = zombieSighting->DebugString();
    NSString *output = [NSString stringWithCString:x.c_str() encoding:[NSString defaultCStringEncoding]];
    NSLog(@"zombie: %@", output);

    // Instantiate another zombie from the previous zombie's raw bytes.
    NSData *rawZombie = [self getDataForZombie:zombieSighting];
    kotancode::ZombieSighting *otherZombie = [self getZombieFromData:rawZombie];

    // Dump the second zombie so we can see they match identically...
    NSString *newOutput = [NSString stringWithCString:otherZombie->DebugString().c_str() encoding:[NSString defaultCStringEncoding]];
    NSLog(@"other zombie: %@", newOutput);

    // Grimace all you want, but this is C++ and we need to clean up after ourselves.


// Serialize to NSData. Note this is convenient because
// we can write NSData to things like sockets...
- (NSData *)getDataForZombie:(kotancode::ZombieSighting *)zombie {
    std::string ps = zombie->SerializeAsString();
    return [NSData dataWithBytes:ps.c_str() length:ps.size()];

// De-serialize a zombie from an NSData object.
- (kotancode::ZombieSighting *)getZombieFromData:(NSData *)data {
    int len = [data length];
    char raw[len];
    kotancode::ZombieSighting *zombie = new kotancode::ZombieSighting;
    [data getBytes:raw length:len];
    zombie->ParseFromArray(raw, len);
    return zombie;


Now when I run this application, I get no linker errors, my stuff compiles, and my console output log shows the following:

2012-10-14 16:42:23.919 ProtoPhone[15434:c07] zombie: name: "Kevin"
longitude: 21.007
latitude: 41.007
description: "This is a zombie"
zombieType: FAST
2012-10-14 16:42:23.920 ProtoPhone[15434:c07] other zombie: name: "Kevin"
longitude: 21.007
latitude: 41.007
description: "This is a zombie"
zombieType: FAST

While there’s an awful lot more to protocol buffers than just this, hopefully this blog post has shown you a way to get protobufs up and running in your iOS and Mac applications without you having to depend on a semi-maintained modification of protoc and can instead use the most currently available code straight from Google.

Because this is a binary, cross-platform data interchange format, you can use these messages to talk to web services, to communicate with C++ back-ends running on Unix/Linux boxes in the enterprise, or even use these for efficient persistence and file storage, which also comes in handy on storage-limited devices like iPhones and iPads.

Teach Yourself Mac OS X Lion Application Development in 24 Hours – Code

For those few of you who have not yet posted a horrible review of my book, Teach Yourself Mac OS X Lion Application Development in 24 Hours, I have attached the code for this book. Apparently there has been an issue with the publisher not actually hosting the code the way they should or in the location they were supposed to use … so below is a link to a ZIP file that contains the raw, unedited, source code that I used to build the book. All of these samples were tested and ran on OS X Lion before the book was published.

Teach Yourself Lion in 24 Hours – Code


Getting the Android Emulator to Work on the Macbook Pro Retina Display

Recently I posted about my thoughts on the first impression left by the Android SDK using Eclipse and the ADT Plugin for Eclipse (this is the “traditional route” of Android developers). My first impression was less than stellar.

So I wondered if the inherent crappiness in this was due to Windows or just that overall patchwork, cobbled together Rube Goldberg feeling you get when working with certain open source projects above a certain size. So, I pulled out the Macbook Pro (a 2012 retina display model, the retina display will play a key factor in my impression) and went through the process of installing the SDK.

The Android SDK installs just fine on OS X Mountain Lion and Eclipse “Juno” installed just fine as well. I had trouble with the SSL URL for the developer tools that many books and Google themselves give you, and even had trouble just removing the S from HTTP in the URL, having to decipher what the plugin URL was for the non-SSL download. Really, they could make that process a crapload easier. Again, I had this problem both on Windows and Mac, so the suck was cross-platform.

After finally getting all of the various pieces of the puzzle installed on the Mac, I went through the process of creating an Android Virtual Device (AVD). I started the emulator and noticed that it showed up in a big window but was only drawing on a small portion of it. It didn’t seem to respond to mouse-clicks.

I wasted hours of my life “troubleshooting” this issue, checking everything from memory issues to bad APIs to re-installing the SDK. After a while of swearing and pounding the forehead against the desk, I noticed that it actually did respond to mouse-clicks, but in empty areas of the window. A button that was in the bottom of the drawn portion would respond in the bottom of the larger, empty window. A-HA!

I then thought:

I’ll bet the retina display’s annoying scaling crap is actually confusing the emulator.

Turns out I was right. The emulator is using a deprecatedabsurdly old piece of code that is unaware of situations when the pixels being drawn are not in the same place as the pixels being displayed. I could either wait for Google to fix this (really Google, this is inexcusable in a non-beta, shipping product. Open source or no, this is bull****) or I could settle for a temporary workaround.

That temporary workaround is a tool I found called SetResX. This tool allows you to set real resolution not the annoying “best for retina” and “not so best for retina” user-friendly options you get with the Mountain Lion and Lion settings dialogs. All you need to do is pick any resolution big enough to support a 1:1 pixel-faithful resolution of your emulated screen (e.g. I picked 1680×1050 to support my emulated tablet’s 1080p HD resolution) and you can then run the emulator without the bizarre side-effects.

So, what this highlights in my experience are two things, in order of suckiness:

  1. Shame on Google for releasing non-beta, shipping tools that use deprecated, out-of-date API calls that are incompatible with any Mac retina display.
  2. Shame on Apple for their Macbook Pro Retina display. They release it and without an external tool like SetResX, you can’t actually access all of the pixels the monitor is capable of, you just get scaled and obscured versions. This is a little disappointing, really. It’s my damn computer, don’t pretend to know what’s best for me and hide all of the possible resolutions the card/monitor is capable of from me. Apple used to typically allow developers to get around such “we know what’s best for you” assumptions with standard Unix command-line tools, but there is no such stock tool in this case.

So, if you have a Retina Display Macbook Pro and you want to do some Android development off-device, you’re going to need a tool that futzes with your resolution, or, you can actually hook your laptop up to a non-retina monitor and slide the emulator window onto that monitor and you no longer have an issue (because the non-retina monitor has a 1:1 pixel faithful copy).

In my quest for things that follow the kotan (elegant simplicity) philosophy, my experience with the Android toolset is that it eschews both elegance and simplicity.

iOS and Mac OS X Convergence Continues with Mountain Lion

Just the other day, Apple announced the major features coming up in their new operating system release, Mac OS X Mountain Lion. Before going into details on Mountain Lion, it’s worth remembering here that less than a year ago, Apple released Lion, which included a host of features that it borrowed from the iPad, including Popovers, the option to use “natural” scrolling the way you do on the iPad, iOS-style invisible scroll bars, iCloud support, full-screen applications, and even some great new enhancements for developers using Objective-C.

So what is Apple planning to do with Mac OS X Mountain Lion? According to the information I can find publicly, here are some of the highlights:

  • Game Center – Apple’s game service that provides everything from matchmaking to leader boards, achievements, and even in-game multiplayer voice chat is coming to the Mac. This also means that developers writing games for the Mac will be able to participate in all that amazing goodness that iOS developers have been enjoying since iOS 4.1.
  • iCloud – I don’t really know all the details here only that iCloud is even more integrated into the OS now and I’m assuming the developer experience around iCloud is getting better. I’m actually hoping that experience gets better because writing iCloud code on Lion is a pain in the ass.
  • Sharing – More iOS goodness comes to the Mac with sharing “sheets”. Every application on Mountain Lion now gets a little sharing icon that uses sharing services, allowing you to share whatever you’re looking at in the application with your buddies via e-mail or whatever other services are registered on the Mac, including Twitter. I would imagine that it wouldn’t take much work, assuming the sharing APIs are good, to add other sharing targets like Facebook, Dropbox, LinkedIn, etc to your Mac – turning it into just as much of a social hub as your phone.
  • Twitter – Twitter is a first-class citizen on the Mac just like it became first-class on iOS 5. This means that Mountain Lion users can tweet from pretty much anywhere and using the “sharing” services, they can share pretty much whatever they’re working on in any application (that supports it) via Twitter. Not only is twitter a first-class citizen, but applications can send Tweets on behalf of their users without any extra work. Twitter appears to be accessible in API form to developers without them having to figure out which of the 10 open-source Objective-C twitter libraries they want to shoehorn into their app. This is fantastic news for developers and I hope we get similar integration possibilities with Facebook, Dropbox, etc via Sharing “sheet” APIs.
  • Notifications – In what looks to be very similar to the notification center on iOS 5, Apple now has a unified display of messages that are pertinent to the user, including IMs, iMessages (also now a fully integrated part of Mountain Lion), and application-level notifications. In classic Apple style, they are aiming to push popular 3rd parties out of this market with their 1st party offering. Applications like Growl may find it hard to compete with the unified interface, but time will tell how the 1st-vs-3rd party battles are settled.
  • Gatekeeper – Again I don’t know all the details, but this feature aims to make your application more secure and, more importantly, provides developers with a secure way of distributing verified, signed applications outside the app store. For most developers, the App Store is absolutely the best way to go. But for some applications, it makes no sense to put in the app store and many people don’t need Apple’s distribution channel and so aren’t comfortable sharing 30% of their profit with the company. Gatekeeper and Developer IDs and signing give developers a way of distributing applications that users can feel comfortable downloading, installing, and using.
  • 64-Bit – You simply cannot run Mountain Lion on a 32-bit machine. The kernel is 64-bit and an entire host of 32-bit “wrappers” are missing in Mountain Lion, further drawing a line in the sand against 32-bit apps. If only some other software giant whose name starts with M that makes an operating system would also draw a similar line. In words from one of my favorite movies of all time (Zombieland), “It’s time to nut up or shut up.”
  • SSO – In order to support seamless sharing and such, there appears to be some kind of single sign-on facility in OS X much like Windows has been allowing you to link your “LiveID” to your user account for quite some time … only with the Twitter integration I would imagine Apple’s SSO allows for more than just Apple ID storage.

All in all Mountain Lion is looking pretty promising. Again, there’s absolutely nothing groundbreaking in here, but starting with Lion and continuing with Mountain Lion, it appears that Mac developers are finally getting access to the same amount of lovin’ that the iOS developers have been enjoying since iOS 4.

SAMS Teach Yourself Mac OS X Lion Programming in 24 Hours

As some of you may know, I spent a tremendous amount of time and effort working on this book, which you can buy over here at Amazon.com.

Cover Art - SAMS Teach Yourself Mac OS X Lion Programming in 24 Hours

Cover Art - SAMS Teach Yourself Mac OS X Lion Programming in 24 Hours

I am posting this blog post here to let people know that all of the revisions are done, all of the proofs have been approved and accepted, and the only thing left to do for this book is to print it.

So now there is no excuse – go out and buy yourself a copy. Then buy one for your friends and your parents and your friends’ parents.

I hope you enjoy reading the book and learning from it as much as I enjoyed writing it.

Getting App Store Receipts in your Mac OS X Lion App

As I was trying to write code that utilized StoreKit to allow users of my sample application to make purchases, I ran into a particularly sticky problem: I couldn’t get receipts for my application.

The first time you sift through the Apple documentation, it makes it seem as though if you check for a receipt in your bundle and do not find one, then you simply exit the application with code 173 and a receipt will magically appear within that bundle. While technically correct, as with many Apple documents, it doesn’t give you the whole story in the same place.

The issue here is that you cannot obtain receipts while running underneath Xcode. Further, receipts are only possible while running as an App that was installed via an App Store package. So here’s the rub – how the heck do you get a receipt in your application (which is required before your application can support In-App Purchases) if you can’t do so from inside Xcode?

First, you need to write the code that does an exit(173) if there is no receipt in your App Bundle (if you read my previous post, then you’ll know that you should also be validating the contents of the receipt, not just its presence). You can do so with code like this:

    NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
    if (![[NSFileManager defaultManager] fileExistsAtPath:[receiptURL path]])
        NSLog(@"no receipt - exit the app with code 173");

The purpose of the exit(173) is to tell the OS that there was a problem with receipt validation. If you have signed your application with a Developer certificate (and your app is running outside of Xcode as an App Store-installed App!), then the OS will obtain a development receipt for the application and place it in the bundle for you automatically.

To test your code, you need to build an installer package for the application. To do that in Xcode 4.2, click the “Product” menu then choose “Build for Archiving”. Then choose “Product” and then “Archive”. This will create a new archive for your application. Note that your application must be signed with a developer certificate and your provisioning profile needs to be valid as well.
From the Xcode Organizer window, select the archive you just created and click “Share…”. When prompted, choose the “Mac OS X App Store” package type and save the package to some location that has a relatively short and simple path (like your desktop).

You cannot double-click this .pkg file!!! (Did I mention you can’t double-click this file?!)

Secondly, before you do anything, CLEAN YOUR BUILD. Using Xcode, select “Product” and then “Clean”. If you run the command line I’m about to show you while you still have a compiled bundle on disk, your application will not install into /Applications but will get all messed up and be installed in some obscure location you can’t find.

Now that you have created the package and cleaned your product (There is no .app file for your app on disk!), you can run the following command from a Terminal prompt:

sudo installer -store -pkg (path to package including filename) -target /

This will install the application in the /Applications directory and you should even see the application appear as an icon in your Launchpad list. Now when you launch your application it will obtain a receipt. With a receipt in the bundle, all of the StoreKit code for completing financial transactions will work.

Great, right? Well, not really. The sucky part of this is that the StoreKit code for completing purchases will not work when debugging in Xcode because when you’re debugging in Xcode your application does not have a receipt. This means you’re going to have to litter your code with #ifdefs to keep it from attempting to discover and validate the receipt when in debug/Xcode and you’ll have to avoid attempting to complete an In-App Purchase when you’re debugging in Xcode. Also, don’t forget that you need to create test users in iTunes Connect in order to complete purchases for sandbox In-App Purchases.

It’s not the end of the world but I think it could definitely be smoother. Ideally, I should be able to simulate purchases while Xcode is running in some fashion so that I don’t have to stop my debugging session, build an archive, do a clean, install my app, and then launch the app just so I can watch In-App Purchases go through.

Anyway, I hope these instructions help someone who is struggling with App Store receipts on Mac OS X like I was this weekend.

App Store Developer Experiences – Separating the Wheat from the Chaff

This weekend I spent a considerable amount of time working with Apple’s In-App Purchase system so that I could get sample code and screenshots for the In-App Purchases chapter of my upcoming book on Mac OS X Lion programming. The experience easily ranks among the most frustrating learning curves I have experienced for any technology. I read and re-read the iTunes Connect Developer Guide, read and re-read the StoreKit Programming Guide, read and re-read five or six other documents. As is typical with Apple documentation, each document provided a tiny nugget of insight hidden deep among the prose and, only upon reading each document a third or fourth time did the true “how to” information surface.

To be fair, there is a learning curve to any new development platform and it’s a foolish assumption that the App Store portion of any mobile platform should be “easy”. The problem here is that Apple consumers always assume that Apple stuff “just works” and Apple developers know better – it’s rarely that easy.

So, how painful should an App Store experience be? I feel that there needs to be some level of complexity. After all, you are participating in a supply chain where real money and real products exchange hands and this exchange needs to be secure and Apple needs to be able to weed out those who would attempt to defraud or dilute the marketplace.

What it really boils down to is this – the marketplace vendor (Apple, Microsoft, and Google, for example) has a choice when they design the interaction between developers and the marketplace. They can choose how much work they do on behalf of the developer and how much work the developer must do.

Let’s take a quick example. On Mac OS X, you must manually validate the receipts issued by the App Store. Very early in the life of the Mac App Store, Angry Birds did not validate receipts. As a result, it was possible for people to take a legitimate, purchased App Store bundle, rip out the legit receipt and replace it with the receipt for a Free application … and then the bundle could be distributed (read: pirated) outside the App Store.

This manual validation process involves using a third party command-line tool to generate ANSI C classes that rip open the PKCS file and extract individual bits and bytes from the underlying, encrypted binary data. You’re not done there. You then need to figure out how to utilize the ASN.1 code that was generated on your behalf in order to validate the receipt you find in your App’s bundle. Once you get that working, you’re going to need to modify your code further so it doesn’t look like everybody else’s code to avoid giving hackers a replacement pattern on which to search for malicious injection and hijacking (e.g. replace the return value in your “IsRecieptValid()” function to always be YES, etc).

While I am all for security, and I can certainly see the need for this level of security, what I disagree with is the fact that Apple is deferring this particular task to developers. Many developers are going to skip this process because it is maddeningly difficult to get right and it employs a skill set that many developers new to Mac OS X will simply not have (low-level C, encryption “by hand”, etc). The argument here is that it’s a necessary evil so suck it up, be a man, take your lumps, blah blah.

But does it have to be? Do we really need to go through that effort? We can’t even re-use libraries we find sitting on github because any of them with a common surface area are detectable by hackers who have access to the same code, making all our hard work completely meaningless.

I don’t know what the Android store is like but I know that the Windows Phone 7 store does not foist this kind of gruntwork requirement onto WP7 application developers. The security infrastructure takes care of this kind of thing. Hell, the security infrastructure on iOS even lets us make web calls to validate receipts, and Apple promised we could do the same for Lion but – are you going to explain to your users that you don’t know if the app is legit because you can’t communicate with iTunes? (this is why DRM-haters hate iTunes, BTW…). Windows 8’s security and signing infrastructure mirrors that of Windows Phone 7 and will not require developers to drop into generated C code to validate the legitimacy of the application – “it just works”.

So, what’s a developer to do? Nothing, of course. The potential target audience of all Mac laptop and desktops make this a necessary evil if you want to make commercial applications for Mac OS X. So we will have to suck it up and take our beating if we want to reach that target audience. The point is that we shouldn’t have to. It should be easier, it should be simpler, it should just work.

Remember: If it seems more complicated than necessary, it probably is. That said, there are times (like this) when you can’t do anything about it other than rant and rave.

Working on Mac and Windows Interchangeably

My partner in crime at Exclaim Computing showed me a screenshot of something that happened to him recently. Both of us regularly switch back and forth between writing code for iPhone and Windows Phone 7 and both of us use our Macs as often as our Windows PCs. Unfortunately, this leads to a little bit of “bleed-over” from one platform to the other.

In this screenshot, you’ll see that Nate has tried to reset IIS on his box. Unfortunately, he’s made the fatal Windows 7/Vista mistake of opening an unprivileged command prompt. Rather than closing the command prompt and opening a new one with elevated privileges (as sucky as this sounds, this is what you have to do…), he instead tries the Unix command ‘sudo’ to try and reset IIS.

sudo reset IIS

sudo reset IIS

This is funny both because Nate did it and because of  THIS classic XKCD comic.

Let this be a lesson to you kids: Keep your Mac out of your PC 🙂