SlideShare a Scribd company logo
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)! //Success 
result.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.0 
13 ** 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 sugar 
switch 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 sugar 
switch 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 sugar 
switch 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 sugar 
switch 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 sugar 
switch 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 sugar 
switch 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 
Вопросы

More Related Content

What's hot

Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101
Anton Arhipov
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++
Alexander Granin
 
Javascript
JavascriptJavascript
Javascript
Vasya Petrov
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Sergey Platonov
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
Eugeniy Tyumentcev
 
Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Unsafe: to be or to be removed?
Unsafe: to be or to be removed?
Alexey Fyodorov
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Mikhail Matrosov
 
Парсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksПарсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricks
Roman Dvornov
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
Sergey Platonov
 
Очень вкусный фрукт Guava
Очень вкусный фрукт GuavaОчень вкусный фрукт Guava
Очень вкусный фрукт Guava
Egor Chernyshev
 
CSSO – история ускорения
CSSO – история ускоренияCSSO – история ускорения
CSSO – история ускорения
Roman Dvornov
 
Консервативный Backend на Node.js / Дмитрий Ляпин (Recrumatic)
Консервативный Backend на Node.js / Дмитрий Ляпин (Recrumatic)Консервативный Backend на Node.js / Дмитрий Ляпин (Recrumatic)
Консервативный Backend на Node.js / Дмитрий Ляпин (Recrumatic)
Ontico
 
FPUG Dzyga presentation
FPUG Dzyga presentationFPUG Dzyga presentation
FPUG Dzyga presentationIvan Filimonov
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгирование
Python Meetup
 
Прикладная теория Application Security
Прикладная теория Application SecurityПрикладная теория Application Security
Прикладная теория Application Security
Vladimir Kochetkov
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
Sergey Platonov
 
Component Inspector
Component InspectorComponent Inspector
Component Inspector
Roman Dvornov
 

What's hot (20)

Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101Joker 2016 - Bytecode 101
Joker 2016 - Bytecode 101
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++
 
Javascript
JavascriptJavascript
Javascript
 
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионаловПолухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Unsafe: to be or to be removed?
Unsafe: to be or to be removed?
 
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
Повседневный С++: алгоритмы и итераторы @ C++ Russia 2017
 
Парсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricksПарсим CSS: performance tips & tricks
Парсим CSS: performance tips & tricks
 
Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++Павел Беликов, Как избежать ошибок, используя современный C++
Павел Беликов, Как избежать ошибок, используя современный C++
 
Очень вкусный фрукт Guava
Очень вкусный фрукт GuavaОчень вкусный фрукт Guava
Очень вкусный фрукт Guava
 
Zagursky
ZagurskyZagursky
Zagursky
 
CSSO – история ускорения
CSSO – история ускоренияCSSO – история ускорения
CSSO – история ускорения
 
Консервативный Backend на Node.js / Дмитрий Ляпин (Recrumatic)
Консервативный Backend на Node.js / Дмитрий Ляпин (Recrumatic)Консервативный Backend на Node.js / Дмитрий Ляпин (Recrumatic)
Консервативный Backend на Node.js / Дмитрий Ляпин (Recrumatic)
 
FPUG Dzyga presentation
FPUG Dzyga presentationFPUG Dzyga presentation
FPUG Dzyga presentation
 
Очередной скучный доклад про логгирование
Очередной скучный доклад про логгированиеОчередной скучный доклад про логгирование
Очередной скучный доклад про логгирование
 
C sharp deep dive
C sharp deep diveC sharp deep dive
C sharp deep dive
 
Прикладная теория Application Security
Прикладная теория Application SecurityПрикладная теория Application Security
Прикладная теория Application Security
 
Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++Борис Сазонов, RAII потоки и CancellationToken в C++
Борис Сазонов, RAII потоки и CancellationToken в C++
 
course js day 2
course js day 2course js day 2
course js day 2
 
Component Inspector
Component InspectorComponent Inspector
Component Inspector
 

Similar to Mera Dev Fest - Swift vs. Obj-C

Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
Vasil Remeniuk
 
Swift School #2
Swift School #2Swift School #2
Swift School #2
Sergey Pronin
 
automation is iOS development
automation is iOS developmentautomation is iOS development
automation is iOS development
Ivan Trifonov
 
