SwiftlintTemplate/ViewController.swift (152 lines of code) (raw):
//
// ViewController.swift
// SwiftlintTemplate
//
// Created by Liu, Henry on 17/12/21.
//
import UIKit
class ViewController: UIViewController {
// MARK: ENABLED RULES TESTS: General Formatting
// Colum limit
/// SWIFTLINT: line_length.
/// Swift Guide Rule: (Column Width) Swift code has a column limit of 100 characters. Any lines that exceed this limit can use Line-wrapping
/// (Warning if the above rule description is on the same line)
// Semicolons
/// SWIFTLINT: trailing_semicolon
/// Semicolons(;) are not used, either to terminate or separate statements.
/// Warnings
func printSum(_ param1: Int, _ param2: Int) {
let sum = param1 + param2;
print(sum);
}
// Horizontal Whitespace (Comma)
/// SWIFTLINT: comma
/// Rule guide: Whitespace after, but not before, the comma in parameter lists and in tuple/array/dictionary literals.
let numbers2 = [1,2,3] // Warning
let numbers3 = [1 ,2 ,3] // Warning
let numbers4 = [1 , 2 , 3] // Warning
// Horizontal Whitespace (Colon)
/// SWIFTLINT: colon
/// Rule guide: Whitespace after, but not before, the colon (:) in certain cases.
class MyClass : Formatter { // Warning
}
func greet2(person : String) -> String { // Warning
let val1 : Int = 0 // Warning
let val2: [String : [Int]] = ["Num" : [1, 2, 3]] // Warning
return "hello world"
}
// Parentheses
/// SWIFTLINT: control_statement
/// Rule guide: Parentheses are not used around the top-most expression that follows an if, guard, while, or switch keyword.
func testFunction() {
let valX = 0, valY = 1, valZ = 2
if (valX == 0) { // Warning
print("x is zero")
}
if ((valX == 0 || valY == 1) && valZ == 2) { // Warning
print("...")
}
}
// MARK: ENABLED RULES TESTS: Programming Practices
// Types with Shorthand Names - Void
/// SWIFTLINT: redundant_void_return and void_return
func doSomething() -> Void { // Warning
// ...
}
func doSomething2() -> () { // Warning
let callback: () -> () // Warning
}
// Optional Types
/// SWIFTLINT rule: unused_optional_binding
func testfunction2(val: String) {
let value: String?
value = val
if let _ = value { // Warning
print("value was not nil")
}
}
// Force Unwrapping and Force Casts
/// SWIFTLINT: force_cast
/// Rule guide: Avoid using as! to force a downcast, or ! to force unwrapping. Use as? to attempt the cast, then deal with the failure case explicitly.
class Animal {}
class Bird: Animal {}
func testCast() {
let animal: Animal = Bird()
animal as! Bird // Warning
}
// For-where Loops
/// SWIFTLINT: for_where
/// When the entirety of a for loop’s body would be a single if block testing a condition of the element, the test is placed in the where clause of the for statement instead.
func testForWhereLoop() {
let collection = [1, 2, 3]
for item in collection where item == 2 {
}
// MARK: OPT IN RULE TESTS
// SWIFTLINT: operator_usage_whitespace
/// Guide Rule: "On both sides of any binary or ternary operator, including the operator-like symbols (eg. =, &, ==, →).
let operatorTest1 = true
let operatorTest2=false // Warning
// SWIFTLINT: multiline_parameters
/// Guide Rule: "When a function call is line-wrapped, each argument is written on its own line, indented +2 from the original line."
func test1( // Warning
veryLongVariableName1: Int,
veryLongVariableName2: Int, veryLongVariableName3: Int) {
print("Hello world")
}
// No Warning
func test2(
veryLongVariableName1: Int,
veryLongVariableName2: Int,
veryLongVariableName3: Int) {}
// SWIFTLINT: implicitly_unwrapped_optional
/// Guide Rule: "Implicitly unwrapped optionals are inherently unsafe and should be avoided whenever possible.
func test3() {
let int: Int! = nil // Warning
}
// Swiftlint: modifier_order
// Guide Rule: "When using access modifiers, write the keyword first."
// Correct
let initialFactor1 = 2 // Comment
// Incorrect
let initialFactor2 = 2 // Comment
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// SWIFTLINT: modifier_order
/// Guide Rule: "When using access modifiers, write the keyword first."
private static let firstValue: Int = 20
static private let secondValue: Int = 20 // Warning
}
// SWIFTLINT: no_extension_access_modifier
// Guide Rule: "Specifying an explicit access level at the file level on an extension is forbidden."
// Correct
extension String {
}
// // Error Warning (uncomment to test)
// public extension String {
//
// }
}
func printSum(_ abc: Int, _ bcd: Int) {
let sum = abc + bcd;
print(sum);
}
// MARK: Formatting Specific Constructs and Naming
// SWIFTLINT: switch_case_on_newline
// Guide Rule: "Case statements must be on a newline"
// Correct
enum testEnvironment {
case development
}
// Wrong (Error Warning uncomment to test)
/* switch testEnvironment2 {
case 1: return true
}
*/
// SWIFTLINT: switch_case_alignment
// Guide Rule: "Case statements should align with their enclosing switch statement"
// Correct
func testWeekday(day: Int) -> String {
let day = 4
switch day {
case 1:
print("Monday")
case 2:
print("Tuesday")
case 3:
print("Wednesday")
case 4:
print("Thursday")
case 5:
print("Friday")
default:
print("Invalid day")
}
}
// Wrong
func testWeekend(dayOfWeek: Int) -> String {
let dayOfWeek = 5
switch dayOfWeek {
case 1:
print("Monday - not the weekend")
case 2:
print("Tuesday - not the weekend")
case 3:
print("Wednesday - not the weekend")
case 4:
print("Thursday - not the weekend")
case 5:
print("Friday - not the weekend")
case 6:
print("Weekend")
case 7:
print("Weekend")
default:
print("Invalid day")
}
}
// SWIFTLINT: explicit_enum_raw_value
// Guide Rule: "Enums should be explicitly assigned their raw values with only one case per line"
// Correct
enum testExplicit1 {
case int(Int)
case short(Int16)
}
enum testExplicit2: Int {
case one = 1
case two = 2
}
enum testExplicit3: String {
case one = "one"
case two = "two"
}
// Wrong
enum testExplicit4: Int {
case one = 10, two, three = 30
}
enum testExplicit5: String {
case one, two = "two"
}
// SWIFTLINT: redundant_string_enum_value
// Guide Rule: "Enum values can be omitted when they are equal to the enumcase name"
// Correct
enum testRedundant1: String {
case one
case two
}
enum testRedundant2: String {
case one, two
}
// Wrong
enum testRedundant3: String {
case one = "one"
case two = "two"
}
enum testRedundant4: String {
case one = "one", two = "two"
}
enum testRedundant5: String {
case one, two = "two"
}
// SWIFTLINT: comment_spacing
// Guide Rule: "One space after slashes for comments"
// Correct
// This is a comment
// Multiline double-slash
// comment
// - MARK: Mark comment
// Wrong
//Something
///MARK
}