Saturday, August 10, 2013

Update

So I took a break from this blog, and in switching jobs I lost access to the Retina MBP about which I started a series of posts.  Windows 8 on MBP is probably old news by now anyway.  I may post more here if I start a new iOS app or a small webapp for work.

Tuesday, November 27, 2012

What I Did Instead of the Xamarin Contest

So I really did intend to throw together an entry for the Xamarin contest, but realistically I didn't have time in my evenings and Saturday mornings to get anything substantial built.  In light of reality, it was nice to stumble across an article with a silly signature and post a Facebook status that escalated into a more suitably-scaled diversion.  Here's two weeks' worth of my free time:

68 74 74 70 3a 2f 2f 62 69 74 2e 6c 79 2f 57 75 65 62 63 39

Note: I failed to test on a touch device until just now, and it doesn't work.  Use a real computer.

Post your answers as comments on this entry.  Hints are available, within reason.  Enjoy!

Monday, November 19, 2012

Mono for Mac Scripting: Rawr!

I take it all back.  In the end, I'm unable to use Mono to script my little project on the Mac, because:
  1. I can't wait for processes to complete.  I call System.Diagnostics.Process.Start(myStartInfo).WaitForExit(), but files written by the command-line programs I'm calling aren't on disk by the time I open them for processing in the next step.  I read several places that you need to set UseShellExecute = false to have the process called directly rather than via the "open" command (which returns immediately by default), so I set this property, but it didn't help.
  2. The PNG support in libgdiplus is apparently busted.  [Link here when I bother to find the blog post/bug report again.]
Given that this was a project to script the generation of some PNGs with ImageMagick, read them in, and spit out their raw bytes....

Friday, November 16, 2012

Serious Mono Development on the Mac: Why Not?

I've had Mono installed on my Macs for years now.  Mostly it was a novelty--occasionally I'd test some CLI or trivial Windows Forms app I'd written at work, just to see if it would run.  I wrote one quick image stitching program on the Mac for a friend's wife's blog (using GDI+, which actually worked, which in hindsight I realize is pretty impressive), but I've never done any "real" C# development on the Mac, for a few reasons:
  1. That's just wrong.
  2. I didn't have a good IDE (more on that in a bit).
  3. Compiling and running from the command line is gross.  (Yes, I know, MonoDevelop, getting to that...)
  4. I mostly wanted to do GUI stuff, the Windows Forms support was only partial, GTK sounds gross because it's not native to either .NET *or* the Mac, I didn't know any Cocoa, and Cocoa# sounded like a pretty experimental hack when I first read about it anyway.

Not So Wrong Anymore

I think I've gotten past point 1.  It comforts me somehow that Mono is now something of a commercial product thanks to Xamarin's work on MonoTouch, which presumably has positive implications for the desktop Cocoa bindings, etc.

