Ugly Swift Syntax for Checking Errors

A common code pattern I see a lot in iOS code is:

service.execute(request) { (response, error) in
    if let error = error {
        handleError(error)
        return
    }

    // work with response...
}

I don’t like that if statement. I’d much rather use a guard statement.

For those who don’t know guard, the docs explain:

A guard statement, like an if statement, executes statements depending on the Boolean value of an expression. You use a guard statement to require that a condition must be true in order for the code after the guard statement to be executed.

I like guard over if cause it’s more expressive about my intentions that the code after it should only run if there was no error found. Unfortunately, because of the boolean nature of the guard clause, to do this requires using Implicitly Unwrapped Optionals.

service.execute(request) { (response, error) in
    guard error == nil else {
        handleError(error!)
        return
    }

    // work with response...
}

I really try to avoid Implicitly Unwrapped Optionals, so much so I use SwiftLint to throw warnings for their use. Adding lint exceptions for this regular occurrence, for me, is not an option.

If you have more control over the service implementation you might choose to use a Result type.

enum Result<T> {
    case success(T)
    case failure(Error)
}

service.execute(request) { (result) in
    switch result {
    case .failure(let error):
        handleError(error)
    case .success(let response):
        handleResponse(response)
    }
}

I generally like this but it doesn’t work if you need to support a mixed Swift/Objective-C environment. It also doesn’t account UIKit itself does not use a Result type.

Code should be beautiful and so I think it’s important to document these things. I’d love to find a better solution and welcome feedback.

Swift Style: Dequeuing and Populating Cells From UITableView

Everyone has an opinion when it comes to Swift code style, and here is mine when it comes to dequeuing and populating cells from UITableView.

First you should know Apple maintains two methods for dequeuing cells from UITableView:

func dequeueReusableCell(withIdentifier identifier: String) -> UITableViewCell?

and

func dequeueReusableCell(withIdentifier identifier: String, for indexPath: IndexPath) -> UITableViewCell

The second version, with the indexPath argument addition and non-optional return value, was added in iOS 6 but strangely the original version was never marked as deprecated. The indexPath version is the one you should use. (I know of no reason why anyone should prefer the original, but I welcome feedback.)

Now let’s take a look at an implimentation:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: CustomCell.identifier, for: indexPath)
    if let customCell = cell as? CustomCell {
        customCell.item = itemForIndexPath(indexPath)
    }
    return cell
}

First we dequeue our cell. Notice how we use a class property to provide the cell identifier string value. We do it this way to avoid typos and enable easier refactoring.

Also note how we avoid any type casting on this dequeue line and instead capture the cell in a simple UITableViewCell reference. We do this because there is a chance that our tableview might not be properly registered with the cell identifier. Under such a scenario we’ll still get a cell instance but it will not be a CustomCell instance. I’d much rather return a boring UITableViewCell than crash with some explicit type casting using as! here.

Next we do our type casting using the more forgiving as?, making a new casted reference if a match happens.

To populate our cell there are two basic paterns. One would have a very generic cell expose its interface outlets and so you could configure the cell as you see fit depending on your model. The second approach would be to keep the cell’s outlets private and instead have the cell accept a model the cell is suppose to represent.

I generally lean towards the model approach. I also like to make a method called itemForIndexPath which helps if I ever refactor the view and introduce sections. If you are worried about coupling consider building a model just for the cell’s needs; a CellViewModel or something similar.

And finally, we return our cell reference. đź‘Ť

Hello Firefox, Goodbye Chrome

A few weeks ago I said to myself, enough was enough and dropped the Chrome web browser.

If you aren’t actively following the web development world it’s easy to miss, but Google and Chrome have really been hostile toward the open web over the last few years. A few examples:

In 2016 Google introduced Accelerated Mobile Pages. From its wikipedia page:

