Sidekick 4.1 Beta
Today I posted the first public beta of Sidekick v4.1. Anyone can get access to it by running `defaults write com.oomphalot.Sidekick EnableBetaUpdates -bool YES` in a Terminal and restarting the app. It should prompt you to update to 4.1b2.
You might not notice anything ‘new’ in the app. Don’t panic… that’s perfectly normal. Nearly all changes in 4.1 are under the hood.
Mountain Lion Support
Sidekick 4.0 ran on Mountain Lion, but not as well as I wanted. v4.1 is the first version of Sidekick that should bring real support for 10.8. This includes Developer ID code signing, so you won’t need Option 3 enabled in Gatekeeper to run Sidekick anymore.
Bye Bye Garbage Collection
Sidekick 4.0 inherited NetworkLocation’s use of of the OS X Garbage Collector. When ARC was announced as the successor to GC, we were too far into the development of Sidekick to consider switching to it without it forcing our ship date to slip (moreso). We also weren’t sure what the impact of switching to ARC from GC would be, we had code that was specifically done to take advantage of GC’s strengths. We decided before 4.0 shipped that yes, eventually we will move to ARC, just not now. 4.1 is when that happens, and the results are nice : lower memory footprint, less CPU being used when the app is inactive (we should be back to nearly 0% cpu usage).
Fixing Broken Things
There were a bunch of little things that have broken over time in Sidekick, like icons for actions. Since we get a lot of those from the system in slightly unsupported ways, there’s always a chance that they break. So we’ve fixed up all the little issues that we’ve found. 10.7 changed how some of the buttons rendered, causing them to look fuzzy. That’s fixed. Little details here and there that have been bugging me.
How beta is this beta?
This is really more of a release candidate than a beta. It’s stable here, and I use it every day. There are no known issues. But I’m not labelling it 4.1.0 just yet simply because I want more eyes on it. We’ve done our testing on 10.7 and 10.8, and it’s looking really good. But I want to put it into the hands of more people and get more feedback and possibly crash logs (hopefully not?).
Go Run That Command
defaults write com.oomphalot.Sidekick EnableBetaUpdates -bool YES
remyworld asked: I've integrated Oomph mapKit in my project, and I want to display a button on the map, so I drag a button from IB and set it as subview of mapKit view. but after the mapView load the data, I can't see the button. could you help me?
GitHub would be a better place to ask these things, but i’ll answer here.
That won’t work because the MKMapView, while it’s a descendent of NSView, actually creates a WebView and makes its frame the whole bounds of the MKMapView. So whatever button you make inside of it will get hidden by the webview. You’d need to use methods to bring it to the front after the webview has been loaded.
SimpleGrep : OpenStep to Cocoa
With the Cube up and running, I did as any developer would do and tried to think up a small app that I could write for it. I had to decide what the goal of this app would be…not what the app did, but what I wanted out of this experiment since let’s be honest: I’m not going to be spending a TON of time using that machine. I decided that I wanted to get a lesson in how different OS X is from OPENSTEP, and so to do that, I was going to write a little app that could be compiled and run on both my 10.7 Mac and this old Cube.
I wanted an app that wasn’t too complex, but at the same time would let me make use of non-trivial things like threads and interprocess communication. I decided that a good candidate for this would be a UI over the UNIX grep utility. Not a full-blown UI that presents all options, just something basic: give it a search term, a directory to start from, and a checkbox for Recursive. Or as I like to call it : grep with the only option I ever use.
Creating The App
My first stop was Interface Builder on OPENSTEP on the cube : had to make sure that this simple UI could be done without much work. Since the nib file format has changed significantly from the days of Project Builder compared to xibs in Xcode4, I allowed myself to think of the nibs as the one platform-dependent part. And if you think about it, that would make sense even for a real app, the controller logic might be common code, but the UI should be done to fit in with the rest of the system that it is running on.
With a photo of what the UI might look like with those glorious 4 shades of gray, I jumped into first building the Mac version of the app. I tried only making use of APIs that I knew had been around since 10.0 as that’d likely mean they’d also be in OpenStep.
It’s not exactly a complex app, in a couple hours I had a basic app. It spun off threads that would use NSTask to execute grep with the right arguments, process output, and feed it back to the main thread, and the results would be shown in the table.
I really had no clue what the porting process was going to be like. Maybe this would just compile and run (one can hope, right?). I copied the source files over to my OPENSTEP virtual machine, and fired up Project Builder to create the project. I used the VM instead of the cube just because it’d be faster. Have I mentioned how slow that cube is? Glacial.
Step 1 was to create the nib, again. Oldschool Interface Builder had no way of looking into class files for outlet and actions, hell, IBOutlet didn’t even exist as a keyword. You have to manually tell it about a class, add all outlets it might have, and the actions that can be triggered. In this case I only had a handful of either, and only 1 class instantiated in the nib (the app controller), so it wasn’t too painful.
The source files were imported into the project, and I attempted to build. Errors. A lot of errors. I commented out the parts where it was complaining about methods not existing (obviously I wasn’t diligent enough), and tried to focus on the other errors. I can fix methods not existing somehow afterwards. One of the errors really stumped me though. Google wasn’t too keen on helping out, and I don’t blame it, I bet you no one has seen this error since 1996. After some trial and error I realized that this version of gcc was so old that it expected all stack variables to be defined at the top of a method/function before any code. Not the end of the world, but man is that ever annoying. This meant having to go over every function and make sure everything was defined at the top.
In my original version, worker thread to main thread communication was done via -performSelectorOnMainThread:withObject:waitUntilDone:. OpenStep has NSThread, seems like a pretty safe assumption that it’d have had this NSObject method. Nope. Turns out that method wasn’t added to Cocoa until 10.2. This meant having to rethink how I was getting data back. Apparently the way to do inter-thread communication back then was to use NSConnection to get a proxy object. It felt a little heavy-handed to use this, since it’s made to support proxy objects to other hosts on the network, but when in Rome…
That was the big change, most of the rest was stuff like using NSString initializers that didn’t exist and could be easily swapped out.
Where’d -R go?!
My original app on the Mac would call `grep` or `grep -R` depending on whether the user checked the Recursive checkbox. On OPENSTEP it would just fail whenever I’d try recursive searches, and I was a little puzzled about why. Reading the (humourlessly short) man page told me that -R wasn’t an argument for grep. Well that sucks. Considered my options, like just dropping that checkbox from one or both versions, and decided instead to move the recursive functionality into the app. Now both could call grep with the same arguments all the time.
Back to the Mac
Once the app ran as expected on OPENSTEP, I moved the code back to the and tried to run it there. Like any good project, it didn’t work. Luckily it only needed a couple small changes with how I was getting the proxy object with NSConnection.
Here’s the app, in all of its glory. You can check out the sources on github:
Screenshots of it running on OS X and OPENSTEP.
Main features of the app:
- Can search recursively
- All searches happen on secondary threads so the UI shouldn’t be blocked
- Displays paths for results as well as the line number that matched, and the line of text itself.
- Shows the respective icon for each file
- Double clicking on a result opens that file with whatever app is associated with it
- Shows the app’s status and how many results found so far.
1989 Called.. It wants its Cube back.
I’ve wanted a NeXTCube since I first learned what they were, which was well after they stopped being made, and some time after Apple bought NeXT. Last summer, I finally got one as Dan Messing decided he didn’t want to lug his out to Portland in his move. It was a physical machine, but not much more than that. It couldn’t boot. It couldn’t even power on. But hey… it had that awesome little logo on every component, and that was a hell of a start.
I can’t speak for all NeXT hardware, but the cube was built so that the display would connect to the cube, then the keyboard, mouse and audio would connect through the display. There’s no physical power button on the cube, the button is on the keyboard. This cube came without the cable that connects the display to the cube. I did some research online, and considered building the cable myself. Decided that since I’m no electrical engineer, and I could manage some damage if I screwed up pins, that it’d be a better idea to just find one somewhere I could buy. There’s a company in the US, Black Hole Inc, that actually sells NeXT equipment, so I ordered one from there.
I got the cable a few weeks later, connected it all together and hit the power button. Fans turned on, the screen lit up, it beeped. I smiled. It spat out an error about the SCSI disk, which Dan told me had gone bad. Attempts at booting went nowhere. Well, at least I can look at the NeXT boot rom, right? The fact that they made that look like their Terminal app is awesome.
Screw that, I didn’t get a cube to just stare at its boot rom. Let’s get this thing up and running! What do I need? Well… something to install the operating system onto would be a good start. And a way to install said operating system would be another requirement. I figured I could likely find ISOs of OPENSTEP install media online, but as it turned out, Chris Dandeneau had an original box of it from when IDFusion used to be a WebObjects company and Apple was dumping inventory. I took a trip to ye olde computer shop that I knew sold antiquated computer equipment and bought a 2gb SCSI-2 hardware along with a SCSI cdrom.
Threw them in there, which was tricker than expected since it wasn’t designed for either 3.5inch harddrives (it came from the days of 5.25inch HDs), nor CDROMs at all. Its front face only really supports that bizarro Magneto-Optical thing the original cubes came with. Let’s just say the CDROM hung out outside. I’m all set, I thought. Once the OS is installed, I don’t really need the CDROM anymore, so it doesn’t matter that it’s a ghetto setup. Well… yeah… no. As it turns out, though SOME NeXT machines could boot off of CDROM, this wasn’t one of them. I wasn’t able to find a floppy drive that was compatible with it, either. I needed something to jumpstart the install process… you know, actually boot the thing.
…I said Boot!
I looked at my options, and realized my best bet was to do a netboot. Every NeXT machine came standard with a network interface. Luckily for me, the cube I have was the first one to have that be “standard ethernet” as opposed to coax (token-ring, I guess?). Unluckily for me, I knew nothing about netbooting other than the fact that it was this cool thing I’ve always wanted to do back when I was a Linux user, but never had hardware capable of it.
I spent a few nights with OS X’s DHCP services, since it’s capable of netbooting other Macs. I never got anywhere with that. I installed NetBSD’s DHCPd on OS X and tried with that. I got to the point of getting an IP over to the cube, but it never did anything beyond that. I knew too little, and was rushed due to our move to Ottawa. I put it aside and said I’d try again when things settled down again.
It took a while for things to settle down. The move, new job, a few conferences, christmas… Some time in February I finally managed to drag it out from the box it was in, and start toying around again.
This time I was smarter: screw OS X as a netbooting host. I know next to nothing about OS X’s network services, but I used to be a sysadmin at an ISP that ran Linux for everything. I setup a Debian virtual machine whose network adapter was bridged with my Mac’s ethernet port. A nice bonus of using Linux was that it actually has read support for the NeXT flavor of UFS they used for the filesystem on the OPENSTEP install media.
It actually didn’t take me that long to get it netbooting from there. It was super interesting to watch tcpdump during the whole process to see what was going on. The trickiest part being setting up the TFTP server for some reason. You need a surprising number of services to netboot the thing: dhcpd, bootparamd, tftpd, nfsd, and dns. I hate bind configuration files. NFS not wanting to serve up the CDROM mount point was also an annoyance, but nothing a little cp -A couldn’t fix.
It could now boot into the installer, from the network. My original plan was just to get it to load the kernel to get it to see the CDROM and do the install that way. The fact that I could now just serve up the whole installer from the network was a huge bonus.
Install where, you say?!
I’m all set, right? Installer can start up, I should be up and running in no time. Well… you see… here’s where I learned that somewhere between packaging the cube up before the move and now, I lost the harddrive I bought. Cause you know… I didn’t have enough trouble.
Plow ahead! A this point I knew more than I’ve ever wanted to know about netbooting, and I’ve been reading from others who permanently run their NeXT boxes purely from the network once the harddrive died. Not a bad idea, why would I want to depend on some old drive? When it dies, I have to go through all of this again? No thanks.
New plan : Let’s setup two NFS shares, one that serves up the installer, and the other that I’ll install it to. Slight wrinkle in that plan : The OPENSTEP installer A) fails when it can’t find a harddrive in the machine, and B) doesn’t support installing to an NFS mount (don’t really blame it there).
Interestingly, the entire installer process is a single shell script, the init process checks for its presence, and runs it if it’s there. A shell script. To install an operating system. Think about that for a second. Even better, it asks about 4 questions then runs: “ditto -arch some_arch -bom somebom / /install_mount”. So…comment out the parts that look for a disk, mount the NFS share, hardcode it to ditto over there and I’m golden.
Well not quite. Cause to get the critical parts to actually work out, I had to edit the install script, and the CDROM’s /etc/fstab. /etc/fstab is one of the files that’s in the BOM list, so it gets copied over. Part of a BOM file is a checksum, and if the checksums don’t match, the whole ditto process fails. So I was getting to the point of copying /etc/, and things would go south. I considered rebuilding my own BOM file, but it seems like that format has changed between then and now (where I have tools for it). I couldn’t just remove the -bom option because then it’d copy the whole CD. I can do that with cp. Obviously it was omitting some files (like the installer script) that would indicate that it should boot as a live system.
I ended up using my Mac to run ditto -arch from one share to another, and moved over the installer manually. When doing that and booting off of the new share, it actually got pretty far into the start up process. It actually got to the point of loading the window server, and I could telnet in, but it seemed stuck in a loop. Looking at log files it seemed stuck running BuildDisk. I’m in over my head. WTF is BuildDisk? I signed up for what’s likely the only active NeXT user forum still in existence, and asked my question there:
As you can see from their answers, they thoroughly did not approve of this ‘clever’ installation method. And obviously I was overthinking this whole thing. Install OPENSTEP in a Virtual Machine, and have it serve the netboot environment to the cube. Duh.
It ain’t over till the FAT lady sings
Getting OPENSTEP running in a VM is a pretty trivial process. The whole driver issue is somewhat maddening (dealing with drivers manually always is), but other than that it was clear sailing. The added bonus of using a VM was that I could snapshot the harddrive and keep notes of what was working and what wasn’t.
Remember that little shell script, and the ditto command it ran? Remember that -arch option? Yea well it trims all FAT binaries to only support the currently running architecture. That virtual machine… it runs i386, and the cube… m68k. I can’t just boot the cube off of this install via netboot, cause all m68k support has been stripped/lipo’ed.
I came up with this idea.. I could write a script which went through their install BOM file, find all the FAT binaries, figure out if they were lipo’ed, and if so, reinstall it from the install cd. It took me a couple tries, but I was able to run such a script. It worked, sort of. But afterwards all sorts of things didn’t quite work right (I’d get bizarre errors), which led me to believe that clearly this isn’t a great idea.
What I ended up having to do was setup a secondary harddrive in the VM, and use the tool they have that can create an install disk from the original. I could then edit the installer script to remove the -arch option to ditto. I was careful to not edit any files that might be listed in the BOM to avoid checksum mismatches. I could then boot that secondary harddisk as the installer, and install over the primary disk.
That finally gave me an install where all binaries were FAT with support for i386 and m68k.
Oh right… the point was to boot the cube
NeXT made some really nice GUI network management tools to configure their NetInfo stuff. I read their system administration guide to get a feel for how it should all be setup, and configured everything accordingly. I should mention that those ‘really nice GUI network management tools’ are ‘incredibly thin window dressings’ over the configuration files. In the sense that they do next to no validation of input, and let you put your machine in a state where it can’t boot anymore. Thanks! Needed salt in the wound at this point.
Eventually… when the VM would boot again, and I was confident in what I had done: power up the cube again, and type in ‘ben’ for the millionth time to have it boot over ethernet. The VM fed it the boot info like a champ. Everything’s going swimmingly… the window server starts up. Spinning beachball in glorious 4 shades of gray. Oh no.. I’ve seen this before. I telnet in and check the logs. BuildDisk in a loop again. *throws chair across the room*
I was pretty much convinced at this point that there was something wrong with the cube, hardware-wise. Now, having used OPENSTEP for more than 2 minutes, I know that BuildDisk is the utility that sets up an initial install. The CD copies itself to a disk, then BuildDisk runs and installs the optional pkg files. Part of its process is figuring out where to install, and it looks for fixed disks. That SCSI bus errors out on every boot, likely because it has no terminator on it. Some googling tells me you probably want to avoid interacting with an un-terminated SCSI bus. OK fine! I’ll buy a terminator for it. If I can find one.
I don’t think Ottawa has any stores that sell antiquated stuff like this. I emailed a few places and got either no responses or “we don’t sell that stuff anymore.” I even emailed Syrotech, my goto place in Winnipeg to see if they could ship me one.
But wait… what’s telling BuildDisk that it should run? Why does it think things aren’t setup? To netboot, you have to feed each machine its own /private mount, which is where /etc/ lives, amongst other things. I was able to confirm that nothing outside of /etc/ should be different for the cube than the host machine. Whatever it is, it would have to be in /etc/. So what I ended up doing was copying over the host’s /etc/ into the netboot client’s /etc/, then having to manually switch stuff out to be appropriate for the cube again. It’s worth a shot, right?
Well… that did it. So there’s something in their new-netboot-client template that marks it “not setup yet”, that I was able to work around by just copying the entire /etc. I still want to figure out what that is, and it shouldn’t be too tough, there’s only ~100 or so files in there. I could script something to diff each one and show me all differences. It’s bound to pop up.
The important thing is: It works! I can start it up, and login, and use the thing!
It works… now what?
I now have a working NeXTCube. It boots off the network, it stores its swapfile on the network, and it’s awesome. It’s fantastically slow, which is probably partially because everything is network based (even though 10Mbps is probably about as fast as the hard disks back in the day?), but most likely because it has a 25Mhz processor. My iPhone probably has 100x the processing performance of this thing.
OPENSTEP is actually really, really cool. Of course, dev tool stuff is neat, but I’m actually starting to finally appreciate some of the stuff I’ve heard that I used think was ridiculous. Like tearing off a menu that you use often and keeping it nearby. It comes in super handy.
I’ve been poking around, and trying to get a better feel for what has changed between then and now. One thing I didn’t realize was the fact that you literally had to write postscript to do drawing. The code in an NSView’s -drawRect: from that time really doesn’t resemble today at all. I always assumed that Quartz and DPS had similar front-end code, and that it was mainly a backend difference.
A big part of this for me was just the challenge. At any point, I could have ordered a SCSI disk from BlackHole with OPENSTEP pre-installed and been done with it. But what fun is that? I learned a ton in the process, and despite the loud cursing that could be heard coming out of my office, this type of stuff is actually really fun for me. Fun in a “I never want to go through that again” kind of way, I mean.
I have a project or two that will make serious use of the cube, one of which is actually mostly done already and I’ll probably blog about it in the not-too-distant future.
Details : Path’s “+” Button
I felt like one of the last people to finally download the new Path app for iOS the other day. It seemed like everyone on my twitter feed thought this app was the coolest thing ever, but the “It’s like a social network!” aspect of it turned me off. I don’t need another social network in my life. But… since everyone praised the UI, it was time to give it a try.
I still don’t know if/how this app would fit into my regular usage, but I won’t talk about that today. The app is an absolute joy to use, and I think this is entirely because of its UI, and the hard work that went into all of the details. The screenshots don’t do it justice, because it’s the interactions and animations that make it shine. I’d only give it a “above average” as far as pure looks go.
A lot of these UI ideas are going to get copied into apps, just like pull-to-refresh did. One of them was redone using CSS. The + button, this is one of my favorite parts of the app. I could play with that button all day long, but the CSS version brings no such joy.
I want to make something perfectly clear before I go on… I think what Victor Coulon has done is really cool, and I applaud him for taking the time to try to replicate this control using CSS. I think it’s using CSS beautifully to do what CSS should do: presentation of elements. So no… this isn’t a rant about how this doesn’t belong in CSS.
The CSS version doesn’t feel as fun as the original because it tries to be just like the original and fails at it. It’s in uncanny valley.
So let’s go through where they differ.
Path’s + button actually gets triggered on touch-down as opposed to touch-up-inside. This is a departure for from most buttons. At first I wasn’t sure I liked this, but I’ve decided that in this case it’s completely appropriate. What’s the harm in accidentally triggering this button? None. It doesn’t bring you to another screen, it’s never destructive, it doesn’t put you in another mode. Accidental tapping in this case can very easily be undone by either re-tapping or tapping anywhere else on the screen (so actually it is modal, I lied). Having it occur on touch-down makes it feel faster than most buttons. It’s false, but that doesn’t matter.
Victor’s CSS version gets triggered on click, which is equivalent to touch-up-inside.
UI animations need to be fast, otherwise they get tiresome after a while because the user can work tap faster than the UI can construct itself. The animation duration of the CSS version is way off. On the open animation, I’d guess it’s about 25% slow. On the close animation I’d guess about 50% too slow.
This accentuates the fact that the close animation isn’t quite like the original in how the rotation of the x back into + is timed against the rolling back in of the other elements. They feel completely separate on the CSS version, but in Path they feel related, if not synchronized.
Key Frame Animations
There are two major components to this key frame animation: Spinning, and Movement (translation).
In the original, you can clearly see that the elements spin upon opening. This might be the case the CSS version, but it ends up looking like a blur because the movement part is inaccurate. What’s clearer is that there’s excessive spinning upon closing in the CSS version. I think the original does either 1, 1.25, or 1.5 revolutions upon closing (likely the same upon opening, but it’s harder to see). The CSS version looks like it’s doing over 2 revolutions. I’ll note though, that being starts, it’s particularly hard to track that.
The movement feels very iOS-ish in Path. It’s similar to elastic scrolling. When the elements roll out they bounce into place. The CSS version has the elements smashing against a wall. Upon closing, the CSS version seems to exaggerate the pull back before they return. The distance that they pull back seems about right, but the proportion of time during the pull back versus the return is off which makes it feel more like a slingshot than the original.
Details Details Details
I think this is a great example of why details matter. This is essentially the same control, as far as functionality goes, but one feels like a treat and the other feels like a gimmick.
I don’t mean to pick on Mr Coulon’s work. I’m sure if he spent more time on it, he could get it looking (err… WORKING) almost exactly like the original. But that’s my point : details take time. Details are exhausting, and require a ton of trial and error. I spent at least 5 minutes last night just tapping Path’s button again and again looking at the animation to try to figure it out exactly, to figure out why it felt so right. Recreating it would take me much longer than those 5 minutes. This exhausting trial and error is how you can manage to create things that not only look good, but feel fantastic.
It’s been two years since I started the big “reworking” of core parts of NetworkLocation. It was my first real Cocoa app. The codebase grew and morphed as I learned the do’s and dont’s of how to write a proper Mac app. Some of the code was still present from v1.0, which could either mean it was doing a really good job or that we had painted ourselves into a corner where replacing it would be painful. There was some of both.
AutoLocate, the little engine we have that figures out where you are, had grown in a way that was really starting to limit us. It had “that one nasty method” that did most of the hard work. It was much too long, and contained approximately zero comments. Modifying it had become something I really dreaded doing because it required thinking of every different permutation that we had designed it to handle, and how that scenario would play down the gauntlet.
The general UI of the app was still very much so inspired by v1.0. We freshened it up with every release, but it was never redesigned.
We decided that it was time to start rethinking things, and that it was ok if this release would take longer than our previous releases to build. At the time, we thought… no real new features, we’ll name this NetworkLocation 3.5.
Chris started plugging away at a redesigned AutoLocate engine that was much better designed, and still every bit as powerful (if not moreso).
Phil and I spent countless hours mocking up different versions of the configuration/preferences screen. How do we make all of this stuff simple to use? The biggest disconnect we dealt with was the relationship between AutoLocate rules and Locations. It was a one-to-many relationship, and each AL rule would contain a set of conditions for each type. Combine that with the fact that it wasn’t an ALL or ANY used to evaluate the rule, instead it was “the magic of ALv1 will figure it out”… and you had yourself something that was technically very cool, but in reality, a real pain to explain how to use. As the person who had to attempt to train support staff in how to figure out what was going on with users’ systems, let me tell you… this was insane.
So the challenge… to make something that’s as powerful as we had, but simple to explain. After many attempts we ended up landing on what we have now in Sidekick which is a simple ANY per type, and an ALL across the types. If I configure “at 700 Corydon Ave” and “connected to 22inch Samsung”, then both have to be true for it to work. If multiple devices are listed, then I need to be at that location, and connected to any of those devices. Much. Much. Simpler. Of course, there’s weighting thrown into the mix to find the best match if there’s a tie.
We realized that CoreLocation was by far the most user friendly way of identifying where a Mac was. Having a user interact with CoreLocation though… what with it being based on longitude/latitude… ouch painful. Obviously a map can help here, but interacting with a map in a Mac app is no trivial task. After a bit (ok a lot) of prodding by Phil, I wrote a little prototype to see how difficult it’d be to interact with a live Google Map. Turns out.. it wasn’t that bad. Definitely feasible, but their API is pretty painful to work with. I was stuck writing a bunch of wrappers around it to make it less painful anyways, so that’s when I started MapKit for Mac.
Fast forward another few months when we realize that “NetworkLocation” really doesn’t fit with what the product has become. NetworkLocation started life out as a faster way to switch OS X’s Network Location (the ones you configure under the Network tab of System Preferences). Now very few people actually use NL to do that at all. It’s a tool to configure your Mac based on where you are. One of those things might be to change network settings, but calling it that is about as appropriate as it would be to call it PrinterLocation because it can set your default printer. We had to find a new name: Sidekick. You’re the super hero, it’s that little dude that hangs out and does those annoying little tasks for you.
By now we’ve gutted the UI, rebuilt the AutoLocate engine, added actions, recoded a bunch of the actions with cleaner code, recoded a ton of old code that I decided was too old/ugly to keep around, and changed the entire branding of the app. It wasn’t a hard decision to stop calling it 3.5 and give it a 4.0 version number.
Of course, there were other setbacks, like the fact that we also decided to rename the company at the same time, switched store providers, and wrote a rather sizeable app that sucked up all of my free time.
We worked really hard on this, but I don’t think the end result would have been in the same league had it not been for a bunch of people who helped us out. Ash Ponders and his team at AptFolk have helped us in a big way by providing end user support. I used to do it all, and it left me with no time to do coding. They also wrote the user guide, and did an awesome job of it. Leanne Havelock from FourLetterWord did all of our copywriting for the new site, press release, and a bunch of other stuff (some of which isn’t out yet). Miles Ponson did our app icon and status menu icon, both of which I think he nailed. Our relentless beta testers (too many to name) who sent me many a crash log to tend to. And of course, Tiff who’s been kind enough to let me have an affair with Xcode.
The end result is something I’m really proud of. Sidekick 4.0 works in both Snow Leopard and Lion. We decided to make it a free upgrade for NL3 owners because we believe it’s substantially better and want all of our users to upgrade as soon as possible, so we removed as many barriers as possible. It should be able to import all of your NL3 actions and locations, and even automatically upgrade your NLPlugins to SKPlugins if you have any installed.
Sidekick is the new NetworkLocation.
Wanted: Ottawa Apartment
As some of you may know (and some of you may not) I am leaving Winnipeg and heading to Ottawa in a month. My girlfriend got into grad school there, so we’re heading there at the end of August.
Why does this matter? Why am I blogging about this?
This is a plea for a very huge favour from those of you from the Ottawa area. You see, we have been searching for apartments for over a month now, and either have been disappointed with our findings, or have not been on time with our application (since we can never be there in person after a viewing). But we have been limited to internet finds - all of those niche places who have no need to post online have been under our radar. I can only assume that Ottawa is like Winnipeg where the good finds just don’t make it online. We’re starting to run out of time, and don’t especially feel like living in the ghetto.
So, if you can help us find something, we will be forever grateful and shower you with gifts (or just take you out to dinner, whichever).
Here is a list of what we are looking for:
Location: Central. Tiff is going to Carleton U, so Glebe and north into Central Ottawa is prime and we want it! Basically the area between Bronson and Elgin from the north to the river. She’s planning on busing it to school every day.
2 bedrooms (or one bedroom with den) Parking (1 spot, small car) and Laundry on site, Decent Kitchen, decent square footage (nothing under 700). We’d love a balcony or patio, or some sort of back porch/yard on which to drink/enjoy beer, but we can definitely do without it.
Price? Technically we are looking in the 1200-1400 range, but we can go as high as 1550 with utils and parking included.
If you can help us out we promise to return the favour. (Did I mention that Tiff makes fresh bread?)
Email me at email@example.com if you’ve got anything.
I was reading Twitter last night and saw someone mention “Monday’s keynote,” and thought.. “I think you mean… a week from Monday.” Then I realized, holy crap, nope, it’s THIS Monday. WWDC 2011 is just around the corner.
This will be an interesting one, I’m sure. Besides the normal “The sessions will be awesome, the beer will be fantastic, and the people will be vulgar” I mean.
This year will be neat for a whole other set of reasons. For one, it’s been like a month since we’ve last seen @cvee, which is the longest we’ve gone without seeing him since we hired the bird-like-individual a few years ago. I look forward to hanging out with him again. There’s no big-bird like a drunk big-bird.
Dave (he uhh… doesn’t do twitter), our new guy, or “Rainman #2” I like to call him (@cvee was Rainman #1) will be joining us for the first time. That’ll be interesting, cause well, he doesn’t drink (guess he didn’t get the memo about what the D stood for). But seriously, I’m looking forward to seeing what he thinks of the conference. Dave quite literally taught me how to code, forever ago. He somehow had the patience to teach highschool-me how to code in assembly. It’s taken me years to convince him to learn Cocoa and tackle consumer software with me.
@chrisfarber will be there. Jesus. Still doubting this one will actually happen. I’ve known @chrisfarber for almost as long as I’ve known Dave, the big difference here is that we’ve been running a business together, and I’ve never met him. When we started NetworkLocation, I think he was still in high school. He’s been in university for what feels like forever. He’ll be bunking with Phil and I, so I fully expect him to leave mentally (and potentially physically/emotionally) scared. He might actually be 21 now, and so there will need to be some type of company initiation thing going on involving medically-unrecommended amounts of beer. Oh… and at one point I have to “accidentally” introduce him to @rudyrichter.
We’ll be sportin some new advert-tees that we just got in this week for Oomph, and Sidekick. Come find us and say hello, we don’t bite. We might say awful awful things, but I promise we don’t physically bite.