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
RACDC – RACify
Search
Dave Lee
September 09, 2014
Programming
1
210
RACDC – RACify
A run through examples of building ReactiveCocoa APIs out of traditional objective-c APIs.
Dave Lee
September 09, 2014
Tweet
Share
More Decks by Dave Lee
See All by Dave Lee
Advanced Debugging & Swift
kastiglione
2
760
Other Decks in Programming
See All in Programming
Angular-Apps smarter machen mit Gen AI: Lokal und offlinefähig - Hands-on Workshop!
christianliebel
PRO
0
120
Agent Skills Workshop - AIへの頼み方を仕組み化する
gotalab555
15
8.9k
20260313 - Grafana & Friends Taipei #1 - Kubernetes v1.36 的開發雜記:那些困在 Alpha 加護病房太久的 Metrics
tico88612
0
210
Windows on Ryzen and I
seosoft
0
320
Linux Kernelの1文字のミスで 権限昇格ができた話
rqda
0
1.6k
米国のサイバーセキュリティタイムラインと見る Goの暗号パッケージの進化
tomtwinkle
2
610
Kubernetesでセルフホストが簡単なNewSQLを求めて / Seeking a NewSQL Database That's Simple to Self-Host on Kubernetes
nnaka2992
0
150
AIコードレビューの導入・運用と AI駆動開発における「AI4QA」の取り組みについて
hagevvashi
0
500
RAGでハマりがちな"Excelの罠"を、データの構造化で突破する
harumiweb
9
2.9k
守る「だけ」の優しいEMを抜けて、 事業とチームを両方見る視点を身につけた話
maroon8021
3
1k
モックわからないマン卒業記 ~振る舞いを起点に見直した、フロントエンドテストにおけるモックの使いどころ~
tasukuwatanabe
3
390
Takumiから考えるSecurity_Maturity_Model.pdf
gessy0129
1
150
Featured
See All Featured
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
118
110k
Utilizing Notion as your number one productivity tool
mfonobong
4
260
WCS-LA-2024
lcolladotor
0
480
Imperfection Machines: The Place of Print at Facebook
scottboms
269
14k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
110
Paper Plane
katiecoart
PRO
0
48k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.1k
Designing for Performance
lara
611
70k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.4k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
640
Making Projects Easy
brettharned
120
6.6k
How to Ace a Technical Interview
jacobian
281
24k
Transcript
RACify Dave Lee @kastiglione RACDC 2014
RACSignalify
Stealth Signals • Blocks • Delegates • Notifications • Errors
• Target-Action • KVO • Method Overriding
Bridging the Gap • +[RACSignal defer:] • -‐[NSNotificationCenter rac_addObserverForName:object:]
• -‐[NSObject rac_signalForSelector:] • +[RACSignal createSignal:] • RACObserve()
[RACSignal new]
[RACSignal return:value]
[RACSignal error:error]
[RACSignal empty]
[RACSubject subject]
+[RACSignal defer:] [RACSignal defer:^{ return [RACSignal return:@(arc4random())];
}]
+[RACSignal defer:] [RACSignal defer:^{ // Perform per-‐subscription side
effects. u_int32_t r = arc4random(); ! // Start (and in this case complete) the signal. return [RACSignal return:@(r)]; }]
+[RACSignal createSignal:] [RACSignal createSignal:^(id<RACSubscriber subscriber) { // Perform
per-‐subscription side effects. u_int32_t r = arc4random(); ! // Start (and in this case complete) the signal. [subscriber sendNext:@(r)]; [subscriber sendCompleted]; ! return (RACDisposable *)nil; }]
+[RACSignal createSignal:] [RACSignal createSignal:^(id<RACSubscriber subscriber) { return (RACDisposable
*)nil; }] [RACSignal empty]
AFNetworking
AFHTTPRequestOperationManager *manager = …; [manager GET:URLString parameters:params
success:^(AFHTTPRequestOperation *op, id response) { // Success-‐y } failure:^(AFHTTPRequestOperation *op, NSError *e) { // Fail-‐y }];
[RACSignal createSignal:^(id<RACSubscriber subscriber) { [manager GET:URLString parameters:params
success:^(AFHTTPRequestOperation *op, id response) { [subscriber sendNext:response]; [subscriber sendCompleted]; } failure:^(AFHTTPRequestOperation *op, NSError *e) { [subscriber sendError:e]; }]; }]
[RACSignal createSignal:^(id<RACSubscriber subscriber) { NSOperation *operation = [manager
GET:URLString parameters:params success:^(AFHTTPRequestOperation *op, id response) { [subscriber sendNext:response]; [subscriber sendCompleted]; } failure:^(AFHTTPRequestOperation *op, NSError *e) { [subscriber sendError:e]; }]; ! return [RACDisposable disposableWithBlock:^{ [operation cancel]; }]; }]
Core Data
__block NSArray *results; [managedObjectContext performBlock:^{ NSError *error;
results = [managedObjectContext executeFetchRequest:fetchRequest error:&error]; }];
[RACSignal createSignal:^(id<RACSubscriber> subscriber) { RACDisposable *disposable = [RACDisposable
new]; ! [managedObjectContext performBlock:^{ if (disposable.disposed) return; ! NSError *error; NSArray *results = [managedObjectContext performFetch:fetchRequest error:&error]; ! if (results != nil) { [subscriber sendNext:results]; [subscriber sendCompleted]; } else { [subscriber sendError:error]; } }];
! [managedObjectContext performBlock:^{ if (disposable.disposed) return;
! NSError *error; NSArray *results = [managedObjectContext performFetch:fetchRequest error:&error]; ! if (results != nil) { [subscriber sendNext:results]; [subscriber sendCompleted]; } else { [subscriber sendError:error]; } }]; ! return disposable; }];
Core Location
CLLocationManager *locationManager = … locationManager.delegate = self; static
volatile int32_t subscriberCount = 0;
[RACSignal createSignal:^(id<RACSubscriber> subscriber) { RACSignal *locations = [[self
rac_signalForSelector:@selector(…didUpdateLocations:) fromProtocol:@protocol(CLLocationManagerDelegate)] reduceEach:^(id _,NSArray *locations) { return locations; }]; ! RACSignal *error = [[[[self rac_signalForSelector:@selector(…didFailWithError:) fromProtocol:@protocol(CLLocationManagerDelegate)] reduceEach:^(id _, NSError *error) { return error; }] filter:^ BOOL (NSError *error) { // Documentation says Core Location will keep // will keep trying after kCLErrorLocationUnknown. return error.code != kCLErrorLocationUnknown;
RACSignal *error = [[[[self rac_signalForSelector:@selector(…didFailWithError:)
fromProtocol:@protocol(CLLocationManagerDelegate)] reduceEach:^(id _, NSError *error) { return error; }] filter:^ BOOL (NSError *error) { // Documentation says Core Location will keep // will keep trying after kCLErrorLocationUnknown. return error.code != kCLErrorLocationUnknown; }] flattenMap:^(NSError *error) { return [RACSignal error:error]; }]; ! RACDisposable *disposable = [[RACSignal merge:@[ locations, error ]] subscribe:subscriber];
RACDisposable *disposable = [[RACSignal
merge:@[ locations, error ]] subscribe:subscriber]; ! if (OSAtomictIncrement32(&subscriberCount) == 1) { [locationManager startUpdatingLocation]; } else { [subscriber sendNext:locationManager.location]; } ! return [RACDisposable disposableWithBlock:^{ [disposable dispose]; if (OSAtomictDecrement32(&subscriberCount) == 0) { [locationManager stopUpdatingLocation]; } }]; }];
AFNetworking
! RACSignal *isReachable = [RACObserve( reachabilityManager, networkReachabilityStatus)
map:^(NSNumber *networkReachabilityStatus) { switch (networkReachabilityStatus.intValue) { case AFNetworkReachabilityStatusReachableViaWWAN: case AFNetworkReachabilityStatusReachableViaWiFi: return @YES; } return @NO; }];
Notifications
UIApplicationWillEnterForegroundNotification UIApplicationDidEnterBackgroundNotification UIApplicationWillResignActiveNotification UIApplicationDidBecomeActiveNotification
RACSignal *isForeground = [RACSignal merge:@[ [[defaultCenter
rac_addObserverForName:WillEnterForeground …] mapReplace:@YES] [[defaultCenter rac_addObserverForName:DidEnterBackground …] mapReplace:@NO] ]]; ! RACSignal *hasLaunchedActive = [RACSignal if:isForeground then:[[defaultCenter rac_addObserverForName:DidBecomeActive …] take:1] else:[RACSignal empty]];
More… • Use -‐rac_signalForSelector:, everywhere. • Check out the AppKit
and UIKit extensions in RAC