January 12, 2020

Swift General task Cheatsheet

Swift General task Cheatsheet
  1. Get length of String
  2. Split String into Array
  3. Enumerate enum
  4. Convert Int to String
  5. Convert String to Int
  6. Convert String to Double
  7. Convert Double to String
  8. Sort object array by value
  9. Sort dictionary by value
  10. Sort dictionary by key
  11. Check if array contains elements
  12. Replace characters in String
  13. Generate a random number
  14. Get nth character in string
  15. Add observer to notification
  16. Merge/Concatenate arrays
  17. Close keyboard
  18. Get reference to AppDelegate
  19. Round number to x decimal places
  20. Determine current device model
  21. Add element to array
  22. Create global constants
  23. Validate email address
  24. Create attributed string
  25. Difference between == and ===
  26. Generate UUID
  27. Check if user is using iPad

Full Source Code

Get length of String

Getting the length is a simple task, simply do the following:

// Get string length
let stringValue = "some string"
let stringLength = stringValue.count

Split String into Array

This will depend on how you want to split. If you want to split a string using a specific character you can do the following:

// Split string into array
let stringToSplit = "string to split"
let splitString = stringToSplit.components(separatedBy: " ")

If you want to split a string into an array of String.Element, also known know as a Character, you can do the following:

let splitToCharacters = Array(stringToSplit)

Enumerate enum

To iterate through the cases of an enum you need to make the enum adopt to CaseIterable:

enum EnumerateEnum: CaseIterable {
	case one
	case two
	case three
	case four
}

for enumCase in EnumerateEnum.allCases {
	print(enumCase)
}

Once you have adopted the CaseIterable protocol you will have access to allCases on the enum which is a collection.

Convert Int to String

let intToStringValue = 15
let stringOfIntValue = String(intToStringValue)

Converting an Int to a String is very simple. All you need to do is pass an Int as an argument when you are initialising a String.

Converting from Int to String does not return an optional String, but, if you convert a String to an Int, that will return an optional Int, which you can see in the following section.

Convert String to Int

let stringValue = "10"
let intValue = Int(stringValue)

Initialising an Int with a String argument will return an optional Int if it can convert the String to an Int. If it cannot convert a String to an Int then it will return nil.

Convert String to Double

let stringToDoubeValue = "100"
let doubleOfStringValue = Double(stringToDoubeValue)
print(doubleOfStringValue)

Creating a Double from a String is as easy as a String to Int. All you need to do is initialise a Double by passing in a String value.

Convert Double to String

Converting a Double to a String is very easy, all you need to do is initialise the String with the Double:

let doubleToString = 110.0
let stringOfDoubleValue = String(doubleToString)
print(stringOfDoubleValue)

Sort object array by value

To sort an array we need to use the Sorted method. To do that let's create a simple array of CGPoint and sort them by their x value:

let pointArray = [CGPoint(x: 10, y: 10),
                  CGPoint(x: 20, y: 10),
                  CGPoint(x: 30, y: 10),
                  CGPoint(x: 40, y: 10)]
let sortedArray = pointArray.sorted(by: { $0.x > $1.x })

In the above example we sorted the array from the largest x value to the smallest x value.

Sort dictionary by value

Sorting a Dictionary by value is similar to sorting an Array because both use the sorted method. But it can be a bit more confusing. So I will first show you an easier to understand way, and then I will show the shortened version.

To start with, let's create the dictionary:

let dictionary = [
    "One" : CGPoint(x: 10, y: 10),
    "Two" : CGPoint(x: 20, y: 10),
    "Three" : CGPoint(x: 30, y: 10),
    "Four" : CGPoint(x: 40, y: 10),
]

We can now sort this dictionary by doing the following:

let sortedDictionary = dictionary.sorted { firstElement, secondElement in
    return firstElement.value.x > secondElement.value.x
}

What I have done here is named the elements/objects in the dictionary as firstElement and secondElement. The firstElement and secondElement have both the key and the value of the first and second elements that are being processed.

So when we want to sort by our value, we need to use the value property, hence we use firstElement.value. The value will be our CGPoint object, now that we know that we can use the x property on our CGPoint and compare it to the secondElement's x property.

The shortcut way of doing the above is the following:

let sortedDictionary = dictionary.sorted { $0.1.x > $1.1.x }

This is much more difficult to read. $0 represents firstElement and $1 represents secondElement. Then use .1 to get the value and finally we can access the x property of our CGPoint.

Sort dictionary by key

Sorting a dictionary by key is very similar to sorting a dictionary by value. If you want to see more information take a look at the Sort dictionary by value section which is just above this section.

Let's implement sort by key:

let dictionaryToSortByKey = [
    "One" : CGPoint(x: 10, y: 10),
    "Two" : CGPoint(x: 20, y: 10),
    "Three" : CGPoint(x: 30, y: 10),
    "Four" : CGPoint(x: 40, y: 10),
]

let keySortedDictionary = dictionaryToSortByKey.sorted { $0.0 > $1.0 }

The difference with the above sort is that the key does not have any property that we want to sort on, so instead of using x like we did in the previous section, we leave that part out.

In the previous section we would use something like $0.1 to get the value, so to get the key we use $0.0. .1 represents the value property and .0 represents the key property if we named our arguments like we did in the previous section.

Check if array contains elements

Checking if an array contains an element is easy as Array already has a method called contains which will return true or false depending on whether the array contains the element or not.

The following code is the implementation:

let arrayOfElements = [1, 2, 3, 4, 5]
let elementToContain = 2

if arrayOfElements.contains(elementToContain) {
    print("Yes, the array contains this element")
}

Replace characters in String

