Running Swift from the command line

A few months back I wrote a fairly simple Swift command line app in Xcode. The app did some Core Graphics drawing and saved the results to a PDF in the user’s Documents directory. The project consisted of a single main.swift file. Running it from with Xcode worked great. The PDF was created and saved to disk.

Today, I tried running either the uncompiled main.swift file or the compiled command line app from the command line with the following results:

$ ./main.swift
./main.swift:102:27: error: 'init(CGContext:flipped:)' is only available on OS X 10.10 or newer
    let graphicsContext = NSGraphicsContext(CGContext: context!, flipped:false)
                          ^
./main.swift:102:27: note: add 'if #available' version check
    let graphicsContext = NSGraphicsContext(CGContext: context!, flipped:false)
                          ^
./main.swift:102:27: note: add @available attribute to enclosing global function
    let graphicsContext = NSGraphicsContext(CGContext: context!, flipped:false)
                          ^

Even though I’m running this on OS X 10.11 and even though this runs just fine from within Xcode, it’s complaining that I’m trying to use a bit of API that might not be available.

Solution #1

The app kicks off by calling a function called drawPDF(). It’s within that function that the call to NSGraphicsContext(CGContext: context!, flipped:false) is made. So the first way to get this to work is to make sure the offending code isn’t executed on a pre-10.10 system. In this case, I’ll use a guard statement at the top of the function that will skip the entire function if the user isn’t on 10.10 or newer:

