An elegant way to update variables without unwrapping optionals using custom Swift operators

In Swift, you may want to update the value of a variable only if it is not nil. This can be cumbersome to do with regular assignment syntax, as you have to first unwrap the optional value and check if it is not nil before performing the assignment.

let originalStory: Story? = ...

if let originalStory = originalStory {
    story.basedOn = originalStory
}

By creating a custom operator, you can easily and elegantly perform this type of conditional assignment in a single step. Creating a custom operator ?= can help make your code more concise and maintainable, here is the code for the operator:

infix operator ?= : AssignmentPrecedence

func ?= <T>(lhs: inout T, rhs: T?) {
    if let value = rhs {
        lhs = value
    }
}

This operator is using generic and can be used with variables of any type, so long that the left and right operands are of the same type.

You could use this operator to update the value of a variable only if the right operand is not nil, like this:

var x = 1
x ?= nil // x remains 1
x ?= 2 // x is now 2

This operator uses the AssignmentPrecedence precedence group, which means that it will have lower precedence than the assignment operator (=).

One of the most useful uses I find in this custom operator is when updating the content of a dictionary if and only the variables are not nil. For instance in this code where both game.clef and game.mode are optional and could be nil:

var properties: [String: Any] = [:]
if let clef = game.clef {
    properties["clef"] = clef
}
if let mode = game.mode {
    properties["mode"] = mode
}

becomes:

var properties: [String: Any] = [:]
properties["clef"] ?= game.clef
properties["mode"] ?= game.mode

ISO8601DurationFormatter

I really had no idea what formatted strings like PT0S, P0D or PT5M30S meant when I first encountered them… And I am not alone, almost all developers who join the team ask the same question: what are these?

Well, did you know that the ISO8601 standard, commonly used to format dates, also has a duration component?

From https://en.wikipedia.org/wiki/ISO_8601#Durations:

Even though the Foundation framework in Swift offers the ISO8601DateFormatter, it obviously doesn’t support durations and since we needed to serialize/deserialize durations for a project, I ended up writing a small library that does just that.

Github repo: https://github.com/cyrilchandelier/ISO8601DurationFormatter

Prevent background view from being resized when using iOS 13+ default modal presentation

This simple trick helps preventing the system from resizing the background view when the modal appears. It keeps the standard behavior (panning view, partial view with dark veil) but leave the background view untouched.

Simply set the following flag on your UIViewController, for instance inside the viewDidLoad method:

definesPresentationContext = true

If the presenting view controller is a child of a navigation controller, then we need to apply this flag to the navigationController instead of self:

navigationController?.definesPresentationContext = true

Nanashi 2.0

I released the first version of Nanashi on the App Store 7 years ago, it’s a turn-based strategy game. The game was relatively simple: a solo mode against an AI and a pass and play mode.

The most requested feature was an online multi-player mode with a leaderboard, but I never found the time to do it… until today.

I finally released the version 2.0 of Nanashi with an online mode and a leaderboard.

The app is available on the App Store: https://apps.apple.com/us/app/nanashi/id649608957

PLAYER VS ROBOT

Rules are simple:
– select your piece to see where you can play
– one square away (including the diagonals) and your piece is cloned
– two squares away and your piece jumps
– capture the pieces of your enemy by cloning or jumping next their piece
– you win if you own the most pieces at the end of the game

Play against a challenging AI or against a friend on your iPhone or iPad……or play online against strangers and rank up the leaderboard!

EDIT: The game has since been feature by GamesKeys.net in their Top Games To Tryout in October 2020!

From zero to the App Store in one week-end

Build a complete app from scratch in a week-end? Challenge accepted! I started the project on Friday evening and submitted the app for review on the App Store on Sunday evening. It was accepted during the night and live on Monday morning.

So what was there time to do in just a weekend? Actually, a lot:

  • SwiftUI: I experimented a tiny bit of SwiftUI before, but nothing compares to building a real app!
  • GPS based location is retrieved in the background, reverse geocoded and stored in CoreData
  • Forms: automatically recording locations is cool, but you sometimes have to go and manually add or edit visits, SwiftUI makes it particularly easy to create dynamic forms with very little code and handles pretty much everything for you
  • In-App Purchase with a paywall selling a non-consumable product to unlock some features like yearly / country reports and PDF export
  • PDF generation from HTML templates, and export using a SwiftUI wrapped version UIActivityController
  • Analytics and Crashlytics integration using Firebase
  • App Store preparation: finding a name, writing description, creating a logo, preparing screenshots, submitting the In-App Purchase product
  • Submission!

What kind of issues did I run into?

  • SwiftUI is fun, but sometimes it’s just really hard to do something really simple (like presetting two modals / sheets from the same view), and sometimes you simply can’t do something simple (like removing the disclosure indicator from list cells without generating random crashes)
  • Fastlane didn’t want to work on my machine, I wanted to automate the screenshots but couldn’t, but it’s ok, since there is only one language for now and the app only support the iPhone, taking screenshots manually wasn’t too long
  • Apple randomly disabled submission from the version of Xcode available on the Mac App Store, and obviously the error message when submitting was super obscure… had to download the next coming GM from the developer download center

Is the code clean? Hell no! But was it fun to do? Absolutely! I don’t know if this app will ever sustain itself, but I’ve to admit we live in a time where very powerful tools are available for us to experiment and iterate really quickly. I’ll definitely do this kind of challenges again 🙂

Link to the app: https://apps.apple.com/us/app/trvl/id1487340379