Developer Insights, from Apple

With all the chatter around making a living on the App Store, and the recent changes to the App Store subscription model for apps, it seems that Apple is now trying to tell us how to create a successful business on top of their platforms.

This one is definitely worth a read.

Swift 3 Migration issues

This is a post that I’ll be updating continuously with all the bumps that I find on the way while developing with Swift 3 and iOS 10.

CloudKit’s database fetchAll methods are missing annotations on Swift 3

Swift 3 API design guidelines favor clarity over brevity. To accomplish that, many of the API’s that we interact with on a daily basis changed radically.

For instance, this method that we’ve known for a long time:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)

changed to:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

These changes are important as help us write more legible code.

On Apple’s CloudKit framework, with Swift 2, you could call

func fetchAllRecordZonesWithCompletionHandler(_ completionHandler: ([CKRecordZone]?,
                                                       NSError?) -> Void)

to get all Record Zones for a given database, or call

func fetchAllSubscriptionsWithCompletionHandler(_ completionHandler: ([CKSubscription]?,
                                                         NSError?) -> Void)

to get all Subscriptions.

However, the API changes on Swift 3, now both methods are named almost the same, with the completion handler’s parameters types being the only ones that change:

func fetchAll(completionHandler: ([CKRecordZone]?, NSError?) -> Void) // to get Record Zones
func fetchAll(completionHandler: ([CKSubscription]?, NSError?) -> Void) // to get Subscriptions

Trying to use any one of those functions make the compiler choke because it doesn’t have enough information to know what you’re trying to fetch, unless you type the parameters yourself:

db.fetchAll { (zones: [CKRecordZone]?, error) in
    // ...

To me, this is a clear example where the API design guidelines are not being respected, favoring brevity over clarity.

Submitted as rdar://26977470.

Updating my codebases to Swift 3

Apple officially released the first beta of Xcode 8 this past Monday, which includes Swift 2.3 (an updated version of the language to work with the new APIs on iOS 10 and macOS 10.12), and Swift 3, the latest big release for the language.

Swift 3 basically breaks your project. If you’re writing Swift and planning to continue doing so, my suggestion is: take the plunge right now and start migrating your project to Swift 3 right away.

That is, of course, providing you’ve got the time and the resources to do so.

In my case, I downloaded Xcode 8 and ran the migrator on a small project (about 1000 lines of Swift 2) with little success. The API changes that Swift 3 brings, such as removing namespaces, are big.

What I’m doing instead of trying to incrementally change my codebase (because the project wouldn’t even try to compile to show errors), is to update each part one by one on a new project, which eventually will replace my codebase.

It may not be the best route for everyone, specially if you’re dealing with large codebases.

This fall is shaping to be a busy one.