WWDC Sells Out in 2 Hours

April 25th, 2012

It's shocking, but I'm not really surprised. As John Gruber put it:

Three years ago it sold out in a month. Two years ago it took a week. Last year it took 12 hours. So, if you want to go, I wouldn’t fuck around.

And indeed he was right. It sold out in two hours. Amazing.

I'm not sure what they'll be doing a year from now - it's likely to get even worse as time goes on. I'm guessing they are just going to have a shorter and shorter sell-out time and let people stay up all night to try and anticipate when they will go on sale.

After all, what else can they do? Raise the price? They'd have to make it 10x to impact the demand in any really significant way, and then the people you really want coming will probably stay away. You want the indie Mac developers that have made it - at least a little, and the soon-to-be indie Mac developers to intermingle and share ideas. This gets the ecosystem going and makes sure that you have great ideas passed around.

I think it's an interesting note that if you were in a long meeting, or might have been sleeping in, you'd have totally missed it. Amazing.

Google Chrome dev 20.0.1115.1 is Out

April 25th, 2012

Google Chrome

This morning I noticed a somewhat minor update to Google Chrome dev to 20.0.1115.1. The release notes only say that there are "fixes" and an update for the V8 javascript engine to 3.10.5.0. Still, it's nice to see that it's making progress still as I'm thinking about a web project to keep me occupied while I'm off. I still need to finish the iOS/OS X library I'm working on, but after that, possibly a little more web stuff? Who knows.

Upgraded to Latest (March 2012) gfortran (4.7.0)

April 11th, 2012

fortran.jpg

I was reading a little from the newsgroups today and decided to have a look at the latest from the HPC on Mac OS X to see if they had an updated gfortran for OS X 10.7 - and indeed they did. I downloaded the package, updated my removal script and then installed the latest version. I then rebuilt my thesis code with it, and was happy to see that it all still worked.

Not that I didn't think it would, but it's nice that it still works.

I'm not sure what I was planning, but I have to admit that it might be really nice to get back into FORTRAN and just write code. But that's the same with C++, isn't it? I just want to write code. Not really mess with GUIs… not mess with people, and politics, and all the cruft that comes from dealing with people -- I just want to write code again.

Maybe I'll dig into my thesis and try to see where the convergence issues really are. I know they are there, but I'm not sure that FORTRAN is the best language to find them. Maybe Obj-C might be nice. It's certainly got all the functionality I'd need, and it'd be nice to be able to have the physics in modules, but we'll have to think about it a bit.

Google Chrome dev 20.0.1096.1 is Out

April 11th, 2012

This morning I noticed a minor milestone for Google Chrome dev - the 20.x.x.x series is out with 20.0.1096.1. There is a new V8 javascript engine, and a few more nice things in the release notes, but it's interesting that since I've been looking, I haven't done a lot of writing, and noes Chrome 20 is out. Kinda wild.

Having a Blast at Panera

April 2nd, 2012

This evening I decided I wanted to get out of the house a little, so I went with Liza to the Naperville North Women's Lacrosse Board Meeting and sat at a little table for two in the corner and did a bit of coding. I can see why Wil Shipley and so many others do the exact same thing. It's so nice to have a simple little break from the home office where I've been hammering on this same problem for quite a while. Just the change of scene… the different background music… the different table and surroundings - all makes for a really wonderful experience.

Now I don't think I'd do this over the home office, but it's certainly nice to have the change of scene. If I went indie, I'd be doing this a few times a week. Maybe Starbucks, Panera, and other similar places would be where I spent my afternoons. Hard to say, but it's a lot of fun. I can see myself doing a lot more coding here if Liza's going to stay on this board.

Very nice change of pace.

And I got a lot of coding done too!

Mou – Interesting Markdown Editor for Mac OS X

March 30th, 2012

Mou - Markdown Editor

When putting work up on GitHub, it really pays to have a nice Markdown previewer or editor for building your README.md file as it's the first thing a new user sees when coming to your project page on GitHub. You want to make a nice impression on the user, have good introductory docs, and even the license on the project, and all this is going to be rendered in Markdown - at least GitHub's version of Markdown.

When I was initially doing this, I was using BBEdit, and while it had a preview that worked with Markdown, it didn't support the GitHub CSS that it was going to be rendered in, and it still required that I edit the file, check it in, push it up to GitHub, and then I could see if I liked what it looked like. Not a great workflow, really.

