Type inference fail

Before I begin I should note that I’ve become a fan of Swift’s trailing closure syntax and that’s what you’ll see here. There are a lot of ways to declare a closure, though, and I’m not particularly religious about my choice.

Also, this example applies to Swift 1.2 from Xcode 6.3 Beta 2. The language is still very much in flux.

When you’re using sort or sorted the compiler should know the argument types passed to the closure that does the comparison. The Swift documentation describes this:

The sorted function takes two arguments:

  • An array of values of a known type.
  • A closure that takes two arguments of the same type as the array’s contents, and returns a Bool value to say whether the first value should appear before or after the second value once the values are sorted. The sorting closure needs to return true if the first value should appear before the second value, and false otherwise.

This lets you write terse closures that don’t have to spell out the array type involved:

So you’d think it would work for slightly more complex data types (PhotoKit’s PHAsset in this case):

But I get this error:

Cannot find an overload for 'sorted' that accepts an argument of list of type '([PHAsset], (_,_) -> _)'

So instead I have to declare types for everything like I’m still at my C/C++ day job:

The same thing happens with sort.

It’s not a big deal, but I’ve come to enjoy Swift’s syntactic sugar and my slight OCD nature doesn’t like having this closure declared differently from the others in my code.

Swift compiler errors suck

A lot of the reticence I see for adopting Swift has been less about the language and more about the tools: long compile times, SourceKit constantly crashing, no refactoring, really slow autocomplete, and incomprehensible compiler errors. It’s that last one that’s been annoying the crap out of me lately (forgive my ancient non-Retina display):

CGRect: Extra argument 'width' in call

“Extra argument ‘width’ in call” doesn’t make any sense since init(x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) is definitely in CGGeometry.h. The actual problem here is that I renamed index to number and forgot to change it for the y argument. No variable named index exists and it would’ve been nice if the error reflected that.

Still, I don’t regret implementing my first iOS project in Swift. It’s modern, incorporates aspects of functional programming, and is generally fun to code in. I’m reasonably confident many of the tools issues will be resolved as the language matures.

Panning multiple scroll views simultaneously

UIScrollView provides a lot of control over the way you can present content to the user, but I have a need for one gesture recognizer to pan  multiple views simultaneously. You can probably use scrollRectToVisible to achieve this by moving the content view programmatically, but implementing the bouncy physics via that method seems painful. Plus I have other customizations I want to make.

In search of a solution, I found Ole Begemann’s outstanding post Understanding UIScrollView on reproducing the functionality of UIScrollView. The idea behind the article was to achieve a better understanding of how this Cocoa feature works, but for this iOS newbie it was a way to produce the behavior I needed.

The original post is excellent so there’s little point in me saying much else about it, other than that I am working in Swift and thus needed an implementation in that language. You can get my implementation on GitHub. I have not yet implemented the inertial scrolling, bouncing and rubber banding that some of Ole’s readers contributed, but I’ll update this post when that work is done.

The benefit of making your own view is that you can determine how that view handles gestures (actually, you can still do this if you subclass UIScrollView, but I’ll get into that later). In this case, I don’t want my custom scroll view to handle gestures at all. So while Ole’s class calls addGestureRecognizer to set one of its own methods as its gesture action handler, my SwiftScrollView.handlePanGesture() is called by its superview (in the example on GitHub this superview is just the ViewController):

And of course the superview sets a UIPanGestureRecognizer so its version of handlePanGesture gets called:

There you have it: one gesture recognizer scrolling two views. If you run the project I have up on GitHub you can see this in action. There’s more stuff I want to do with this and I’ll share that soon.

P.S.: If you want to do something like this but still want features of UIScrollView, you can subclass it and override addGestureRecognizer so it can’t set a pan recognizer:

Pretty crude, but it works. You might also be able to do something like

after self.panGestureRecognizer is set, but I haven’t tried this.

I finished the Swift book

It only took two months, but I finally finished The Swift Programming Language, Apple’s guide to their new app development language (I linked the web version but actually read the iBooks version so I could highlight and annotate). As far as documentation goes, it’s certainly better than most: informal at times to make it more readable, well thought out examples, really nicely formatted. It seems introductory enough for the beginning programmer (though probably not for someone who has never coded before) but it’s also littered with comparisons to C and Objective-C to provide context for more experienced developers.

A lot of books will be written to teach Swift, but unless you’re totally new to programming, I wouldn’t bother buying one. Apple’s book introduces the language nicely, so I’d save my money for the inevitable slew of texts that’ll cover best practices (once the community establishes best practices) and advanced topics.

In the meantime, make sure you follow Apple’s Swift blog for updates on the language and explorations of features that go a little deeper than their book. If you’re ready for more detailed discussion of the language, I recently found the amazing Airspeed Velocity, which often goes all out in explaining things like nil coalescing . Mattt Thompson has been writing about Cocoa and Objective-C for years at NSHipster and has more recently begun diving into Swift with stuff like this great article on literal convertibles.

There’s a lot of wonderful writing out there already and we’re not even at Swift 1.0 yet. How many great issues on Swift will objc.io put out in the months to come? How cool will it be when Brent Simmons details his journey with Swift on Inessential? I can’t wait for it all.