// Do obsługi są trzy przypadki.
if self.selectedTile == nil { // Brak zaznaczonego fragmentu: zaznacz ten fragment i rozpocznij grę.
    self.select(tile:tile)
    self.play(tile:tile)
} else if self.selectedTile == tile { // Naciśnięcie zaznaczonego fragmentu: usuń zaznaczenie fragmentu.
    self.deselectAll()
    self.player?.pause()
} else { // Był zaznaczony pewien fragment i nastąpiło zaznaczenie innego: zamień je ze sobą.
    self.swap(self.selectedTile, with:tile, check:true, fence:true)
}



let prog = n.userInfo?["progress"] as? Double
if prog != nil {
    self.progress = prog!
}



if let ui = n.userInfo {
    if let prog = ui["progress"] as? Double {
        self.progress = prog
    }
}



switch i {
case 1:
    print("Masz 1 przedmiot!")
case 2:
    print("Masz 2 przedmioty!")
default:
    print("Masz \(i) przedmiotów!")
}



switch i {
case 1: print("Masz 1 przedmiot!")
case 2: print("Masz 2 przedmioty!")
default: print("Masz \(i) przedmiotów!")
}



switch i {
case 1:
    print("Masz 1 przedmiot!")
case _:
    print("Masz wiele przedmiotów!")
}



switch i {
case 1:
    print("Masz 1 przedmiot!")
case let n:
    print("Masz \(n) przedmiotów!")
}



switch i {
case 1:
    print("Masz 1 przedmiot!")
case 2...10:
    print("Masz \(i) przedmiotów!")
default:
    print("Masz więcej przedmiotów, niż jestem w stanie policzyć!")
}



switch i {
case 1?:
    print("Masz 1 przedmiot!")
case let n?:
    print("Masz \(n) przedmiotów!")
case nil: break
}



func position(for bar: UIBarPositioning) -> UIBarPosition {
    switch true {
    case bar === self.navbar:  return .topAttached
    case bar === self.toolbar: return .bottom
    default:                   return .any
    }
}



switch i {
case let j where j < 0:
    print("Wartość i jest ujemnma.")
case let j where j > 0:
    print("Wartość i jest dodatnia.")
case 0:
    print("Wartość i wynosi 0.")
default:break
}



switch i {
case ..<0:
    print("Wartość i jest ujemnma.")
case 1...:
    print("Wartość i jest dodatnia.")
case 0:
    print("Wartość i wynosi 0.")
default:break
}



switch d {
case is NoisyDog:
    print("Masz hałaśliwego psa!")
case _:
    print("Masz psa.")
}



switch d {
case let nd as NoisyDog:
    nd.beQuiet()
case let d:
    d.bark()
}



switch i {
case 0 as Int:
    print("To jest 0.")
default:break
}



switch (d["size"], d["desc"]) {
case let (size as Int, desc as String):
    print("Wielkość wynosi \(size) i to jest \(desc).")
default:break
}



enum Filter {
    case albums
    case playlists
    case podcasts
    case books
}



switch type {
case .albums:
    print("Albumy")
case .playlists:
    print("Listy odtwarzania")
case .podcasts:
    print("Podcasty")
case .books:
    print("Audiobooki")
}



enum MyError {
    case number(Int)
    case message(String)
    case fatal
}



switch err {
case .number(let theNumber):
    print("To jest liczba: \(theNumber).")
case let .message(theMessage):
    print("To jest komunikat: \(theMessage).")
case .fatal:
    print("To jest błąd krytyczny.")
}



switch err {
case let .number(n) where n > 0:
    print("To jest dodatni numer błędu \(n).")
case let .number(n) where n < 0:
    print("To jest ujemny numer błędu \(n).")
case .number(0):
    print("To jest zerowy numer błędu.")
default:break
}



switch err {
case .number(1...):
    print("To jest dodatni numer błędu.")
case .number(..<0):
    print("To jest ujemny numer błędu.")
case .number(0):
    print("To jest zerowy numer błędu.")
default:break
}



switch i {
case .none: break
case .some(1):
    print("Masz 1 przedmiot!")
case .some(let n):
    print("Masz \(n) przedmiotów!")
}



switch i {
case 1,3,5,7,9:
    print("Masz małą i nieparzystą liczbę przedmiotów.")
case 2,4,6,8,10:
    print("Masz małą i parzystą liczbę przedmiotów.")
default:
    print("Masz dla mnie zbyt małą liczbę przedmiotów, abym mógł je policzyć.")
}



switch i {
case is Int, is Double:
    print("To jest liczba pewnego rodzaju.")
default:
    print("Nie wiem, co to może być.")
}