So this morning I was on the hunt for a decent Markdown editor for Mac OS X. I knew there were several available in the Mac App Store, so I was willing to buy one, but I wanted to search the web first, to see what the opinions were out there of the best one to get. I've seen several, and there are two that seemed likely candidates, and I decided to try one, but I'm not really sure that it's what I am looking for. Still, it appears to be a lot closer to what I'm looking for than what I'm doing now.

Mou is a free app that does a split-pane view of source and rendered text. The position of the split pane isn't really resizable like a lot of Mac apps, but it is moveable in the sense that it can be moved by some menu commands to change the split from 1:1 to 1:2 or 2:1, and such. It's not ideal, but it's free. It's certainly a very nice start in the right direction as it currently support GitHub flavored Markdown.

BBEdit can work with Markdown, and even preview it, but it doesn't really use the GitHub style for the preview, and try as I might, I was totally unable to get some CSS file for BBEdit's preview that would work. There were perl and PHP versions, but that's far too much, and the Mac App would then be far better.

The problems with Mou are that it's taking up a ton of space on the screen. There's another application called Valletta 1.0, and it's got a unique take on the two-pane system: it keeps it all in one by having the line with the cursor in input mode and the rest of the document in display mode. This is a good idea, but if you're moving between different sized text, you're going to be having your text move all over the place. What I want is a great preview.

Mou does the preview good enough, and it's got a simple editor built in. Not bad for free. There's another app that does just the previewing, and it's on the Mac App Store for $4 - Marked. I might end up going for this as it's exactly what I'm looking for. I can edit in BBEdit all I want, and then preview in a good GitHub renderer and then check it in and push it all up to GitHub.

[4/10] UPDATE: I ended up getting Marked from the Mac App Store. They updated it to 1.4, and included the color syntax highlighting on GitHub. It's exactly what I'm looking for. $4 well spent. I can edit it in BBEdit, save, and it's automatically updated in Marked. Very nice indeed.

Interesting Bug in OS X Lion – and Great Service

March 27th, 2012

Mac OS X Lion

Today I had a crash in MarsEdit, and it had to do with looking up a word in a post I was generating, and I sent the data to the author. Amazingly, Daniel got back to me that there's a known bug with Mac OS X Lion when it comes to the window animations - and specifically turning them off, as I had. This was one of those hidden preferences that I found and used, and, as Daniel said, many have used as well.

The bug is that it's not really working right without it, and so the right thing to do is to turn it back on:

  $ defaults delete -g NSAutomaticWindowAnimationsEnabled

And things will go back to normal.

The real kicker for me is not that there's a bug in OS X Lion - it's that Daniel was on top of this support issue that wasn't even emailed from me to him. It was a crash report that I sent in, and he responded to it. That's amazing customer service. I'm certainly going to remember this as I (hopefully) move towards indie Mac developer. It's something to respond to emails, it's another thing entirely to respond to crash dumps.

Amazing.

Working with XML-RPC, Mac OS X 10.7 and Xcode 4.3

March 26th, 2012

xcode.jpg

For the last week or so I've been working getting something going with an old friend that involves a centralized service, Macs and iOS devices all sharing data. Most of this data is numeric, but that's only a current design consideration, and what we basically needed was something that was similar to iCloud, but not file or key/value based. We needed to have a specific local database (SQLite3 for Mac and iOS), and have that be a local copy of some data in a more centralized database (PostgreSQL) on a centralized server (Apache, PHP).

So the question was How to do it?

My initial thoughts went back to The Broker codec that I worked with back at The Shop, but then I realized that it was a really bad idea to use that as there's no proven need for that level of complexity, and that a far easier solution - and one I've used on the Mac in the past, is to have a simple XML-RPC client and server, and allow the server to be in PHP, and the client in the native frameworks and libraries on Mac OS X (and iOS). So I went that direction instead, and I think I've got something that works really well - and stays away from the entire marshalling/demarshalling issues that The Broker had.

But the XML-RPC route was not without it's trials and tribulations. Neither was using the wonderful FMDB Open Source library for Mac OS X and SQLite3. I had several things to figure out, and while it's all working now, it's not simple to figure all these things out, so I wanted to write this all down in a nice, concise way.

Step 1 - The Changes in Xcode 4.3

One of the firs things I wanted to do was to start a new Xcode project from scratch. Most of the projects I have weren't started with Xcode 4, and I wanted to see what I was going to get if I started clean, and put everything into git right from the start.