AMP has been widely criticized by many in the tech industry for being an attempt by Google to exert its dominance on the Web by dictating how websites are built and monetized, and that “AMP is Google’s attempt to lock publishers into its ecosystem”. AMP has also been linked to Google’s attempt to deprecate URLs so that users will not be able to immediately see whether they are viewing a webpage on the open Web or an AMP page that is hosted on Google’s servers. AMP has been described as being “poisonous to the underlying concept of an open internet.”

In Chrome 68 they began to deprecate HTTP and now list HTTP sites as insecure.

In Chrome 69 they added a behavior that strips the www subdomain from the URL bar. (Try visiting www.mikezornek.com and it becomes mikezornek.com. This may feel like a small thing for users but as a developer its a firm violation for how the web URL works.

Just this weekend I read a story of some more shenanigans:

Matthew Green:

A few weeks ago Google shipped an update to Chrome that fundamentally changes the sign-in experience. From now on, every time you log into a Google property (for example, Gmail), Chrome will automatically sign the browser into your Google account for you. It’ll do this without asking, or even explicitly notifying you.

Paul Frazee:

There’s a reason people are reacting to Chrome like this. This isn’t an overreaction over one single event. It’s a delayed reaction to a pattern of bad behavior.

It’s contextualized by the very messed-up power dynamic between Google and the open Web.

Google’s influence over the web through its search was already over the line in many ways but to see its once celebrated browser go down this road is depressing.

Actions speak and Firefox is treating me well. I now use it across my computers and devices, from MacOS to iOS and even my Windows gaming tower. DuckDuckGo is my default search engine (and has been for like a year now) and works well too. It feels good to be using products from people who share my interests to heart.

Hello from Linode

If you are reading this, then the DNS gods have shown you to my new Linode web server!

Not really sure if I’m happy with WordPress in the long term, but I wanted to move this blog off my old server asap so I stuck with it through the migration. This was the last site to be moved off that old server and now I can close up that account and save $40 a month.

Feels great to be back on Linode too. We used to use Linode back in the day during a old startup I was in (had a few app server nodes, node balancer, db node). I really like the raw access we get on Linode and that it feels like a real computer (unlike AWS which feels like witchcraft for me).

2017 Retrospective

I’ve been kind of heads down with client work the last few months but wanted to say hi to those who still follow me here.

2017 was a bit of a sucker punch for me, but I survive.

After losing my job and having a neck surgery to open the year I was able to reboot my self employment under a new LLC. It took a few months but I finally landed some client work and have things pretty stable these days.

As for side projects I put a lot of time into OwlDeck in the spring but sadly it took a backseat to client work and revenue once summer rolled around. There is a good chance of it finding a second wind in 2018 as I have a bunch of teaching planned and it would be a great tool to have onhand.

I also decided this year to hand off my Philly CocoaHead responsibilities. I had been lead organizer for about 7 years and figured it was time. I still plan to be an active member but hope the extra hours can be put towards side projects in 2018.

Finally I’ve been learning new tech! I really want to get back into some web development and dedicated a fair amount of 2017 to relearning the web, from HTML5, to modern CSS (Flex, Grid, etc.) as well as new languages like Elixir and Elm.

My first Elm site is underway and I’ll share more as it comes together.

Thanks for checking in. Be sure to follow me on Micro.Blog as well. Have a great 2018!

Video: UIKit is Dead, Long Live UIKit!

Philly CocoaHeads held a joint meetup with our Android friends for Philly Tech Week. At said meetup there were a bunch of lightning talks, and I did one.

UIKit is Dead, Long Live UIKit!

With the introduction of Swift and the rise of functional programming ideals in the community, UIKit and its MVC heritage has become a bottleneck for new ideas. This talk speculates how Apple might overcome this in the years to come. Attendee should walk away with a curiosity about the other UI patterns being developed and a resource list to learn more.

UIKit is Dead, Long Live UIKit! from Philly CocoaHeads on Vimeo.

Related Reading:

I actually had a few vocal flubs in the recording (was a little stressed about the 10 minute limit) but figured I’d use the live one anyways since it has more humanity than me speaking to myself in my room. I hope you enjoy!

Meet OwlDeck, a New Mac Presentation App for Programmers and Markdown Geeks.

Today I’m launching the teaser site for my new app, OwlDeck.

OwlDeck is a new macOS presentation tool for programmers and geeks who need to display code and love Markdown.

If you are interested in OwlDeck I’d love for you to signup to its newsletter and email me your thoughts.

If you are interested in some behinds the scene stuff you can checkout the project journal I’ve been keeping over at Rested Experience. I hope to share more now that things are going public and timelines are set.

Really excited to be working on products again. 🙂

Introducing Zorn Labs LLC

As I alluded to after loosing my job at the end of January, I knew I’d take the majority of February to recover from my neck surgery and then get serious about work in March. We’ll it’s almost the end of March so I figured I’d do an update.

First, welcome Zorn Labs LLC, my new company. It will house my future consulting and product work.

Second, I am still looking for work. My goal is to find something 10-30 hours a week, doing iOS or iOS mentoring. To help express my skill set and goals I’ll point you to the new company site. I would appreciate all friends and followers to help spread the word.

Outside of setting up the new business and website, much of March has been spent towards marketing and planning. I had many lunches and coffees with prospects and friends. I even had a few offers but they sadly weren’t the right fit for me at this time. When I haven’t been marketing I’ve been trying to jumpstart some new web skills, refreshing my HTML5/CSS3 knowledge, getting deeper into Hugo template design for the new Philly CocoaHead website, and experimenting with Elixir and Phoenix.

For those interested in my Mac app project, you can also check out my project journal blog at: http://restedexperience.com. I’ve been trying to update that a little more often with my recent progress.

So that’s my March update. Thanks for the interest! More to come in April! 🙂

Accessibility

At the Apple event a few weeks ago they began with a short video on accessibility.

I’ve learned a lot about accessibility on iOS over the last few years. Apple’s products are some of the most accessible in the world and for all the frustrations I have with Apple, this is definitely one of the high points I’m proud of.

I was also really pleased to see our own Philly CocoaHeads give accessibility some attention at a recent Side Project Saturday event. A group of people worked on improving the accessibility of the Wikipedia iOS app.

Group of Programmers using Voice Over on iPhone

Anyways, I think the time is right for development agencies and indy consultants to put accessibility front and center. For them to say loud and proud, any app you hire us to build will have some basic level of accessibility.

Some people whom I bounced this idea off of thought it would be bad for sales. Maybe. But these are the probably the same clients who question code review because they think it is a similar waste of money. At the end of the day we all have have some level of standards onto which we execute our craft. People hire us because they can’t build software. They need us to point them in the right direction.

Somewhere out there, a construction agency is in a discussion whether or not to add a wheelchair ramp to the current project. Some people will add it because it’s required by law, others will add it because it’s the right thing to do.

The software industry moves incredibly fast, maybe even too fast. We don’t have regulations and inspectors like other industries. We have to regulate ourselves. The tools to improve access for our creations are ready. They work really well. They sit there, waiting for us to use them.


I don’t want to come off like I’m some know it all when it comes to accessibility. If you need real help with your app, contact my friend Austin who does consulting on the subject.

I do have some experience enhancing a few personal iOS apps and hope to make it a larger priority with my upcoming side project. Like a lot of things, I think the goal here is for continual learning and small, iterative improvements.

Documentation for NSViewController init(nibName:bundle:) is incorrect

Radar: #28802828

Documentation for NSViewController init(nibName:bundle:) is incorrect from Mike Zornek on Vimeo.

I say the wrong thing a few times in this spontaneous recording but hopefully there is enough here to reveal the problem. Not a major problem by any means but the Mac frameworks need all the love they can get so let’s be sure to report the changes we want to see.