Archive for September, 2018

Tuple Initialization

I’ve been wanting  tuple-initializable in Swift for Core Graphics, where it’s a drag to always use long and cumbersome initializers when I’m not building production code:

let point: CGPoint = (100, 50)

Yeah, it is better form to use labeled initializers but I’m anyone using CGPoint understands the correspondence between (x, y) coordinates. And I don’t want to just build CGPoint.init(_ x:, _ y:) extensions. I like the tuple form.

Right now, the closest you can get is the silly:

let point = (CGPoint.init as (CGFloat, CGFloat) -> CGPoint)(100, 50)

And that’s (pardon the pun) pointless.

It would be pretty cool to allow memberwise tuples with or without labels in place of  initializers when the tuple field types could be unambiguously determined:

let point: CGPoint = (x: 100, y: 50) 
// instead of: let point = CGPoint(x: 100, y: 50)
let person: Person = ("Mary", nil, "Santos")
// instead of: let person = Person(first: "Mary", middle: nil, last: "Santos")

It may be ugly but it would be hella useful in Playgrounds.

That darn Maps app

Dear Maps team,

Please don’t route me onto a dirt road again. It was super un-fun. I ended up going back up to I-80 and heading over to Wyoming from Nebraska, adding another state and about 5 hours to my trip including the not-joy of I-25 rush hour traffic instead of the much quieter I-76 through Fort Morgan.

It was impossible to get any live data from said dirt road so I just went with my gut until I could get directions again, which took about 2 hours, placing me just outside Cheyenne.

Navigation through Nebraska is always horrible horrible horrible, usually just blank tiles until I hit either Colorado or South Dakota. When going state to state, I’d like to cache tiles along several possible routes because with so much highway construction, I don’t want to be caught with blank tiles in the middle of Nebraska when I have to go twenty or forty miles off to the left or right to avoid a road that isn’t roading at the moment.

Caching tiles and directions along many possible routes would have helped the whole dirt road fiasco. The no-data-no-tiles-no-rerouting trap is both unsafe and unpleasant. Plus it made me miss Sidney, NE, with the only truck stop I’ve ever encountered in the United States that offered bidets (!) in their bathrooms. A true tourist’s experience.

While I’m venting, please respect my wishes about “No tolls” or “No highways” for my entire trip, even if I take a slight detour to avoid traffic. Forgetting “Show me how to get to [Someplace] avoiding tolls” when I reroute cost me  unnecessary funds recently by putting me onto 470, aka the hell road. I was properly billed (thankfully!) and paid immediately but no one voluntarily drives on E470.

Maps folk, please let me say “Show me how to get to Colombia, MO avoiding tolls and dirt roads” and remember that request until I’m safely at my destination. And let me add those requests as I’m driving. During rush hour, let me say “Hey, let’s get off the highways until I’m close to 225”. That’s totally doable from a programming point of view.

Speaking of slight detours, I generally know better than Maps how to tweak directions within the first few miles of my home. For example, I prefer to take the relatively quiet 13th and 14th streets from downtown instead of Colfax or 6th. There’s an incredibly unsafe left turn near our house that Maps always recommends. I drive a little further and make a safe U-turn at a light with a dedicated left turn signal.

I do these tweaks near my home all the time and Maps shouldn’t be fighting me on this, announcing updated directions every single block. I’d like a setting that limits any directions at all (after the initial announcement) for the first, say, mile or two or three away from my home or other “known” starting points that I could add to a list.

In fact, I know how to get to many major milestones within the greater Denver metropolitan area like 225 and Vasquez, and Hampden and 25, and Colorado and 70. I’d like to be able to have navigation kick off once  I’m near a known point or I’m close to the highway or fairly far along towards my destination. That shouldn’t be too hard to develop and customize, requiring no in-car interaction so it’s safe.

In many cases, I only need last mile assistance when driving in-city, including other cities I’m familiar with like Colorado Springs and Fort Collins. I wish I could ask for a “guide me when I’m close to” setting for these kinds of navigation requests.

Thank you all. You know I appreciate everything you do!

Making @KeyboardMaestro work in Mojave

Unfortunately, Apple seems to have messed up assistive apps like Keyboard Maestro in Mojave and if you depend on macros, that’s a very bad thing indeed. I upgraded to Mojave late last week (even though it is still not theoretically a GM) and found that although some actions still worked without problem like app launching others (specifically my universal Emacs key equivalents for arrow moves) did not.

I found this thread about the issue on a Keyboard Maestro forum. The hints on that thread helped me work out this solution to the Mojave problem. Note that you may have to repeat steps after rebooting your Mac.

  1. Copy /Applications/Keyboard\ Maestro.app/Contents/MacOS/Keyboard Maestro Engine.app to /Applications.
  2. In Terminal, kill the Keyboard Maestro and Engine processes.
  3. Open System Preferences > Security and Privacy > Accessibility. Grant privileges to both apps: Maestro and the copied Engine. (I also granted privileges to Finder and Safari, which probably wasn’t necessary.)
  4. Launch the Engine from /Applications. Check the process list for /Applications/Keyboard Maestro Engine.app/Contents/MacOS/Keyboard Maestro Engine and test your macros. You may have many types of macros and you’ll want to hit as many bits of the OS as possible when ensuring that each kind of macro is properly launched and executed.

 

Converting projects by hand to Swift 4.2

If Xcode is acting up for you the way it is for me, you may want to step back from automated migration and just do it by hand. I spent far too much time this morning trying to get Xcode to finish migrating for what were extremely trivial changes.

If you’re going by hand, make sure to change your “didFinishLaunching” launch options (in your App delegate) from [UIApplicationLaunchOptionsKey: Any] to use UIApplication.LaunchOptionsKey. (Notice the period in the name.)

To set the compiler from Swift 4 to Swift 4.2, open Target > Build Settings. Navigate to Swift Language Version and use the pop-up to select the proper compiler:

For some projects (especially small sample code) this alone may be sufficient to get you back and working.