The first thing was that the new Xcode projects allow for a simple unit test framework that's very similar to the JUnit framework. You have a nice pair of set-up and tear-down methods, and then anything you define in the implementation file (.m), that starts with test is going to get run in the alphabetical order in which it was defined.

This is very nice and clean, and it means that you really don't have to mess around with the interface (header) file for the tests. Sure, you have to put in the ivars that you might need, but there than that, it's pretty bare. It's all in the implementation file.

There are also a set of methods for assertions like true and not nil, and all kinds of tests that you can sprinkle in the test code to make sure it's running the way you think it should. Very simple to use.

Running the tests is equally easy as it's just a simple, single key-stroke in Xcode to build the project, and the tests, and run the tests. I was very impressed as it made it very easy to run the tests until I got everything working just the way I wanted it.

Step 2 - FMDB as a Framework (well… almost)

I knew I wanted to use Flying Meat's FMDB library on GitHub for access to the SQLite3 database. I've read a lot about this library, and it looks to be set up exactly as I might have done it - but I didn't have to do it. Excellent.

But it wasn't without a little bit of grief. First off, it's not a Framework. Or a Library. It's a group of files. More than that, it's a group of files with a test app that's put together in a way that makes it a little unclear how to actually use it. I had to do a little googling to see that what you needed to do was to extract the files you needed from the project, place them into your project, and then start using them. In short, it's a library that's really a bunch of files.

This isn't bad, but a few sentences in the README would have made it very clear what I needed to do, and based on the things I've seen in Xcode 4.3 - converting it to Xcode 4.3 and using the unit test framework would make this all unnecessary. It could be a library, and it could have unit tests, and it would be the same code, it just would be a lot easier to use. But so it goes.

I added the files to my project, placed them in a 'group' (a folder in Xcode 4, but not on the disk itself), and then I was ready to go. Not horrible, but again, a few sentences, or a migration to Xcode 4 and this would all have been unnecessary.

Step 3 - XML-RPC Service in PHP

I had some code from a while back when I used a different XML-RPC implementation than what now is standard in PHP 5. So I was a little careful about how much to expect to be the same, and how much was implementation-dependent. Turns out, the built-in XML-RPC in PHP 5 is far nicer than the previous version I was using, and far faster as well. Win-win.

I have had no problems writing simple XML-RPC code in PHP 5, and it's nicely compact as well:

  <?php
  /**
   * This is the simple 'ping' service that let's the client know that we
   * are here and answering requests.
   */
  function doPing($method, $args) {
    return "PONG";
  }
 
  /**
   * At this point, we need to set up the XML-RPC server, bind the method
   * calls to the individual functions in this file, and then let the
   * user's call get processed and return the results. It's all pretty
   * simple, and handles all the ugly parts of the marshalling/
   * de-marshalling and method invocation.
   */
  // first off, make an XML-RPC server
  $server = xmlrpc_server_create() or die("Can't create rpc server!");
  // next, let's register the PHP functions as methods
  xmlrpc_server_register_method($server, 'ping', 'doPing') or
      die("Can't register the 'ping' method!");
 
  // now let's get the request and options...
  $request = $GLOBALS['HTTP_RAW_POST_DATA'];
  $options = array('output_type' => 'xml', 'version' => 'xmlrpc');
  // ...and make the call, returning the data to the client.
  print xmlrpc_server_call_method($server, $request, NULL, $options) or
      die("Can't call the method!");
 
  // finally, we can shut down the XML-RPC server.
  xmlrpc_server_destroy($server);
  ?>

This is a simple ping service that was the first thing I built to make sure that I could communicate with the PHP service and the Obj-C client. It's not bad at all in PHP, and since it's implemented in C, it's as fast as we're going to get.

So far, looking very good

Step 4 - XML-RPC Client in Objective-C

