• Swift 5 Frozen enums
  • By Keith Harrison
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: iWeslie
  • Adjuster: Lobster-King

Have you upgraded your Xcode project to be Swift 5 compatible? Upgrading to Swift 5 should probably not be a problem, but you may get a lot of warnings when using switch statements to enumerate unknown values.

Warning of other unknown values

What exactly is the problem? I now use a little code to show how to fit layouts for classes of different sizes. It enumerates all possible values of UIUserInterfaceSizeClass:

func configure(for sizeClass: UIUserInterfaceSizeClass) {
    switch sizeClass {
    case .uppercased:
        // ...
    case .compact:
        // ...
    case .regular:
        // ...}}Copy the code

When I upgrade my project to Swift 5, Xcode will issue some warnings:

Warning Content:

The Switch statement covers all cases, but UIUserInterfaceSizeClass may later add some other unknown value

Use @unknown Default to handle unknown values

If you click Fix, Xcode will automatically add a @Unknown default: case:

switch sizeClass {
case .unspecified:
    // ...
case .compact:
    // ...
case .regular:
    // ...
@unknown default:
    fatalError()}Copy the code

You can modify fatalError(), but what does that really mean?

Frozen and unfrozen enumerations

A switch statement in Swift must be exhaustive or contain a default case to handle all other cases. My original switch statement enumerates all possible values of UIUserInterfaceSizeClass defined by Apple in UIKit for iOS 12.

What would happen if Apple introduced.tiny or.large in iOS 13? When compiling with a newer version of the SDK, the compiler will report an error because the Switch statement is no longer exhaustive. One way to resolve errors is to introduce a default: case. I can rewrite my switch statement:

switch sizeClass {
   case .compact:
      // Layout is what compact should do
   default:
      // What to do by default
      // There are also some unknowns
  }
Copy the code

The Switch is no longer exhaustive, but it handles all known and future unknowns. This is fine, but if the Switch is exhaustive, it’s an advantage for the compiler, and it’s compatible with binary libraries at compile time. You may also need to warn when enumerations are updated with new cases.

Swift Evolution proposal SE-0192 adds the @unknown Default: syntax, which allows you to continue using an exhaustive switch for future scenarios:

switch sizeClass {
case .unspecified:
    // ...
case .compact:
    // ...
case .regular:
    // ...
@unknown default:
    // ...
}
Copy the code

@Unknown Default: This case can only be used to make enumerations exhaustive and match any new cases added to the enumeration. It will still generate warnings for these new cases so that you can decide what action to take. This is different from using default: and a non-exhaustive enumeration, which does not prompt you that there is a new case pending.

Freeze the enumeration

This change also adds the concept of frozen enumerations, which are not meant to get any new cases. It only works for importing C or Objective-C enumerations into Swift. For example, the standard library ComparisonResult. Here’s his definition in Objective-C:

typedef NS_CLOSED_ENUM(NSInteger, NSComparisonResult) {
    NSOrderedAscending = -1L,
    NSOrderedSame,
    NSOrderedDescending
};
Copy the code

There are only three possible cases, so the enumeration will never change. Note the NS_CLOSED_ENUM annotation instead of the usual NS_ENUM. We don’t need to add @unknown default to the switch to make it exhaustive:

let result: ComparisonResult=...switch result {
    case .orderedAscending:
        // ...
    case .orderedSame:
        // ...
    case .orderedDescending:
        // ...
}
Copy the code

If the library author adds a new case to the frozen enumeration, the compilation will report an error.

Frozen or unfrozen?

We don’t know if Apple plans to enumerate cases in UIKit and related frameworks. Most may be non-frozen, but in some cases, freezing may make sense.

For example, the Stack View axis is an enumeration of UILayoutConstraintAxis that remains unfrozen in iOS 12. Here’s the objective-C header (note NS_ENUM) :

typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
    UILayoutConstraintAxisHorizontal = 0,
    UILayoutConstraintAxisVertical = 1
};
Copy the code

This means that if you want to open the stack view axis, you need to allow possible future unknowns:

switch stackView.axis {
case .horizontal:
    // ...
case .vertical:
    // ...
@unknown default:
    // ...
}
Copy the code

Maybe Apple will change it to NS_CLOSED_ENUM, or will stack view have another possible value in iOS 13?

What do we need to do?

  • First, you don’t need to change your own original Swift enumeration. When you upgrade to Swift 5, you don’t need to manually add it to the code from the start@unknown default:. Xcode will issue a warning to indicate where you need to add.
  • This change only applies to C enumerations in the standard library and other frameworks.
  • If your switch containsdefault:Case, then you don’t need to make any changes.
  • Completely switch C language unfrozen enumeration, including all known cases (excludingdefault:) is the warning in Swift 5.
  • You can ask Xcode to fix your code automatically for you, and it will add one@unknown:Case and eliminate the warning.

To read more

For more details, see the Swift Evolution proposal:

  • SE-0192 Handling Future Enum Cases

If you find any mistakes in your translation or other areas that need to be improved, you are welcome to the Nuggets Translation Program to revise and PR your translation, and you can also get the corresponding reward points. The permanent link to this article at the beginning of this article is the MarkDown link to this article on GitHub.


The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.