When Mono on the Mac felt like an unsupported hack (I don't really know what kind of support Novell provided), I wouldn't have thought to use C# for anything but personal tinkering.  In particular, the thought of distributing a Mono app was out of the question, not because it was technically impossible, but because of point 4 and the whole packaging problem.  You can't distribute a Windows Forms app to Mac users; they'll hate and shame you.  The same probably goes for a GTK# app, with the possible exception of MonoDevelop.  So you had to develop a Cocoa# app, which felt both unsafe and unappealing.  And even if you completed one of those funky Cocoa# apps, you'd either have to somehow package it together with Mono or tell your users to go download this weird experimental Windowsy runtime platform to run your app.  Since very few users would have Mono installed by default, that would mean a huge download either way, even if your application itself were trivial.

But Mono on the Mac doesn't seem nearly so wrong now.  Even without Xamarin, C# on the Mac is probably here to stay thanks to the Unity folks.  For GUI development, MonoMac is ostensibly a decent set of Cocoa bindings that is well supported or at least has the interest of Miguel de Icaza, which goes a long way.  There's a MonoDevelop plugin with MonoMac project types, a packaging system for bundling only the assemblies used by your app, and even support for deploying to the Mac App Store.  Combine that with MonoTouch gaining traction as a real solution for iOS development, and MonoMac really doesn't sound too scary anymore.

A Real IDE

Realistically, I'm not going to do any serious coding without an IDE.  One of the things that makes .NET such a productive platform is its discoverability via IDE tools.  In C, how do you learn what you can do with a string?  Get a book?  Google "string manipulation?"  In C#, how do you learn what you can do with a string?  Type a period after the variable name or string literal.  I'm productive in typed, object-oriented, garbage-collected languages not just because of the high-level abstractions provided by the languages but because the typing system, object-orientation, and garbage collection all lend themselves to library design where all functionality pertinent to an object can be accessed via a method on that object.  This means I don't need to know an entire library before I start working with it or interrupt my workflow for an internet search every time I need to call a new method.  I do a quick Google search for a "starting point"--the main class of interest--and Intellisense my way to a working program.  This is huge.

There are other perks of an IDE, of course, like automatic syntax checking (love those red squigglies), GUI access to the file structure, streamlined builds,  and so on.  These are all things provided by IDEs like Visual Studio on Windows and XCode on the Mac.  If I'm going to do C# development on the Mac, I'm going to do it in an IDE.  And that's partly why, to date, I haven't done C# development on the Mac.

When I wrote that quick C# app on my Mac for a friend, it took longer than it should have because I was editing my program in a text editor with no syntax checking or Intellisense and compiling from the command line.  I don't remember if MonoDevelop existed at the time, but if it did, I was probably turned off for the following reasons:

  1. It's GTK.  Ugh.  Nothing against GTK *on Linux*, but this is my Mac and you're making it ugly.  Not even because GTK is especially ugly, but because you're clashing with the rest of my system.
  2. The non-native L&F leads me to expect non-native behaviors (awkward keyboard shortcuts, swapped button order in dialogs, etc.).  Basically I expect the developers to make it Mac-like only as a half-hearted afterthought.  Seriously, if you expect me to Ctrl-C for Copy on my Mac, we're done.
  3. I've used enough OSS GUI apps to keep my expectations really low.
Well, tonight I needed to script some command-line work, and I very nearly used Perl.  But I thought to myself, "Why am I doing this?  I'm going to have to go re-learn all the basics like I do every time I write a Perl script, and yes, it will be terse, but even if it takes me twice as many lines in C#, it'll take me half the time because I know C# and what I don't know or don't remember is discoverable with a good IDE, and I have this MonoDevelop thing sitting on my Mac for the Xamarin contest that I will never complete now that I'm distracted by silly code riddles (and would never have completed anyway), so let's give it a shot!

I fired up MonoDevelop and created a Console solution.  Aesthetically un-awesome, but behaviorally not unlike Visual Studio project setup.  I started typing and got some lovely code completion, with a few gotchas:
  1. Code completion is case sensitive.  Gah!  I can't tell you how many times in an evening I typed "System.io<TAB>" and ended up with "System.IndexOutOfRangeException."  Hopefully there's a setting to configure this.  If not I may submit a feature request.  They'll probably just tell me I'm spoiled by VS.
  2. In general it appears pickier than Visual Studio, especially VS 2010+, which match any text within a suggestion, not just the first word.
The syntax checking appears to be less than awesome too.  I frequently had to build before discovering I had a typo or other syntactical problem.

All that said, I think it's good enough.  Here are some things it does right:
  1. Project creation and organization is nice.
  2. Build and run works as expected, with configurable "Custom Execution Modes" for saving lists of command-line arguments and whatnot.
  3. The keyboard shortcuts are correct!  It behaves like a native Mac app for the shortcuts I use frequently, and that's enough.
Okay, that's a short list, but this is from one evening's use.  Basically, it's a real IDE that isn't so horribly un-Mac-like as to be unusable, and it lets you develop C# code on your Mac.

Better Than the Alternatives

What I realized tonight was that developing a quick C# console app in MonoDevelop was my best choice for the task at hand.  I had lots of scripting languages to choose from, but I know C# better and I have a decent environment for writing and running it, so why not?  I'm thinking about how this logic extends to real Mac GUI development.  If the Cocoa bindings are decent, MonoDevelop is an acceptable IDE (XCode is certainly nothing to write home about anyway), and C# beats the pants off of Objective-C.  There's a real developer community around the iOS stuff, and presumably there's some trickle-up to the Mac.  I don't have the time or interest to get good at Objective-C, but I could see learning enough of the Cocoa API to string a GUI to some good, sensible C# model/controller code.  Mono might actually get me developing for the Mac.

Wednesday, November 14, 2012

Swipe Gesture Overloading Considered Harmful

So both Firefox 17 and Chrome 23 interpret a two-fingered right-swipe on my RMBP trackpad as a "back" gesture.  This would be a really nifty feature if right-swipe didn't have the system-wide canonical meaning "drag the scrollable content right."  You say, "What?  No horizontal scroll gestures in Firefox and Chrome?!!"  No, it's worse than that.  You get horizontal scrolling until you can't scroll anymore, at which point your next swipe unloads the current page.  Hope it was just a page, not a client-side webapp, or you just lost your work.  Somebody fix this.

Edit: apparently this behavior is due to a misguided attempt on Firefox and Chrome's part to be good OS X citizens and implement the OS-wide "Swipe between pages" gesture, configurable in the "More Gestures" tab of the Trackpad Preference pane.  Such a gesture may make sense for, say, the Preview app, but is a truly bad idea for a "page" that may contain dynamic content.

Saturday, November 10, 2012

MacPorts vs. Homebrew: My Uneducated 2¢

For the server side of my project for the Xamarin contest, I'm trying Ruby on Rails.  Never used Ruby or Rails before, but I know how slow Java webapp development is (at least with the stack of technologies I'm familiar with) and that won't cut it.  My hope is that I can copy-paste enough code from the web to get a working Rails site going quicker than I could do the same thing in Java.  This seems like a fair test of Rails, right?