switch err {
case let .number(n) where n > 0, let .number(n) where n < 0:
    print("To jest niezerowy numer błędu \(n).")
case .number(0):
    print("To jest zerowy numer błędu.")
default:break
}



switch pep {
case "Mariusz": fallthrough
case "Mieczysław": fallthrough
case "Jacek":
    print("\(pep) to chłopiec.")
default:
    print("Nie wiem, kim jest \(pep).")
}



let title = switch type { // Błąd w trakcie kompilacji.
case .albums:
    "Albumy"
case .playlists:
    "Listy odtwarzania"
case .podcasts:
    "Podcasty"
case .books:
    "Audiobooki"
}



let title : String = {
    switch type {
    case .albums:
        return "Albumy"
    case .playlists:
        return "Listy odtwarzania"
    case .podcasts:
        return "Podcasty"
    case .books:
        return "Książki"
    }
}()



let arr = ["Mariusz", "Mieczysław", "Jacek"]
let target = // Dowolny ciąg tekstowy.
let pos = arr.firstIndex(of:target)
let s = pos != nil ? String(pos!) : "NIE ZNALEZIONO"



while self.movenda.count > 0 {
    let p = self.movenda.removeLast()
    // …
}



var v : UIView? = textField
repeat {v = v?.superview} while !(v is UITableViewCell || v == nil)
if let c = v as? UITableViewCell {
    // W tym miejscu c przedstawia komórkę.
}



var i = 0
while case let .message(message) = arr[i]  {
    print(message) // "Au!", następnie "Oj!", a później pętla zakończy działanie.
    i += 1
}



var g = (1...5).makeIterator()
while let i = g.next() {
    print(i) // Dane wyjściowe: 1, 2, 3, 4, 5.
}



let p = Pep()
// p.boys() to niestety tablica typu Any. 
for boy in p.boys() as! [String] {
    // …
}



let range = (0...10).reversed().filter{$0 % 2 == 0}
for i in range {
    print(i) // Dane wyjściowe: 10, 8, 6, 4, 2, 0.
}



let seq = sequence(first:1) {$0 >= 10 ? nil : $0 + 1}
for i in seq {
    print(i) // Dane wyjściowe: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
}



let seq = sequence(first:1) {$0 + 1}
for i in seq.prefix(5) {
    print(i) // Dane wyjściowe: 1, 2, 3, 4, 5.
}



let fib = sequence(state:(0,1)) { (pair: inout (Int,Int)) -> Int in
    let n = pair.0 + pair.1
    pair = (pair.1,n)
    return n
}
for i in fib.prefix(10) {
    print(i) // Dane wyjściowe: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89.
}



struct Primes {
    static var primes = [2]
    static func appendNextPrime() {
        next: for i in (primes.last!+1)... {
            let sqrt = Int(Double(i).squareRoot())
            for prime in primes.lazy.prefix(while:{$0 <= sqrt}) {
                if i % prime == 0 {
                    continue next
                }
            }
            primes.append(i)
            return
        }
    }
}



enum MyFirstError : Error {
    case firstMinorMistake
    case firstMajorMistake
    case firstFatalMistake
}
enum MySecondError : Error {
    case secondMinorMistake(i:Int)
    case secondMajorMistake(s:String)
    case secondFatalMistake
}



do {
    // W tym miejscu następuje zgłoszenie błędu.
} catch MyFirstError.firstMinorMistake {
    // Przechwycenie błędu MyFirstError.firstMinorMistake.
} catch let err as MyFirstError {
    // Przechwycenie wszystkich pozostałych błędów MyFirstError.
} catch MySecondError.secondMinorMistake(let i) where i < 0 {
    // Przechwycenie błędu, tj. MySecondError.secondMinorMistake(i:-3).
} catch {
    // Przechwycenie wszystkich pozostałych błędów.
}



do {
    // W tym miejscu następuje zgłoszenie błędu.
} catch MyFirstError.firstMinorMistake {
    // Brak obiektu błędu, choć wiadomo, że jest to MyFirstError.firstMinorMistake.
} catch let err as MyFirstError {
    // Błąd MyFirstError jako err.
} catch MySecondError.secondMinorMistake(let i) where i < 0 {
    // Pojawia się tylko i, ale wiadomo, że jest to MySecondError.secondMinorMistake.
} catch {
    // Pojawiający się obiekt błędu.
}



enum NotLongEnough : Error {
    case iSaidLongIMeantLong
}
func giveMeALongString(_ s:String) throws {
    if s.count < 5 {
        throw NotLongEnough.iSaidLongIMeantLong
    }
    print("Dziękuję za ciąg tekstowy.")
}



