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
A Swift Approach (Warsaw 2014)
Search
Kyle Fuller
November 27, 2014
Technology
4
240
A Swift Approach (Warsaw 2014)
Kyle Fuller
November 27, 2014
Tweet
Share
More Decks by Kyle Fuller
See All by Kyle Fuller
Design APIs and deliver what you promised
kylef
0
99
Preparing for the future of API Description Languages
kylef
0
110
Resilient API Design
kylef
1
330
Building a Swift Web API and Application Together
kylef
2
2k
Testing without Xcode - CMD+U 2016
kylef
0
250
End-to-end: Building a Web Service in Swift (MCE 2016)
kylef
2
480
Designing APIs for Humans - Write the Docs 2016
kylef
0
330
Embracing Change - MBLTDev 2015
kylef
3
680
Practical Declarative Programming (360 iDev 2015)
kylef
3
510
Other Decks in Technology
See All in Technology
LLM時代のパフォーマンスチューニング:MongoDB運用で試したコンテキスト活用の工夫
ishikawa_pro
0
170
大「個人開発サービス」時代に僕たちはどう生きるか
sotarok
20
10k
ブロックテーマ時代における、テーマの CSS について考える Toro_Unit / 2025.09.13 @ Shinshu WordPress Meetup
torounit
0
130
普通のチームがスクラムを会得するたった一つの冴えたやり方 / the best way to scrum
okamototakuyasr2
0
110
Codeful Serverless / 一人運用でもやり抜く力
_kensh
7
450
現場で効くClaude Code ─ 最新動向と企業導入
takaakikakei
1
260
Generative AI Japan 第一回生成AI実践研究会「AI駆動開発の現在地──ブレイクスルーの鍵を握るのはデータ領域」
shisyu_gaku
0
320
プラットフォーム転換期におけるGitHub Copilot活用〜Coding agentがそれを加速するか〜 / Leveraging GitHub Copilot During Platform Transition Periods
aeonpeople
1
210
Autonomous Database - Dedicated 技術詳細 / adb-d_technical_detail_jp
oracle4engineer
PRO
4
10k
「その開発、認知負荷高すぎませんか?」Platform Engineeringで始める開発者体験カイゼン術
sansantech
PRO
2
130
AIのグローバルトレンド2025 #scrummikawa / global ai trend
kyonmm
PRO
1
310
DDD集約とサービスコンテキスト境界との関係性
pandayumi
3
290
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
525
40k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
30
9.7k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
127
53k
Building a Modern Day E-commerce SEO Strategy
aleyda
43
7.6k
We Have a Design System, Now What?
morganepeng
53
7.8k
jQuery: Nuts, Bolts and Bling
dougneiner
64
7.9k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
It's Worth the Effort
3n
187
28k
Git: the NoSQL Database
bkeepers
PRO
431
66k
Art, The Web, and Tiny UX
lynnandtonic
303
21k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
48
9.7k
Transcript
A SWIFT APPROACH KYLEFULLER
KYLEFULLER
None
None
NEW CONCEPTS
RUNTIME
@objc / NSObject
NSKeyValueObserving
RUNTIME
WWDC 2015
OPTIONALS?
func compute() -> Bool?
true false neither
LACK OF A VALUE
NOT AN EMPTY VALUE
CAN'T WE DO THIS IN OBJECTIVE-C?
nil Nil NULL CGRectNull -1 0 NSNotFound NSNull ...
EXPRESS YOU DON'T ACCEPT NIL
EXPRESS YOU WILL NOT RETURN NIL
/// You **MUST** pass in a URL - (instancetype)initWithURL:(NSURL *)URL
{ NSParameterAssert(URL != nil); }
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)path { return nil; }
None
RUNTIME ERROR
RUNTIME ERROR
COMPILE ERROR
None
TUPLES
func get(username:String) -> (Person?, NSError?)
let person, error = get("Kyle")
OBJECTIVE-C
NSError *error; Person *person = [Person getPerson:@"Kyle" error:&error];
NAMED TUPLES
func get(username:String) -> (person:Person?, error:NSError?)
let result = get("Kyle") result.person result.error
- (NSArray *)getPerson:(NSString *)username; - (NSDictionary *)getPerson:(NSString *)username;
NSDictionary *components = [Person getPerson:@"kyle"]; Person *person = components["person"]; NSError
*error = components["error"];
TYPE SAFETY?
FRAGILE
ENUMERATIONS
enum Result { case Success(String) case Error(Error) }
switch result { case .Error(let error): println("There was an error
(\(error)).") case .Success(let string): println("\(string)") }
CLOSURES
EVERYTHING IS A CLOSURE
class TestObject { func testA() -> () { println("first test")
} var testB:(() -> ()) = { println("second test") } }
let testing = TestObject() testing.testA() testing.testB()
testing.testB = testing.testA
testing.testB() // Actually calls testA
CONSISTENCY
FUNCTIONAL
None
let string = "Hello World" let matches:[NSTextCheckingResult] = /* regex
for words in string */ matches.map { string.substringWithRange($0.range) }
let string = "Hello World" let matches:[NSTextCheckingResult] = /* regex
for words in string */ var strings = [String]() for match in matches { let catch = string.substringWithRange(match.range) strings.append(catch) }
func reduce(initial, combine) -> result
combine : ((previous, current) -> (result))
let items = [["a", "b"], ["c", "d"], ["e"]] items.reduce([]) {
initial, expressions -> [String] in initial + expressions } => ["a", "b", "c", "d", "e"]
let items = [["a", "b"], ["c", "d"], ["e"]] items.reduce([], +)
=> ["a", "b", "c", "d", "e"]
func +<T>(lhs:[T], rhs:[T]) -> [T]
items.sort { $0 > $1 }
items.sort(>)
items.filter { $0.hasPermission }
func isAdmin(user:User) -> Bool { return user.username == "Kyle" }
users.filter(isAdmin)
GENERICS
Array<String>
Dictionary<String, Int>
func max<T : Comparable>(a:T, b:T) -> T { return a
> b ? a : b }
max(anInteger, anotherInteger) max(aFloat, anotherFloat) max(aString, anotherString)
PATTERN MATCHING
let point = (1, 2) switch point { case (0,
0): println("(0, 0) is at the origin.") case (-2...2, -2...2): println("(\(point.0), \(point.1)) is near the origin.") default: println("The point is at (\(point.0), \(point.1)).") } // prints "(1, 2) is near the origin."
@auto_closure
delay(5, println("Hello World"))
func delay(time:UInt32, block:@auto_closure) { sleep(time) block() }
BUILDING ASSERT() IN SWIFT
assert(someExpensiveComputation() != 42)
func assert(predicate : () -> Bool) { #if !NDEBUG if
!predicate() { abort() } #endif }
PLAYGROUNDS
PLAYGROUNDS
SWIFT
SAFER
CONVENTIONS
CONVENTIONS
LANGUAGE CONSTRAINTS
BETTER CODE
BETTER DEVELOPERS
LESS BUGS
WE'RE ALL BEGINNERS
PERFECTING
BREAKING CHANGES
- Xcode 6.1 + Xcode 6.1.1
FOR GOOD, NOT EVIL
!
FILE RADARS
FUTURE
COMMON DESIGN PATTERNS
KYLEFULLER