Mera Dev Fest - Swift vs. Obj-C

Post on 02-Dec-2014

361 views 1 download

description

Презентация с конференции Mera Dev Fest

Transcript of Mera Dev Fest - Swift vs. Obj-C

Swiftвторое рождение

Objective-C?

Сергей Пронин Empatika НИУ-ВШЭ

Сергей Пронин

Full-stack Developer Empatika

Senior Developer, Co-Founder App in the Air

ПреподавательНИУ-ВШЭ Департамент Программной Инженерии

WWDC 2014

Первые мысли

• WAT?

• У меня были планы на лето

• Пора качать Xcode Beta

• Первый Playground

Apple Good to great

Почему Swift сменит Objective-C

Новый hardware

Watch

WatchKit

Почему Swift?

Почему Swift?• Возможность вернуть несколько значений из метода

Почему Swift?• Возможность вернуть несколько значений из метода

• Optionals

Почему Swift?• Возможность вернуть несколько значений из метода

• Optionals

• Защита от ошибок

Почему Swift?• Возможность вернуть несколько значений из метода

• Optionals

• Защита от ошибок

• Playgrounds

Почему Swift?• Возможность вернуть несколько значений из метода

• Optionals

• Защита от ошибок

• Playgrounds

• Полнофункциональные Enum

Почему Swift?• Возможность вернуть несколько значений из метода

• Optionals

• Защита от ошибок

• Playgrounds

• Полнофункциональные Enum

• “Сладкий” синтаксис

Защита от глупостей

let lang = "swift"

let lang = "swift"switch (lang) {

let lang = "swift"switch (lang) { case "swift":

let lang = "swift"switch (lang) { case "swift": println("young")

let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"):

let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?")

let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css":

let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web")

let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default:

let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default: println("java, is it you?")

let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default: println("java, is it you?")}

let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default: println("java, is it you?")}

let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default: println("java, is it you?")}

//<break> чтобы прервать

let lang = "swift"switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default: println("java, is it you?")}

//<break> чтобы прервать//<fallthrough> чтобы “провалиться”

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt {

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

NSArray *langsArr = dict[@"langs"];

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

NSArray *langsArr = dict[@"langs"];NSString *langs = nil;

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) {

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];}

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];}if (langs) {

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];}if (langs) { //…

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];}if (langs) { //…}

var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")

if let langs = langsOpt { println("langs=\(langs)")}

NSArray *langsArr = dict[@"langs"];NSString *langs = nil;if ([langs isKindOfClass:[NSArray class]]) { langs = [langsArr componentsSeparatedByString:@", "];}if (langs) { //…}

Инструменты языка• Отсутствие try-catch конструкций

• Все методы в протоколах - обязательные

• Наличие ключевого слова required

• Модификаторы доступа

• Обязательная инициализация динамических переменных в конструкторе

“Сладкий” синтаксис

enum Status: Int {

enum Status: Int { case Undetermined, Success, Failure

enum Status: Int { case Undetermined, Success, Failure}

enum Status: Int { case Undetermined, Success, Failure}

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status {

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()switch result {

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()switch result { case .Success:

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()switch result { case .Success: println("success")

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()switch result { case .Success: println("success") case .Failure:

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure")

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure") case .Undetermined:

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure") case .Undetermined: println("n/a")

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure") case .Undetermined: println("n/a")}

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure") case .Undetermined: println("n/a")}result = Status.fromRaw(1)! //Success

enum Status: Int { case Undetermined, Success, Failure}

func sendRequest() -> Status { //networking magic return Status.Success}

var result = sendRequest()switch result { case .Success: println("success") case .Failure: println("failure") case .Undetermined: println("n/a")}result = Status.fromRaw(1)! //Successresult.toRaw() //1

func isEven(n: Int) -> Bool {

func isEven(n: Int) -> Bool { return n % 2 == 0

func isEven(n: Int) -> Bool { return n % 2 == 0}

func isEven(n: Int) -> Bool { return n % 2 == 0}

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool)

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] {

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = []

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a {

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) {

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n)

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) }

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) } }

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) } } return result

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) } } return result}

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) } } return result}

func isEven(n: Int) -> Bool { return n % 2 == 0}

func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a { if check(n) { result.append(n) } } return result}

filter(0...10, isEven)

