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.

Apple’s Use of Donations as Marketing

The other day Tim Cook (‪@tim_cook‬) tweeted:

Our hearts go out to the people of Sulawesi and all of Indonesia after this weekend’s devastating earthquake and tsunami. Apple is donating $1 million to aid relief efforts as this beautiful country starts to rebuild.

I feel bad for the earthquake victims too, but this kind of marketing makes me a little ill.

Best I can tell Apple reported 53.8 billion dollars in profit over the last year. If you compared the ratio of their donation to say a person making $100,000 a year, the donation would be $1.86.

Now I don’t want to say a million dollars isn’t a big impact to the receivers of the donation, I’m sure it is — but it just feels a little cheap to announce it and have everyone retweet it, the media website repost it, all to build up this fake “good will” sentiment. Hell, you can’t even buy a media ad campaign for that cheap.

Anytime you read this stuff remember, these are the same big corporations dodging taxes that could normally fund proper emergency relief and preparedness along with other infrastructure needs.

Some might say, well Apple needs to answer to their shareholders and this is how every company works. Well I say, everyone has a choice, and yeah it can be easier to fall in line and do the expected but I root for the person who is going to step out of line and Think Different.

At a minimum, donate your $1.86 annomously without looking for a thank you.

Gaming Update, September 2018

Forgive me, it’s been a while since my last gaming update. So, what am I playing?

Well first off, I’m officially done with Hearthstone. It’s a shame cause I like the game, but the price has just gotten out of control.

Paperkut

I was playing a bunch of World of Warcraft over the summer and into the new expansion. I leveled my rogue Paperkut to 120 but ended up unsubscribing right when the raid came out. I’m not interested in doing the whole “guild and 2-3 nights a week” raiding schedule and while I’m sure I would enjoy the braindead yet soothing process of leveling and gearing my alts it will still be there for me in a few months. For now I wanted to try some new games and put some more time into programming side projects.

After WoW, I went retro, starting games of Wind Waker, Earthbound and even a Pokemon Platinum Nuzlock. I consider them all still active playthroughs. Since my last nuzlock update I was able to finish the second gym with only one death so far. (RIP Perch, the Starly.)

And finally, last weekend I bought Cities Skylines — and oh man am I having fun building my cities. I’ll fault the game with having a poor built-in tutorial process but I was saved by lots of helpful web tips and tutorials. The base game is $29 with lots of paid for DLC. You don’t need the DLC to get started so if you fancy city simulators and have not checked it out yet, I do recommend. PC preferred, since it has a large mod community.

Let me know what you are playing! Email is fine, but blogging is better. See ya next time.

ElixirConf 2018 Notes

After attending ElixirConf I am as confident as ever that Elixir is a language, community and ecosystem I want to continue to personally invest and participate in.

About two years ago I made the decision that I needed to diversify my technical skills outside the Apple ecosystem. I then went on to experiment and research lots of different languages and frameworks, including EmberJS, Go, Rust, Elm, HTML5 updates, React and Elixir.

The Elixir interest started from a broad recommendation from Dave Thomas who I had years before followed heavily while doing Ruby on Rails development. Elixir also had gotten momentum from my interests in Functional Programming and looking to solve problems outside of traditional Object Oriented Programming design patterns. Over the last few months I’ve gotten deeper into Elixir and I really like what I’ve found.

I’ll do a post in the future about why I’m liking Elixir so much. It’s a potentially large topic and I want to give it the space it deservers.

ElixirConf was a great event. Two days of training and two days of conference sessions; I took it all in. My personal estimate would put the training day attendance at around 150 and the full conference at around 500.

While educational, I found the class pacing to be mixed. I felt one went a little too slow and the other a little too fast. There was a wide gamut of Elixir experience in the audience so I think it’s challenging for the instructors to find a pace everyone can agree with. That said, I learned a ton in each of the two more introduction-based classes I attended. I was envious of the more advanced classes that were covering GraphQL and hardware development using Nerves — I heard people were very impressed with them. Maybe next year.

For the conference days we had some great keynotes and session. I loved hearing JosĂ© Valim (creator of Elixir) talk about the future of the language including the core teams failed experiments with adding a type system and why it’s not on the horizon. Chris McCord (creator of Phoenix) did a closing keynote, reviewing progress with the framework including a preview of Phoenix LiveView which was very impressive and has an opportunity to shake things up in the single-page app space. Aaron Renner had a great talk on taming complexity which mirrored some of my previous iOS code patters with way better naming. Aaron Votre’s excitement about GraphQL is contagious and I’m anxious to get my hands dirty. Andrew Bennett has some great tips in his Sustainable Testing talk. Daniel Azuma did a great job showing how we can mix and match Docker with traditional OTP deployments for unique benefits. Some time slots were competitive for my attention. I sadly missed Boyd Multerer’s Introduction of Scenic and Eric Oestrich’s Going Multi-Node session which both were well received from chat in the hallways. I’ll be sure to watch them on YouTube in the week ahead. In fact the majority of the conference keynotes and sessions are already posted on YouTube if you want to take a look.

