Slide 1

Slide 1 text

Refactoring Ugly Objective-C

Slide 2

Slide 2 text

I am - !" ! - Swift ! - Programming ! - Swift Package Manager http://swifthighperformance.com ! Swift Hight Performance

Slide 3

Slide 3 text

Swift Syntax and Expressiveness ~ 30% less code

Slide 4

Slide 4 text

Let's talk about Objective-C

Slide 5

Slide 5 text

Amazing Feature № 1 KKOStorage *storage = [KKOStorage new]; [storage saveItem:@"New item"]; KKONetwork *network = [KKONetwork new]; [network uploadItem:@"Some stuff"];

Slide 6

Slide 6 text

Amazing Feature № 1 KKOStorage *storage = [KKOStorage new]; [storage saveItem:@"New item"]; KKONetwork *network = [KKONetwork new]; [network uploadItem:@"Some stuff"]; [network saveItem:@"Some stuff"]; ❗Error❗

Slide 7

Slide 7 text

BUT

Slide 8

Slide 8 text

[network performSelector: @selector(saveItem:)]; id network = [[KKONetwork alloc] init]; [network saveItem:@"!"]; [network arrayByAddingObjectsFromArray: @[ @10 ]]; [network URLByAppendingPathComponent:@"/me.com"];

Slide 9

Slide 9 text

But who does ever use id?

Slide 10

Slide 10 text

! Does! // @interface NSObject // - (id)copy; NSMutableArray *ar = [NSMutableArray arrayWithArray:@[@1, @1]]; NSMutableArray *aCopy = [ar copy]; // it's a NSArray [aCopy addObject: @2]; //Crash here!!

Slide 11

Slide 11 text

VS Swift let storage = Storage() storage.saveItem("Apple") let network = Network() network.uploadItem("Item") // network.saveItem("i") // Error! Always!

Slide 12

Slide 12 text

VS Swift let any: Any = Network() // any.saveItem("i") // Can't!! if let any = any as? Storage { any.saveItem("i") }

Slide 13

Slide 13 text

safety += 1

Slide 14

Slide 14 text

Objc id vs Swift Any

Slide 15

Slide 15 text

Objc id Can do Anything. Whatever you Want! id some; [some URLCache]; [some stringByAppendingString:@":("];

Slide 16

Slide 16 text

Swift Any Can't do Nothing let any: Any = "String" any. //Any is empty. It has 0 methods print(any)

Slide 17

Slide 17 text

safety += 2

Slide 18

Slide 18 text

3: Initialization

Slide 19

Slide 19 text

- (instancetype)init { self = [super init]; if (self) { // Init ivars! // Don't access properties!!! } return self; }

Slide 20

Slide 20 text

Go Crazy - (instancetype)init { return 0; // -1, etc } - (instancetype)init { return [self init]; } - (instancetype)init { return nil; } - (instancetype)init { // Do whatever You Want }

Slide 21

Slide 21 text

@interface KKOArticle : NSObject @property (nonatomic, readonly, strong) NSString *title; @property (nonatomic, readonly, strong) NSString *text; @property (nonatomic, readonly, strong) NSDate *date; - (instancetype)initWith:(NSString *)title text:(NSString *)text date:(NSDate *)date; @end @implementation KKOArticle - (instancetype)initWith:(NSString *)title text:(NSString *)text date:(NSDate *)date { self = [super init]; if (self) { _title = title; _text = text; _date = date; } return self; } @end KKOArticle *article = [[KKOArticle alloc] initWith:@"title" text:@"text" date:[NSDate date]];

Slide 22

Slide 22 text

No boilerplate code! init () init () { // ! Just put code here }

Slide 23

Slide 23 text

Can't go Crazy :( init () { // - must initialize all properties // - super.init is required when has a superclass // - can't access properties and methods until filly initialized // - very safe }

Slide 24

Slide 24 text

Swift struct Article { let title: String let text: String let date: NSDate } Article(title: "title", text: "Text", date: NSDate())

Slide 25

Slide 25 text

Safety += 3 Clean += 2

Slide 26

Slide 26 text

Optionals !

Slide 27

Slide 27 text

Fun Quiz a + b = c b + a = c

Slide 28

Slide 28 text

NSString *a; [a stringByAppendingString:@"b"];

Slide 29

Slide 29 text

NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a];

Slide 30

Slide 30 text

NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a]; // Crash! WAT ?!

Slide 31

Slide 31 text

NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a]; // Crash! [nil stringByAppendingString:@"b"]; [@"b" stringByAppendingString: nil];

Slide 32

Slide 32 text

NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a]; // Crash! [nil stringByAppendingString:@"b"]; // Error [@"b" stringByAppendingString: nil];

