Space Station Live for the Apple TV

Space Station Live icon large

I am proud to announce the latest update of my app. Formerly called “ISS Live: Video from the International Space Station and NASA TV,” I’ve given it the more concise name “Space Station Live,” and it’s available now in the Apple TV App Store.

In addition to squashing a bug that caused the app to crash at launch for some users, the new version sports a new icon, one that I believe looks nicer in the grid of Apple TV icons.

It’s once again available for purchase in all regions. Unfortunately, Apple does not provide URLs for Apple TV apps, so if you’re interested in checking it out, open the App Store on your fourth-generation Apple TV and search for “Space Station Live.”

If you were affected by the crash-on-launch bug, thank you for being patient. This update should fix the issue for everyone. If you still encounter problems, please email me or send me a tweet.

I want to make this app as good as it can be. I’m working on a few great new features, and I can’t wait to share them with you.

Thank you, and enjoy Space Station Live!

I’ve temporarily pulled ISS Live from the Apple TV App Store

The crash reports keep rolling in. Though I’ve submitted a bug fix and new build, the turnaround time for app approvals is currently estimated at four days. That means I’d essentially be selling a broken app for four days. That’s unacceptable to me.

I’ve pulled ISS Live from the Apple TV App Store until the new build is pushed to existing users. Then, I’ll be able to confirm that the problem has been resolved. After that, I’ll make it available again.

If you’re one of the affected users, hang tight. I apologize for the bug and a new build is on the way. Thank you for your patience. I’ll keep working and debugging until it’s working for everyone.

This has been frustrating, but I’m really proud of the new features and I can’t wait for you to see them.

How I symbolicated a Apple TV crash report from a bitcode build

Since I released version 1.1 of ISS Live on Wednesday, a number of crash reports have come in via Xcode. Early Saturday morning, I received a very kind email from a user in the Netherlands to let me know that the app crashes a few seconds after launch and dumps him back on the main Apple TV menu. I emailed back and forth with him to do some basic troubleshooting, but it sounded like the trouble was with my code, not with his device.

So I went to my Apple TV, downloaded a fresh copy of my app from the App Store, but was unable to replicate the crash. I tried it in the simulator under a number of regional and bandwidth conditions, but was still unable to replicate the issue. I asked a couple friends to try it on their devices. Nobody else was able to replicate crash, either.

Not good, I thought. On Saturday morning, I made some extra coffee, opened Xcode, and got to work.

I took a look at the crash reports in Xcode. Apple helpfully sends anonymous crash data from users’ devices to developers. These crash reports include bits of machine code that point to memory addresses in the app. In theory, when you open these crash reports in Xcode, it will symbolicate these memory addresses and reveal the part of your code that caused the crash.

But when I opened my crash logs, they weren’t symbolicated. Instead of helpful pointers to my app’s code, I saw a hex string of a memory address, virtually useless for debugging.

How it’s supposed to work

When you upload an app to the App Store, you’re given the option to include app symbols:

Symbols

When you receive crash reports, Xcode uses these app symbols to translate the memory addresses to human-readable identifiers. It does this based on a combination of two things: a UUID and a dSYM file.

An app’s Universal Unique Identifier, or UUID, is assigned to identify a specific build. When an app crashes on a device, the crash report includes this UUID. Xcode matches the UUID in the crash report with the UUID in the local copy of the build.

It then uses a debug symbols (dSYM) file to translate the memory addresses in the crash report to human-readable object names that will make debugging easier.

But in my case, it didn’t.

What went wrong

When I opened my crash logs in Xcode, they didn’t symbolicate. Instead of pointing to the part of my code that caused the crash, it gave me raw memory addresses:

Memory addresses

The crash reports go in reverse-chronological order, with the crash at zero. As you can see, these numbers aren’t very helpful in pinpointing the crash.

I opened the crash report in Sublime Text and discovered that the UUID in the crash report did not match the UUID of the submitted build. So, of course Xcode wouldn’t be able to symbolicate it; it doesn’t have a dSYM file with a matching UUID.

So… wait. Why do my crash reports have a mysterious new UUID in them? Why is that UUID different than the UUID of the app build I submitted?

Why (I think) it went wrong

I think bitcode is the culprit. According to Apple:

Bitcode is an intermediate representation of a compiled program. Apps you upload to iTunes Connect that contain bitcode will be compiled and linked on the store. Including bitcode will allow Apple to re-optimize your app binary in the future without the need to submit a new version of your app to the store.

If my app was recompiled on Apple’s server, it would have been assigned a new UUID, which I suspect is the UUID that showed up in the crash reports. Using bitcode to optimize builds is a great idea, but Xcode 7.2.1 is unable to symbolicate my crash reports, making it impossible to tell for certain what part of my code causes the crash.

Apple continues:

For iOS apps, bitcode is the default, but optional. For watchOS and tvOS apps, bitcode is required.

I was stuck with a bitcode build that didn’t match my dSYM file, a growing number of crash reports for a crash I was unable to replicate.

Crap.

I filed a bug report with Apple and posted to an Apple Developer Forums thread started by an Apple employee (who, ironically, insisted that Xcode specifically would not have this problem). It looked like I wasn’t the only one experiencing this issue. Frustratingly, it also seemed sporadic. Other developers reported seeing symbolicated crash reports for some builds but memory addresses for others.

Meanwhile, a new batch of crash reports came in for my app. The crash appeared to be more widespread than I’d thought, and I still didn’t have a great way to pinpoint the problem. Frustration City.

How I got desperate and symbolicated my crash log

First, I opened up Terminal to match the UUID of my dSYM and build. I wanted to sanity-check myself.

$ dwarfdump -u ISS\ Live.app.dSYM/

That returned:

UUID: 17204124-1C54-9327-7ND3-66B9AD4F5A73 (arm64) ISS Live.app.dSYM/Contents/Resources/DWARF/ISS Live

Great. I had the UUID for my dSYM. Next, I wanted to confirm the UUID of the build. In Xcode:

  1. I opened the Organizer, selected the Archives tab,
  2. right-clicked the 1.1 build and selected “Show in Finder”,
  3. right-clicked the .xarchive file and selected “Show Package Contents”,
  4. navigated to Products > Applications,
  5. and ran dwarfdump again on the ISS Live application.
$ dwarfdump -u ISS\ Live.app/ISS\ Live

UUID: 17204124-1C54-9327-7ND3-66B9AD4F5A73 (arm64) ISS Live.app/ISS Live

Confirmed: both the dSYM and application have matching UUIDs.

Here comes the desperate part.

I opened up the crash log in Sublime Text and navigated to the Binary Images section of the crash file. This is where you can find the UUID of the app that crashed:

Binary Images:
0x10009c000 - 0x1000b3fff ISS Live arm64  <01fa95353176671a4b4c209d2327a424> /var/mobile/Containers/Bundle/Application/6FB8A954-0AA9-4606-853B-73666EC8B083/ISS Live.app/ISS Live

The 01fa95353176671a4b4c209d2327a424 part is the UUID. It’s formatted differently, without dashes and with lowecase letters. I replaced it with 172041241c5493277nd366b9ad4f5a73, saved it, and went back the terminal.

There’s a command line tool called symbolicatecrash that you can use to manually symbolicate a crash report. I followed Christopher Hale’s great blog post to get it set up. First, I set up an alias for the command and the Developer directory:

alias symbolicatecrash='/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash'

export DEVELOPER_DIR='/Applications/Xcode.app/Contents/Developer'

And then I ran symbolicatecrash on my crash report.

symbolicatecrash 2016-02-12_18-32-31.31_-0500-ac90400c13649647ec79e540f1254b2cec5b8fc4.crash

Finally, I ran it on my newly hand-edited crash report. It worked! Instead of memory addresses, helpful data appeared in my terminal window.

...
Thread 0 name:
Thread 0 Crashed:
0  ISS Live  0x00000001000a7438 specialized MainViewController.findCurrentExpedition(NSArray) -> NSObject? (MainViewController.swift:136)
1  ISS Live  0x00000001000a5134 MainViewController.fetchCrewData() -> () (MainViewController.swift:58)
2  ISS Live  0x00000001000a4dac MainViewController.viewDidLoad() -> () (MainViewController.swift:23)
3  ISS Live  0x00000001000a4e28 @objc MainViewController.viewDidLoad() -> () (MainViewController.swift:0)
...

as opposed to something like:

...
Thread 0 name:
Thread 0 Crashed:
0  ISS Live  0x00000001000ff438 0x1000f4000 + 46136
1  ISS Live  0x00000001000fd134 0x1000f4000 + 37172
2  ISS Live  0x00000001000fcdac 0x1000f4000 + 36268
3  ISS Live  0x00000001000fce28 0x1000f4000 + 36392
...

This probably worked because the only version of my app is a tvOS app. When I add builds for iPhone and iPad, I’m not sure this will work. But for now, I made progress, located what I think caused the crash, and submitted a new build. But it would sure be nice to have this work in Xcode.

This whole process was a real pain, and I hope Xcode is able to symbolicate future bitcode builds I submit. But, until they do, this may be a workaround for debugging tvOS crash logs that don’t symbolicate automatically.

My (briefly) best-selling Apple TV app, ISS Live

