Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Refactoring an Ugly Objective-C with Swift
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Konstantin
February 11, 2016
Programming
0
250
Refactoring an Ugly Objective-C with Swift
Refactoring an Ugly Objective-C with Swift
Konstantin
February 11, 2016
Tweet
Share
More Decks by Konstantin
See All by Konstantin
How does complier see your app
konstantinkoval
4
170
Swift Package Manager
konstantinkoval
2
190
Swift rEvolution
konstantinkoval
1
240
React Native - from a mobile (iOS) developer prospective
konstantinkoval
0
79
Swift - Pushing technology limits
konstantinkoval
1
270
WatchKit
konstantinkoval
0
78
Intro in WatchKit and Watch apps
konstantinkoval
0
72
Functional Swift
konstantinkoval
1
150
I love swift.pdf
konstantinkoval
1
200
Other Decks in Programming
See All in Programming
なるべく楽してバックエンドに型をつけたい!(楽とは言ってない)
hibiki_cube
0
130
CSC307 Lecture 02
javiergs
PRO
1
770
責任感のあるCloudWatchアラームを設計しよう
akihisaikeda
3
130
AIによるイベントストーミング図からのコード生成 / AI-powered code generation from Event Storming diagrams
nrslib
2
1.7k
AI Schema Enrichment for your Oracle AI Database
thatjeffsmith
0
190
AI によるインシデント初動調査の自動化を行う AI インシデントコマンダーを作った話
azukiazusa1
1
610
副作用をどこに置くか問題:オブジェクト指向で整理する設計判断ツリー
koxya
1
560
KIKI_MBSD Cybersecurity Challenges 2025
ikema
0
1.3k
Denoのセキュリティに関する仕組みの紹介 (toranoana.deno #23)
uki00a
0
270
React 19でつくる「気持ちいいUI」- 楽観的UIのすすめ
himorishige
11
5.8k
例外処理とどう使い分ける?Result型を使ったエラー設計 #burikaigi
kajitack
16
5.9k
CSC307 Lecture 03
javiergs
PRO
1
480
Featured
See All Featured
A Tale of Four Properties
chriscoyier
162
24k
How to build a perfect <img>
jonoalderson
1
4.9k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
190
Making Projects Easy
brettharned
120
6.6k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
300
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
150
The Cost Of JavaScript in 2023
addyosmani
55
9.4k
Paper Plane (Part 1)
katiecoart
PRO
0
3.7k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
0
420
Into the Great Unknown - MozCon
thekraken
40
2.2k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
0
1.8k
Transcript
Refactoring Ugly Objective-C
I am - !" ! - Swift ! - Programming
! - Swift Package Manager http://swifthighperformance.com ! Swift Hight Performance
Swift Syntax and Expressiveness ~ 30% less code
Let's talk about Objective-C
Amazing Feature № 1 KKOStorage *storage = [KKOStorage new]; [storage
saveItem:@"New item"]; KKONetwork *network = [KKONetwork new]; [network uploadItem:@"Some stuff"];
Amazing Feature № 1 KKOStorage *storage = [KKOStorage new]; [storage
saveItem:@"New item"]; KKONetwork *network = [KKONetwork new]; [network uploadItem:@"Some stuff"]; [network saveItem:@"Some stuff"]; ❗Error❗
BUT
[network performSelector: @selector(saveItem:)]; id network = [[KKONetwork alloc] init]; [network
saveItem:@"!"]; [network arrayByAddingObjectsFromArray: @[ @10 ]]; [network URLByAppendingPathComponent:@"/me.com"];
But who does ever use id?
! Does! // @interface NSObject <NSObject> // - (id)copy; NSMutableArray
*ar = [NSMutableArray arrayWithArray:@[@1, @1]]; NSMutableArray *aCopy = [ar copy]; // it's a NSArray [aCopy addObject: @2]; //Crash here!!
VS Swift let storage = Storage() storage.saveItem("Apple") let network =
Network() network.uploadItem("Item") // network.saveItem("i") // Error! Always!
VS Swift let any: Any = Network() // any.saveItem("i") //
Can't!! if let any = any as? Storage { any.saveItem("i") }
safety += 1
Objc id vs Swift Any
Objc id Can do Anything. Whatever you Want! id some;
[some URLCache]; [some stringByAppendingString:@":("];
Swift Any Can't do Nothing let any: Any = "String"
any. //Any is empty. It has 0 methods print(any)
safety += 2
3: Initialization
- (instancetype)init { self = [super init]; if (self) {
// Init ivars! // Don't access properties!!! } return self; }
Go Crazy - (instancetype)init { return 0; // -1, etc
} - (instancetype)init { return [self init]; } - (instancetype)init { return nil; } - (instancetype)init { // Do whatever You Want }
@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]];
No boilerplate code! init () init () { // !
Just put code here }
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 }
Swift struct Article { let title: String let text: String
let date: NSDate } Article(title: "title", text: "Text", date: NSDate())
Safety += 3 Clean += 2
Optionals !
Fun Quiz a + b = c b + a
= c
NSString *a; [a stringByAppendingString:@"b"];
NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a];
NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a]; // Crash!
WAT ?!
NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a]; // Crash!
[nil stringByAppendingString:@"b"]; [@"b" stringByAppendingString: nil];
NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a]; // Crash!
[nil stringByAppendingString:@"b"]; // Error [@"b" stringByAppendingString: nil];
NSString *a; [a stringByAppendingString:@"b"]; // Nothing [@"b" stringByAppendingString:a]; // Crash!
[nil stringByAppendingString:@"b"]; // Error [@"b" stringByAppendingString: nil]; // Warning //stringByAppendingString:(nonnull NSString *)
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]; // !
!"
let a = "a" a + "b" /* ! */
"b" + a /* ! */
let a = "a" let a: String? a + "b"
/* ! */ a + "b" // Error "b" + a /* ! */ "b" + a // Error
let a: String? a + "b" // Error "b" +
a // Error if let a = a { a + "b" // ! }
let a: String? a + "b" // Error "b" +
a // Error a.stringByAppendingString("b") // Error if let a = a { a + "b" // ! } a?.stringByAppendingString("b") // !
typedef NS_ENUM(NSInteger, Action) { ActionDelete, ActionCreate, ActionEdit, ActionCopy };
typedef NS_ENUM(NSInteger, Action) { ActionDelete, ActionCreate, ActionEdit, ActionCopy }; //+
(void)runAction:(Action)action; [Runner runAction:ActionCreate];
typedef NS_ENUM(NSInteger, Action) { ActionDelete, ActionCreate, ActionEdit, ActionCopy }; //+
(void)runAction:(Action)action; [Runner runAction:ActionCreate]; [Runner runAction:20]; // WAT ?!
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];
+ (NSString *)actionString:(Action)action { switch (action) { case ActionDelete: return
@"Delete"; case ActionCreate: return @"Create"; case ActionEdit: return @"Edit"; case ActionCopy: return @"Copy"; } }
Swift enum Action { case Delete case Create case Edit
case Copy }
enum Action { case Delete case Create case Edit case
Copy } runAction(.Delete) //runAction(10) // Error!!
enum Action: String { case Delete case Create case Edit
case Copy } let action = Action.Delete.rawValue // Delete
enum Action: String { case Delete case Create case Edit
case Copy var isDangerous: Bool { return self == .Delete } } let danger = Action.Delete.isDangerous // true
- (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
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)
"Is Swift ready for production?"
"Is Objective-C dying?" !
Q & A