Swift

Swift

Made by DeepSource
Prefer using Array(seq) over seq.map { $0 } to convert a sequence into an Array SW-R1000
Anti-pattern
Major
Autofix

Using the Array initializer Array(seq) is a more concise and performant way of converting a sequence into an Array in Swift, as opposed to using seq.map { $0 }. Here's why: Performance: When using seq.map { $0 } to convert a sequence into an Array, the map function creates a new array and copies all the elements from the sequence into the new array. The Array initializer, on the other hand, creates an array with the exact same elements as the sequence, without any intermediate steps. This makes Array(seq) more performant than seq.map { $0 } for large sequences.

@objc is redundant when used with implicit Objective-C attribute SW-R1011
Anti-pattern
Minor
Autofix

The @objc attribute is used to expose Swift declarations to Objective-C code. However, it can be redundant in some cases, where the declaration is already implicitly @objc, or it's not necessary for the declaration to be exposed to

Setter access control should be different from the variable's access level SW-R1013
Anti-pattern
Minor

This issue highlights the redundant use of access control for property setters in Swift. If the access level of the variable and the setter are the same, it's unnecessary to specify the access level for the setter explicitly.

Avoid using unneeded break statements SW-R1018
Anti-pattern
Minor

Unneeded break statements are often found in switch cases in Swift. These break statements are redundant since they are executed automatically at the end of each case block. There is no harm in using break explicitly, but it

Always specify message when invoking fatalError() SW-R1021
Anti-pattern
Major

When invoking fatalError() in Swift, it is essential to provide a descriptive message to help with debugging and understanding the cause of the crash. This is because fatalError() is essentially an assertion that always fails, and the message provided helps identify the source of the failure. If a message is not provided, it can be challenging to track down the issue that caused the crash. The developer would have to rely on the stack trace, which is often not sufficient to identify the root cause of the problem.

Do not name an enum member as none SW-R1025
Anti-pattern
Major

Using "none" as a member name in an enum may create ambiguity and confusion while working with optional values. This is because Optional.none is a reserved keyword in Swift, and using it as a member name in an enum may conflict with that. If you use "none" as a member name in an enum, it may lead to unexpected behavior when working with optional values. For example, consider the following code:

Types used for hosting only static members should be implemented as a caseless enum to avoid instantiation SW-R1030
Anti-pattern
Minor

Types that are used solely for hosting static members should be implemented as a caseless enum in Swift. By using a caseless enum, you explicitly indicate that the type should not be instantiated. This helps prevent accidental creation of instances, which can lead to unnecessary memory allocation and potential misuse of the type.

String enum values can be omitted when they are equal to the enum case name SW-R1031
Anti-pattern
Minor

When defining enum cases in Swift, it is unnecessary and redundant to explicitly specify the enum values when they are same as the enum case name. Redundantly specifying the enum values can lead to code duplication and increase the likelihood of mistakes.

An XCTFail call should include a description of the assertion SW-R1032
Anti-pattern
Major

When a test case fails, the XCTFail call is used to indicate the failure. However, without a description, it becomes challenging to determine the specific reason for the failure. This can lead to confusion and increase debugging time, especially when multiple assertions are present in the same test case. It is recommended to always include a descriptive message when using XCTFail to provide clarity and context for failed assertions.

fileprivate should be avoided SW-R1027
Anti-pattern
Major

Using the fileprivate modifier in Swift can lead to several issues and is generally considered a bad practice. Here are a few reasons why:

Prefer using the hash(into:) function instead of overriding hashValue SW-R1001
Anti-pattern
Major

Overriding the hashValue property in Swift for custom types is now considered an anti-pattern. Instead, use the hash(into:) function to generate hash values for your objects. Here are a few reasons why: Clarity: The hash(into:) function is more explicit than hashValue. It makes it clear that the intent is to generate a hash value and not just return a random integer. This helps other developers understand the purpose of the function and avoid common pitfalls.

Use named arguments in multiline Swift closures SW-R1004
Anti-pattern
Major

When using closures in Swift with multiple parameters, it is often necessary to split the closure into multiple lines to improve readability. However, if the arguments are not named explicitly, it can be difficult to determine which argument a particular line refers to. This can lead to bugs and make the code harder to understand and maintain. To improve the readability and maintainability of your code, it is recommended to use named arguments in closures that span multiple lines. This makes it clear which argument each line is referring to, and can make the code much easier to follow.

where clauses are preferred over a single if inside a for loop SW-R1005
Anti-pattern
Minor

Prefer using where clauses over a single if statement to filter items inside a for loop. Using where clauses results in more readable and expressive code.

Swift constructors are preferred over legacy convenience functions SW-R1008
Anti-pattern
Major
Autofix

Legacy convenience functions are often used to initialize values in Swift. However, Swift constructors provide a better alternative for initializing objects. Here are some reasons why:

Prefer .zero over explicit init with zero parameters SW-R1009
Anti-pattern
Major
Autofix

Using the .zero initializer in Swift is generally more readable and concise than using a custom initializer with zero arguments when initializing an object with default values. Here are a few reasons why:

Redundant Optional initialization SW-R1012
Anti-pattern
Minor
Autofix

Initializing an optional variable with nil in Swift is redundant. This is because Swift automatically initializes all optional variables with nil by default. Initializing with nil adds no value to the code and makes it more

Returning values from a function returning Void should be avoided SW-R1014
Anti-pattern
Major

Returning values from a function that is declared to return Void is unnecessary and can lead to confusion and potential bugs in the code. Here are a few reasons why returning values from a Void function should be avoided:

Declare operators as static functions instead of free functions SW-R1015
Anti-pattern
Minor

Declaring operators as free functions in Swift can lead to several issues and make the code harder to read and maintain.

Use #unavailable/#available instead of #available/#unavailable with an empty body SW-R1017
Anti-pattern
Minor

Using the #available and #unavailable compiler directives with an empty body can be misleading and result in unintended behavior. It is recommended to use the #available directive with a non-empty body or the #unavailable

Extensions shouldn't override declarations SW-R1020
Anti-pattern
Minor

Using extensions to override declarations in Swift can lead to unexpected and hard-to-debug behavior. This is because extensions are intended to add new functionality to a type, not to modify or replace existing functionality. Overriding declarations in extensions can cause confusion, as it can be unclear which declaration is in effect at any given time.