The client side was a little more code, but logically, it was very simple as well. I wanted to encapsulate the XML-RPC call into a simple method that would take Foundation objects and return Foundation objects so that I wouldn't have to worry about data type conversions, or any marshaling or demarshalling issues. What I came up with was a general 'call' method:

  - (NSObject*) call:(NSURL*)aURL method:(NSString*)aMethod
     with:(NSDictionary*)aParams orderedBy:(NSArray*)aKeyOrder
  {
    BOOL      error = NO;
    NSObject* retval = nil;
 
    // first, make sure that we have something to do
    if (!error) {
      if (aURL == nil) {
        error = YES;
        NSLog(@"[SKPipe(Protected) -call:method:with:orderedBy:] - the
               provided URL is nil and that means that there's nothing
               I can do!");
      }
    }
    if (!error) {
      if (aMethod == nil) {
        error = YES;
        NSLog(@"[SKPipe(Protected) -call:method:with:orderedBy:] - the
               provided method name is nil and that means that there's
               nothing I can do!");
      }
    }
 
    // make the XML-RPC method invocation as it's the basis of the call
    WSMethodInvocationRef    rpcCall;
    if (!error) {
      rpcCall = WSMethodInvocationCreate((__bridge CFURLRef)aURL,
                  (__bridge CFStringRef)aMethod, kWSXMLRPCProtocol);
      if (rpcCall == NULL) {
        error = YES;
        NSLog(@"[SKPipe(Protected) -call:method:with:orderedBy:] - the
               XML-RPC method invocation to '%@' with method '%@' could
               not be created and this is a real problem. Please check
               on it.", aURL, aMethod);
      } else {
        // set the parameters for the invocation - if we have any
        if (aParams != nil) {
          // see if the user has given us the key order to use
          if (aKeyOrder != nil) {
            WSMethodInvocationSetParameters(rpcCall,
                               (__bridge CFDictionaryRef)aParams,
                               (__bridge CFArrayRef)aKeyOrder);
          } else {
            WSMethodInvocationSetParameters(rpcCall,
                               (__bridge CFDictionaryRef)aParams, NULL);
          }
        }
      }
    }
 
    // do the actual XML-RPC call and get the results
    if (!error) {
      NSDictionary* pkg = (__bridge NSDictionary *)
                                 (WSMethodInvocationInvoke(rpcCall));
      if (pkg == nil) {
        error = YES;
        NSLog(@"[SKPipe(Protected) -call:method:with:orderedBy:] - the
               XML-RPC call returned nothing at all and that's a serious
               problem. Check on it.");
      } else if (WSMethodResultIsFault((__bridge CFDictionaryRef)pkg)) {
        error = YES;
        NSLog(@"[SKPipe(Protected) -call:method:with:orderedBy:] - the
               XML-RPC invocation of '%@' to '%@' returned a fault: %@",
               aMethod, aURL,
               [pkg objectForKey:(__bridge NSString *)kWSFaultString]);
      } else {
        // looks OK... get the results
        retval = [pkg objectForKey:(__bridge NSString *)
                                         kWSMethodInvocationResult];
      }
    }
 
    return (error ? nil : retval);
  }

The code is pretty simple - we first check to see if we have the necessary arguments to the method, and then we construct the method invocation. If there are parameters to pass to the call, then we add them, and if there is an array defining the order of the arguments in the dictionary, then we supply that as well.

We then first off the method invocation and get the return value. Pretty clean, but you have to know all the little tricks to get it to work. Thankfully, once we have this one method, we don't have to mess with XMl-RPC any more and can just stay in Objective-C and Foundation objects.

Calling the ping method isn't too bad… in fact, one of my tests does exactly that:

  - (void) test_1_Ping
  {
    if (![_pipe ping]) {
      STFail(@"The server ping failed!");
    }
  }

where:

  - (BOOL) ping:(NSURL*)aURL
  {
    BOOL      error = NO;
 
    NSObject* ans = [self call:aURL method:@"ping"];
    if (![ans isEqual:@"PONG"]) {
      error = YES;
      NSLog(@"[SKPipe(Protected) -pingServiceAt:] - the XML-RPC response
             was not good: %@", ans);
    }
 
    return !error;
  }

It's really pretty simple to use for strings, integers, arrays, dictionaries, and most data types and values. But there are two things that XML-RPC doesn't do really well, and I needed them both: NULL and Date/Time values.

Step 5 - Dealing with NULLs

XML-RPC just can't send a NULL. No way to tag it. I found a reasonable solution in the idea of sending a special value and then interpreting that special value as a NULL in the different parts of the code. For instance, if we sent a string: "__NULL__", then we could test for the data being a string, and it's value being '__NULL__'. It's possible that a call would have that as an argument, but not very likely.

If we decode this as the true NULL, then we're OK. Not easy given all the places that I'd like to have an argument or return value be NULL, but it's possible.

Step 6 - Dealing with Dates

NSDate values can be passed through - but they are passed through as string values where the NSDate is expanded out to it's human-readable value. This is OK, but it means that we need to have quite a bit of standardization on the format across different machines and platforms, and it means that we have to take the time to decode it and encode it on every call. Non-ideal.

Far nicer would be to send milliseconds since epoch as the date and then reconstruct the dates on the other side. This is easily done in Obj-C using the NSDate class:

  // build up the parameters to pass into the call - the local 'as of'
  NSMutableDictionary*	params = [NSMutableDictionary
                                     dictionaryWithCapacity:3];
  [params setObject:[NSNumber numberWithInt:aPID] forKey:@"pid"];
  [params setObject:[NSNumber numberWithDouble:
                        [aDate timeIntervalSince1970]]
             forKey:@"asof"];

I essentially turn it into a simple 'number' and then pass it through without any problems. On the other end, we have to worry about how to interpret this data properly. After all, it's not a date, it's a number of milliseconds since epoch, and that means that in PHP and PostgreSQL we need to account for this. What I found was that it was fairly simple to do something like:

  function removeData($method, $args) {
    // first, get the SQL that we need based on the method name invoked
    if ('removeIt' == $method) {
      $sql = "delete from meas where pid=" . (int)$args[0]
             . " and mid=" . (int)$args[1]
             . " and extract(epoch from taken)=" . (double)$args[2];
    }
    // now we need to open up the database, make the call, get the response
    $conn = pg_connect('host=localhost port=5432 dbname=primary');
    if (!$conn) {
      $retval = "no db";
    } else {
      $result = pg_exec($conn, $sql);
      if (!$result) {
        $retval = "no result for: " . $sql;
      } else {
        $result = pg_exec($conn, $sql);
        if (!$result) {
          $retval = "BAD";
        } else {
          $retval = "OK";
          // make sure to free up the result
          pg_free_result($result);
        }
        // make sure to close up the database connection
        pg_close($conn);
      }
      // make sure to close up the database connection
      pg_close($conn);
    }
    return $retval;
  }

Finishing Up

This has a lot of partial code, but it's all in the git repos for the project, and if you really need it, let me know. However, I think this is a great start for what you need, and a little experimentation should get you where you need to be. It's not perfect, but it's pretty close.

Google Chrome dev 19.0.1077.3 is Out

March 26th, 2012

Google Chrome

This morning I noticed that Google Chrome dev 19.0.1077.3 was out with a few little updates and a few known Mac issues. Interestingly, the new V8 javascript engine is there, but there are a few incorrectly drawn icons in the Mac version. Odd little combination of changes, but I'm guessing it's a merge that needs to be done, and then things will clear up. There's also a fix for the Flash plug-in, but it's going to be interesting to see what becomes of Flash now that Adobe is all but giving up on it. Google may go back to HTML5 and the more widely supported codecs. Hard to say.

Open Source Falling Out – ZeroMQ

March 15th, 2012

ZeroMQ

Well… today has been an interesting day for one open source project that I've been working with for about the last year or so - ZeroMQ. Today I learned that two of the key developers in the group have "jumped ship" and forked the codebase, and are calling themselves Crossroads I/O. Their project, libxs, is really just a fork of the ZeroMQ code, and they are off to the races with a new Open Source company/project, and without the backing and support of a lot of the ZeroMQ community.

Today in IRC, it was a real surprise to hear Pieter talking about all the grief that was hidden from me, at least, in 2011. Trying to keep the group together was his job - and in the end, he realized that it just wasn't possible. So away Mato and Martin went, and the group is now light those two major developers.

I look at this with a lot of curiosity. When they had 2.1.x, it was good, decent, and while not perfect, it could have used a lot of improvement. Rather than do that, they started a 3.0 branch, with a completely different API, and all of a sudden, the upgrade path to me wasn't clear. I didn't mind it so much as we were moving away from it as the delivery transport in the project, but it still bothered me that they wanted to have a new API and a re-write of large sections of the code so soon after they just got 2.x out the door.

Dynamic and flamboyant individuals are nice to really move a project, but I can see that they can also be the worst liability to a project like ZeroMQ, as well. If they want to take the project in directions that the majority of users don't want, then they are going to make the project appear to be run by lunatics. But without them, you may face the problem that fixing the bugs they made are near to impossible in any reasonable timeframe.

So on the whole, I hope things work out for ZeroMQ, I really do. I think it's got a good idea that needs a little work to make it a really robust and reliable messaging system. But it's going to need to attract a few key, strong, developers to make it work.