$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Refactoring an Ugly Objective-C with Swift
Search
Konstantin
February 11, 2016
Programming
0
240
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
160
Swift Package Manager
konstantinkoval
2
180
Swift rEvolution
konstantinkoval
1
240
React Native - from a mobile (iOS) developer prospective
konstantinkoval
0
76
Swift - Pushing technology limits
konstantinkoval
1
260
WatchKit
konstantinkoval
0
70
Intro in WatchKit and Watch apps
konstantinkoval
0
67
Functional Swift
konstantinkoval
1
150
I love swift.pdf
konstantinkoval
1
200
Other Decks in Programming
See All in Programming
[堅牢.py #1] テストを書かない研究者に送る、最初にテストを書く実験コード入門 / Let's start your ML project by writing tests
shunk031
11
6.4k
生成AIを活用したリファクタリング実践 ~コードスメルをなくすためのアプローチ
raedion
0
180
251126 TestState APIってなんだっけ?Step Functionsテストどう変わる?
east_takumi
0
290
FluorTracer / RayTracingCamp11
kugimasa
0
140
Combinatorial Interview Problems with Backtracking Solutions - From Imperative Procedural Programming to Declarative Functional Programming - Part 1
philipschwarz
PRO
0
110
AWS CDKの推しポイントN選
akihisaikeda
1
220
全員アーキテクトで挑む、 巨大で高密度なドメインの紐解き方
agatan
8
13k
目的で駆動する、AI時代のアーキテクチャ設計 / purpose-driven-architecture
minodriven
11
3.7k
jakarta-security-jjug-ccc-2025-fall
tnagao7
0
100
AI時代もSEOを頑張っている話
shirahama_x
0
200
Reactive Thinking with Signals and the new Resource API
manfredsteyer
PRO
0
140
TVerのWeb内製化 - 開発スピードと品質を両立させるまでの道のり
techtver
PRO
3
1.3k
Featured
See All Featured
Producing Creativity
orderedlist
PRO
348
40k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3k
Build The Right Thing And Hit Your Dates
maggiecrowley
38
2.9k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.1k
Making Projects Easy
brettharned
120
6.5k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
360
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
Documentation Writing (for coders)
carmenintech
76
5.2k
How GitHub (no longer) Works
holman
316
140k
Building Flexible Design Systems
yeseniaperezcruz
329
39k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
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