Unused setter value is likely a mistakeSW-W1004Duplicate key in dictionary is likely a mistakeSW-E1000Default parameters should always be positioned at the endSW-W1001Duplicate conditions in branch instruction is likely a mistakeSW-W1005Enum should always have unique casesSW-W1007Use of an insecure version of TLS protocolSW-S1002Use of an insecure block cipher modeSW-S1003Use of an insecure cipher algorithmSW-S1004Prefer using `min()` or `max()` over `sorted().first` or `sorted().last`SW-P1011Prefer using `.first(where:)` over `.filter { }.first` in collectionsSW-P1007Prefer `contains` over `range(of:) != nil` and `range(of:) == nil`SW-P1012Force unwrapping should be avoidedSW-W1023An object should only remove itself as an observer in `deinit`SW-W1028Prefer `contains` over comparing `filter(where:).count` to zeroSW-P1001Prefer `reduce(into:_:)` over `reduce(_:_:)` for copy-on-write typesSW-P1010Prefer using `.allSatisfy()` or `.contains()` over `reduce(true)` or `reduce(false)`SW-P1000Prefer `contains` over using `filter(where:).isEmpty`SW-P1002Prefer `contains` over `first(where:) != nil` and `firstIndex(where:) != nil`SW-P1003Prefer checking `isEmpty` over comparing collection to an empty array or dictionary literalSW-P1004`@IBInspectable` should be applied to variables only, have its type explicit and be of a supported typeSW-W1006`try!` statements should be avoidedSW-W1008When the index or the item is not used, `.enumerated()` can be removedSW-W1002The initializers declared in compiler protocols such as `ExpressibleByArrayLiteral` shouldn’t be called directlySW-W1027Avoid using `dynamic` and `@inline(__always)` togetherSW-W1026Subclasses of `NSObject` should implement `isEqual` instead of `==`SW-W1029Passing `NSNumber.init` or `NSDecimalNumber.init` as a function reference is dangerous as it can cause the wrong initializer to be used, causing crashes; use `.init(value:)` insteadSW-W1030Delegate protocols should be class-only so they can be weakly referencedSW-R1029Prefer using `.last(where:)` over `.filter { }.last` in collectionsSW-P1009TODOs and FIXMEs should be resolvedSW-D1000Extensions shouldn't override declarationsSW-R1020Duplicate import statements are redundant and can be removedSW-W1000Unused parameters in a closure can be replaced with the underscore identifierSW-W1009Audit: Use of legacy functions to generate random values can be insecureSW-A1000Comparing two identical operands is likely a mistakeSW-W1015Unit tests marked `private` are silently skippedSW-W1016Void functions should not be used with ternary operatorsSW-W1018Use of unrestricted base URL in web viewSW-S1000Use of insufficient number of iterations during hash computationSW-S1001Audit: Use of potentially insecure options during XML parsingSW-A1001Prefer using `Array(seq)` over `seq.map { $0 }` to convert a sequence into an ArraySW-R1000Always specify message when invoking `fatalError()`SW-R1021Do not name an enum member as `none`SW-R1025An `XCTFail` call should include a description of the assertionSW-R1032`@IBOutlet`s shouldn’t be declared as weakSW-W1020`fileprivate` should be avoidedSW-R1027Delegates should be weak to avoid reference cyclesSW-W1025Prefer using the `hash(into:)` function instead of overriding `hashValue`SW-R1001Use named arguments in multiline Swift closuresSW-R1004Swift constructors are preferred over legacy convenience functionsSW-R1008Prefer `.zero` over explicit init with zero parametersSW-R1009Returning values from a function returning `Void` should be avoidedSW-R1014Extensions shouldn’t be used to group code within the same source fileSW-R1028Force casts should be avoidedSW-W1013self refers to the unapplied `NSObject.self()` method, which is likely not expectedSW-W1017Implicitly unwrapped optionals should be avoided when possibleSW-W1022Prefer using `Set.isDisjoint(with:)` over `Set.intersection(_:).isEmpty`SW-R1007Shorthand syntactic sugar should be used, i.e. `[Type]` instead of `Array<Type>`SW-C1003`@objc` is redundant when used with implicit Objective-C attributeSW-R1011Setter access control should be different from the variable's access levelSW-R1013Avoid using unneeded break statementsSW-R1018Fallthrough should be avoidedSW-W1012Types used for hosting only static members should be implemented as a caseless enum to avoid instantiationSW-R1030String enum values can be omitted when they are equal to the enum case nameSW-R1031Follow conventions while naming typesSW-C1000Missing documentation commentSW-D1001Use shorthand syntax for optional bindingSW-C1001Prefer `flatMap` over `map` followed by `reduce([], +)`SW-P1008`where` clauses are preferred over a single `if` inside a `for` loopSW-R1005`nil` coalescing operator is never evaluated as it's in RHSSW-R1010Redundant `Optional` initializationSW-R1012Declare operators as static functions instead of free functionsSW-R1015Use `#unavailable`/`#available` instead of `#available`/`#unavailable` with an empty bodySW-R1017Do not explicitly call `.init` methodSW-R1022Unused control flow label should be removedSW-W1010Unimplemented functions should be marked as `unavailable`SW-W1014Use `assertionFailure()` and `preconditionFailure()` over `assert(false)`SW-W1021Generic type name should only contain alphanumeric characters, start with an uppercase character and span between 1 and 20 characters in lengthSW-C1002Prefer checking `isEmpty` over comparing `count` to zeroSW-P1005The constant literal should be placed on the right-hand side of the comparison operatorSW-R1003Catch statements should not declare error variables without type castingSW-R1019Empty `XCTest` method should be avoidedSW-W1031Prefer checking `isEmpty` over comparing `string` to an empty string literalSW-P1006Function with cyclomatic complexity higher than thresholdSW-R1002
Swift logoSwift/
SW-W1022

Implicitly unwrapped optionals should be avoided when possibleSW-W1022

Major severityMajor
Bug Risk categoryBug Risk

Implicitly unwrapped optionals (IUOs) are a type of optional in Swift that are automatically unwrapped when used. While they can be convenient in some cases, they can also lead to unexpected crashes if the value is nil. This is because IUOs are treated as non-optionals by the compiler, and accessing a nil value will result in a runtime error. In general, it is recommended to use regular optionals instead of IUOs wherever possible.

There are several reasons why IUOs should be avoided:

  • Safety: Using regular optionals forces you to explicitly handle the case where the value is nil, which can help prevent runtime errors and crashes. With IUOs, it's possible to accidentally access a nil value and cause a crash.
  • Readability: When you see an IUO in code, it's not immediately clear whether the value can be nil or not. This can make the code harder to read and understand, especially for new developers joining a project.
  • Maintainability: If a value that was previously non-nil is changed to nil, any code that uses an IUO to access that value will now crash. This can make it difficult to track down the cause of the crash and fix the underlying issue.

To avoid using IUOs, you can use regular optionals and safely unwrap them using if let or guard statements. Here's an example of how to convert an IUO to a regular optional:

Bad Practice

var nameLabel: UILabel!
var nameLabel: UILabel?

And then unwrap it safely using optional binding:

if let nameLabel = nameLabel {
    nameLabel.text = "John Doe"
}