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
Konstantin
February 11, 2016
Programming
0
220
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
130
Swift Package Manager
konstantinkoval
2
160
Swift rEvolution
konstantinkoval
1
230
React Native - from a mobile (iOS) developer prospective
konstantinkoval
0
63
Swift - Pushing technology limits
konstantinkoval
1
230
WatchKit
konstantinkoval
0
60
Intro in WatchKit and Watch apps
konstantinkoval
0
55
Functional Swift
konstantinkoval
1
130
I love swift.pdf
konstantinkoval
1
180
Other Decks in Programming
See All in Programming
データの整合性を保つ非同期処理アーキテクチャパターン / Async Architecture Patterns
mokuo
41
15k
CNCF Project の作者が考えている OSS の運営
utam0k
5
690
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
10
1.8k
Amazon Q Developer Proで効率化するAPI開発入門
seike460
PRO
0
110
『品質』という言葉が嫌いな理由
korimu
0
160
ARA Ansible for the teams
kksat
0
150
負債になりにくいCSSをデザイナとつくるには?
fsubal
9
2.3k
chibiccをCILに移植した結果 (NGK2025S版)
kekyo
PRO
0
210
富山発の個人開発サービスで日本中の学校の業務を改善した話
krpk1900
4
370
バックエンドのためのアプリ内課金入門 (サブスク編)
qnighy
8
1.7k
[JAWS-UG横浜 #80] うわっ…今年のServerless アップデート、少なすぎ…?
maroon1st
1
170
Rails アプリ地図考 Flush Cut
makicamel
1
110
Featured
See All Featured
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7.1k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
Building Applications with DynamoDB
mza
93
6.2k
GitHub's CSS Performance
jonrohan
1030
460k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
12
950
Visualization
eitanlees
146
15k
Scaling GitHub
holman
459
140k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
8
270
A Tale of Four Properties
chriscoyier
158
23k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
The Language of Interfaces
destraynor
156
24k
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