Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Functional Reactive Programming in the Mobile W...

Edward Dale
November 27, 2013

Functional Reactive Programming in the Mobile World

Edward Dale

November 27, 2013
Tweet

More Decks by Edward Dale

Other Decks in Programming

Transcript

  1. Agenda • Theory • The mobile world • Functional Reactive

    Programming (FRP) • Practice • ReactiveExtensions (RX) • ReactiveCocoa • RxJava !2 http://knowyourmeme.com/memes/business-cat
  2. The Mobile World • (or maybe the desktop world) •

    Event-based (onTouch, onLongClick, network connection lost, etc) • Concurrent • Messy !3
  3. Lots of solutions to concurrency complexity • Grand Central Dispatch

    • NSOperationQueue • Loader • AsyncTask • ExecutorService • Thread !4 http://www.flickr.com/photos/30630175@N07/2950272850
  4. Lots of solutions to concurrency complexity • Grand Central Dispatch

    • NSOperationQueue • Loader • AsyncTask • ExecutorService • Thread Still using! imperative! programming !4 http://www.flickr.com/photos/30630175@N07/2950272850
  5. Functional Reactive Programming (FRP) • Functional • Emphasize functions as

    the building blocks of a program • Avoid mutable data and side effects • x′ = f(x) • Reactive • Emphasize data flow and propagation of change • Similar to Observer pattern • a := b + c λ !5
  6. FRP in Practice • Reactive Extensions (Rx) • from Microsoft

    • Rx = Observables + Operators + Schedulers • Observables represent asynchronous data streams • Operators query 
 asynchronous data streams • Schedulers parameterize
 the concurrency in
 asynchronous data streams !6
  7. Observer 1 //Provides a mechanism for receiving push-based notifications. 2

    public interface IObserver<in T> { 3 //Provides the observer with new data. 4 void OnNext(T value); 5 6 // Notifies the observer that the provider has 7 // experienced an error condition. 8 void OnError(Exception error); 9 10 // Notifies the observer that the provider has 11 // finished sending push-based notifications. 12 void OnCompleted(); 13 } !7
  8. ReactiveCocoa Example 1 1 - (id)init 2 { 3 self

    = [super initWithFrame:CGRectZero]; 4 if (self) { 5 // Build objects... 6 RAC(backButton, enabled) = RACObserve(self, backEnabled); 7 RAC(forwardButton, enabled) = RACObserve(self, forwardEnabled); 8 RAC(titleLabel, text) = RACObserve(self, title); 9 10 RACSignal *loadingSignal = RACObserve(self, loading); 11 RAC(refreshButton, hidden) = loadingSignal; 12 RAC(stopButton, hidden) = [loadingSignal map:^id(NSNumber *enabled) { 13 return [NSNumber numberWithBool:![enabled boolValue]]; 14 }]; 15 } 16 return self; 17 } !10
  9. 1 - (RACSignal *) savedPages { 2 return [[[RACSignal createSignal:^RACDisposable

    *(id<RACSubscriber> subsc) { 3 NSURLSessionDataTask *op = 4 5 [self GET:@"saved_pages" 6 parameters:nil 7 success:^(NSURLSessionDataTask *operation, NSXMLParser *parser) { 8 GVSavedPagesParserDelegate *parDel = 9 [GVSavedPagesParserDelegate new]; 10 parser.delegate = parDel; 11 if([parser parse]) { 12 [subsc sendNext:RACTuplePack(parDel.savedPages, 13 parDel.homepage)]; 14 [subsc sendCompleted]; 15 } else { 16 [subsc sendError:parser.parserError]; 17 } 18 } 19 failure:^(NSURLSessionDataTask *operation, NSError *error) { 20 [subsc sendError:error]; 21 }]; 22 23 return [RACDisposable disposableWithBlock:^{ 24 [op cancel]; 25 }]; 26 }] replayLazily] subscribeOn:[RACScheduler scheduler]]; 27 } ReactiveCocoa Example 2 WIP !11
  10. RxJava Example 1 1 @Override 2 public void onCreate(Bundle savedInstanceState)

    { 3 4 // ... 5 6 final Button sendButton = (Button) findViewById(R.id.send); 7 final EditText bodyEdit = (EditText) findViewById(R.id.body); 8 final Observable<String> bodyText = Events.text(bodyEdit); 9 10 // send button is only enabled when we have some body content 11 bodyText.map(new Func1<String, Boolean>() { 12 @Override 13 public Boolean call(String text) { 14 return !text.trim().equals(""); 15 } 16 }).subscribe(Properties.enabledFrom(sendButton)); 17 } !13 https://github.com/andrewhr/rxjava-android-example/blob/master/app/src/main/java/com/example/rx/ComposeMessageActivity.java
  11. RxJava Example 2 1 public Observable<WeatherData> getWeatherData(final String city) {

    2 return Observable.create(new Observable.OnSubscribeFunc<WeatherData>() { 3 @Override 4 public Subscription onSubscribe(Observer<? super WeatherData> obs) { 5 try { 6 obs.onNext(apiManager.getWeather(city, "metric")); 7 obs.onCompleted(); 8 } catch (Exception e) { 9 obs.onError(e); 10 } 11 12 return Subscriptions.empty(); 13 } 14 }).subscribeOn(Schedulers.threadPoolForIO()); 15 } !14 http://howrobotswork.wordpress.com/2013/10/28/using-rxjava-in-android/