func receiveThrower(_ f:(String) throws -> ()) {
    // …
}
func callReceiveThrower() {
    receiveThrower {
        s in // Można użyć "s throws in", choć nie jest to wymagane.
        if s.count < 5 {
            throw NotLongEnough.iSaidLongIMeantLong
        }
        print("Dziękuję za ciąg tekstowy.")
    }
}



func canThrowOrReturnString(shouldThrow:Bool) throws -> String {
    enum Whoops : Error {
        case oops
    }
    if shouldThrow {
        throw Whoops.oops
    }
    return "cześć"
}



do {
    let s = try self.canThrowOrReturnString(shouldThrow: true)
    print(s)
} catch {
    print(error)
}



func receiveThrower(_ f:(String) throws -> ()) rethrows {
    try f("Okej?")
}
func callReceiveThrower() { // Brak konieczności użycia słowa kluczowego throws.
    receiveThrower { s in // Brak konieczności użycia słowa kluczowego try.
        print("Dziękuję za ciąg tekstowy.")
    }
}



if let s = try? self.canThrowOrReturnString(shouldThrow: true) {
    print(s)
} else {
    print("Błąd.")
}



- (instancetype)initWithContentsOfFile:(NSString *)path
                              encoding:(NSStringEncoding)enc
                                 error:(NSError **)error;



NSError* err;
NSString* s =
    [[NSString alloc] initWithContentsOfFile:f
                                    encoding:NSUTF8StringEncoding
                                       error:&err];
if (s == nil) {
    NSLog(@"%@", err);
}



do {
    let f = // Przykładowa ścieżka dostępu do pewnego pliku.
    let s = try String(contentsOfFile: f)
    // Jeżeli operacja zakończyła się sukcesem, można przeprowadzić pewną operację z użyciem s.
} catch CocoaError.fileReadNoSuchFile {
    print("Brak podanego pliku.")
} catch {
    print(error)
}



do {
    var myVar = "howdy"
    // W tym miejscu można używać myVar.
}
// W tym momencie zmienna myVar już nie istnieje, a jej wartość została usunięta.



out: do {
    // …
    if somethingBadHappened {
        break out
    }
    // Nie dotrzesz do tego miejsca, jeśli somethingBadHappened ma wartość true.
}
// Przejście do tego miejsca, jeśli somethingBadHappened ma wartość true.



func doSomethingTimeConsuming() {
    UIApplication.shared.beginIgnoringInteractionEvents()
    // Wykonanie pewnego zadania.
    UIApplication.shared.endIgnoringInteractionEvents()
}



func doSomethingTimeConsuming() {
    UIApplication.shared.beginIgnoringInteractionEvents()
    // Wykonanie pewnego zadania.
    if somethingHappened {
        return
    }
    // Wykonanie kolejnego zadania.
    UIApplication.shared.endIgnoringInteractionEvents()
}



func doSomethingTimeConsuming() {
    defer {
        UIApplication.shared.endIgnoringInteractionEvents()
    }
    UIApplication.shared.beginIgnoringInteractionEvents()
    // Wykonanie pewnego zadania.
    if somethingHappened {
        return
    }
    // Wykonanie kolejnego zadania.
}



@objc func tapField(_ g: Any) {
    // g musi być egzemplarzem rozpoznawania gestów…
    guard let g = g as? UIGestureRecognizer else {return}
    // …który z kolei musi mieć widok.
    guard g.view != nil else {return}
    // W porządku, teraz można kontynuować działanie…
}



@objc func tapField(_ g: Any) {
    // g musi być egzemplarzem rozpoznawania gestów…
    // …który z kolei musi mieć widok.
    guard let g = g as? UIGestureRecognizer, g.view != nil
        else {return}
    // W porządku, teraz można kontynuować działanie…
}



class Dog {
    var name = ""
    private var whatADogSays = "hau"
    func bark() {
        print(self.whatADogSays)
    }
}



class CancelableTimer: NSObject {
    private var q = DispatchQueue(label: "timer")
    private var timer : DispatchSourceTimer!
    private var firsttime = true
    private var once : Bool
    private var handler : () -> ()
    init(once:Bool, handler:@escaping () -> ()) {
        // …
    }
    func start(withInterval interval:Double) {
        // …
    }
    func cancel() {
        // …
    }
}



class Dog {
    private var whatADogSays = "hau"
}
extension Dog {
    func speak() {
        print(self.whatADogSays) // Można użyć takiego wywołania.
    }
}