Кодогенерация на службе оптимизации, Игорь Чевдарь, СКБ Контур
 Кодогенерация на службе оптимизации, Игорь Чевдарь, СКБ Контур  Кодогенерация на службе оптимизации, Игорь Чевдарь, СКБ Контур
Кодогенерация на службе оптимизации, Игорь Чевдарь, СКБ Контур
it-people
 
Язык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовЯзык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистов
Andrew Shitov
 
Swift + Kotlin = ❤, Станислав Таланов и Сергей Моляк. 8 июня, 2019
Swift + Kotlin = ❤, Станислав Таланов и Сергей Моляк. 8 июня, 2019Swift + Kotlin = ❤, Станислав Таланов и Сергей Моляк. 8 июня, 2019
Swift + Kotlin = ❤, Станислав Таланов и Сергей Моляк. 8 июня, 2019
Mail.ru Group
 
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
Iosif Itkin
 
XML Magic
XML MagicXML Magic
XML Magic
Igor Khotin
 
Go Template Toolkit, Сергей Свистунов, Lazada
Go Template Toolkit, Сергей Свистунов, LazadaGo Template Toolkit, Сергей Свистунов, Lazada
Go Template Toolkit, Сергей Свистунов, Lazada
Mail.ru Group
 
Mike ponomarenko java17-fork-v1.2
Mike ponomarenko java17-fork-v1.2Mike ponomarenko java17-fork-v1.2
Mike ponomarenko java17-fork-v1.2
Alex Tumanoff
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кодаAndrey Karpov
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
Pavel Tsukanov
 
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Ivan Tsyganov
 
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
JSFestUA
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
SmartTools
 
Groovy On Grails
Groovy On GrailsGroovy On Grails
Groovy On Grailsguest32215a
 

Similar to Mera Dev Fest - Swift vs. Obj-C (20)

Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
Swift School #2
Swift School #2Swift School #2
Swift School #2
 
automation is iOS development
automation is iOS developmentautomation is iOS development
automation is iOS development
 
20110227 csseminar alvor_breslav
20110227 csseminar alvor_breslav20110227 csseminar alvor_breslav
20110227 csseminar alvor_breslav
 
Bytecode
BytecodeBytecode
Bytecode
 
Кодогенерация на службе оптимизации, Игорь Чевдарь, СКБ Контур
 Кодогенерация на службе оптимизации, Игорь Чевдарь, СКБ Контур  Кодогенерация на службе оптимизации, Игорь Чевдарь, СКБ Контур
Кодогенерация на службе оптимизации, Игорь Чевдарь, СКБ Контур
 
Язык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистовЯзык программирования Go для Perl-программистов
Язык программирования Go для Perl-программистов
 
Perl in practice
Perl in practicePerl in practice
Perl in practice
 
Swift + Kotlin = ❤, Станислав Таланов и Сергей Моляк. 8 июня, 2019
Swift + Kotlin = ❤, Станислав Таланов и Сергей Моляк. 8 июня, 2019Swift + Kotlin = ❤, Станислав Таланов и Сергей Моляк. 8 июня, 2019
Swift + Kotlin = ❤, Станислав Таланов и Сергей Моляк. 8 июня, 2019
 
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
TMPA-2015: Expanding the Meta-Generation of Correctness Conditions by Means o...
 
XML Magic
XML MagicXML Magic
XML Magic
 
Go Template Toolkit, Сергей Свистунов, Lazada
Go Template Toolkit, Сергей Свистунов, LazadaGo Template Toolkit, Сергей Свистунов, Lazada
Go Template Toolkit, Сергей Свистунов, Lazada
 
Mike ponomarenko java17-fork-v1.2
Mike ponomarenko java17-fork-v1.2Mike ponomarenko java17-fork-v1.2
Mike ponomarenko java17-fork-v1.2
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?Moscow Python Conf 2016. Почему 100% покрытие это плохо?
Moscow Python Conf 2016. Почему 100% покрытие это плохо?
 
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
JS Fest 2019. Владимир Агафонкин. Быстро по умолчанию: алгоритмическое мышлен...
 
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScriptСтажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
Стажировка 2016-07-14 02 Евгений Тарасенко. JavaScript
 
Асинхронный JavaScript
Асинхронный JavaScriptАсинхронный JavaScript
Асинхронный JavaScript
 
Groovy On Grails
Groovy On GrailsGroovy On Grails
Groovy On Grails
 

More from Sergey Pronin

