Analyzing a Failed Build

I’m getting to work on Scorebook again this week, thanks to zulily’s allowance for a hack week for tech employees. It’s really nice to be in that codebase, even if I’m now horrified by much of what I see past me doing in there. That’s a good sign of growth, right?

Anyways, I wanted to setup a CI service and we had a demo of BuddyBuild at Xcoders a few months back. So I want to give them a shot. And my build fails. And fails. And fails. I had to fix bad file locations for my prefix.pch file, as well as my bridging header. But it was still failing.

Thankfully the folks over there are great. They followed up with me and asked that I clone the repo to a clean location and try building from there. It failed. Now I had to wonder what was going on. The BuddyBuild log was giving me a super helpful message:

** BUILD FAILED **
    The following build commands failed:
    	Analyze Scorebook/Scorebook/View\ Controllers/SBHomeScreenViewController.m

Alright, that’s not actually very helpful. Xcode’s error log pointed to importing my Scorebook-Swift.h file as being problematic. The funny thing about that file is that it’s auto-generated by Xcode. So the logs point to analyzing failures, and that file doesn’t exist yet. I had the RUN_CLANG_STATIC_ANALYZER flag set to “Yes” and the order seems to matter. So instead of building the project and then running the analyzer Xcode analyzes the files as they are being built.

See the problem?

When analyzing that view controller, it’s trying to follow a file reference that can’t exist until a successful build. If I set that flag to “No”, build, then back to “Yes”, the build succeeds. But clean builds will fail. So I guess I have to run the analyzer myself by hand.

Is this worth filing a radar over?

Making NSNotifications Type Safe

A while back, the good folks at Swift Talk posted an episode about using typed notifications. As one who deals with lots of notifications in the app I build for my day job I was intrigued. However it didn’t feel like their crack at the problem of using types in notifications went quite far enough. I wanted a way to make any notification easily accessible wherever I needed to use it.

So I took a swing. Here’s what I came up with.

I started off where Swift developers usually do: a protocol.

public protocol NotificationDescriptor {
    associatedtype Payload
    var noteName: Notification.Name { get }
    func encode(payload: Payload) -> Notification
    func decode(_ note: Notification) -> Payload
}

public extension NotificationDescriptor {
    private var _modelKey: String {
        return "ModelKey"
    }
    
    public func encode(payload: Payload) -> Notification {
        let info = [_modelKey: payload]
        let note = Notification(name: noteName, object: nil, userInfo: info)
        return note
    }
    
    public func decode(_ note: Notification) -> Payload {
        let model = note.userInfo![_modelKey] as! Payload
        return model
    }
}

So, what we have here is the definition of our protocol. We have the Payload that conformers will typealias something to tell us what is going to be handled be the encode and decode functions. Then we have the notification that is posted or listened for. So far, so good.

Next is an extension to give us boilerplate implementations of encoding and decoding. This is really only useful with custom notifications that you create, and not ones given by iOS.

To get this working, we need to also extend NotificationCenter so that it can listen for one of these descriptors. But first, there’s one class we need to build.

public final class NotificationToken {
    let token: NSObjectProtocol
    let center: NotificationCenter
    init(token: NSObjectProtocol, center: NotificationCenter) {
        self.token = token
        self.center = center
    }
    
    deinit {
        center.removeObserver(token)
    }
}

This class will handle de-registering from NotificationCenter so we just need to hold onto whatever tokens are necessary. When the token goes out of scope and it deinits, then it removes the observer automatically. That really is the worst part of using block based notification observers.

Next is the NotiicationCenter extension:

public extension NotificationCenter {
    public func addObserver<A: NotificationDescriptor>(descriptor: A, queue: OperationQueue? = nil, using block: @escaping (A.Payload) -> ()) -> NotificationToken {
        let token = addObserver(forName: descriptor.noteName, object: nil, queue: queue, using: { note in
            block(descriptor.decode(note))
        })
        return NotificationToken(token: token, center: self)
    }
}

This method will add the observer for the notification’s name, and – using the specified queue – decode the notification and call the block which will have the payload as its argument. This makes call sites really nice:

struct CustomNotification: NotificationDescriptor {
    struct Output {
        let name: String
        let type: String
    }
    
    typealias Payload = Output
    let noteName = Notification.Name("CustomNotificationPosted")
}

class Foo {
    var token: NotificationToken?
    
    init() {
        token = NotificationCenter.default.addObserver(descriptor: CustomNotification(), using: { (output) in
            print("received a \(output.name) of type \(output.type)")
        })
    }
}

var myFoo: Foo? = Foo()
let output = CustomNotification.Output(name: "thing", type: "superclass")
let note = CustomNotification().encode(payload: output)
NotificationCenter.default.post(note)
myFoo = nil