struct Dog : CustomStringConvertible {
    var name = "Fido"
    var license = 1
    var description : String {
        var desc = "Dog ("
        let mirror = Mirror(reflecting:self)
        for (k,v) in mirror.children {
            desc.append("\(k!): \(v), ")
        }
        return desc.dropLast(2) + ")"
    }
}



struct Dog : CustomReflectable {
    var name = "Fido"
    var license = 1
    var customMirror: Mirror {
        let children : [Mirror.Child] = [
            ("imię", self.name),
            ("licencja na zabijanie", self.license)
        ]
        let m = Mirror(self, children:children)
        return m
    }
}



struct Vial {
    var numberOfBacteria : Int
    init(_ n:Int) {
        self.numberOfBacteria = n
    }
}



extension Vial {
    static func +(lhs:Vial, rhs:Vial) -> Vial {
        let total = lhs.numberOfBacteria + rhs.numberOfBacteria
        return Vial(total)
    }
}



let v1 = Vial(500_000)
let v2 = Vial(400_000)
let v3 = v1 + v2
print(v3.numberOfBacteria) // Dane wyjściowe: 900000.



extension Vial {
    static func +=(lhs:inout Vial, rhs:Vial) {
        let total = lhs.numberOfBacteria + rhs.numberOfBacteria
        lhs.numberOfBacteria = total
    }
}



var v1 = Vial(500_000)
let v2 = Vial(400_000)
v1 += v2
print(v1.numberOfBacteria) // Dane wyjściowe: 900000.



infix operator ^^
extension Int {
    static func ^^(lhs:Int, rhs:Int) -> Int {
        var result = lhs
        for _ in 1..<rhs {result *= lhs}
        return result
    }
}



infix operator ^^
extension Int {
    static func ^^(lhs:Int, rhs:Int) -> Int {
        var result = lhs
        for _ in 1..<rhs {result *= lhs}
        return result
    }
}



struct Vial {
    var numberOfBacteria : Int
    init(_ n:Int) {
        self.numberOfBacteria = n
    }
}
extension Vial : Equatable {
    static func ==(lhs:Vial, rhs:Vial) -> Bool {
        return lhs.numberOfBacteria == rhs.numberOfBacteria
    }
}



let v1 = Vial(500_000)
let v2 = Vial(400_000)
let arr = [v1,v2]
let ix = arr.firstIndex(of:v1) // Typ opcjonalny opakowujący 0.



struct Vial : Equatable {
    var numberOfBacteria : Int
    init(_ n:Int) {
        self.numberOfBacteria = n
    }
}



enum MyError : Equatable {
    case number(Int)
    case message(String)
    case fatal
}
let err1 = MyError.number(1)
let err2 = MyError.number(1)
if err1 == err2 {
    // Te obiekty są takie same.
}



struct Dog : Equatable {
    let name : String
    let license : Int
    let color : UIColor
    static func ==(lhs:Dog,rhs:Dog) -> Bool {
        return lhs.name == rhs.name && lhs.license == rhs.license
    }
}



struct Dog : Hashable { // To oznacza również zgodność z protokołem Equatable.
    let name : String
    let license : Int
    let color : UIColor
    static func ==(lhs:Dog,rhs:Dog) -> Bool {
        return lhs.name == rhs.name && lhs.license == rhs.license
    }
    func hash(into hasher: inout Hasher) {
        name.hash(into:&hasher)
        license.hash(into:&hasher)
    }
}



var getFirstName : Bool = // …
let name : String = {
    if getFirstName {
        return p.firstName
    } else {
        return p.lastName
    }
}()



let c1 = v2.topAnchor.constraint(equalTo:v1.topAnchor)
c1.isActive = true
let c2 = v2.bottomAnchor.constraint(equalTo:v1.bottomAnchor)
c2.isActive = true



for anch in [\UIView.topAnchor, \UIView.bottomAnchor] {
    let c = v2[keyPath:anch].constraint(equalTo:v1[keyPath:anch])
    c.isActive = true
}



@dynamicMemberLookup
struct Flock {
    var d = [String:String]()
    subscript(dynamicMember s:String) -> String? {
        get {
            return d[s]
        }
        set {
            d[s] = newValue
        }
    }
}



var flock = Flock()
flock.chicken = "kura"
flock.partridge = "kuropatwa"
if let s = flock.partridge {
    print(s) // Dane wyjściowe: kuropatwa.
}