Slide 33

Slide 33 text

NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a]; // Crash! [nil stringByAppendingString:@"b"]; // Error [@"b" stringByAppendingString: nil]; // Warning //stringByAppendingString:(nonnull NSString *)

Slide 34

Slide 34 text

NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a]; // Crash! [nil stringByAppendingString:@"b"]; // Error [@"b" stringByAppendingString: nil]; // Warning //stringByAppendingString:(nonnull NSString *) [(id)nil stringByAppendingString:a]; // !

Slide 35

Slide 35 text

!"

Slide 36

Slide 36 text

let a = "a" a + "b" /* ! */ "b" + a /* ! */

Slide 37

Slide 37 text

let a = "a" let a: String? a + "b" /* ! */ a + "b" // Error "b" + a /* ! */ "b" + a // Error

Slide 38

Slide 38 text

let a: String? a + "b" // Error "b" + a // Error if let a = a { a + "b" // ! }

Slide 39

Slide 39 text

let a: String? a + "b" // Error "b" + a // Error a.stringByAppendingString("b") // Error if let a = a { a + "b" // ! } a?.stringByAppendingString("b") // !

Slide 40

Slide 40 text

typedef NS_ENUM(NSInteger, Action) { ActionDelete, ActionCreate, ActionEdit, ActionCopy };

Slide 41

Slide 41 text

typedef NS_ENUM(NSInteger, Action) { ActionDelete, ActionCreate, ActionEdit, ActionCopy }; //+ (void)runAction:(Action)action; [Runner runAction:ActionCreate];

Slide 42

Slide 42 text

typedef NS_ENUM(NSInteger, Action) { ActionDelete, ActionCreate, ActionEdit, ActionCopy }; //+ (void)runAction:(Action)action; [Runner runAction:ActionCreate]; [Runner runAction:20]; // WAT ?!

Slide 43

Slide 43 text

typedef NS_ENUM(NSInteger, Action) { ActionDelete, ActionCreate, ActionEdit, ActionCopy }; //+ (void)runAction:(Action)action; [Runner runAction:ActionCreate]; [Runner runAction:20]; // WAT ?! // !"# Action action = ActionEdit; action += ActionCopy; action /= 56; [Runner runAction:action];

Slide 44

Slide 44 text

+ (NSString *)actionString:(Action)action { switch (action) { case ActionDelete: return @"Delete"; case ActionCreate: return @"Create"; case ActionEdit: return @"Edit"; case ActionCopy: return @"Copy"; } }

Slide 45

Slide 45 text

Swift enum Action { case Delete case Create case Edit case Copy }

Slide 46

Slide 46 text

enum Action { case Delete case Create case Edit case Copy } runAction(.Delete) //runAction(10) // Error!!

Slide 47

Slide 47 text

enum Action: String { case Delete case Create case Edit case Copy } let action = Action.Delete.rawValue // Delete

Slide 48

Slide 48 text

enum Action: String { case Delete case Create case Edit case Copy var isDangerous: Bool { return self == .Delete } } let danger = Action.Delete.isDangerous // true

Slide 49

Slide 49 text

- (void)setup { [self setupWithName:[App name]]; } - (void)setupWithName:(NSString *)name { [self setupWithName:name mode:ModeSqlite]; } - (void)setupWithName:(NSString *)name mode:(Mode)mode { [self setupWithName:name mode:ModeSqlite logeLevel:LogLevelVerbose]; } - (void)setupWithName:(NSString *)name mode:(Mode)mode logeLevel:(LogLevel)logLevel { ... } CoreDataStack *stack; [stack setup]; [stack setupWithName:@"Data" mode:ModeInMemory]; [stack setupWithName:@"Data" mode:ModeInMemory logeLevel:LogLevelNone]; //[stack logeLevel:LogLevelNone]; Error

Slide 50

Slide 50 text

Swift - Parameters default values func setup(name: String = App.name, mode: Mode = .Sqlite, logLevel: LogLevel = .Verbose) { ... } let stack = CoreDataStack() stack.setup() stack.setup(logLevel: .None) stack.setup(mode: .InMemory, logLevel: .None) stack.setup("DB", mode: .InMemory, logLevel: .None)

Slide 51

Slide 51 text

"Is Swift ready for production?"

Slide 52

Slide 52 text

"Is Objective-C dying?" !

Slide 53

Slide 53 text

Q & A