Despite my general shyness, the community was very welcoming and friendly when I put myself out there. I had some great conversations during breaks and lunch. Hopefully these will continue on the community Slack and forums — I need to spend some more time with those.

Finally, everyone is hiring. Almost every speaker who represented a company said they were hiring. While I’m not looking for full time employment its relieving to see such hiring interest in a more niche language than say my current source of income, iOS.

Next year ElixirConf will be in Denver and assuming I find a way to keep Elixir active in my development schedule (I have a potential Elixir subcontract in the fall as well as some personal projects) I plan to be there.

For more on Elixir check out its homepage.

Photos

Self Employment Estimate Numbers

In a world of being self-employed you need to constantly be evaluating your finances. I was lucky enough recently to finish paying off some long standing debit and so I did a revisit. Today I want to share with you how I do my estimate numbers and hopefully you can use some of these ideas to help plan your own independence and/or make sure your current indie life is in good shape.

The software I use to do this is Soulver. Think of it as a really smart text editor for crunching numbers. Watch the demo video on their site to see it in action. If you are not interested in Soulver, any spreadsheet should do fine. Just keep it on file somewhere so you can come back and rework it as needed.

First thing you need is a list of personal expenses. If you are single you can do this yourself but if you are married or in a relationship where you share expenses get them involved too. You want to have a full and truthful collection of costs here. The goal is understanding what you need to survive and ultimately what you can cut to help make your dream that much more possible.

I did this by first using my credit card and debit card statements as a source. Every item needs to be recorded. Make three lists, some will be monthly expenses, some yearly expenses and some one-time expenses. Once you get done with the statement history try to brainstorm where the undocumented cash goes. Hopefully these lists will help.

Personal Monthly Expense Examples:

  • Rent / Mortgage
  • Home / Renters Insurance
  • Car Payments
  • Car Insurance
  • Car Maintenance
  • Car Fuel
  • Health Insurance
  • Expected Monthly Copays / Medicines
  • Netflix
  • Hulu
  • Monthly Gaming Subscriptions
  • Game Purchases
  • Eat Out Food
  • Spotify
  • iTunes
  • Patreon Gifts
  • Podcast Subscriptions
  • Haircut

Some of these items might be hard to quantify as monthly. If so just make a yearly entry for them.

Personal Yearly Expense Examples:

  • Christmas Presents
  • Birthday Presents
  • Yearly Clothes Budget
  • Vacations
  • Car Inspection

Once I have my yearly and one time costs I like to total them as a monthly expenses (YearlyTotal+OneTime/12) so I can later think in terms of months. This is fine for back of the hand estimates but if you need to plan out your money for specific times (summer vacation, fall back-to-school kind of stuff) you’ll need to do more planning.

Now do the same for your company.

Company Monthly Expense Examples:

  • Coworking Membership
  • Downtown Parking
  • GitHub Membership
  • Linode Hosting
  • Amazon Hosting
  • Books
  • Google Apps
  • Verizon Phone
  • Dropbox
  • Micro.Blog
  • Clicky / Web Statistics
  • Cushion / Finacial Software
  • Frontend Masters / Online Education

Company Yearly Expense Examples:

  • Two Conferences Events: $4000
  • Tax Preparation
  • New Mac every other year: $4000 Ă— 0.5
  • New iPad every other year: $1100 Ă— 0.5
  • New iPhone every other year: $1000 Ă— 0.5
  • Vimeo PRO Membership
  • Apple Developer Membership
  • Trello
  • Hover Domains
  • Other Software

Notice how I distribute the costs of various hardware upgrades, which are bi-yearly, and do keep in mind this is all for rough estimating. I in-fact have held off on upgrading my iPhone recently so that’s extra money in the bank (kind of).

Next I work out my income:

## hours a week
## hours Ă— $### per hour
{WeeklyRevenue} Ă— 4 weeks
{MonthlyRevenue} - {TotalOfCompanyMonthlyExpenses} tax-free
{AdjustedMonthlyRevenueA} - 0.10 for Savings
{AdjustedMonthlyRevenueB} - 0.30 Tax Estimate Payments
{AdjustedMonthlyRevenueC} x 10 months // assuming 8 weeks off
{AdjustedYearlyRevenue} / 12 months of payouts
{AdjustedMonthlyIncome} $/month personal income

This last number needs to be able to cover your personal expenses. Using this formula you can get an idea of how many hours and at what rate you want to target for the year. Also, just covering personal expenses is probably a risky goal. You might want to up that savings calculation until you have 12 months of living expenses in the bank.

These things vary person to person, hopefully you’ve found this post useful. If I’ve forgotten anything blog your additions and share along. Thanks for reading.