func drawPDF() {
    guard #available(OSX 10.10, *) else {return}
    // ... the rest of the function ...

This allows the file to be run from the command line, but then Xcode flags that line with a warning: Unnecessary check for 'OSX'; minimum deployment target ensures guard will always be true. Yes, my Xcode project requires at least OS X 10.11, so Xcode is pointing out that I don’t need this check because we are guaranteed to always be running at OS 10.11. That’s a little annoying and I’m sure there’s a project setting to silence this kind of warning. But I’m not a big fan of silencing warnings. So this is an imperfect solution.

Solution #2

Add a @available attribute on the function that makes the potentially problematic API:

@available (OSX 10.10, *)
func drawPDF() {
    // ... the rest of the function ...

This doesn’t quite work because running from the command line now complains that I’m calling drawPDF() and that function requires at least OS X 10.10. So I have to do an if #available check before calling it:

if #available(OSX 10.10, *) {
    drawPDF()
}

And with that, it works great at the command line, but I get another one of those warning from Xcode telling me that I’m doing an unnecessary #available check.

Conclusion

I’m not sure what the best/correct solution is. These both work but I don’t like the warnings in Xcode. ¯\_(ツ)_/¯

Safari can’t find the server `localhost`

The Problem

I’m running the latest version of MAMP (3.4) on my Mac running the latest version of OS X (10.11.3). When I nav to localhost:8888/, Safari gives me the following message:

Safari can’t find the server.

Safari can’t open the page “localhost:8888” because Safari can’t find the server “localhost”.

It works just fine in Chrome and Firefox. And I swear this worked a few months ago in Safari.

I can get Safari to connect to MAMP using 127.0.0.1:8888 or lapalapa.local:8888 (lapalapa is my Computer Name as set in System Preferences > Sharing). But that workaround isn’t ideal. I would really like localhost:8888 to just work as it should so that my local install of a WordPress site I’m working on loads in Safari.

The Solution

Are you f’ing kidding me? Restarting my Mac fixed it. I wonder if just killing Safari would have fixed it.

sigh

`sass –watch` Not Watching

Seems that sass --watch is not actually seeing changes made to .scss files. Running the command does the initial scss-to-css conversion just fine, but doesn’t seem to actually be watching for changes.

$ sass --watch scss:css
>>> Sass is watching for changes. Press Ctrl-C to stop.
      write css/main.css
      write css/main.css.map

Also, I have to hit ⌃-C twice to stop, at which point it spits out a bunch of error messages:

$ sass --watch scss:css
>>> Sass is watching for changes. Press Ctrl-C to stop.
      write css/main.css
      write css/main.css.map
^C^C/Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/celluloid-0.16.0/lib/celluloid/proxies/cell_proxy.rb:55:in `thread': Interrupt
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/celluloid-0.16.0/lib/celluloid/actor.rb:96:in `join'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/celluloid-0.16.0/lib/celluloid/actor_system.rb:79:in `block (2 levels) in shutdown'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/celluloid-0.16.0/lib/celluloid/actor_system.rb:77:in `each'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/celluloid-0.16.0/lib/celluloid/actor_system.rb:77:in `block in shutdown'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/2.2.0/timeout.rb:88:in `block in timeout'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/2.2.0/timeout.rb:32:in `block in catch'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/2.2.0/timeout.rb:32:in `catch'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/2.2.0/timeout.rb:32:in `catch'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/2.2.0/timeout.rb:103:in `timeout'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/celluloid-0.16.0/lib/celluloid/actor_system.rb:66:in `shutdown'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/celluloid-0.16.0/lib/celluloid.rb:156:in `shutdown'
    from /Users/erikhansen/.rbenv/versions/2.2.3/lib/ruby/gems/2.2.0/gems/celluloid-0.16.0/lib/celluloid.rb:145:in `block in register_shutdown'

So I installed Ruby 2.3.0 (I was using 2.2.3) just to get a fresh start.

$ rbenv install 2.3.0
$ rbenv global 2.3.0

Then I installed Sass again: $ gem install sass

Then, when running sass --watch I got some new output about a [Listen warning]::

$ sass --watch scss:css
>>> Sass is watching for changes. Press Ctrl-C to stop.
      write css/main.css
      write css/main.css.map
[Listen warning]:
  Listen will be polling for changes. Learn more at https://github.com/guard/listen#polling-fallback.

Made a change to my .scss file, and it worked!

>>> Change detected to: scss/main.scss
      write css/main.css
      write css/main.css.map

Also, I only had to hit ⌃-C once to quit.

So I’m back in business, but I still want to figure out how to fix this while still using Ruby 2.2.3, just for kicks.

Another oddity: After installing Compass under my fresh Ruby 2.3.0 install, everything still worked, but when I ran the sass --watch command I no longer got the [Listen warning]: but everything worked like it should:

$ sass --watch scss:css
>>> Sass is watching for changes. Press Ctrl-C to stop.
>>> Change detected to: scss/main.scss
      write css/main.css
      write css/main.css.map

So far this isn’t a great solution. “Just blow everything away and start fresh” is basically like giving up. But if all else fails, it might work for you.

TextMate-style selections in Atom or Sublime

One of the features I miss from TextMate is the ability to convert a multi-line selection into a column selection by simply tapping on the ⌥ (Option/Alt) key. 99% of the time I used this create multiple cursors without anything selected. The following animated GIF should explain what I mean. I’m using the keyboard to select multiple lines and then I tap ⌥ to convert my selection into a bunch of cursors stacked on top of each other.

TextMate - Toggle Column Selection

Both Atom and Sublime have a command to convert a selection into multiple lines “Selection > Split into Lines” and it’s mapped to ⇧⌘L by default. This almost does what I want. It gives me multiple selections, but it doesn’t give me a nice stack of cursors the way TextMate does.

To get the same thing TextMate gives me with a simple tap of the ⌥ key, I have to hit:

  1. ⇧⌘L
  2. ⌘→
  3. ⌘←

Yes, I could just hold ⇧⌃ and tap the up or down arrows to create a stack of cursors right where I want them. And there are still times when I do this in Atom or Sublime. I have two issues with creating the column of cursors this way: First, my muscle memory is wired to make a selection first and then convert to cursors or selections. Secondly, the ⇧⌃↓ method is less forgiving; if you overshoot, you have to start the process over over.

Okay, so let’s try to get that TextMate-style behavior working in Atom or Sublime.

First, grab a copy of Karabiner and install it. Karabiner will allow us to remap a single tap of the Option key to a sequence of keyboard commands while in Atom or Sublime. Karabiner has tons of other features that I’m not going to mention here. At the very least, you should look into using it to set up a Hyper Key on your Mac.

In Karabiner, do the following:

  1. In the Misc & Uninstall tab, hit the Open private.xml button.

  2. That will open a Finder window with the private.xml so you can easily open it in your text editor.

  3. If you’re using Atom, enter the following <item> node within the <root>:

    <item>
      <name>Tap left Option to convert selection to multiple cursors in Atom</name>
      <identifier>private.lo_cursors.atom</identifier>
      <only>Atom</only>
      <autogen>
        --KeyOverlaidModifier--
        KeyCode::OPTION_L, ModifierFlag::OPTION_L,
        KeyCode::OPTION_L,
        KeyCode::L, ModifierFlag::COMMAND_L | ModifierFlag::SHIFT_L,
        KeyCode::CURSOR_RIGHT, ModifierFlag::COMMAND_L,
        KeyCode::CURSOR_LEFT, ModifierFlag::COMMAND_L
      </autogen>
    </item>
    

    For Sublime, the important difference is the <only> node:

    <item>
      <name>Tap left Option to convert selection to multiple cursors in Sublime</name>
      <identifier>private.lo_cursors.sublime</identifier>
      <only>SUBLIME TEXT</only>
      <autogen>
        --KeyOverlaidModifier--
        KeyCode::OPTION_L, ModifierFlag::OPTION_L,
        KeyCode::OPTION_L,
        KeyCode::L, ModifierFlag::COMMAND_L | ModifierFlag::SHIFT_L,
        KeyCode::CURSOR_RIGHT, ModifierFlag::COMMAND_L,
        KeyCode::CURSOR_LEFT, ModifierFlag::COMMAND_L
      </autogen>
    </item>
    
  4. Save private.xml. Back in Karabiner, in the Change Key tab, hit the Reload XML button.

  5. Finally, in Karabiner, make sure your new option, either “Tap left Option to convert selection to multiple cursors in Atom” or “Tap left Option to convert selection to multiple cursors in Sublime”, is checked.

This works the way I want it to. Most of the time. There are times when I want to create a column of stacked cursors in the middle of lines of text. In that case, this hack doesn’t work because the column of cursors always ends up at the start of the lines. Totally copying the TextMate behavior might be possible with a custom Atom plugin.

Adding GPS Data to Maplets

I had really high hopes that Maplets would be great for hiking in Portland. Sadly a key component of the app is really half-baked.

My complaint is rooted in the fact that the maps I tried did not have GPS data baked in. Without GPS data, the maps are basically useless for hiking. I want to have the map on my phone and be able to fire up my phone’s GPS to show where I am on the trail. A common use-case, I think.

A map without GPS data is no big deal, though, because the Maplets website lets you add GPS data to any of their maps. This is where the problems start. Specifically, I wanted to edit the GPS data for the Portland Forest Park map. Before I visited the Maplet GPS Editor to see how it works, I assumed you could simply drop points on the map and set the GPS coordinates for those points. GPS data for all other points on the map could be interpolated from the data you gave it.

No such luck.

What you actually have to do is perfectly align the Maplet map layer over Google Maps. If you have to rotate the Maplet map layer for any reason, which I did for Forest Park because North does not point directly up, you need to turn on Google Earth mode. That’s problem number one because the Google Earth plugin is basically dead. 64-bit Chrome and Safari both don’t support the 32-bit Google Earth plugin. By the way, there are no warnings about this in Chrome or on the Google Earth plugin page. The plugin just doesn’t work. Safari gives you a fairly useless error message when you try to use the plugin. However, the plugin does still work in Firefox. Yipee.

So in Firefox I now have the unenviable task of aligning the Maplet map of Forest Park over the Google Earth view of Forest Park and its surrounding area. This is maddening. You can get it fairly close, but it’s impossible to get perfect. Why? For starters, the Google Earth plugin area is too small on the webpage to work with comfortably. Getting the alignment right is an endless cycle of:

  • zooming in to check alignment
  • then possibly zooming out and repositioning the map so you can adjust the Maplet layer position on Google Earth
  • if you want to scale the Maplet layer, you have to zoom out or reposition the map to find a Maplet layer handle to drag to adjust the scale

Repeat those three steps endlessly. And add in rotation adjustments from time to time.

Beyond that slow and painful workflow, I had to two other big issues. First, I really needed to use the Full Res version of the Maplet map, not the Thumbnail version. There isn’t enough visual info in the thumbnail to be sure it’s aligning properly. But the full res version is ~20MB and took forever to load from Maplet’s server. So I gave up on that. I suspect that trying to work with a 20MB layer overlay in the Google Earth plugin would prove difficult anyway. Second, the only way to scale the Maplet layer is by dragging the handles of the Maplet layer. In addition to forcing you to zoom out enough to see a handle, there is zero precision with this method. It’s impossible to adjust the size in small amounts. Once I discovered that, I gave up on setting the GPS data and gave up on Maplets entirely.

Animated GIFs in Twenty Sixteen

UPDATE Shortly after initially posting this, I discovered that Photon, part of Jetpack, was to blame for the animated GIF issues.

Embedding animated GIFs into Twenty Sixteen makes them look awful. (I just checked and the same issue happens with Twenty Fifteen and Twenty Fourteen.) I’m telling WordPress to embed the full size, original image. But that’s too large to fit in the template so they are scaled down with CSS. I’d guess that the CSS scaling was to blame, but you can totally scale the same animated GIFs with CSS in a simple HTML page and it works just fine. What am I doing wrong?

Native size is 1444x896, embedded at full size, looks awful
Native size is 1440×896, embedded at full size, looks awful
This animated GIF is 720x448 and also looks horrible
This animated GIF is 720×448 and also looks horrible

Back to WordPress

Moving back to WordPress has so far been a bit of a pain in the ass. Some of this is WordPress’s fault. Some of it is my host’s fault. Some of it is technology’s (?) fault.

Some issues off the top of my head:

  • I can’t get Jet Pack’s Markdown functionality to work when playing around locally with MAMP. So I can’t write test posts locally and see how they’ll look.
  • Moving my local DB to my site hosted on MediaTemple was a pain because (mt) is still using MySQL 5.1.72 but locally I’m running 5.5.4. So I had to make some adjustments to my exported .sql file. Specifically I exported from phpMyAdmin using the MYSQL40 option. I then had to manually edit the .sql file to change mentions of utf8mb4 to utf8. Since I was already messing with the .sql in a text editor, I adjusted all of the absolute URLs, changing mentions of localhost to the actual blog URL. I had to jump through these formatting hoops because of MediaTemple doing everything they can to force me to upgrade to a much more expensive plan, which isn’t going to happen. And moving all my online stuff to a new host is not something I want to deal with right now. Especially since (mt) is hosting my mail and I don’t want to deal with moving that somewhere else.
  • Turns out I really do need to use utf8mb4 on MySQL because if I don’t, I lose the unicode characters I want to use in blog posts. Specifically, I want to be able to enter the unicode symbols for keyboard modifiers like shift, control, and option. Unicode characters for arrow keys work just fine without utf8mb4. Until I move to a better host, I am stuck without these characters.
  • I converted some very short screencasts to animated GIFs so that I could insert them into a post. That in itself was a pain. It might be possible to make a quality animated GIF of a simple screencast that shows nothing but a text editor, I can’t figure out how. Jesus this is frustrating. If any was born to be converted to an animated GIF it’s a screencast of editing code. The color palette is already small. I looks perfectly fine at even 96 colors. And the animation itself is already stop-motion style. I ended up with low frame rates, low resolutions, and poor color palettes. Trying to fix these issues just caused GIFBrewery to blow up. But the bigger problem is that when said animated GIFs are embedded in my WordPress post, they get horribly distorted as they play back. This seems to be an issue with the Twenty Sixteen template. It looks like turning the channel knob on the old TV I watched Sesame Street on in 1982. Awful.

So I’ve got this nice little blog post I want to get onto my fresh install of WordPress 4.4 running the Twenty Sixteen theme and I can’t.