filter(0..<10, { (item: Int) -> Bool in

filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0

filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})

filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})

filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})

filter(0...100, { item in item % 10 == 0 })

filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})

filter(0...100, { item in item % 10 == 0 })

filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})

filter(0...100, { item in item % 10 == 0 })

filter(0...100, { $0 % 10 == 0 })

filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})

filter(0...100, { item in item % 10 == 0 })

filter(0...100, { $0 % 10 == 0 })

filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0})

filter(0...100, { item in item % 10 == 0 })

filter(0...100, { $0 % 10 == 0 })

filter(0...100) { $0 % 10 == 0 }

var globalLazy: String = {

var globalLazy: String = { return "Hello, lazy boy"

var globalLazy: String = { return "Hello, lazy boy"}()

var globalLazy: String = { return "Hello, lazy boy"}()

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample {

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? {

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet {

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone }

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet {

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)")

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") }

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults()

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults() var prop: String? {

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get {

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String }

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set {

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set { defaults.setObject(newValue, forKey: “myDef”)

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set { defaults.setObject(newValue, forKey: “myDef”) defaults.syncrhonize()

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set { defaults.setObject(newValue, forKey: “myDef”) defaults.syncrhonize() }

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set { defaults.setObject(newValue, forKey: “myDef”) defaults.syncrhonize() } }

var globalLazy: String = { return "Hello, lazy boy"}()

class Sample { lazy var x: Int = CallMethod()

var propDidWill: String? { didSet { //tell everyone } willSet { println("gonna set \(newValue)") } }

let defaults = NSUserDefaults.standardUserDefaults() var prop: String? { get { return defaults.objectForKey("myDef") as? String } set { defaults.setObject(newValue, forKey: “myDef”) defaults.syncrhonize() } }}

func + (left: Vector2D, right: Vector2D) -> Vector2D {

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) {

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}

infix operator ** {}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}

infix operator ** {}func ** (left: Double, right: Double) -> Double {

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}

infix operator ** {}func ** (left: Double, right: Double) -> Double { return pow(left, right)

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}

infix operator ** {}func ** (left: Double, right: Double) -> Double { return pow(left, right)}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}

infix operator ** {}func ** (left: Double, right: Double) -> Double { return pow(left, right)}

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}

infix operator ** {}func ** (left: Double, right: Double) -> Double { return pow(left, right)}

5 ** 2 // 25.0

func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)}

func += (inout left: Vector2D, right: Vector2D) { left = left + right}

let vector = Vector2D(x: 1.0, y: 2.0) + Vector2D(x: 0.5, y: -1.0) // {x: 1.5, y: 1.0}

vector += Vector2D(x: 1.0, y: 2.0) // {x: 2.5, y: 3.0}

infix operator ** {}func ** (left: Double, right: Double) -> Double { return pow(left, right)}

5 ** 2 // 25.013 ** 2 // 169.0

Перечисления Enum

“Ассоциированные” значения

• Каждый объект перечисления может содержать объект другого типа в качестве соответствия

• В таком случае их типы могут быть разными

• Позволяет “ассоциировать” любую информацию

enum Barcode { case UPCA(Int, Int, Int) case PDF417(String) }

var productBarcode = Barcode.UPCA(1, 2, 3) productBarcode = .PDF417("ABCD")

Ассоциированные значения доступны в switch-case конструкции

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check):

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code):

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}

// Syntax sugar

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}

// Syntax sugarswitch productBarcode {

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}

// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check):

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}

// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}

// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")case let .PDF417(code):

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}

// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")case let .PDF417(code): println("PDF417 with value of \(code).")

Ассоциированные значения доступны в switch-case конструкции

switch productBarcode {case .UPCA(let system, let ident, let check): println("UPCA with value of \(system), \(ident), \(check).")case .PDF417(let code): println("PDF417 with value of \(code).")}

// Syntax sugarswitch productBarcode {case let .UPCA(system, ident, check): println("UPCA with value of \(system), \(ident), \(check).")case let .PDF417(code): println("PDF417 with value of \(code).")}

“Замещающие” значения

• Каждый объект перечисления может быть сопоставлен с объектом другого типа