There are a few ways to do this. Let's start off by replacing a certain character in the entire string. To do that we can use the following code:

let stringToReplaceCharacters = "test string"
let replacedCharacterString = stringToReplaceCharacters.replacingOccurrences(of: "t", with: "+")

The above code will replace the t's in the string, test string, with a plus sign.

The other way that this can be done is to give a range that you want to replace characters within.

let endIndex = stringToReplaceCharacters.index(stringToReplaceCharacters.startIndex, offsetBy: 3)
let range = stringToReplaceCharacters.startIndex...endIndex
let replaceInRange = stringToReplaceCharacters.replacingCharacters(in: range, with: "-")

This will replace the first four characters with -.

Generate a random number

let randomNumber = Int(arc4random_uniform(100))

That is all that is needed to generate a random number. arc4random_uniform takes an argument which will be the upper bound value. The random values that can be return will be between 0 and 99 because it will be 100-1. arc4random_uniform will return a UInt32, so in this example I have just created a new Int with the value that gets returned.

Get nth character in string

I have written tutorial on this which you can find here.

Add observer to notification

NotificationCenter.default.addObserver(self,
                                       selector: #selector(notifcationObserverFunction),
                                       name: NSNotification.Name("myNotificationName"),
                                       object: nil)

To add an observer for a notification we need to use the above code. This will allow you to set the name of the notification and which selector you want to call when the notification gets posted.

@objc
func notifcationObserverFunction(_ notification: Notification) {
    print(notification)
}

I have added this simple function to print out the notification that gets passed to it, and this is the function that gets used as the selector when adding an observer to a notification.

Merge/Concatenate arrays

Merging an array is as simple as this:

let arrayOne = [1, 2, 3, 4]
let arrayTwo = [5, 6, 7, 8]

let mergedArray = arrayOne + arrayTwo

The merged array will now be [1,2,3,4,5,6,7,8].

Close keyboard

If a textfield is currently the first responder and you know which textfield is the first responder then you can do this:

yourTextField.resignFirstResponder()

Or, if you do not know which text field is current the first responder you can use the following:

self.view.endEditing(true)

Get reference to AppDelegate

Getting a reference to app delegate is a simple one liner:

let appDelegate = UIApplication.shared.delegate as? AppDelegate

Round number to x decimal places

Rounding a number to a certain amount of decimal places can be frustrating, and to me the solution is not super clean, but it does work, see the following code:

let doubleValue = 1.011201
let roundedToThreePlaces = (doubleValue * 1000).rounded() / 1000
let roundedToFourPlaces = (doubleValue * 10000).rounded() / 10000
let roundedToTwoPlaces = (doubleValue * 100).rounded() / 100

The above code would print out 1.011, this is because we are multiplying and then dividing by 1000. I you want 4 decimal places then you would need to divide and multiply by 10000, if you want two decimal places then you would need to divide and multiply by 100.

Determine current device model

To get the device model you can use the following:

let deviceModel = UIDevice.current.name

This will return a name like, iPhone Xs.

Add element to array

To add an element to an array we can use the append method like this:

var baseArray = [1, 2, 3, 4, 5]
baseArray.append(6)

This will add 6 to the array which will now look like this [1,2,3,4,5,6].

Create global constants

If I ever need to create global constants I would generally use a Struct like below:

struct Constants {
    static let WELCOME_MESSAGE = "Welcome!"
}

To use it as simple as:

print(Constants.WELCOME_MESSAGE)

If you wanted to, you could also use an Enum, it will work in a similar way to the Struct:

enum ConstantsEnum {
    static let WELCOM_MESSAGE = "Welcome from enum"
}

And to use the above you can do the following:

print(ConstantsEnum.WELCOM_MESSAGE)

Validate email address

Validating an email address is a bit of a pain because we need to use regex. Luckily it is not too tough to use regex with Swift, but I wish it was easier. The following will print if them email is valid or not:

let email = "[email protected]"
let emailFormat = "[A-Z0-9a-z._%+-][email protected][A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let emailPredicate = NSPredicate(format:"SELF MATCHES %@", emailFormat)

if emailPredicate.evaluate(with: email) {
    print("valid")
} else {
    print("invalid")
}

Create attributed string

Creating attributed string can become complicated, but in this example we will simply add a background color to our string:

let stringToBeAttributed = "string to be attributed"
let attributes = [NSAttributedString.Key.backgroundColor: UIColor.green]
let attributedString = NSAttributedString(string: stringToBeAttributed,
                                          attributes: attributes)

Now you can use attributedString where ever you need to use the attributed string.

Difference between == and ===

Using == is to test if two object are equatable, while === is to see if the objects point to the same memory address.

Let's create a simple class that conforms to equatable:

class TestClass: Equatable {
    static func == (lhs: TestClass, rhs: TestClass) -> Bool {
        return lhs.property == rhs.property
    }
    
    let property: String
    
    init(property: String) {
        self.property = property
    }
}

We can now use the following code to see if they are equatable and if the two instances of TestClass are point to the same memory:

let a = TestClass(property: "test string")
let b = TestClass(property: "test string")

// Test if a and b are eqautable
if a == b {
    print("true")
} else {
    print("false")
}

// Test if a and b are pointing to the same memory
if a === b {
    print("true")
} else {
    print("false")
}

Using === is only available when using classes.

Generate UUID

To generate a UUID you can use the following code:

let uuid = UUID()

If you want the UUID as a string, then you can use the uuidString property like this:

let uuidString = uuid.uuidString

Check if user is using iPad

if UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad {
    print("true")
}

Source Code

Full source code can be found here. I have commented out most of the print statements, so if you want to see the results for each section just uncomment those prints.