App in the Air Internship 2018
App in the Air Internship 2018App in the Air Internship 2018
App in the Air Internship 2018
Sergey Pronin
 
PTA Ancillaries
PTA AncillariesPTA Ancillaries
PTA Ancillaries
Sergey Pronin
 
Things you might have missed from CoreData
Things you might have missed from CoreDataThings you might have missed from CoreData
Things you might have missed from CoreData
Sergey Pronin
 
Департамент Программной Инженерии
Департамент Программной ИнженерииДепартамент Программной Инженерии
Департамент Программной Инженерии
Sergey Pronin
 
Swift School #4
Swift School #4Swift School #4
Swift School #4
Sergey Pronin
 
Swift School #3
Swift School #3Swift School #3
Swift School #3
Sergey Pronin
 
Swift School #1
Swift School #1Swift School #1
Swift School #1
Sergey Pronin
 
Empatika Design Hours
Empatika Design HoursEmpatika Design Hours
Empatika Design HoursSergey Pronin
 
Greenfield Feedback Squeek
Greenfield Feedback SqueekGreenfield Feedback Squeek
Greenfield Feedback SqueekSergey Pronin
 

More from Sergey Pronin (15)

App in the Air Internship 2018
App in the Air Internship 2018App in the Air Internship 2018
App in the Air Internship 2018
 
PTA Ancillaries
PTA AncillariesPTA Ancillaries
PTA Ancillaries
 
Things you might have missed from CoreData
Things you might have missed from CoreDataThings you might have missed from CoreData
Things you might have missed from CoreData
 
Департамент Программной Инженерии
Департамент Программной ИнженерииДепартамент Программной Инженерии
Департамент Программной Инженерии
 
Swift School #4
Swift School #4Swift School #4
Swift School #4
 
Swift School #3
Swift School #3Swift School #3
Swift School #3
 
Swift School #1
Swift School #1Swift School #1
Swift School #1
 
Empatika Design Hours
Empatika Design HoursEmpatika Design Hours
Empatika Design Hours
 
Greenfield Feedback Squeek
Greenfield Feedback SqueekGreenfield Feedback Squeek
Greenfield Feedback Squeek
 
Squeek School #8
Squeek School #8Squeek School #8
Squeek School #8
 
Squeek School #7
Squeek School #7Squeek School #7
Squeek School #7
 
Squeek school #6
Squeek school #6Squeek school #6
Squeek school #6
 
Squeek School #5
Squeek School #5Squeek School #5
Squeek School #5
 
Squeek school 4
Squeek school 4Squeek school 4
Squeek school 4
 
Squeek School #3
Squeek School #3Squeek School #3
Squeek School #3
 

