How-to: Silence individual warnings for select cocoapods

As usual, Xcode 9 introduced new default warnings and tightened existing ones. Some of these changes don’t seem to get applied to existing projects during the upgrade check. For better or worse though, running pod install or pod update has the effect of setting warnings for all pods like it’s a new project. This led to me seeing a lot of warnings in the form of 'RandomCocoaTouchAPI' is only available on iOS 10.0 or newer in certain pods. The build setting responsible is CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE.

Since there’s no telling when these warnings are going to be fixed, if ever, I used the following post_install snippet in my Podfile to manually relax just this setting on the offending pods. It’s a better solution than suppressing all warnings. It also prints out a notice to remind me to check later if the warnings have been fixed.

post_install do |installer|
  # Manually relax CLANG_WARN_UNGUARDED_AVAILABILITY for some pods temporarily
  unguardedAvailabilityTargets = ['FBSDKCoreKit']
  installer.pods_project.targets.each do |target|
    if unguardedAvailabilityTargets.include?
      target.build_configurations.each do |config|
        config.build_settings['CLANG_WARN_UNGUARDED_AVAILABILITY'] = 'YES'
      puts "CLANG_WARN_UNGUARDED_AVAILABILITY was set to YES for #{}"

If you don’t care to enumerate individual pods, you can also change the setting at the pod project level.

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    config.build_settings['CLANG_WARN_UNGUARDED_AVAILABILITY'] = 'YES'
    puts "CLANG_WARN_UNGUARDED_AVAILABILITY was set to YES for all pods"

How-to: Integrating Google Analytics into iOS apps

Google recently reorganized their Cocoapods offerings, moving components like their analytics package back into its own pod and deprecating the Google pod in the process.

It would have been a good time to redo their integration docs as well, but unfortunately, they are still outdated and incomplete.

I’d like to quickly go over how I incorporate Google Analyics into iOS app nowadays.

First, add the tracking ID to your info.plist.

A screenshot of Xcode's plist editor


Next, add pod to your Podfile, run pod update, and then add the necessary includes to your bridging header file.

#import <GoogleAnalytics/GAI.h>
#import <GoogleAnalytics/GAIDictionaryBuilder.h>
#import <GoogleAnalytics/GAIFields.h>
#import <GoogleAnalytics/GAIEcommerceFields.h>

The existing docs tell you to guard against misconfiguration like this:

// wrong
guard let gai = GAI.sharedInstance() else {
  assert(false, "Google Analytics not configured correctly")

Unfortunately, this will break as soon as you do a release build, since assertions are removed in release configurations, and a guard block must end execution of the current scope. Here’s a better solution:

if let gai = GAI.sharedInstance() {
    // configure GAI here
} else {
    assertionFailure("Google Analytics not configured correctly")

You still get the assertion helping you out while debugging, without running into problems later on.

Next you’ll want to some basic configuration.

    let gai = GAI.sharedInstance(),
    let gaConfigValues = Bundle.main.infoDictionary?["GoogleAnalytics"] as? [String: String],
    let trackingId = gaConfigValues["TRACKING_ID"]
    gai.logger.logLevel = .error
    gai.trackUncaughtExceptions = false
    gai.tracker(withTrackingId: trackingId)
    // gai.dispatchInterval = 120.0
} else {
    assertionFailure("Google Analytics not configured correctly")

When you first start integration, I recommend setting the log level to verbose. You could even schemes or your build configurations to set it to different values as needed.

Similarly, I wouldn’t change the dispatchInterval from the default, unless you’re actively working on your analytics code and need events to show up quicker in the reporting dashboard.

If you want google analytics to record uncaught exceptions, you can enable this feature here. However, be aware that this will interfere with other crash reporting libraries like Crashlytics. If you use one of them or another library that registers exception handlers, set trackUncaughtExceptions to false or initialize them after Google Analytics so the exception handler can be reset.

That should cover the basics, but I’ve also included an Analytics helper struct below. It’s similar to what I use in my apps. Using enums for actions and screen names helps to prevent typos from creeping in.

struct Analytics {
    static func trackEvent(withScreen screen: Screen, category: String, label: String, action: Actions, value: Int? = nil) {
            let tracker = GAI.sharedInstance().defaultTracker,
            let builder = GAIDictionaryBuilder.createEvent(withCategory: category, action: action.rawValue, label: label, value: NSNumber(integerLiteral: value ?? 0))
        else { return }

        tracker.set(kGAIScreenName, value: screen.rawValue)
        tracker.send( as [NSObject : AnyObject])

    static func trackPageView(withScreen screen: Screen) {
            let tracker = GAI.sharedInstance().defaultTracker,
            let builder = GAIDictionaryBuilder.createScreenView()
        else { return }

        tracker.set(kGAIScreenName, value: screen.rawValue)
        tracker.send( as [NSObject : AnyObject])

    enum Actions: String {
        case search = "Search"
        case tap = "Tap"
        case toggle = "Toggle"

    enum Screen: String {
        case exampleScreenName = "exampleScreenName"

Live scroll notifications from NSScrollView

Prior to OS X 10.9, observing NSScrollView scroll events involved either subscribing to bounds changes on the accompanying NSClipView or subclasses the scrollView and overriding scrollWheel(_:). In 10.9, Apple introduced responsive scrolling and a whole host of related improvements. One of those are LiveScrollNotifications. Live Scroll Events are user-initianted (via touchpad, mouse-wheel, etc) scroll events.

There are 3 available notifications:


The major caveat that’s unfortunately not mentioned in the documentation (only in this WWDC session), is that only NSScrollViewDidLiveScrollNotification is fired universally. The start and end notifications are not triggered if scrolling with a mouse wheel for example. The upside is that there’s no subclassing or messing with unrelated views involved. Just register for the notifcation and pass the scrollView as notificationSender.

    selector: #selector(scrollViewDidScroll(_:)),
    name: NSScrollViewDidLiveScrollNotification,
    object: scrollView

Generic read/write locks in Swift

About 18 months ago, Mike Ash had a detailed look at locks and thread safety in Swift. I’ve been thinking a lot about threading lately because of a side project I’m working on, so I thought I’d try to build a generic version of a dispatch queue lock.

You can find it here. Parse and have good general primers on concurrency in Apple platform development.

Some caveats:

@inline(__always) func with<T>(queue: dispatch_queue_t, @autoclosure(escaping) get block: () -> T) -> T {
    assert(dispatch_queue_get_label(queue) != dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), "Invoked dispatch_sync in a way that will deadlock")
    var result: T!
    dispatch_sync(queue) {
        result = block()

    return result

First, the autoclosure here is marked as escaping even though it clearly ought to be non-escaping. Unfortunately, dispatch_sync’s function signature doesn’t include the @noescape marker, and thus can’t be used in this way. This appears to have been fixed in Swift 3. I think I have to mark result as force-unwrap for the same reason, but I won’t know until I get a chance to play with Swift 3.

Second, since dispatch_sync doesn’t return until the block you pass has been executed on the queue, calling in from the same queue you’re dispatching to will deadlock your program. The assert will catch some, but not all such calls. For example, it doesn’t know about target queues. It’s mainly meant for manually created queues.

Chaotic alignment bug in Metal shaders

All I wanted to do was put some texture on a cube. 😒

This doesn't look right

I ported the Metal tutorial at to OSX and came across this bug in the shader compiler backend, leading to distored textures.

When using a VertexIn struct with packed floats such as

struct VertexIn {
    packed_float3 position;
    packed_float4 color;
    packed_float2 texCoord;

the shader compiler backend will generate invalid offsets for the struct member texCoord. This seems to be related specifically to the combination of packed_float3 and packed_float2 since:

  • using packed_float4 fixes the issue
  • color is unaffected
  • reordering the members produces different invalid output
  • manually calculating the correct texCoord member offset fixes the issue

The issue is specific to Nvidia 750M cards as found in mid 2014 rMBPs. Running the same code on the built-in Intel Iris Pro produces valid output. From reports, the 650M is not affected either, but I was unable to verify that myself.

Big thanks to @warrenm for helping to diagnose and providing the workaround code.

I submitted the bug to Apple at rdar://24249981. You can find the code I used at Github.

Games I've Played In 2015

One of my low-effort side projects this year was writing down which games I’ve played and if I’ve actually completed them. I didn’t write down any thoughts after I played them because I wanted to see how much I actually remember at the end of the year. This is list is roughly in the order of when I started playing the games.

League of Legends (PC)

Hey look, I’m still playing League of Legends.

Secret of Mana (Emulator) (finished)

I’m pretty sure I played this game on the SNES way back when, but I don’t think I finished it before. I enjoyed it overall, despite the sometimes clunky combat mechanics and the grinding necessary for leveling up weapons and spells.

Xenonauts (PC) (finished)

I’m a big fan of the original X-COM: UFO Defense and X-COM: Terror from the Deep. They’re two of the few games I’ve played through more than once. I kickstarted Xenonauts and was pretty happy with the game overall. It hit all the same spots X-COM did, except for somewhat forgettable music (I had to double check whether the game actually had music) and an overall sterile feel.

Asura’s Wrath (PS3) (finished)

Punching Your Problems Until They Go Away: The Game: The Anime: The Movie

The game started entertainingly enough, due to the bombastic opening and generally entertaining gameplay. However, once they novelty wore off, gameplay became quite tedious and repetitive, with the story being low on character development and leaving me ultimately unsatisfied despite 3 consecutive endings.

Fire Emblem: Awakening (3DS)

I really enjoyed this game, but since I was playing on a borrowed 3DS, I’ve haven’t gotten around to finishing it yet.

Shadow of Mordor (PC) (finished)

Orc Murder Simulator of the Year. I found this game to be an enjoyable alternative to the Assassin’s Creed/Arkham Batman kind of games. Story was heavy on the tropes.

Elite: Dangerous (PC) (MMO)

Best space game I’ve played in a long time. I put significant time into combat and exploration. Mining and trading seemed to inaccessible to be enjoyable for me. The biggest problem for me was the lack of mission variety and that’s what kept me from checking out the expansion so far.

Dying Light (PC) (finished)

Pretty enjoyable open world zombie killing game. The story was as dumb as could be excepted and got much dumber than that in the last few hours.

Tales of Xilia (PS3) (finished)

Easily one of the best JRPGs I’ve played. Likeable cast, funny dialogue, fast-paced low-grind combat, and a story that actually makes sense! Visuals and voice work were top notch as well.

Homeworld HD Remaster (PC)

I love all the Homeworld games, so I acutally pre-ordered this HD remaster. For better or worse, that’s all it is though. They faithfully restored every aspect of the original games, including the pacing issues of some of the missions and the lackluster AI. I fully intended on finishing at least the first game. However, I ran into a showstopping bug roughly halfway through the campaign and sort of forgot about it while waiting for a patch. I intend to revisit it next year.

Bastion (PC) (finished)

Somehow, I had to start playing this game three times over the past 3 years, but I finally finished it! I had a great time, although I was unmoved by the ending. (I generally don’t enjoy time travel based plots)

Xenosaga Episode I (PS2)

I actually wish I had taking some proper notes while I was playing this game. I guess I sort of did, on Twitter:

I got about 3/4 through the game before abandoning it. The mecha component of the battle system was pointless to me, but mainly the plot was just a mess of arglebargle. I read quite a few pages on Wikia about the whole thing afterwards, and it just confirmed that I made the right choice.

Final Fantasy Type-0 HD (PS4)

I actually really liked what I played, but felt like I was missing too much stuff without a guide. I’ll probably pick this up for PC at some point and get a strategy guide.

Bloodborne (PS4) (finished)

I’m a sucker for the Souls games, and this one was no different. Interesting new setting and aesthetic. I hope they’ll make another.

Rogue Legacy (PC) (rogue-like)

I put a few hours into it, but the difficulty is pretty unforgiving and I didn’t get very far.

Mortal Kombat X (PC)

I actually enjoyed the over-the-top story antics of the previous installment, but couldn’t get into this one because of technical problems.

Digital: A Love Story (PC) (finished)

I loved it! I’m looking forward to playing more visual novel type games next year.

Rise of the Triad (2013) (PC)


Alien Breed 3 (PC)

Solid top down shoot’em’up, but I just couldn’t get myself to finish the series.

Car Mechanic Simulator 2015 (PC) (sandbox)

I wanted to try one of the endless number of *** Simulator games and actually found this one to be pretty engaging. Interface could have been a lot better though.

GTA V (PC) (finished)

I hate-played this game. I was curious about the triple protagonist mechanic and the heists, so I just tried to finish the story as quickly as possible. Predictably, all characters I encountered were unlikable assholes and there was little I found very enjoyable besides the driving.

Kerbal Space Program (PC) (sandbox)

Spaaaaaaaaaaaaaace. A great, kid-friendly game. I wish it were better explained/tutorialized though, especially when you’re playing with a child. They tend to get bored when you have to read a lengthy guide in order to figure out how to do basic things.

Carmageddon: Reincarnation (PC)

Solid sequel to the oddball original games. Haven’t had a chance yet to check out the major update they put out recently.

Legend of Grimrock (PC) (finished)

Great (difficult) tile-based dungeon crawler. Looking forward to the sequel.

Banished (PC) (sandbox)

Dense, kind of bland village builder. Mechanically solid, but I didn’t find it very engaging.

Witcher 2 (PC)

This was the second time I started playing this game, and once again I didn’t get past the first act. This time, I tried to play with a mod that was supposed to improve the combat, but all it did was fuck up my level progression. Maybe third time’s the charm?

TIS-100 (PC)

Pretty spot on. I need to give this another shot now that it’s out of early access.

Super Mario 3D World (Wii U) (finished)

I’ve hugely enjoyed this game. Art style, music, visuals, level design (mostly), co-op. Super Mario Galaxy was the last one I enjoyed this much.

Captain Toad Treasure Tracker (Wii U)

Very cute, super-fun puzzler. It somehow ended up in a moving box in a storage unit, so I haven’t been able to finish it yet.

System Shock 2 (PC) (finished)

Despite playing it shortly after it was first released, I had never finished it. I played it with a few mods to improve the visuals and it hold up nicely. I still prefer System Shock 1 though and can’t wait for the HD remaster.

Rising Thunder Beta (PC)

This was billed as an effort to make fighting games more accessible. It failed for me, but I might give it another shot once it leaves beta.

Final Fantasy X HD (PS4) (finished)

Despite being generally too grindy, it’s still a great RPG that mostly holds up mechanically. I had played this on PS2 before, and found the story made a lot of sense this time around.

Command & Conquer (PC)

A classic that simply doesn’t hold up. The interface is clunky and the missions take too long as a result.

Command & Conquer: Red Alert (PC)

See above.

Monument Valley (iOS) (finished)

Beautiful puzzler. Too short, if anything.

Steven Universe: Attack the Light (iOS) (finished)

The only game I 100%-ed this year.

World of Warships (PC)

Enjoyable timesink. The biggest advantage over MOBAs is the short game length, IMO.

Guild Wars 2 (PC) (MMO)

I liked what I played, but I just can’t get into MMOs without friends to play with.

Demon’s Souls (PS3)

I wanted to revisit the original Souls game. It’s still great and I might finish it next year.

Metro Last Light Redux (PC)

Not much to say here. It’s a good FPS, but it didn’t hold my attention long enough to finish it.

SOMA (PC) (finished)

Despite an absence of jump scares, this game manages to create such heavy tension that I had to play parts of it during the day. I loved the story and enjoyed the exploration of humanity and identity.

Avadon (PC)

I’ve been following Jeff Vogel’s blog for a while now, so I thought it was time to give one of his indie RPGs a try. I ended up putting about 34 hours into it, but the draw of the story was not strong enough to get me to finish it.

Starcraft 2: Legacy of the Void (PC) (finished)

The missions were mostly great. The story was mostly sterile filled characters that were exeedingly hard to care about.

Her Story (PC) (finished)

My wife and I played this one night and got to the conclusion in about 2 hours. We watched fewer than 50% of the available clips (according to achievements), not we might be missing a significant part of the narrative. Nevertheless, we really enjoyed it.

Fallout 4 (PC)

Without mods, I would probably not be playing this game anymore. I didn’t encounter any gamebreaking bugs, mostly just humorous glitches. However, the interface is atrocious, especially with regards to inventory management and dialogue options. Storywise, they removed a lot of the nuanced interactions in favor of making an action-RPG shooter that is easy to get lost in (often in a good way). It’s good that western RPGs are going through a revival right now and there are richer options to choose from.

Resident Evil Revelations 2 (PS4) (finished-ish)

I only got the bad ending so far (which I only realized when I checked achievements). Resident Evil games occupy a weird spot for me. The villains are universally cartoonish, unsympathetic, poorly motivated, and their actions usually unjustifiable. The clunky interface is often just as dangerous as the monsters, and the boss fights are mostly hit or miss. So I have to ask myself what keeps me coming back. This installment was definitely my favorite out of the last 3 I played (RE6, Rev1, Rev2). I liked the protagonists (especially Moira), the improved interface, inventory management, and the buddy system. Loading times were pretty bad though.

Tagged Pointers in Objective-C

On Tuesday, I gave a tech talk about the use of tagged pointers in Objective-C at the local iOS developer meetup. You can find the slides, demo, and supporting docs at Github.