> ## Content Index
> Fetch the complete content index at: https://developerinsider.co/llms.txt
> Use this file to discover other available public pages before exploring further.

# Tips to become a better Swift (iOS) Developer
- URL: https://developerinsider.co/tips-to-become-a-better-swift-ios-developer/
- Published: 2017-12-24T09:50:31.000Z
- Updated: 2018-03-29T17:01:03.000Z
- Author: Vineet Choudhary
- Tags: Swift, iOS, Swift4

Swift is friendly to new programmers. It's an industrial-quality programming language that's as expressive and enjoyable as a scripting language. Here the some tips to become a better Swift Developer. You can copy and paste the code snippets into Playground, to make it easier for you to understand -

## 1\. For loop with Half-open range

The half-open range [operator](https://developerinsider.co/operator-declarations-by-example-swift-programming-language/) (a ..< b) defines a range that runs from a to b, but doesn’t include b. The half-open range operator also has a one-sided form that’s written with only its final value.

#### 1.1 With Half-open range operator (or 😎 Code)

```swift
let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names[..<2] {
    print(name)
}
/* prints -
Anna
Alex */

for name in names[1..<3] {
    print(name)
}
/* prints -
 Alex
 Brian
 */

```

#### 1.2 Without Half-open range operator (or 💩 Code)

```swift
let names = ["Anna", "Alex", "Brian", "Jack"]
for (index, name) in names.enumerated(){
    if index < 2 {
        print(name)
    }
}
/* prints -
 Anna
 Alex */

```

or with while loop (still 💩 Code)

```swift
let names = ["Anna", "Alex", "Brian", "Jack"]
var index = 0
while index < 2 {
    print(names[index])
    index += 1
}
/* prints -
 Anna
 Alex */

```

## 2\. For loop with Closed range

The closed range [operator](https://developerinsider.co/operator-declarations-by-example-swift-programming-language/) (a...b) defines a range that runs from a to b, and includes the values a and b. The value of a must not be greater than b. The closed range operator has an alternative form for ranges that continue as far as possible in one direction.

#### 2.1 With Closed range operator (or ❤️ Code)

```swift
let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names[...2] {
    print(name)
}
/* prints -
 Anna
 Alex
 Brian
 */

for name in names[1...2] {
    print(name)
}
/* prints -
 Alex
 Brian
 */

```

#### 2.2 Without Closed range operator (or 💩 Code)

```swift
let names = ["Anna", "Alex", "Brian", "Jack"]
for (index, name) in names.enumerated(){
    if index >= 1 && index <= 2 {
        print(name)
    }
}
/* prints -
 Alex
 Brian
 */

```

## 3\. Subscripts

[Classes, structures](https://developerinsider.co/classes-and-structures-by-example-swift-programming-language/), and [enumerations](https://developerinsider.co/enum-enumerations-by-example-swift-programming-language/) can define subscripts, which are shortcuts for accessing the member elements of a collection, list, or sequence. You use subscripts to set and retrieve values by index without needing separate methods for setting and retrieval. For example, you access elements in an [Array](https://developerinsider.co/array-by-example-swift-programming-language/) instance as `someArray[index]`.

The following example defines a Matrix structure, which represents a two-dimensional matrix of [Double](https://developerinsider.co/double-by-example-swift-programming-language/) values with and without subscripts :

#### 3.1 Without Subscripts (or Okay Version)

```swift
struct Matrix {
    let rows: Int, columns: Int
    var grid: [Double]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        self.grid = Array(repeatElement(0.0, count: rows * columns))
    }
    
    func getValue(row: Int, column: Int) -> Double{
        return grid[(row * columns) + column]
    }
    
    mutating func setValue(row: Int, column: Int, value: Double){
        grid[(row * columns) + column] = value
    }
}

var matrix = Matrix(rows: 2, columns: 2)
matrix.setValue(row: 0, column: 0, value: 1.0)
matrix.setValue(row: 0, column: 1, value: 2.0)
matrix.setValue(row: 1, column: 0, value: 3.0)
matrix.setValue(row: 1, column: 1, value: 4.0)

print(matrix.getValue(row: 0, column: 0)) //prints "1.0"
print(matrix.getValue(row: 0, column: 1)) //prints "2.0"
print(matrix.getValue(row: 1, column: 0)) //prints "3.0"
print(matrix.getValue(row: 1, column: 1)) //prints "4.0"

```

#### 3.2 With Subscripts (or Better Version)

```swift
struct Matrix {
    let rows: Int, columns: Int
    var grid: [Double]
    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        self.grid = Array(repeatElement(0.0, count: rows * columns))
    }
    subscript(row: Int, column: Int) -> Double {
        get {
            return grid[(row * columns) + column]
        }
        set {
            grid[(row * columns) + column] = newValue
        }
    }
}

var matrix = Matrix(rows: 2, columns: 2)

matrix[0,0] = 1.0
matrix[0,1] = 2.0
matrix[1,0] = 3.0
matrix[1,1] = 4.0

print(matrix[0,0]) //prints "1.0"
print(matrix[0,1]) //prints "2.0"
print(matrix[1,0]) //prints "3.0"
print(matrix[1,1]) //prints "4.0"

```

## 4\. Function vs Computed Property

#### 4.1 Function (or 💩 Code)

As you know, functions are self-contained chunks of code that perform a specific task. Here's an example of a function implementation, this example find the diameter of a circle from circle radius or visa-versa :

```swift
func getDiameter(radius: Double) -> Double {
    return radius * 2
}

func getRadius(diameter: Double) -> Double {
    return diameter / 2
}

print(getDiameter(radius: 100)) //prints "200"
print(getRadius(diameter: 100)) //prints "50"

```

#### 4.2 Computed Property (or ❤️ Code)

Computed [property](https://developerinsider.co/properties-by-example-swift-programming-language/) provide a getter and an optional setter to retrieve and set other properties and values indirectly. Computed properties do not actually store a value. Here's the same example of with computed property, this example find the diameter of a circle from circle radius or visa-versa :

```swift
var radius: Double = 100
var diameter: Double {
    get {
        return radius * 2
    }
    set {
        radius = newValue / 2
    }
}

print(diameter) //prints "200.0"

diameter = 100
print(radius) //prints "50.0"

```

## 5\. Extensions

Extensions add new functionality to an existing class, structure, enumeration, or protocol type. This includes the ability to extend types for which you do not have access to the original source code. Extensions are similar to categories in Objective-C.

Here's an example of a extension implementation, this example adds four computed instance properties to Swift's built-in [Double](https://developerinsider.co/double-by-example-swift-programming-language/) type, to provide basic support for working with distance units (default is meters):

#### 5.1 With Extensions (or Awesome Code)

```swift
extension Double {
    var m: Double { return self }
    var km: Double { return self * 1000.0 }
    var cm: Double { return self / 100.0 }
    var mm: Double { return self / 1000.0 }
}

let thousandCentimeter = 1000.cm
print("Thousand centimeter is \(thousandCentimeter) meters")
// Prints "Thousand centimeter is 10.0 meters"

let threeKilometer  = 3.km
print("Three km is \(threeKilometer) meters")
// Prints "Three km is 3000.0 meters"

```

#### 5.2 Without Extensions (or Bad Code)

```swift
func centimeterToMeter(value: Double) -> Double{
    return value / 100.0
}

func kilometerToMeter(value: Double) -> Double{
    return value * 1000.0;
}

let thousandCentimeter = 1000.0
print("Thousand centimeter is \(centimeterToMeter(value: thousandCentimeter)) meters")
// Prints "Thousand centimeter is 10.0 meters"

let threeKilometer  = 3.0
print("Three km is \(kilometerToMeter(value: threeKilometer)) meters")
// Prints "Three km is 3000.0 meters"

```

## 6\. Ternary conditional

The ternary conditional [operator](https://developerinsider.co/operator-declarations-by-example-swift-programming-language/) is a special operator with three parts, which takes the form `question ? answer1 : answer2`. It’s a shortcut for evaluating one of two expressions based on whether `question` is `true` or `false`. If question is `true`, it evaluates `answer1` and returns its value; otherwise, it evaluates `answer2` and returns its value.

Here's an example of ternary conditional operator, which change the value of `rowHeight` based on either that row has a header or not.

#### 6.1 With ternary coditional operator (or ❤️ Code)

```swift
let contentHeight = 40
let hasHeader = true
let rowHeight = contentHeight + (hasHeader ? 50 : 20)
print(rowHeight)

//prints "90"

```

#### 6.2 Without ternary coditional operator (or 💩 Code)

```swift
let contentHeight = 40
let hasHeader = true
var rowHeight: Int
if hasHeader == true {
    rowHeight = contentHeight + 50
} else {
    rowHeight = contentHeight + 20
}
print(rowHeight) //prints "90"

```

## 7\. Nil coalescing

The nil-coalescing [operator](https://developerinsider.co/operator-declarations-by-example-swift-programming-language/) (`a ?? b`) unwraps an optional `a` if it contains `a` value, or returns `a` default value `b` if `a` is `nil`. The expression `a` is always of an optional type. The expression `b` must match the type that is stored inside `a`.

Here's an example of Nil coalescing operator, in which if `userDefinedColorName` returns nil, choose `defaultColorName` (red). If not, choose `userDefinedColorName`.

#### 7.1 With Nil coalescing (or 😎 Code)

```swift
let defaultColorName = "red"
var userDefinedColorName: String?   // defaults to nil

var colorNameToUse = userDefinedColorName ?? defaultColorName
print(colorNameToUse)

//prints "red"
// userDefinedColorName is nil, so colorNameToUse is set to the default of "red"

userDefinedColorName = "green"
colorNameToUse = userDefinedColorName ?? defaultColorName
print(colorNameToUse)

//prints "green"
// Now userDefinedColorName is "green", so colorNameToUse is set to the value of userDefinedColorName of "green"

```

#### 7.2 Without Nil coalescing (or 💩 Code)

```swift
let defaultColorName = "red"
var userDefinedColorName: String?   // defaults to nil

var colorNameToUse: String!
if let color = userDefinedColorName {
    colorNameToUse = color
} else {
    colorNameToUse = defaultColorName
}
print(colorNameToUse)

//prints "green"
//userDefinedColorName is "green", so colorNameToUse is set to the value of userDefinedColorName of "green"

```

## 8\. Optional Unwrapping (if let vs guard let)

As you know, the `if let` allows us to unwrap optional values safely only when there is a value, and if not, the code block will not run. On other hand, a `guard statement` is used to transfer program control out of a scope if one or more conditions aren't met. The guard statement makes our code more readable. Readability and easy maintenance are extremely important, especially when working with other programmers.

Here's an example for creating a new user:

```swift
let emailField = UITextField()
emailField.text = "abcd@mail.com"
let usernameField = UITextField()
usernameField.text = "vineet"
let passwordField = UITextField()
passwordField.text = "123456"
let conifrmPasswordField = UITextField()
conifrmPasswordField.text = "123456"

```

#### 8.1 if let (or Bad Code)

```swift
func loginIfLet(){
    if let email = emailField.text {
        if let username = usernameField.text {
            if let password = passwordField.text {
                if let conifrmPassword = conifrmPasswordField.text {
                    if password == conifrmPassword {
                        print("Email - \(email)")
                        print("Username - \(username)")
                        print("Password - \(password)")
                    } else {
                        print("Password didn't match with conifrm password.")
                    }
                } else {
                    print("Conifrm password is empty.")
                }
            } else {
                print("Password is empty.")
            }
        } else {
            print("Username is empty.")
        }
    } else {
        print("Email is empty.")
    }
}
loginIfLet()

```

#### 8.2 guard let (or Awesome Code)

```swift
func loginGuardLet(){
    guard let email = emailField.text else {
        print("Email is empty.")
        return
    }
    guard let username = usernameField.text else {
        print("Username is empty.")
        return
    }
    guard let password = passwordField.text else {
        print("Password is empty.")
        return
    }
    guard let conifrmPassword = conifrmPasswordField.text else {
        print("Conifrm password is empty.")
        return
    }
    if password == conifrmPassword {
        print("Email - \(email)")
        print("Username - \(username)")
        print("Password - \(password)")
    } else {
        print("Password didn't match with conifrm password.")
    }
}
loginGuardLet()

```

## 9\. Functional Programming

As you know, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.

Here's an example, that print all the even numbers between 1 and 10:

#### 9.1 Old Approach (or Bad Code)

```swift
var evenNumbers = [Int]()
for number in 1...10 {
    if number % 2 == 0 {
        evenNumbers.append(number)
    }
}
print(evenNumbers) //prints "[2, 4, 6, 8, 10]"

```

#### 9.2 Modern Approach (or Good Code)

```swift
var evens = Array(1...10).filter { (num) -> Bool in
    return num % 2 == 0
}
print(evens) //prints "[2, 4, 6, 8, 10]"

```

or

```swift
var evens = Array(1...10).filter { $0 % 2 == 0 }
print(evens) //prints "[2, 4, 6, 8, 10]"

```

## 10\. Generics

Generics are one of the most powerful features of Swift. Generic code enables you to write flexible, reusable functions and types that can work with any type, subject to requirements that you define.

Here's an example of swaping two integer and string values:

#### 10.1 Without Generics (or 💩 Code)

```swift
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}

func swapTwoStrings(_ a: inout String, _ b: inout String) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt = \(someInt)")
print("anotherInt = \(anotherInt)")
/* prints
 someInt = 107
 anotherInt = 3
 */
 
var someString = "hello"
var anotherString = "world"
swapTwoStrings(&someString, &anotherString)
print("someString = \(someString)")
print("anotherString = \(anotherString)")
/* prints
 someString = world
 anotherString = hello
 */

```

#### 10.2 With Generics (or 👊 Code)

```swift
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
print("someInt = \(someInt)")
print("anotherInt = \(anotherInt)")
/* prints
 someInt = 107
 anotherInt = 3
 */

var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
print("someString = \(someString)")
print("anotherString = \(anotherString)")
/* prints
 someString = world
 anotherString = hello
 */

```

## 11\. Type safe using Enum (enumeration)

An [enumeration](https://developerinsider.co/enum-enumerations-by-example-swift-programming-language/) defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code.

#### 11.1 Without Enum (or 💩 Code)

```swift
let directionToHead = "east"
switch directionToHead {
case "north":
    print("Lots of planets have a north")
case "south":
    print("Watch out for penguins")
case "east":
    print("Where the sun rises")
case "west":
    print("Where the skies are blue")
default:
    print("Unknown direction")
}
//prints "Where the sun rises"

```

#### 11.2 With Enum (or 👊 Code)

Without Enum, you are hard coding the values for each case — north, south, east, and west. Let's now see how enums can add beauty to your code.

```swift
enum CompassPoint {
    case north, south, east, west
}
let direction: CompassPoint = .east

switch direction {
case .north:
    print("Lots of planets have a north")
case .south:
    print("Watch out for penguins")
case .east:
    print("Where the sun rises")
case .west:
    print("Where the skies are blue")
}

```

Do you think you have some tips and tricks which can improve the skills of other Swift Developers? Why not share them in the comments section below!

---

#### You can download the swift playground of all above examples from [Here](https://github.com/developerinsider/developer-insider-content/blob/master/POST/iOS/Swift/Playgrounds/BecomeABetterSwiftDeveloper.playground.zip?raw=true&ref=developerinsider.co)

---