Late last year, I switched from being a web developer and plunged into iOS development. I fell in love with the Swift programming language and the process of building iOS apps. I’d always wanted to become an iOS developer, but had never wrapped my head around Objective-C1. Learning Swift has felt like unlocking a super power. It’s been scary to step out of my comfort zone, but Swift is an exciting language and has been great to learn. I’ve had to become familiar with loads of new concepts and patterns, but each struggle has led to a satisfying “Ah-ha!” moment.

In December, I built an app for the new, fourth-generation Apple TV. It started with a simple idea and a personal challenge to myself. NASA live-streams video of the Earth from a camera mounted on the International Space Station. They call it the High Definition Viewing Experiment (HDEV if you’re nasty). It’s one of the coolest things on the Internet. Here’s an idea of what that looks like:

HDEV screen shot

It’s mesmerizing. I figured: Hey! Let’s get that on the Apple TV. I’d like to watch the Earth live from space on my TV. With the basics under my belt, I wrote a simple app. Very simple. It had two buttons: one for the HDEV video and one for NASA Television. I called it “ISS Live: Video from the International Space Station and NASA TV” and submitted it to the App Store. A week later, it was approved and went live. Yay!

And then, within a few days, it became the bestselling app on the nascent Apple TV App Store.

ISS Live at the #1 spot

What!

I was shocked, excited, and embarrassed. Shocked because it had happened so quickly, excited because Yay! I’m an iOS developer and people are paying money for an app I wrote, but embarrassed because of how bare-bones it was. I mean, it was really bare-bones. If I’d been a customer and bought that version of the app, I’d have been disappointed. In fact, a lot of customers were disappointed, which is why it got an average two-star review and, after a few weeks, sank back down to obscurity.

But there were several users who really liked it, and they took the time to send me sweet, thoughtful emails to let me know. I think that’s been the coolest part of this experience.

So, that was December and January.

Meanwhile, my fiancée Sophia and I moved across the country from San Francisco to Baltimore, which cut into my development time. I worked on the app for a few hours here and there, in between packing boxes and selling furniture and saying goodbye to friends and getting our dog and a cat ready to fly across the country. I worked on new features, proper features that made the app feel less like an experiment and more like a Real App Made by a Grown-Up Who Knows What He’s Doing™.

And so, as of yesterday, February 10, 2016, I am proud to announce that version 1.1 of ISS Live is available on the Apple TV App Store with a new feature. I’ve added information about the current ISS crew. Check it out:

Crew member menu

When you select one of the crew members, a detail view appears with a full portrait photo, launch and landing information, country and space agency, and a running clock of how long that person has been in space.

Simulator Screen Shot Feb 11 2016 4 19 45 PM

This was a lot of fun to put together. I learned about network requests in Swift, how to parse JSON data, and how to deal with date and time objects. I also had to organize data on the server so that the app can automatically update crew info as people return to earth and new crew members launch.

I’m proud of this version. Plus, it’s an app that I also really enjoy using. I don’t expect it to rocket back up the charts, but I hope existing users like the update. According to iTunes Connect, 12,900 Apple TVs auto-updated the app yesterday. Holy crap. That’s a lot of users.

I still have a lot of work to do. The app is far from complete. There are at least three more major features I want to add. I feel good about this app, and I’m excited to nudge it forward and make it even better.

Note: Apple doesn’t provide URLs for Apple TV apps, so I can’t link directly to my app from here. If you have the latest Apple TV and would like to check it out, search for “ISS Live”. The full title is “ISS Live: Video from the International Space Station and NASA TV”. It’s kind of a pain in the butt to find Apple TV apps right now, and I hope Apple improves the process.


  1. Before Swift, Objective-C was the programming language for Mac and iOS development. For me, coming from a web background, it seemed like a daunting thing to learn. Ironically, now that I have some Swift experience, Objective-C is easier to read and understand. Maybe it was all in my head. 

KitTea, a cat café in San Francisco

There’s a cat café in my neighborhood called KitTea. It’s been open for a little while, and Sophia and I finally made it there with some of our friends. Oh boy, it was an awesome idea. Relaxing music, bottomless mugs of tea, and an hour of cat playtime. All the cats are available for adoption, too. If you’re in San Francisco and want a fun way to unwind, you’ve got to try it out. (They even have cat yoga and “mewvie” nights. So great.)

Hello!

Hi! I’m Gavin. I’m a writer, musician, and iOS developer in San Francisco, but I’m moving back home to Baltimore, MD in a couple weeks.

I used to have a more traditional portfolio-style site where I talked about my projects, but it felt impersonal and stale. I’m trying something different now. Instead of making a static list of past projects, I’m going to use this blog to write about the things I’m working on as I work on them. I’ll talk about apps in-progress. I’ll share videos, music, and stories as I write them, and talk about the creative process behind them. I’ll discuss technical problems and how I resolved them. It’ll be nice for me to have a record of what I’ve done, but if I can help someone else out, that would be awesome, too.

Time to get to work.