Well, the Rails installer strongly encouraged me to get Homebrew and do all my prerequisite installs that way.  All I knew about Homebrew was that it existed.  I've already installed a lot of UNIX stuff via MacPorts, which seems to work fine, so I did some quick reading about the differences.  They seem to be:

  1. Installation directory: Homebrew uses usr/lib; MacPorts uses /opt/local.
  2. Dependency resolution: Homebrew uses existing system installs where possible; MacPorts always installs the latest and greatest version of your dependencies.
  3. Notions of ownership: Homebrew wants to take over /usr/lib, which is a standard UNIX install location, and set ownership for that folder to a single user to eliminate the need for sudo; MacPorts uses a nonstandard location to avoid interfering with other installs and requires sudo for installation, making installed software available to all users.
  4. OS upgrade support: Since MacPorts is in its own little world, it's not broken by system updates; since Homebrew installs to /usr/lib and depends on system libraries, it can be.
  5. Database Management: Homebrew uses git and Sqlite to track installed apps; supposedly this makes it easier to upgrade Homebrew itself.  Or something.
  6. Coolness/Prettiness Factor:  Homebrew's website is all pretty and modern and makes everything look simple and seamless.
  7. Community: Since Homebrew is written in Ruby, all the Ruby fanboys use it and all the Ruby stuff takes for granted that you're going to be using Homebrew.  I haven't yet hit any snags where Homebrew had something I needed that MacPorts didn't, but there's a lot of pressure to conform.
The best article I found comparing the two this one by Ted Wise.  I also read one slightly scary story about MacPorts.

After some reading, here were my thoughts:
  1. MacPorts sounds a lot less problematic, especially when it comes to OS upgrades.
  2. Having to download less for Homebrew sounds nice for installations at home over a not-super-fast cable internet connection.
  3. Git and Sqlite are cool, but I guess I don't really care how things are stored so long as the installs are seamless.
  4. I'm already using MacPorts, and I don't know what happens when I start mixing the systems.  I suppose everything's fine so long as I don't install the same package from both, but what about dependencies that get sucked in?  Plus, if I use both systems, I have to decide which to use for every package I install.
  5. While I don't *like* Homebrew's notions of ownership, I'm the only user of my system and I guess I don't care what it does so long as none of my existing stuff breaks and Homebrew does its thing right.  The Homebrew page assures you that's how it'll go.
  6. It would be nice to be doing things the "default" way for all the Ruby stuff.
  7. I already have stuff in /usr/lib that I've built and installed from source.  I *think* Homebrew is supposed to leave that stuff alone so long as you don't try to install the same package via Homebrew.  But I wasn't sure.
In short, I saw pros and cons for installing Homebrew but definitely didn't want to switch to it wholesale.  I decided to try things the "no-nag" way to appease the Ruby folks and install my Ruby dependencies via Homebrew.

Upon installing, Homebrew warned me that I was using MacPorts and that I should probably rename, if not delete, my MacPorts install directory.  Uh-oh.  I hoped this was only necessary if Homebrew and MacPorts installed conflicting versions of the same library, and I was going to keep my Homebrew installs to a minimum, so I proceeded.  But the Homebrew installer also encouraged me to run "brew doctor" to list all the potential problems with my system.  It complained about all the stuff in /usr/lib and then about some library from my Mono install.  And I thought, y'know, this MacPorts-all-in-its-own-world thing is starting to sound pretty nice.  So I uninstalled Homebrew using this script, installed the Ruby/Rails dependencies via MacPorts, and went on my merry way.

So.  MacPorts for me.