Unwrapping Swift

I recently rewritten my toy program that prints the ISO week, e.g. 2026-W18-04, from Rust to Swift. The previous version was approaching roughly 100 lines of code (excluding the self updater portions) and imported dozens of third-party libraries compared to the newer version that’s roughly 30 lines that only pulls from Swift’s build-in standard library, Foundation. Granted, this doesn’t include all the options from the original but --utc was reintroduced.

Adding UTC support proved a bit tricky. Swift 6 brought native support for concurrency and protection against data races. This brought with it unwrapping and the concept of ownership. Ya’ know. The very thing I threw a fit over Rust about, but there are some differences.

The TimeZone struct, included in Foundation, provided the solution to this but also introduced a new problem in regards to implementation. I needed to unwrap it in order to properly get the value needed to change the calendar’s time zone property. Luckily, this proved to be rather easier than I thought. All I had to do was apply timeZone ?? .autoupdatingCurrent to the property.

While the actual implementation is fairly straight forward, there is a lot going on under the hood that resulted in using this fairly simple solution. Because time zone abbreviations aren’t standardized and may have contradicting meanings, it is possible to not return no value at all. In order to account for this, we fall back to the user’s “current” (i.e. local) time zone.

When I had to use Rust, unwrapping often invoking the unwrap() method or using Some() struct for more complex routines. In my experience, using the unwrap method can cause trouble in it’s own right because it expects there to be a value. It’s basically the equivalent of adding the exclamation mark at the end of the field in order to override the safety checks. (That’s actually what I originally did in my first attempt with time zone switcher.) The Some() is used in if statements in order to test for the right value, which is to say but that can lead to the Pyramid of Doom if not done right. You could do a simple if statement using Ok() and Err() (the raw version of vlaue1 ?? value2), which is basically to saying, “okay, this is true, but if it isn’t you can throw an error,” but that too can easily lead down the same path of doom.

To be fair, there is no right or wrong way of handling concurrency. In fact, both Rust, and Swift do overlap in some places. It’s just the way Swift does it tends to behave more like C#’s error checking than Rust’s verbose way of doing things.

Leave a Reply

Your email address will not be published. Required fields are marked *