Swift

Swift

Made by DeepSource
Fallthrough should be avoided SW-W1012
Bug risk
Minor

Using the fallthrough keyword in switch statements can lead to subtle and hard-to-find bugs in Swift. The fallthrough keyword allows the control flow to move to the next case in a switch statement. This can be useful in some cases, but it can also make the code harder to read and increase the risk of unexpected behavior.

Unused setter value is likely a mistake SW-W1004
Bug risk
Critical

In Swift, setters should always access the value that is provided for the backing field. If a setter does not access this value, it is possible that the backing field contains a value other than what the user intended. This can result in unexpected behavior and is likely a mistake.

Comparing two identical operands is likely a mistake SW-W1015
Bug risk
Critical

Comparing two identical operands in a binary operator can be a mistake. If two identical operands are used in a binary operator, the result is always predictable and will always be true. This can lead to unintended consequences if the code is meant to compare two different variables.

@IBOutlets shouldn’t be declared as weak SW-W1020
Bug risk
Major
Autofix

By declaring @IBOutlets as weak, you are creating a weak reference to the outlet. Weak references do not keep the referenced object alive, meaning that the outlet can be deallocated if there are no other strong references to it. This can result in unexpected crashes or undefined behavior when accessing the outlet.

Force unwrapping should be avoided SW-W1023
Bug risk
Major

Force unwrapping should be avoided in Swift as it can lead to runtime errors and crashes. Force unwrapping is when an optional value is forcefully unwrapped using the exclamation mark (!) operator without checking if the value is nil or not. This can result in a fatal error if the optional value is actually nil at runtime.

An object should only remove itself as an observer in deinit SW-W1028
Bug risk
Major

When an object registers itself as an observer for notifications using the NotificationCenter API, it is responsible for removing itself as an observer when it is no longer needed. This is typically done in the deinit method of the object. By removing itself as an observer in deinit, the object ensures that it will no longer receive notifications after it has been deallocated. If an object removes itself as an observer outside of its deinit method, it can lead to unexpected behavior. For example, if the object is deallocated before it removes itself as an observer, the notification center will still try to send notifications to the deallocated object, resulting in a crash.

Delegates should be weak to avoid reference cycles SW-W1025
Bug risk
Major

Delegates in Swift should be declared as weak to avoid creating reference cycles. When a delegate is strongly referenced by the object it is delegating to, a retain cycle can occur preventing both objects from being deallocated and causing a memory leak.

Duplicate key in dictionary is likely a mistake SW-E1000
Bug risk
Critical

This issue occurs when there are duplicate keys in a Swift dictionary. A dictionary is a collection data type that stores key-value pairs. Each key in a dictionary is unique, and it maps to a single value. When a dictionary contains duplicate keys, it leads to confusing and error-prone behavior.

nil coalescing operator is never evaluated as it's in RHS SW-R1010
Bug risk
Minor
Autofix

Using the nil coalescing operator (??) in Swift can be helpful to provide default values when dealing with optional types. However, it can be easy to fall into the trap of using it unnecessarily, leading to redundant code that

Duplicate conditions in branch instruction is likely a mistake SW-W1005
Bug risk
Critical

Duplicate conditions in branch instruction is likely a mistake and can lead to confusion and unexpected behavior in your code. In particular, having multiple if statements in an if-else chain with the same condition is redundant and can make your code harder to read and maintain. This can also lead to logical errors and unexpected side effects.

@IBInspectable should be applied to variables only, have its type explicit and be of a supported type SW-W1006
Bug risk
Major

The @IBInspectable attribute in Swift is used to expose properties to Interface Builder, allowing them to be configured visually. However, there are certain guidelines and restrictions that should be followed when using this attribute. The issue arises when the @IBInspectable attribute is applied to something other than a variable, or when the type of the variable is not explicit or not one of the supported types (boolean, integer or floating point number, string, localized string, rectangle, point, size, color, range, and nil).

Enum should always have unique cases SW-W1007
Bug risk
Critical

Enum should always have unique cases as having multiple cases with the same name can lead to unintended behavior. When cases in enum are not unique, it can cause confusion and make the code difficult to maintain. This is especially true when the cases are mapped to different values.

try! statements should be avoided SW-W1008
Bug risk
Major

Force tries in Swift should be avoided as they can lead to runtime errors and make error handling difficult. Force tries are denoted by using a try! statement before a throwing function call. It basically makes an assertion that although the function has the ability to throw an error, it will not throw in this particular scenario and you want to skip the error handling.

Unused control flow label should be removed SW-W1010
Bug risk
Minor
Autofix

Unused control flow labels in Swift should be removed as they can clutter the code and make it harder to read and understand. Control flow labels are used to specify which loop or conditional statement to break or continue when there are multiple nested loops or conditional statements. However, if a label is not used, it should be removed to avoid unnecessary complexity and confusion.

Force casts should be avoided SW-W1013
Bug risk
Major

Casting is a way to convert an instance of one type to another. Swift's type system is designed to be safe, and casts can lead to unexpected errors if done incorrectly. Why is this an issue:

Unimplemented functions should be marked as unavailable SW-W1014
Bug risk
Minor

Unimplemented functions in Swift code can cause confusion for users who may think the function is available to use. This can lead to runtime errors and unexpected behavior. To prevent this issue, it's recommended to mark any unimplemented functions as unavailable using the @available attribute. This communicates to users that the function is not yet implemented and should not be used.

Unit tests marked private are silently skipped SW-W1016
Bug risk
Critical
Autofix

Marking unit tests as private in Swift can lead to several issues and is generally considered a bad practice. Here are a few reasons why: Test Visibility: Unit tests are essential for verifying the correctness of your code. By marking tests as private, you limit their visibility only to the file where they are defined.

self refers to the unapplied NSObject.self() method, which is likely not expected SW-W1017
Bug risk
Major

When using self inside a Swift class or struct, it normally refers to the instance of the class or struct. However, in certain cases, if self is used in conjunction with the NSObject class, it can unintentionally refer to the NSObject.self() method instead of the instance of the class. This can lead to unexpected behavior and subtle bugs.

The initializers declared in compiler protocols such as ExpressibleByArrayLiteral shouldn’t be called directly SW-W1027
Bug risk
Major

Compiler protocols like ExpressibleByArrayLiteral define a contract that types adopting the protocol must adhere to. By calling the initializer directly, you bypass this contract and can potentially create instances that do not conform to the expected behavior defined by the protocol. This can lead to runtime errors and unpredictable results. Compiler protocols often provide a convenient way to initialize instances of a type using literals. By calling the initializer directly, you lose the type safety that the protocol provides. This can lead to code that is harder to understand, maintain, and debug.

Void functions should not be used with ternary operators SW-W1018
Bug risk
Critical

Using void functions with ternary operators can lead to unexpected behavior and should be avoided. When using a ternary operator, there must be a return value in both cases. If a void function is used as one of the return values, the function will be executed but the result will not be used. This can lead to confusion for other developers reading the code, as it may not be clear what the intended behavior is.