func testRetainCycle() {
    class Dog {
        deinit {
            print("Pożegnanie z egzemplarzem typu Dog.")
        }
    }
    class Cat {
        deinit {
            print("Pożegnanie z egzemplarzem typu Cat.")
        }
    }
    let d = Dog()
    let c = Cat()
}
testRetainCycle() // Dane wyjściowe: Pożegnanie z egzemplarzem typu Cat i Pożegnanie z egzemplarzem typu Dog.



func testRetainCycle() {
    class Dog {
        var cat : Cat?
        deinit {
            print("Pożegnanie z egzemplarzem typu Dog.")
        }
    }
    class Cat {
        var dog : Dog?
        deinit {
            print("Pożegnanie z egzemplarzem typu Cat.")
        }
    }
    let d = Dog()
    let c = Cat()
    d.cat = c // Utworzenie…
    c.dog = d // …cyklu przytrzymania. 
}
testRetainCycle() // Brak danych wyjściowych w konsoli.



func testRetainCycle() {
    class Dog {
        weak var cat : Cat?
        deinit {
            print("Pożegnanie z egzemplarzem typu Dog.")
        }
    }
    class Cat {
        weak var dog : Dog?
        deinit {
            print("Pożegnanie z egzemplarzem typu Cat.")
        }
    }
    let d = Dog()
    let c = Cat()
    d.cat = c
    c.dog = d
}
testRetainCycle() // Pożegnanie z egzemplarzem typu Cat., Pożegnanie z egzemplarzem typu Dog.



func testUnowned() {
    class Boy {
        var dog : Dog?
        deinit {
            print("Pożegnanie z egzemplarzem typu Boy.")
        }
    }
    class Dog {
        let boy : Boy
        init(boy:Boy) { self.boy = boy }
        deinit {
            print("Pożegnanie z egzemplarzem typu Dog.")
        }
    }
    let b = Boy()
    let d = Dog(boy: b)
    b.dog = d
}
testUnowned() // Brak danych wyjściowych w konsoli.



func testUnowned() {
    class Boy {
        var dog : Dog?
        deinit {
            print("Pożegnanie z egzemplarzem typu Boy.")
        }
    }
    class Dog {
        unowned let boy : Boy // *
        init(boy:Boy) { self.boy = boy }
        deinit {
            print("Pożegnanie z egzemplarzem typu Dog.")
        }
    }
    let b = Boy()
    let d = Dog(boy: b)
    b.dog = d
}
testUnowned() // Dane wyjściowe: Pożegnanie z egzemplarzem typu Boy. i Pożegnanie z egzemplarzem typu Dog.



var b = Optional(Boy())
let d = Dog(boy: b!)
b = nil // Usunięcie egzemplarza Boy "za plecami" obiektu Dog.
print(d.boy) // Awaria aplikacji.



class FunctionHolder {
    var function : (() -> ())?
    deinit {
        print("Pożegnanie z egzemplarzem typu FunctionHolder.")
    }
}
func testFunctionHolder() {
    let fh = FunctionHolder()
    fh.function = {
        print(fh)
    }
}
testFunctionHolder() // Brak danych wyjściowych w konsoli.



class FunctionHolder {
    var function : (() -> ())?
    deinit {
        print("Pożegnanie z egzemplarzem typu FunctionHolder.")
    }
}
func testFunctionHolder() {
    let fh = FunctionHolder()
    fh.function = {
        [weak fh] in // *
        print(fh)
    }
}
testFunctionHolder() // Dane wyjściowe: Pożegnanie z egzemplarzem typu FunctionHolder.



class FunctionHolder {
    var function : (() -> ())?
    deinit {
        print("Pożegnanie z egzemplarzem typu FunctionHolder.")
    }
}
func testFunctionHolder() {
    let fh = FunctionHolder()
    fh.function = {   // Wykorzystanie odwołań słabego i silnego.
        [weak fh] in  // Odwołanie słabe.
        guard let fh = fh else { return }
        print(fh)     // Odwołanie silne.
    }
}
testFunctionHolder() // Dane wyjściowe: Pożegnanie z egzemplarzem typu FunctionHolder.



class SecondViewController : UIViewController {
    weak var delegate : SecondViewControllerDelegate?
    // …
}



let c = UIColor.purple
var components = Array(repeating: CGFloat(0), count: 4)
c.getRed(&components[0], green: &components[1],
    blue: &components[2], alpha: &components[3]) // Błąd w trakcie kompilacji.



extension UIColor {
    func getRedGreenBlueAlpha() -> [CGFloat] {
        var (r,g,b,a) = (CGFloat(0),CGFloat(0),CGFloat(0),CGFloat(0))
        self.getRed(&r, green: &g, blue: &b, alpha: &a)
        return [r,g,b,a]
    }
}



