0
TimeZone(abbreviation: "GMT+1") ?? TimeZone.current

If you want to have a non optional and assert before TimeZone.current fallback is used after ?? what syntax would I use in swift?

something like this

TimeZone(abbreviation: "GMT+1") ?? (assertionFailure("what weird runtime have you've got????"), TimeZone.current)

(which obviously does not compile)

Anton Tropashko
  • 5,486
  • 5
  • 41
  • 66
  • ```TimeZone(abbreviation: "GMT+1") ?? { assertionFailure("what weird runtime have you got????"); return TimeZone.current }()``` – udi Aug 17 '23 at 11:00
  • 2
    "Avoid optionals"??? I'm pretty sure that's not what your teammates are saying. – matt Aug 17 '23 at 13:25
  • 2
    What's wrong with just force unwrapping it? `TimeZone(abbreviation: "GMT+1")!` – JeremyP Aug 17 '23 at 14:33
  • 2
    @JeremyP The advantage of a function (like the one you offer) is that you can provide more information in the failure, perhaps including logging that is recoverable from the user. `!` is a fairly blunt hammer. Plus, as you demonstrate, you can support debug assertions or fatal errors. I think your answer really demonstrates what's wrong with just force unwrapping. :D (Or at least what could be done better.) – Rob Napier Aug 17 '23 at 20:23
  • 2
    @RobNapier I wrote that comment before I thought of my answer. :) – JeremyP Aug 18 '23 at 08:15

2 Answers2

4

I have a slightly different solution using a generic function.

import Foundation

func fail<T>(_ message: @autoclosure () -> String, fallback: T) -> T
{
    assertionFailure(message())
    return fallback
}

let x = TimeZone(abbreviation: "GMT+1") ?? fail("x is not a valid time zone", fallback: TimeZone.current)

let y = TimeZone(abbreviation: "GMT+1fdsgfds") ?? fail("y is not a valid time zone", fallback: TimeZone.current)
// On evaluating the last statement, aborts with Fatal error: y is not a valid time zone
// in a debug or playground context
JeremyP
  • 84,577
  • 15
  • 123
  • 161
2

Try to write extension for Optional where you can handle your case, for example:

extension Optional {
    func rescue(
        _ assertion: String, 
        _ fallback: Wrapped
    ) -> Wrapped {
        guard case let .some(value) = self else {
            assertionFailure(assertion)
            return fallback
        }
        
        return value
    }
}
TimeZone(abbreviation: "GMT+1").rescue("what weird runtime have you've got????", .current) // GMT+0100
TimeZone(abbreviation: "GMT+1lalala").rescue("what weird runtime have you've got????", .current) // what weird runtime have you've got????