Mera Dev Fest - Swift vs. Obj-C

  • 1. Swift второе рождение Objective-C? Сергей Пронин Empatika НИУ-ВШЭ
  • 2. Сергей Пронин Full-stack Developer Empatika Senior Developer, Co-Founder App in the Air Преподаватель НИУ-ВШЭ Департамент Программной Инженерии
  • 3.
  • 5.
  • 6.
  • 7. Первые мысли • WAT? • У меня были планы на лето • Пора качать Xcode Beta • Первый Playground
  • 8.
  • 9.
  • 10.
  • 11. Apple Good to great
  • 15.
  • 17. Почему Swift? • Возможность вернуть несколько значений из метода
  • 18. Почему Swift? • Возможность вернуть несколько значений из метода • Optionals
  • 19. Почему Swift? • Возможность вернуть несколько значений из метода • Optionals • Защита от ошибок
  • 20. Почему Swift? • Возможность вернуть несколько значений из метода • Optionals • Защита от ошибок • Playgrounds
  • 21. Почему Swift? • Возможность вернуть несколько значений из метода • Optionals • Защита от ошибок • Playgrounds • Полнофункциональные Enum
  • 22. Почему Swift? • Возможность вернуть несколько значений из метода • Optionals • Защита от ошибок • Playgrounds • Полнофункциональные Enum • “Сладкий” синтаксис
  • 24.
  • 25. let lang = "swift"
  • 26. let lang = "swift" switch (lang) {
  • 27. let lang = "swift" switch (lang) { case "swift":
  • 28. let lang = "swift" switch (lang) { case "swift": println("young")
  • 29. let lang = "swift" switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"):
  • 30. let lang = "swift" switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?")
  • 31. let lang = "swift" switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css":
  • 32. let lang = "swift" switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web")
  • 33. let lang = "swift" switch (lang) { case "swift": println("young") case let x where x.hasSuffix("#"): println("wat?") case "js", "css": println("web") default:
  • 34. 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?")
  • 35. 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?") }
  • 36. 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?") }
  • 37. 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> чтобы прервать
  • 38. 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> чтобы “провалиться”
  • 39.
  • 40. var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
  • 41. var langsOpt = dict["langs"]? .componentsJoinedByString?(", ")
  • 42. var langsOpt = dict["langs"]? .componentsJoinedByString?(", ") if let langs = langsOpt {
  • 43. var langsOpt = dict["langs"]? .componentsJoinedByString?(", ") if let langs = langsOpt { println("langs=(langs)")
  • 44. var langsOpt = dict["langs"]? .componentsJoinedByString?(", ") if let langs = langsOpt { println("langs=(langs)") }
  • 45. var langsOpt = dict["langs"]? .componentsJoinedByString?(", ") if let langs = langsOpt { println("langs=(langs)") }
  • 46. var langsOpt = dict["langs"]? .componentsJoinedByString?(", ") if let langs = langsOpt { println("langs=(langs)") }
  • 47. var langsOpt = dict["langs"]? .componentsJoinedByString?(", ") if let langs = langsOpt { println("langs=(langs)") } NSArray *langsArr = dict[@"langs"];
  • 48. var langsOpt = dict["langs"]? .componentsJoinedByString?(", ") if let langs = langsOpt { println("langs=(langs)") } NSArray *langsArr = dict[@"langs"]; NSString *langs = nil;
  • 49. var langsOpt = dict["langs"]? .componentsJoinedByString?(", ") if let langs = langsOpt { println("langs=(langs)") } NSArray *langsArr = dict[@"langs"]; NSString *langs = nil; if ([langs isKindOfClass:[NSArray class]]) {
  • 50. 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:@", "];
  • 51. 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:@", "]; }
  • 52. 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) {
  • 53. 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) { //…
  • 54. 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) { //… }
  • 55. 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) { //… }
  • 56. Инструменты языка • Отсутствие try-catch конструкций • Все методы в протоколах - обязательные • Наличие ключевого слова required • Модификаторы доступа • Обязательная инициализация динамических переменных в конструкторе
  • 58.
  • 60. enum Status: Int { case Undetermined, Success, Failure
  • 61. enum Status: Int { case Undetermined, Success, Failure }
  • 62. enum Status: Int { case Undetermined, Success, Failure }
  • 63. enum Status: Int { case Undetermined, Success, Failure } func sendRequest() -> Status {
  • 64. enum Status: Int { case Undetermined, Success, Failure } func sendRequest() -> Status { //networking magic
  • 65. enum Status: Int { case Undetermined, Success, Failure } func sendRequest() -> Status { //networking magic return Status.Success
  • 66. enum Status: Int { case Undetermined, Success, Failure } func sendRequest() -> Status { //networking magic return Status.Success }
  • 67. enum Status: Int { case Undetermined, Success, Failure } func sendRequest() -> Status { //networking magic return Status.Success }
  • 68. enum Status: Int { case Undetermined, Success, Failure } func sendRequest() -> Status { //networking magic return Status.Success } var result = sendRequest()
  • 69. enum Status: Int { case Undetermined, Success, Failure } func sendRequest() -> Status { //networking magic return Status.Success } var result = sendRequest() switch result {
  • 70. enum Status: Int { case Undetermined, Success, Failure } func sendRequest() -> Status { //networking magic return Status.Success } var result = sendRequest() switch result { case .Success:
  • 71. enum Status: Int { case Undetermined, Success, Failure } func sendRequest() -> Status { //networking magic return Status.Success } var result = sendRequest() switch result { case .Success: println("success")
  • 72. 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:
  • 73. 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")
  • 74. 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:
  • 75. 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")
  • 76. 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") }
  • 77. 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
  • 78. 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 result.toRaw() //1
  • 79.
  • 80. func isEven(n: Int) -> Bool {
  • 81. func isEven(n: Int) -> Bool { return n % 2 == 0
  • 82. func isEven(n: Int) -> Bool { return n % 2 == 0 }
  • 83. func isEven(n: Int) -> Bool { return n % 2 == 0 }
  • 84. func isEven(n: Int) -> Bool { return n % 2 == 0 } func filter(a: [Int], check: Int -> Bool)
  • 85. func isEven(n: Int) -> Bool { return n % 2 == 0 } func filter(a: [Int], check: Int -> Bool) -> [Int] {
  • 86. func isEven(n: Int) -> Bool { return n % 2 == 0 } func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = []
  • 87. func isEven(n: Int) -> Bool { return n % 2 == 0 } func filter(a: [Int], check: Int -> Bool) -> [Int] { var result: [Int] = [] for n in a {
  • 88. 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) {
  • 89. 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)
  • 90. 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) }
  • 91. 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) } }
  • 92. 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
  • 93. 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 }
  • 94. 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 }
  • 95. 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)
  • 96.
  • 97. filter(0..<10, { (item: Int) -> Bool in
  • 98. filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0
  • 99. filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0 })
  • 100. filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0 })
  • 101. filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0 }) filter(0...100, { item in item % 10 == 0 })
  • 102. filter(0..<10, { (item: Int) -> Bool in return item % 2 == 0 }) filter(0...100, { item in item % 10 == 0 })
  • 103. 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 })
  • 104. 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 })
  • 105. 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 }
  • 106.
  • 108. var globalLazy: String = { return "Hello, lazy boy"
  • 109. var globalLazy: String = { return "Hello, lazy boy" }()
  • 110. var globalLazy: String = { return "Hello, lazy boy" }()
  • 111. var globalLazy: String = { return "Hello, lazy boy" }() class Sample {
  • 112. var globalLazy: String = { return "Hello, lazy boy" }() class Sample { lazy var x: Int = CallMethod()
  • 113. var globalLazy: String = { return "Hello, lazy boy" }() class Sample { lazy var x: Int = CallMethod()
  • 114. var globalLazy: String = { return "Hello, lazy boy" }() class Sample { lazy var x: Int = CallMethod() var propDidWill: String? {
  • 115. var globalLazy: String = { return "Hello, lazy boy" }() class Sample { lazy var x: Int = CallMethod() var propDidWill: String? { didSet {
  • 116. var globalLazy: String = { return "Hello, lazy boy" }() class Sample { lazy var x: Int = CallMethod() var propDidWill: String? { didSet { //tell everyone
  • 117. var globalLazy: String = { return "Hello, lazy boy" }() class Sample { lazy var x: Int = CallMethod() var propDidWill: String? { didSet { //tell everyone }
  • 118. var globalLazy: String = { return "Hello, lazy boy" }() class Sample { lazy var x: Int = CallMethod() var propDidWill: String? { didSet { //tell everyone } willSet {
  • 119. 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)")
  • 120. 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)") }
  • 121. 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)") } }
  • 122. 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)") } }
  • 123. 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()
  • 124. 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? {
  • 125. 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 {
  • 126. 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
  • 127. 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 }
  • 128. 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 {
  • 129. 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”)
  • 130. 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()
  • 131. 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() }
  • 132. 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() } }
  • 133. 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() } } }
  • 134.
  • 135. func + (left: Vector2D, right: Vector2D) -> Vector2D {
  • 136. func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y)
  • 137. func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y) }
  • 138. func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y) }
  • 139. func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y) } func += (inout left: Vector2D, right: Vector2D) {
  • 140. 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
  • 141. 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 }
  • 142. 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 }
  • 143. 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}
  • 144. 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}
  • 145. 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}
  • 146. 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}
  • 147. 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}
  • 148. 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 ** {}
  • 149. 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 {
  • 150. 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)
  • 151. 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) }
  • 152. 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) }
  • 153. 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
  • 154. 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 13 ** 2 // 169.0
  • 156. “Ассоциированные” значения • Каждый объект перечисления может содержать объект другого типа в качестве соответствия • В таком случае их типы могут быть разными • Позволяет “ассоциировать” любую информацию
  • 157. enum Barcode { case UPCA(Int, Int, Int) case PDF417(String) } var productBarcode = Barcode.UPCA(1, 2, 3) productBarcode = .PDF417("ABCD")
  • 159. Ассоциированные значения доступны в switch-case конструкции switch productBarcode {
  • 160. Ассоциированные значения доступны в switch-case конструкции switch productBarcode { case .UPCA(let system, let ident, let check):
  • 161. Ассоциированные значения доступны в switch-case конструкции switch productBarcode { case .UPCA(let system, let ident, let check): println("UPCA with value of (system), (ident), (check).")
  • 162. Ассоциированные значения доступны в switch-case конструкции switch productBarcode { case .UPCA(let system, let ident, let check): println("UPCA with value of (system), (ident), (check).") case .PDF417(let code):
  • 163. Ассоциированные значения доступны в 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).")
  • 164. Ассоциированные значения доступны в 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).") }
  • 165. Ассоциированные значения доступны в 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).") }
  • 166. Ассоциированные значения доступны в 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
  • 167. Ассоциированные значения доступны в 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 productBarcode {
  • 168. Ассоциированные значения доступны в 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 productBarcode { case let .UPCA(system, ident, check):
  • 169. Ассоциированные значения доступны в 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 productBarcode { case let .UPCA(system, ident, check): println("UPCA with value of (system), (ident), (check).")
  • 170. Ассоциированные значения доступны в 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 productBarcode { case let .UPCA(system, ident, check): println("UPCA with value of (system), (ident), (check).") case let .PDF417(code):
  • 171. Ассоциированные значения доступны в 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 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).")
  • 172. Ассоциированные значения доступны в 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 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).") }
  • 173. “Замещающие” значения • Каждый объект перечисления может быть сопоставлен с объектом другого типа • “Замещающие” значения не меняются (в отличие от “ассоциированных” • Допустимые типы: Character, String, Double, Float, Int*
  • 174. // для 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() //... }
  • 176.
  • 177.
  • 179. Готовимся typedef enum { StatusSuccess, StatusFailure } Status typedef NS_ENUM(NSInteger, Status) { StatusSuccess, StatusFailure };
  • 180. + (id)sharedInstance { //your singleton magic } + (instancetype)sharedInstance { //singleton magic } - (instancetype)init { //initial magic }
  • 181.
  • 182. • В существующей Objective-C codebase -> New File - Cocoa Touch Class -> Swift -> Configure Header
  • 183. • В существующей Objective-C codebase -> New File - Cocoa Touch Class -> Swift -> Configure Header • В созданный Bridging Header импортируем все, что Swift должен видеть из Obj-C #import “MyAFAPIClient.h”
  • 184. • В существующей 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”
  • 185. • В существующей 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 {…}
  • 186. Конвенции //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() } }
  • 187. Недоступны из Swift в Obj-C • Swift enum • Вложенные классы • Перегруженные операторы • Swift Extensions (Categories) • Функции (вне классов)
  • 188. Недоступны из Obj-C в Swift • Objective-C++ (.mm) • typedef enum -> только NS_ENUM • id -> AnyObject?
  • 190.
  • 191. 4 занятия 20 участников Скринкасты на YouTube Презентации на SlideShare
  • 193.
  • 194. • Защита от ошибок
  • 195. • Защита от ошибок • Модификаторы доступ
  • 196. • Защита от ошибок • Модификаторы доступ • Optionals
  • 197. • Защита от ошибок • Модификаторы доступ • Optionals • “Обновлённый“ switch-case
  • 198. • Защита от ошибок • Модификаторы доступ • Optionals • “Обновлённый“ switch-case • Никаких try-catch - “умный” код
  • 199. • Защита от ошибок • Модификаторы доступ • Optionals • “Обновлённый“ switch-case • Никаких try-catch - “умный” код • Обаятельная инициализация
  • 200. • Защита от ошибок • Модификаторы доступ • Optionals • “Обновлённый“ switch-case • Никаких try-catch - “умный” код • Обаятельная инициализация • Playgrounds
  • 201. • Защита от ошибок • Модификаторы доступ • Optionals • “Обновлённый“ switch-case • Никаких try-catch - “умный” код • Обаятельная инициализация • Playgrounds • “Сладкий” синтаксис
  • 202. • Защита от ошибок • Модификаторы доступ • Optionals • “Обновлённый“ switch-case • Никаких try-catch - “умный” код • Обаятельная инициализация • Playgrounds • “Сладкий” синтаксис • Перегрузка операторов
  • 203. • Защита от ошибок • Модификаторы доступ • Optionals • “Обновлённый“ switch-case • Никаких try-catch - “умный” код • Обаятельная инициализация • Playgrounds • “Сладкий” синтаксис • Перегрузка операторов • Совместимость Obj-C <-> Swift