Space is Disorienting

Mobile Engineer

Read this first

Versioning and Xcode

If you’ve ever used agvtool to manage versioning your project you know it’s a pain. Among other complaints, I’d rather not have version information buried in project files (or have to modify that project file to bump the version).

 Pre-process Info.plist

My initial reaction was to extract the version into something like an xcconfig file and use plist pre-processing to inject it into the Info.plist. The issue there is that Xcode doesn’t correctly pick up changes to the xcconfig file (it’s presumably looking at mod times of the Info.plist file itself), so any version bumps require a clean build to pick up.

 Build Rule

My next thought was to use a build rule to process the Info.plist file manually. The downside there is that you need to change the INFOPLIST_FILE build setting to point to the processed file in the derived sources directory, but doing so disables Xcode’s built-in editing...

Continue reading →


Deciphering Xcode’s index

At work we’re having to wait an inordinate amount of time for Xcode to finish indexing our rather large Swift project. I’ve consequently spent a lot of time over the past few weeks digging into the internals of indexing. This is more or less a brain dump of what I’ve discovered thus far.

 File structure

Xcode’s index is broken into a number of files, located in {project derived data}/Index/{build config}/{platform}/{project}.xcindex/:

db.xcindexdb
db.xcindexdb-shm
db.xcindexdb-wal
db.xcindexdb.strings-cmp
db.xcindexdb.strings-dir
db.xcindexdb.strings-file
db.xcindexdb.strings-moduleurl
db.xcindexdb.strings-res
db.xcindexdb.strings-sym

 SQLite files

  • db.xcindexdb: The index’s SQLite database, which we’ll cover below
  • db.xcindexdb-shm: The SQLite shared-memory file
  • db.xcindexdb-wal: The SQLite write-ahead log

 Strings files

These files are collections of strings separated by 0x00...

Continue reading →


Singular Resources in Phoenix

I recently stumbled across Elixir and Phoenix. The more I dig in, the more I’m drinking the Kool-Aid and loving it. Coming from Rails, things feel familiar, but there has definitely been some grinding of gears as I’ve ramped up.

One of the things I ran into today was how to make a “singular resource” for something like a user profile or account. My first instinct was to do something like this:

# web/router.ex
scope "/", MyApp do
    ...
    resource "/account", UserController
end

That didn’t work. It complained about not finding the function resource/2:

== Compilation error on file web/router.ex ==
** (CompileError) web/router.ex:31: undefined function resource/2
    (phoenix) expanding macro: Phoenix.Router.scope/3
    web/router.ex:17: MyApp.Router (module)
    (elixir) lib/kernel/parallel_compiler.ex:116: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1

At this...

Continue reading →


When Full-Disk Encryption Goes Wrong

Last September I watched in horror as my MacBook Pro slowly died.

It started with a text from my wife:

iMessage.png

“Hmmm,” I thought. “Maybe the System folder or something got corrupted. Should be a quick fix.” Little did I know that we had just lost every piece of data on that computer.

Side note: I love that the only thing the MacBook is displaying is an icon equivalent of ¯_(ツ)_/¯. No helpful error message, nothing. Just a “Yeah, I’m not even going to try.”

I’ve been a “computer person” for most of my life. I worked in tech support in high school and college, so I went through a pretty exhaustive list of things to attempt to get the computer to boot.

After a few unsuccessful attempts at getting the system to boot off the disk (and the usual exorcism of zapping the NVRAM a few times for good measure), I booted into Apple Hardware Test.

Continue reading →


The Apple Watch: Impressions After 1 Year

I stayed up late the night of April 9, 2015 to pre-order the Apple Watch. I actually ordered two — work was paying for them, and we wanted to ensure there were enough devices for the team (we were busy putting the finishing touches on our watch app at the time). The device I kept was a 38mm Apple Watch Sport.

 The Good

 Comfortable

I’m not huge into watches. I used to occasionally wear one for a few hours on the weekends. I’ve been fighting pain in my wrists for years, so the thought of wearing a watch all the time was a pretty tough sell. Sure enough, when the Apple Watch finally arrived and I put it on it was pretty uncomfortable.

After a few days of this I swapped out the band for the larger one and moved the watch to my non-dominant hand. Both of these improved the comfort immensely. Props to the team at Apple — you can not only swap which wrist you wear it on but also flip the...

Continue reading →


PNG Manipulation in Ruby

A few years ago, I was working on a project building an internal App Store for a client. The backend was written using Ruby on Rails. I was giving a demo to some other engineers in the company when I noticed that app icons were failing to load. When I started digging into it I noticed that this only happened in Chrome — Safari loaded and displayed the images just fine.

Knowing a bit about the PNG optimizations Xcode performs, I started looking into the images. Sure enough, the root cause was that the images I was extracting from the .ipa files as part of the build upload process had their channels swapped. Safari, for whatever reason, knew how to reverse the process; Chrome did not (not that I blame it — good on it for refusing to load random files masquerading as PNGs).

I kicked around several potential approaches for fixing the problem. The most foolproof solution was to use Xcode’s...

Continue reading →


Hello, world.

Or how I learned to stop procrastinating and write something down.

After several failed attempts at this I finally decided to let somebody else deal with the infrastructure, and I’ll focus on the writing instead (more on that in a later post).

In retrospect, this may very well turn out to be a bad idea — if there’s anything the Internet needs it surely isn’t yet another person yelling into the wind. Maybe I should have asked Ryan to setup my blog.

View →