• “Замещающие” значения не меняются (в отличие от “ассоциированных”

• Допустимые типы: Character, String, Double, Float, Int*

// для Int работает auto-increment enum Number: Int { case One = 1, Two, Three, Four, Five, Six, Seven, Eight, FortyTwo = 42 }

enum APIMethod: String { case GET = "GET" case POST = "POST" case DELETE = "DELETE" case PUT = "PUT" case HEAD = "HEAD" } func request(method: APIMethod) { var req = NSMutableURLRequest() req.HTTPMethod = method.toRaw() //... }

Скорость?

Objective-C + Swift

Готовимся

typedef enum { StatusSuccess, StatusFailure } Status

typedef NS_ENUM(NSInteger, Status) { StatusSuccess, StatusFailure };

+ (id)sharedInstance { //your singleton magic }

+ (instancetype)sharedInstance { //singleton magic }

- (instancetype)init { //initial magic }

• В существующей Objective-C codebase -> New File - Cocoa Touch Class -> Swift ->Configure Header

• В существующей Objective-C codebase -> New File - Cocoa Touch Class -> Swift ->Configure Header

• В созданный Bridging Header импортируем все, что Swift должен видеть из Obj-C#import “MyAFAPIClient.h”

• В существующей Objective-C codebase -> New File - Cocoa Touch Class -> Swift ->Configure Header

• В созданный Bridging Header импортируем все, что Swift должен видеть из Obj-C#import “MyAFAPIClient.h”

• Чтобы Obj-C видел из Swift импортируем#import “ProductModuleName-Swift.h”

• В существующей Objective-C codebase -> New File - Cocoa Touch Class -> Swift ->Configure Header

• В созданный Bridging Header импортируем все, что Swift должен видеть из Obj-C#import “MyAFAPIClient.h”

• Чтобы Obj-C видел из Swift импортируем#import “ProductModuleName-Swift.h”

• Открыть Swift-классы и протоколы через @objc@objc(Venue)class Venue {…}

Конвенции//Person.h @interface Person @property (nonatomic, strong) NSString *name; + (instancetype)personWithName:(NSString *)name; + (instancetype)person; @end

//MyApp-Bridging-Header.h #import "Person.h"

//Main.swift class Main { var person1: Person var person2: Person init() { person1 = Person(name: "Sergey") person2 = Person() } }

Недоступны из Swift в Obj-C

• Swift enum

• Вложенные классы

• Перегруженные операторы

• Swift Extensions (Categories)

• Функции (вне классов)

Недоступны из Obj-C в Swift

• Objective-C++ (.mm)

• typedef enum -> только NS_ENUM

• id -> AnyObject?

Школа

4 занятия20 участников

Скринкасты на YouTube Презентации на SlideShare

Резюме

• Защита от ошибок

• Защита от ошибок

• Модификаторы доступ

• Защита от ошибок

• Модификаторы доступ

• Optionals

• Защита от ошибок

• Модификаторы доступ

• Optionals

• “Обновлённый“ switch-case

• Защита от ошибок

• Модификаторы доступ

• Optionals

• “Обновлённый“ switch-case

• Никаких try-catch - “умный” код

• Защита от ошибок

• Модификаторы доступ

• Optionals

• “Обновлённый“ switch-case

• Никаких try-catch - “умный” код

• Обаятельная инициализация

• Защита от ошибок

• Модификаторы доступ

• Optionals

• “Обновлённый“ switch-case

• Никаких try-catch - “умный” код

• Обаятельная инициализация

• Playgrounds

• Защита от ошибок

• Модификаторы доступ

• Optionals

• “Обновлённый“ switch-case

• Никаких try-catch - “умный” код

• Обаятельная инициализация

• Playgrounds

• “Сладкий” синтаксис

• Защита от ошибок

• Модификаторы доступ

• Optionals

• “Обновлённый“ switch-case

• Никаких try-catch - “умный” код

• Обаятельная инициализация

• Playgrounds

• “Сладкий” синтаксис

• Перегрузка операторов

• Защита от ошибок

• Модификаторы доступ

• Optionals

• “Обновлённый“ switch-case

• Никаких try-catch - “умный” код

• Обаятельная инициализация

• Playgrounds

• “Сладкий” синтаксис

• Перегрузка операторов

• Совместимость Obj-C <-> Swift

https://www.appintheair.mobi/download

swift@pronin.me swift@empatika.com

Вопросы