If you put this all in a playground (and the files can be found here: https://gist.github.com/jsorge/a216f95d871371d1684f45519a59c5a6), you will see in your console the printed output of the block placed in Foo’s initializer. Pretty cool.

This gets a little bit more complicated if you want to use an iOS system notification. It all still works, you will just have to implement the decode function safely.

struct KeyboardDidShowNotification: NotificationDescriptor {
    typealias NotificationOutput = (begin: CGRect?, end: CGRect?)
    typealias Payload = NotificationOutput
    let noteName: Notification.Name = .UIKeyboardDidShow
    
    func decode(_ note: Notification) -> NotificationOutput {
        let begin = note.userInfo![UIKeyboardFrameBeginUserInfoKey] as? CGRect
        let end = note.userInfo![UIKeyboardFrameEndUserInfoKey] as? CGRect
        return (begin, end)
    }
}

That’s all there is to it. I hope this is as useful to you as it has been to me!

Leveling Up as an iOS Developer

I posted to my microblog recently that I feel like I’ve been leveling up as an iOS developer. The main way has been diving into programatic layout as opposed to using Interface Builder. This has been really insightful to me and I have come to love writing my views this way. But mostly I’m learning that I can do it.

You can too.

I remember hearing about the devs who didn’t use IB and thought to myself, “that sounds like so much work.” Bear in mind that those prior folks were likely using manual layout to set frames and relied on a lot of math to get things done. Recent improvements to the Auto Layout system (especially layout anchors) make writing UI code incredibly straightforward.

For instance, to pin a view to the edges of its superview (something I have to do often) all I need is this:

firstView.addSubview(secondView)
secondView.leadingAnchor.constraint(equalTo:firstView.leadingAnchor).isActive = true
secondView.trailingAnchor.constraint(equalTo:firstView.trailingAnchor).isActive = true

And that’s really it. If you’re used to thinking about views in the relationship style of Auto Layout you too can easily start writing your views in code. There are lots of benefits: no more optional properties for @IBOutlets, you can keep you layouts contained to a single file instead of a source file and a layout file, and you can use things like UILayoutGuide to line up views without resorting to dummy UIView instances.

But my main idea has really nothing to do with ditching Interface Builder. There have been lots of blog posts about that and I’m not sure I could add much to that discussion.

My main idea is that mountains can be intimidating. You look up at someone who is at a higher point than you and wonder if you have what it takes to get up there with them. Start at base camp and get going.

You’ll try new things. You’ll fail. Get back up and keep climbing.

Months or years into your journey you’ll look down and remember where you started. Take stock of things in that moment. Praise the Lord for getting you where you are. It’s a big deal!

From there it’s important to stay humble and keep going. Try to help someone climb alongside you. Reach out to the people who are where you want to be and ask questions (you may be shocked at the generous people you meet along the way). We weren’t meant to live solitarily – find your community.

I’m taking this verse completely out of context but Romans 5:3-4 (NIV) says:

Not only so, but we also glory in our sufferings, because we know that suffering produces perseverance; perseverance, character; and character, hope.

Perseverance builds character. We level up when we keep going in the face of difficulty.

Swift Function Passing & Memory Management

I’ve started using a pattern where I use a struct that has a series of optional closures on it to serve as a way to hook into default implementations of things like data source and delegate calls. We have a fairly complex way of presenting data in our collection views that requires a lot of boilerplate, but specific areas of our app needs to add behavior to fit its requirements.

The problem that I’m running into now is that I want to assign these closures to functions on my object instead of having a ton of inline closures. I really like this approach because it allows me to keep things well organized. But there’s a problem in my memory graph.

When I pass these functions into the closures, I’m capturing a strong reference to self. When using a closure syntax I could use a capture list to take either [weak self] or [unowned self] and be fine (in fact, replacing the function references with closures doing just that makes the problem go away).

Here’s a gist replicating the issue:

If you copy the file into a playground and run it you will see deinit called on the VC but not on the data source or the frame. If you uncomment the closure on lines 46-48, they will all have deinit called as you would expect.

Is there a way to capture an [unowned self] when passing a function by reference like this?

Update: I wound up going with a solution that uses a closure for the hook instead of the function reference – passing in unowned self inside the capture list. Inside that closure I call the method. It doesn't look quite as nice as what I wanted to do, but gets the job done. Here's what that would look like with the example:

hooks.numberOfSectionsIn = { [unowned self] (section) -> Int? in
    return self.numberOfSectionsIn(section)
}

I'm Microblogging

I backed Manton Reece's Kickstarter project for micro.blog back in January. Invites started rolling out this week and I got mine the other day. If you're interested, I'm setup at http://jsorge.micro.blog.

I'm not sure how I'll use this vs using Twitter but I do have cross-posting setup so my posts become tweets. I'm also thinking about writing a lightweight posting client for the Mac. but we will see.