Each iOS app is composed of at least the following parts:
Source: Apple
State | Description |
---|---|
Not running | The application has not been launched or was running but was terminated by the system |
Inactive | The application is running in the foreground but is currently not receiving events |
Active | The application is running in the foreground and is receiving events. |
Background | The application is in the background and executing code (only iOS > v.4) |
Suspended | The application is in the background but is not executing code (only iOS > v.4) |
Source: Apple
var str = "Hello World"
print(str)
var myvariable = 0
var myvariable : Int = 0
var name = "Name" // Type is inferred as String
var age = 38 // Type is inferred as Int
var weight = 90.5 // Type is inferred as Double
var myvariable : Int // Type annotation defining type Int
var myName : String = "Ansgar"
let myconstant = 10
var myvariable = 0, yourvar = 1, anothervar = 3
var rabbit : String? //declares optional String
... //rabbit = "running"
if(rabbit != nil){
print("Rabbit is \(rabbit!)") //unwraps Optional
}
else {
print("Rabbit is nil")
}
enum GraphicalObjects {
case Circle
case Rectangle
case Polygon
}
var go = GraphicalObjects.Circle
if go == GraphicalObjects.Circle {
print("is a Circle")
}
else if go == .Rectangle {
print("is a Rectangle")
}
else {
print("is a Polygon")
}
var smallInt : UInt8 = 5
var largertInt : Int16 = 10
var evenLargerInt : Int32 = 100
var biggestInt : UInt64 = 1000
UInt8.min //0
UInt8.max //255
Int16.min // -32768
Int16.max // 32768
var mySmallFloat : Float = 2.34352
var myBigFloat : Double = 3.42323
let pi = 3 + 0.14159
let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1
let hdmIsGreat = true
let swiftIsBoring = false
let i = 1
if i {
//will not compile and report an error
}
let i = 1
if i==1 {
//this works
}
A Range or CountableRange (since Swift 3.0) is a type in Swift that defines a number of elements that can be iterated over, e.g. a number of integer values or String.Index values
The Range can be created using the range operator:
ClosedRange operator: ...
Range operator: ..<
let myFromZeroTo5Range = 0...5 //CountableClosedRange(0...5)
let myFromZeroToSmallerSixRange = 0..<6 //CountableRange(0..<6))
Since Swift 3.0 ClosedRange (...
) and Range (..<
) are two different types which can not be converted into each other.
Swift Strings and Characters are value types, Unicode compliant and easy to use
let emptyImmutableString = ""
var emptyMutableString = ""
var emptyString = String()
let sparklingHeart = "\u{1F496}"
String values can be constructed by passing an array of Characters
let catCharacters: [Character] = ["C", "a", "t", "!", "🐱"]
let catString = String(catCharacters)
Concatenation of Strings and Characters is simple
let string1 = "Hello "
let string2 = "HdM"
let char1: Character = "!"
var concatenatedString = string1 + string2 //"Hello HdM"
concatenatedString.append(char1) // "Hello HdM!"
String interpolation allows to create a new String from multiple variables or literals
let multiplier = 3
let message = "\(multiplier) times 2 is \(multiplier*2)"
//„3 times 2 is 6“
Expressions in the parentheses cannot contain double quotes, backslashes, a carriage return or line feed You can call functions within the parentheses
func getHint() -> String {
return "special hint"
}
let newmessage = "New hint: \(getHint())" //„New hint: special hint“
The property „characters“ allows you to iterate over all characters in a String
for letter in string.characters {
print("\(letter)")
}
Use count() to count Chars
string.characters.count // 19
Use can create a range to access Characters of a part of a String
let range = string.index(string.startIndex, offsetBy: 5)..<string.index(before: string.endIndex)
for mindex in string.characters.indices[range] {
print("\(string[mindex])",terminator: "")
}
To modify strings, you can use insert(), remove() and removeSubrange()
var myString = "Hello HdM"
var idx = myString.index(myString.endIndex, offsetBy: -2) //7
myString.remove(at: idx) // „Hello HM“
let r = myString.index(myString.startIndex, offsetBy: 5)..<myString.endIndex
myString.removeSubrange(r) // „Hello“
myString.insert("!", at: myString.endIndex) //"Hello HM!"
String and Character equality is checked using the „equal to“ operator (==) Strings are equal if they have the same linguistic meaning and appearance, even if they are composed from different Unicode scalars
let eAcuteQuestion = "Voulez-vous un caf\u{E9}?"
let combinedEAcuteQuestion = "Voulez-vous un caf\u{65}\u{301}?"
if eAcuteQuestion == combinedEAcuteQuestion {
print("\(eAcuteQuestion) and \(combinedEAcuteQuestion) are considered equal")
}
// "Voulez-vous un café? and Voulez-vous un café? are considered equal"
You can check the prefix or suffix of a String using hasPrefix() and hasSuffix()
let stringArray = ["1st String of 2","2nd String of 2"]
for string in stringArray {
if string.hasPrefix("1st"){
print("String starting with 1st: \(string)")
}
if string.hasSuffix("2") {
print("String ending with 2: \(string)")
}
}
Arrays are next to sets and dictionaries the mostly used collections in swift To create a mutable array, assign it to a variable (e.g. var myArray)
var shoppingList = [String]()
Initialize directly by writing:
var shoppingList = ["Apples","Pears","Bread","Milk"]
Appending items to an Array
shoppingList.append("Soap")
//or
shoppingList += ["Juice"]
Adding Arrays and creating new ones
var familyList = shoppingList + ["Cornflakes","Ice Cream"]
Removing items from an Array
shoppingList.remove(at: 2)
shoppingList.removeLast()
shoppingList.removeAll(keepingCapacity: true)
Check if an Array is empty
if shoppingList.isEmpty {
...
}
Retrieve a certain item or a part of the Array
shoppingList[5] //-> "Cornflakes"
shoppingList[1...3] //["Pears", "Bread", "Milk"]
Tuples group multiple values into a single compound value
let httpStatus = (404, "Not Found")
Each single value is accessible by a number, e.g.:
httpStatus.0 // 404
httpStatus.1 // "Not Found"
Tuples can be decomposed into their separate values
let (statusCode, description) = httpStatus
print("Statuscode: \(statusCode) means: \(description)")
You can name the elements in a tuple and access them using the names
let newHttpStatus = (code: 200, description: "OK")
print("code: \(newHttpStatus.code)")
print("description: \(newHttpStatus.description)")
Iterating over an Array
var familyList = ["Milk", "Bread","Soap","Juice"]
for item in familyList {
print(item)
}
Iterating with index and value
for (index,value) in familyList.enumerated() {
print("item nbr. \(index + 1) is: \(value)")
}
Since Swift 3.0 for-loops look like this:
for index in 0 ..< 3 {
print("index is \(index)")
}
C-style loops are not supported anymore
Use the while loop to iterate while a condition is true
var shoppingList = ["Apples","Pears","Bread","Milk"]
while !shoppingList.isEmpty {
print("remove one item from list")
shoppingList.removeLast()
}
Use do-while to test the condition after executing the statements
shoppingList = ["Apples","Pears","Bread","Milk"]
repeat {
shoppingList.removeLast()
} while !shoppingList.isEmpty
Test a condition using if The else-if and final else clause is optional
var temperatureInFahrenheit = 90
if temperatureInFahrenheit <= 32 {
print("It's very cold. Consider wearing a scarf.")
} else if temperatureInFahrenheit >= 86 {
print("It's really warm. Don't forget to wear sunscreen.")
} else {
print("It's not that cold. Wear a t-shirt.")
}
// prints "It's really warm. Don't forget to wear sunscreen."
let someCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
print("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
print("\(someCharacter) is a consonant")
default:
print("\(someCharacter) is not a vowel or a consonant")
}
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
print("(\(x), \(y)) is just some arbitrary point")
}
// prints "(1, -1) is on the line x == -y"
func greet(name: String, day: String) -> String {
return "Hello \(name), today is \(day)."
}
greet(name: "Bob", day: "Tuesday")
func greet(name: String, day d: String) -> String {
return "Hello \(name), today is \(d)."
}
greet(name: “Bob", day: "Tuesday")
It is possible to return multiple values from a function using Tuples
func getGasPrices() -> (Double, Double, Double) {
return (3.59, 3.69, 3.79)
}
getGasPrices()
Functions can take a variable number of arguments
func sumOf(numbers: Int...) -> Int {
var sum = 0
for number in numbers {
sum += number
}
return sum
}
sumOf()
sumOf(numbers: 42, 597, 12)
func returnFifteen() -> Int {
var y = 10
func add() {
y += 5
}
add()
return y
}
returnFifteen()
func makeIncrementer() -> ((Int) -> Int) {
func addOne(number: Int) -> Int {
return 1 + number
}
return addOne
}
var increment = makeIncrementer()
increment(7)
func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
for item in list {
if condition(item) {
return true
}
}
return false
}
func lessThanTen(number: Int) -> Bool {
return number < 10
}
var numbers = [20, 19, 7, 12]
hasAnyMatches(list: numbers,condition: lessThanTen)
var numbers = [20, 19, 7, 12]
numbers.map({
(number: Int) -> Int in
let result = 3 * number
return result
})
class Shape {
var numberOfSides = 0
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
class Shape {
var numberOfSides = 0
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
let myShape = Shape()
myShape.numberOfSides = 10
myShape.simpleDescription()
class NamedShape {
var numberOfSides: Int = 0
var name: String
init(name: String) {
self.name = name
}
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
let s = NamedShape(name: "MyShape")
let age = -3
assert(age >= 0, "A person's age cannot be less than zero")
// this causes the assertion to trigger, because age is not >= 0
class FatherChristmas {
enum DeliveryError : Error {
case NoPresentsRemaining
}
var numberOfPresents = 0
func deliverPresents() throws {
guard numberOfPresents > 0 else {
throw DeliveryError.NoPresentsRemaining
}
print("Presents delivered")
}
func itIsChristmasEve(){
do {
try deliverPresents()
} catch DeliveryError.NoPresentsRemaining{
print("Could not deliver presents!")
} catch {
print("Unknown error")
}
}
}
let fatherChristmas = FatherChristmas()
fatherChristmas.itIsChristmasEve()
//this protocol defines the "description" method used by many classes
extension CustomStringConvertible {
var shoutyDescription: String {
return "\(self.description.uppercased())!!!"
}
}
let greetings = ["Hello", "Hi", "Yo yo yo"]
print("\(greetings.description)")
// prints "["HELLO", "HI", "YO YO YO“]!!!\n"
print("\(greetings.shoutyDescription)")
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
import UIKit // UIViewController is part of the UIKit Framework
class ViewController: UIViewController {
@IBOutlet weak var myLabel: UILabel!
override func viewDidLoad() { // called when the view becomes visible
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() { // called when the system is running low on memory
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func buttonTouched(sender: UIButton) { // custom action method
myLabel.text = "Hello Swift"
}
}
override func touchesBegan(_: Set<UITouch>, with: UIEvent?){
print("touches began")
}
override func touchesEnded(_: Set<UITouch>, with: UIEvent?){
print("touches ended")
}
override func touchesMoved(_: Set<UITouch>, with: UIEvent?){
print("touches moved")
}
override func touchesCancelled(_: Set<UITouch>, with: UIEvent?){
print("touches cancelled")
}
@IBAction func returnPressed(sender: AnyObject) {
myTextField.resignFirstResponder()
}
protocol SomeProtocol {
// protocol definition goes here
}
class SomeClass: SomeSuperClass, FirstProtocol, SomeProtocol {
// class definition goes here
}
protocol SomeProtocol {
// a settable Property must be implemented using
// var in the implementing class
var mustBeSettable: Int { get set }
// a only gettable Property should be implented using let
var doesNotNeedToBeSettable: Int { get }
}
protocol RandomNumberGenerator {
func random() -> Double
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Selected row \(indexPath.item)")
}
// Override to define the number of sections for the table
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
// Override to define the number of rows in each section
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return shoppingList.count
}
// Override to define the cell for a given row
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
// Configure the cell...
cell.textLabel?.text = shoppingList[indexPath.item]
return cell
}