# Swift Language
###### tags: `Swift` `iOS`
[TOC]
## Swift Annotation
It is still prefer to use the double slash, no matter what language you are using.
```swift
//Single Line Annotation
/*Multiple Line
Annotation*/
```
## print
print in java is Log.d, the difference between it is that when adding variables, it is divided by commas.
**Note:** If you need to add int in print, it is divided by comma, otherwise you can add string by using +.
```swift=
let num1 : Int = 50
let num2 : Int = 25
var sum : Int = num1 + num2
print("The sum of", num1, "and", num2, "is", (num1 + num2))
print("The sum of", num1, "and", num2, "is " + String(sum))
print("The sum of \(num1) and \(num2) is \(sum)")
//Hello, World!
//The sum of 50 and 25 is 75
///Program ended with exit code: 0
```
As for String you can still use **\\(var/let)** to display in print.
```swift=
let name : String = "Claudia"
var age : Int = 18
print("My name is \(name) and my age is \(age)")
```
## let vs var
**let** is a constant, once it declared and cannot be changed afterwards. **var** instead can be reassigned as many times as you like.

# Structures
## Dictionary
Dictionary is similar to Java's Hashmap.
>**Note:** If you get the values or keys, it might not be in the order you placed in.[color=red]
```swift=
//Dictionary
var studentDic = [Int:String]()
studentDic[1] = "Claudia"
studentDic[2] = "Diego"
print(studentDic) //[1: "Claudia", 2: "Diego"]
print(studentDic[1]) //Optional("Claudia") > means it might be nil
print(studentDic[1]!) //Claudia > because using ! means you are telling it is not nil
print(studentDic.values) //["Diego", "Claudia"]
print(studentDic.keys) //[2, 1]
print(studentDic.capacity) //3
print(studentDic.count) // 2
```
## Array
```swift=
//Array
var studentArr = [String]()
studentArr.append("Claudia")
studentArr.append("Diego")
print(studentArr) //["Claudia", "Diego"]
```
### Sorted/Inversed Array
```swift=
//Sorted Array
var messedArray : Array<Int> = [5,2,3,1,7]
let sortedArr : Array<Int> = messedArray.sorted()
print(sortedArr)
//Inversed Array
let inversedArr : Array<Int> = messedArray.sorted(by: {n1, n2 in return n1 > n2})
print(inversedArr)
```
### map method
```swift=
//map method
var numArr = [1,2,3,4,5]
print(numArr)
//[1, 2, 3, 4, 5]
let numArrPlusTen = numArr.map{
(number:Int) -> Int in
return number + 10
}
print(numArrPlusTen)
//[11, 12, 13, 14, 15]
let stringArr = numArr.map{
(number:Int) -> String in
return "My number is \(number)"
}
print(stringArr)
//["My number is 1", "My number is 2", "My number is 3", "My number is 4", "My number is 5"]
```
# Conditionals
## Switch
You can give a value or even a condition. No need for **break** in each case.
```swift=
//Switch
let mark = 99
switch(mark){
case 100:
print("Full Score! Congrats")
case _ where mark >= 80:
print("Pass with merit!")
case let score where mark >= 60:
print("PASS \(score)")
default:
print("DROP \(mark)")
}
```
## if && for in
```swift=
//Conditionals
//if && for ...in
let scores = [90, 50, 60, 21, 59, 80, 70]
var passCount : Int = 0
var dropCount : Int = 0
for score in scores{
if(score >= 60){
passCount+=1
} else {
dropCount+=1
}
}
print("Students Passed: \(passCount), Drop: \(dropCount)")
```
## Repeat...While VS While
**Repeat...While** will at least run once and then check condition.
**While** will check condition from the very first time.
```swift=
//Repeat.. While
var bit = 100
repeat {
bit *= 2
print("bit \(bit)")
} while (bit < 100)
//prints 200
//While
while (bit < 100){
bit *= 2
print("bit \(bit)")
}
//No Prints
```
# Optional
## Optional Value
```swift=
//Optional Value
var nameDisplay : String? = nil
if let name = nameDisplay{
print("Hello \(name)")
}
print("Hello \(nameDisplay ?? "No Name")")
//No Print
//Hello No Name
nameDisplay = "Claudia"
if let name = nameDisplay{
print("Hello \(name)")
}
print("Hello \(nameDisplay ?? "No Name")")
//Hello Claudia
//Hello Claudia
```
```swift=
var x : Int?
let strings = ["ABC", "123"]
//Random 0 || 1
let randomIndex = arc4random_uniform(2)
let string = strings[Int(randomIndex)]
//If string is ABC, it will not be able to convert to int, therefore nil will be placed
x = Int(string)
if let intValue = x {
print(intValue * 2)
} else {
print("Can't Convert!")
}
```
## Optional Chaining
```swift=
//Optional Chaining
var optionalName : String?
if let size = optionalName?.count{
print("Name has \(size) characters")
} else {
print("No name!")
}
//No name!
optionalName = "Claudia"
if let size = optionalName?.count{
print("Name has \(size) characters")
} else {
print("No name!")
}
//Name has 7 characters
```
# Functions
## Basic Function
```swift=
//Function
func greetHi(){
print("Hi")
}
greetHi()
```
## Function with Return Variable
```swift=
//Function Return Variable
func greetHiString() -> String {
return "Hi!"
}
print(greetHiString())
```
## Function Parameter and Return Variable
```swift=
//Function Parameter and Return Variable
func greetHiString(name : String) -> String {
return "Hi \(name)!"
}
print(greetHiString(name : "Lily"))
```
## Function 2 Parameter and Return Variable
```swift=
//Function 2 Parameter and Return Variable
func greetHiString(greeting : String, name : String) -> String {
return "\(greeting) \(name)!"
}
print(greetHiString(greeting : "Morning", name : "Lily"))
```
## Function 1 parameter, many return Values
```swift=
//Function 1 parameter, many return Values
func generateNums(num : UInt32) -> (var1 : UInt32, var2 : UInt32, var3 : UInt32){
return(
arc4random_uniform(num)
, arc4random_uniform(num)
, arc4random_uniform(num)
)
}
print(generateNums(num: 10))
//(var1: 5, var2: 4, var3: 6)
```
## Function unknown amount of paraments, 1 return variable
**Sum Example**
```swift=
//Function unknown amount of paraments, 1 return variable
func sumOf(numbers : Int...) -> Int {
var num = 0
for number in numbers{
num += number
}
return num
}
print(sumOf(numbers: 1, 3)) //4
print(sumOf(numbers: 2, 4, 8)) //14
```
**Avg Example**
```swift=
func avgOf(numbers : Int...) -> Float {
var num = 0
for number in numbers{
num += number
}
if(numbers.count == 0){
return 0
} else {
return Float(num)/Float(numbers.count)
}
}
print(avgOf(numbers: 1, 2, 3, 4))
```
## Skip Parameters
After adding _ before parameter, you can skip note in constructor when making an instance.
```Swift=
class Square : Shape {
var sideLength : Double = 0
init(_ length : Double){
sideLength = length
super.init(name: "Square", side: 4)
}
func getArea() -> Double {
return sideLength * sideLength
}
override func describe() -> String {
return super.describe() + ", Area: \(getArea())"
}
}
var square : Shape = Square(4.0)
//instead of var square : Shape = Square(length : 4.0)
```
## Check Parameters Quick Key
OPTION + ESC

# Object and Class
```swift=
// Object and Class
var numerator : Int = 1
var denominator : Int = 3
print("The fraction is \(numerator)/\(denominator)")
class Fraction {
var numerator : Int
var denominator : Int
init(num1 : Int, num2 : Int){
numerator = num1
denominator = num2
}
func printFunc(){
print("The fraction is \(numerator)/\(denominator)")
}
}
var myFraction = Fraction(num1: 2, num2: 3)
myFraction.printFunc()
```