Menu
  • HOME
  • TAGS

Should I rebind models in ReactiveCocoa MVVM?

objective-c,reactive-cocoa

You can drastically simplify this case by moving the movieModel from the static to the dynamic part of the RACObserve macro: RAC(self.titleLabel, text) = RACObserve(self, movieModel.title); Then, your view will update both when the model instances are exchanged and when a model instance itself changes. If your view model contains...

ReactiveCocoa : Chain a signal with a repeating signal

ios,reactive-programming,reactive-cocoa,racsignal

First of all, the each5SecondSignal can be much simpler. You don't have to call take: as it will cause the signal to complete after 5 seconds, and if I understood you correctly you want the signal to go on forever. RACSignal *each5SecondSignal = [RACSignal interval:5 onScheduler:[RACScheduler mainThreadScheduler]] And you can...

Cancel RACCommand execution

objective-c,cocoa,reactive-cocoa,raccommand

I'm a bit new to RACCommand, so I'm not certain there's a better way to do this. But I have been using takeUntil: with a cancellation signal to halt execution. RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) { return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { while (true) { [subscriber sendNext:nil];...

How to refactor the almost identical logic when using AFNetworking and ReactiveCocoa?

objective-c,refactoring,afnetworking-2,reactive-cocoa

This is untested, but should get you most of the way there: - (RACSignal *)GET:(NSString *)url parameters:(NSDictionary *)parameters { SEL sel = @selector(GET:parameters:success:failure:); return [self signalForRequest:sel url:url parameters:parameters]; } - (RACSignal *)POST:(NSString *)url parameters:(NSDictionary *)parameters { SEL sel = @selector(POST:parameters:success:failure:); return [self signalForRequest:sel url:url parameters:parameters]; } - (RACSignal *)PUT:(NSString *)url...

How to update SceneKit nodes to 'automatically' reflect underlying model?

swift,cocoa-touch,scenekit,reactive-cocoa

I would recommend you having a look at this course by Stanford University and having a look at the MVC lectures: https://itunes.apple.com/gb/course/developing-ios-8-apps-swift/id961180099 They recommend using NSNotifications to alert your controller (which in your case could be your SCNScene) of changes in your model. Your controller then goes and makes changes...

Add and remove from array carried by RACSignal

objective-c,reactive-cocoa

For lack of time, I'll go with a more laconic answer compared to @IanHenry's :) For anything here that doesn't make sense, please comment and I'll be happy explain in detail. // Map additions into blocks that add the bookmark to the given mutable array. RACSignal *addBookmarkSignal = [[addBookmarkCommand concat]...

ReactiveCocoa ignore nil in Swift

swift,reactive-cocoa

Finally, with help from powerj1984 I created this method for now: extension RACSignal { func ignoreNil() -> RACSignal { return self.filter({ (innerValue) -> Bool in return innerValue != nil }) } } ...

Reactive Cocoa Conditional Delay

ios,objective-c,functional-programming,reactive-programming,reactive-cocoa

I got some help at the GitHub page for ReactiveCocoa : You can use -flattenMap: to do this since it lets you return a signal instead of just a single value: RAC(self.displayLink, paused) = [changeSignal flattenMap:^id(RACTuple *value) { RACSignal *pauseSignal = [RACSignal return:@([((NSMutableArray *)value.first) count] == 0)]; if (pause) {...

RACObserve bounds or frame of a UIView?

reactive-cocoa

There's no one answer, some code will call -setFrame:, while other code will call -setBounds:. If the code that sets the rect is not your code, then you could observe both bounds and frame and merge the two signals. For example: [[[RACSignal merge:@[RACObserve(view, frame), RACObserve(view, bounds)]] logNext] map:^(NSValue *value) {...

Possible race condition with ReactiveCocoa in MVVM app with Core Data

ios,objective-c,core-data,mvvm,reactive-cocoa

The race condition may be that name2IsValidSignal can be true before name1IsValidSignal is false. Which means that isValidSignal can be true momentarily before turning false (which would trigger the save). One solution is to combine the validation logic into a single unit: self.isValidSignal = [RACSignal combineLatest:@[RACObserve(self, name1), RACObserve(self, name2)] reduce:^id(NSString...

How to use ReactiveCocoa for UITextViewDelegate

ios,objective-c,reactive-cocoa

Unfortunately there's no good way to "lift" a protocol method that returns a value, since it'd require that the signal is synchronous. Could you disable the text view instead?

Reactivecocoa doesn't recognize new instance changes

objective-c,reactive-cocoa

RAC(self.lbl, userName) = RACObserve(self.viewModel, user.userName); The comma denotes the break between the "static" part (self.viewModel) and the dynamic, changing part (user.userName). This is a really nice feature of RACObserve, but you could implement this yourself, to modify Leo's answer so that it works with a changing userName: map not into...

How to chain signals in a proper way with Reactive Cocoa?

ios,objective-c,reactive-programming,reactive-cocoa

You can simplify the nesting a bit by using the then helper, which will simplify error handling and prevent the separate twitterLoginCommand.errors subscription: [self.viewModel.twitterLoginCommand.executionSignals subscribeNext:^(id x) { [x then:^{ NSLog(@"%@", @"completed"); [ALTAlert wait:@""]; return [self.viewModel appLoginWithTwitter]; }] subscribeNext:^(id x) { NSLog(@"%@", x); } error:^(NSError *error) { [ALTAlert dismiss]; [ALTAlert error:error.localizedDescription];...

How to set up a pipeline for dynamically created RACSignals - dynamic Form application - Reactive Cocoa

objective-c,forms,dynamic,reactive-cocoa,racsignal

Fo your first question, you can use map along with RACTuple: @property (assign, nonatomic) BOOL formComplete; - (void)setUpSignals { NSMutableArray *fieldCompleteSignals = [NSMutableArray arrayWithCapacity:self.fields.count]; for (Field *field in self.fields) { RACSignal *completeSignal = [field complete]; [fieldCompleteSignals addObject:completeSignal]; } RAC(self, formComplete) = [[RACSignal combineLatest:self.fieldCompleteSignals] map:^id (RACTuple *allValues) { return @([allValues.rac_sequence all:^BOOL(id...

Reactive Cocoa diferences between KVC and instance object

ios,key-value-observing,reactive-cocoa,key-value-coding,kvc

What you are probably looking for is the following: [[keyValueCodingArray rac_signalForSelector:@selector(addObject:)] subscribeNext:^(id x) { <#code#> }]; and [[keyValueCodingArray rac_signalForSelector:@selector(removeObject:)] subscribeNext:^(id x) { <#code#> }]; Your code only checks the changes on the array property, not calls to it's value....

ReactiveCocoa: throttle never executes / not working

objective-c,reactive-cocoa

-throttle: accepts an NSTimeInterval, which is a floating-point specification of seconds, not milliseconds. Given the code in the question, I expect you would see results after 500 seconds have elapsed....

RACDelegateProxy vs Common Delegate implementation

ios,delegates,reactive-cocoa

Your question can be generalised to "What are the advantages of signals over callbacks". There used to be a link on RAC's github repo called Escape from Callback Hell - link is no longer working, but I think that title highlights the point perfectly. Basically, one of the advantages of...

RACSignal combineLatest: cannot reduce

objective-c,objective-c-blocks,reactive-cocoa

I know it looks horrible, but as I'm using Objective-C++ this thing goes crazy. I solve this thing by casting it to id and it works... don't ask me why. RACSignal* contactIdentifierSignal = RACObserve(self, contactIdentifier); RACSignal* displayNameSignal = RACObserve(self, displayName); RACSignal* mappedThing = [RACSignal combineLatest:@[contactIdentifierSignal, displayNameSignal] reduce:(id)^id(NSString* identifierValue, NSString* displayNameValue){...

Observing sub-class properties in Swift (Reactive Cocoa)

swift,reactive-cocoa,frp

The observation is backwards. Try: userLocation.rac_valuesForKeyPath("newLocation", observer: self).subscribeNextAs { (value) -> () in println("New location received!") } ...

Reactivecocoa ignore further calls to a function until previous call to it has completed

ios,reactive-cocoa

You should in my opinion use RACCommand : RACCommand* command = [[RACCommand alloc] initWithSignalBlock:^(id _) { return [#mysignal]; }]; // then later [command execute:nil]; // or [[command execute:nil] take:1];// synchronous but be careful ! here be dragons You can call execute as many time as you want, it wont subscribe...

ReactiveCocoa: How do you bind a button's title to a text property?

ios,reactive-cocoa

If you mean they're synced with one property, something like this: [RACAble(self.buttonTitle) subscribeNext:^(NSString *newTitle) { NSString *normalTitle = [NSString stringWithFormat:@"Normal %@", newTitle]; NSString *highlightedTitle = [NSString stringWithFormat:@"Highlighted %@", newTitle]; [self.button setTitle:normalTitle forState:UIControlStateNormal]; [self.button setTitle:highlightedTitle forState:UIControlStateHighlighted]; }]; If you mean there're two properties, something like this: [RACAble(self.normalButtonTitle)...

Reactive Cocoa Splitting a signal without code duplication?

ios,objective-c,reactive-programming,reactive-cocoa

First of all, in order to change the button's title, you have to call its setTitle:forState: method. Also please note that using self inside the subscribeNext block is likely to create a retain cycle (and therefore a memory leak). You can read more about it in this answer. You can...

RACCommand compilation failure on swift 1.2

ios,swift,compiler-errors,reactive-cocoa

Typo is in argument of doError() (and incorrectly identified by compiler): it should be of type (NSError!) -> Void instead of (NSError) -> Void. Modified like this it compiles fine: loginButton.rac_command.executionSignals.flatten() .logAll() .doError { (err:NSError!) -> Void in println(err.description) } .subscribeNext { (_:AnyObject!) -> Void in println("Sent next") } Additional...

ELI5: (Reactive cocoa ) - React to a Filter returning no

ios,objective-c,reactive-cocoa

I take it that whole block is wrapped in a createSignal:, hence the calls to subscriber. But that's probably not necessary. Instead of: RACSignal *imageSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber>subscriber) { [[[imageSearch filter:^BOOL(NSString *path) { ... Just assign it to be a derived signal: RACSignal *imageSignal = [[[imageSearch filter:^BOOL(NSString *path) {...

What is the difference between RACSequence and RACSignal

ios,functional-programming,reactive-cocoa

One is pull driven (RACSequence) and the other is push driven (RACSignal). From here: Push-driven means that values for the signal are not defined at the moment of signal creation and may become available at a later time (for example, as a result from network request, or any user input)....

ReactiveCocoa subscribeNext with nil check

ios,objective-c,reactive-cocoa

The ignore operation on an RACSignal can be used to filter out specific values: [[RACObserve(self, maybeNilProperty) ignore:nil] subscribeNext:^(id x) { // x can't be nil }]; ...

ReactiveCocoa repeat command does not use modified values

ios,reactive-cocoa

The method -repeatFunc: captures an immutable reference to its own pointer to dc, and so each repeat sends that reference, not the local reference which you have nil'd out. It could be done like so: __block DataClass *dc = [[DataClass alloc] init]; RACSignal *signal = [[[RACSignal defer:^{ return [RACSignal return:dc];...

ReactiveCocoa - How to get one item at a time from RACSequence?

reactive-cocoa,racsequence

You should be able to accomplish this with +zip:reduce: RACSignal *arraySig = [@[@1, @2, @3].rac_sequence signal]; RACSubject *triggerSig = [RACSubject subject]; [[RACSignal zip:@[arraySig, triggerSig] reduce:^id(id arrayVal, id triggerVal) { return arrayVal; }] subscribeNext:^(id x) { DDLogVerbose(@"Subscriber got %@ from array", x); }]; [triggerSig sendNext:@"Give me data!"]; The zip operation waits...

Property vs RACSignal

reactive-cocoa

If you want to start writing more RAC-based code, then I would highly encourage you to use a RACSignal instead of a value property, for two reasons: RACSignal use on view models is arguably more idiomatic (i.e.: a more "RAC" way of doing things). Not having access to the property...

How to bind a property with changes found in any of multiple RACObserves

ios,objective-c,reactive-cocoa

I found the cause of this problem, though I do not know the reason how it triggered this error. In my Podfile, I have included ReactiveCocoa pod in both the application and test targets. Removing the ReactiveCocoa pod from the test target resolves the issue. Original version having issues: target...

What is wrong with this simple `-flattenMap` ReactiveCocoa code?

objective-c,reactive-cocoa

Two things: The order does matter, since this is a subject, so change it to this: RACSubject *test = [[RACSubject alloc] init]; [test flattenMap:^RACStream *(id value) { NSLog(@"here: %@", value); return [RACSignal return:@NO]; }]; [test sendNext:@1]; [test sendNext:@2]; [test sendCompleted]; Now, you're still not going to see anything -- because...

How to create a looping RACSignal with RACScheduler

swift,reactive-cocoa,racsignal

There is! I think you're looking for interval:onScheduler:. It will emit the current NSDate, which is usually not that useful, so you can use it to sample another signal that has the data you want. For example, with a constant value: [[RACSignal return:@20] sample:[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]]]; Edit: ...or you...

ReactiveCocoa- Error in map method

ios,objective-c,reactive-cocoa

ReactiveCocoa has a construct exactly for this situation called tryMap:. Check it out: [signal tryMap:^id(NSDictionary *dictionary, NSError **errorPtr) { return [MTLJSONAdapter modelOfClass:SAMWebServiceResponse.class fromJSONDictionary:dictionary error:errorPtr]; }] This assumes that modelOfClass:fromJSONDictionary:error: will return nil when an error occurs -- which is pretty standard -- but it's worth checking the docs on that...

NSUserDefaults and RACChannelTo

ios,objective-c,reactive-cocoa

Ok. While creating the test project I found the problem. As stupid as it was, the class which created the Settings object wasn't registered for the test target. Don't ask me why it was compiling and running until it crashed...

Checking for nil model using reactive cocoa?

reactive-programming,reactive-cocoa

Just to give an example for other viewers, a way to make sure that you're not fetching any images from a model that is nil - one could do something like: RAC(self.someImageView, image) = [[RACObserve(self, model) filter:^BOOL(PhotoModel *currentModel) { return currentModel != nil; }] map:^id(PhotoModel *currentModel) { return [self someMethodToDownloadImageFromModel:currentModel];...

Can't observe NSMutableSet additions with ReactiveCocoa

ios,objective-c,reactive-cocoa,nsmutableset

I'd imagine you're not getting the notification since you're observing a pointer to selectedEmails, and as far as ReactiveCocoa is concerned, this value has not changed. The information contained at that location has changed (i.e. the object has been mutated), but the pointer itself is still referencing the same object....

Updating a UITableViewCell from a view model with ReactiveCocoa

ios,mvvm,uitableview,viewmodel,reactive-cocoa

Ok - I figured it out. The labels where all nil in initWithCoder: - so I had to postpone the RAC() binding until the everything is loaded from the nib. - (void)awakeFromNib { [super awakeFromNib]; RAC(self.workoutNameLabel, text) = RACObserve(self, viewModel.workoutName); RAC(self.numberOfExercisesLabel, text) = RACObserve(self, viewModel.numberOfExercises); } And now the labels...

How to prevent a signal to send a next event before subsequent asynchronous calls are completed?

ios,objective-c,reactive-cocoa

Although I don't have self-confidence in understanding what you are meaning, I recommend using "map", instead of the combination of "createSignal" and "flattenMap". Like this. - (RACSignal *) fetchNearbyDatasForLocation: (CLLocationCoordinate2D)coordinate { return [[self.apiClient fetchNearbyDatasforLocation:coordinate] flattenMap:^RACStream *(NSArray* datas) { /* ... */; return [[RACSignal combineLatest:signals] map:^(RACTuple *unused) { return datas; }]];...

ReactiveCocoa: dispose receiver of replayLazily

reactive-cocoa

It might be represented like that using -[RACMulticastConnection autoconnect]: RACSignal* data1FromNetwork = ...; RACSignal* data1FromNetworkHub = [[data1FromNetwork publish] autoconnect]; // Or below if you want replaying behavior. // RACSignal* data1FromNetworkHub = [[data1FromNetwork multicast:RACReplaySubject.subject] autoconnect]; RACSignal* derivedData = [data1FromNetworkHub flattenMap:...]; RACSignal* data2FromNetwork = ...; RACSignal* result = [RACSignal combineLatest:@[data1FromNetworkHub, derivedData, data2FromNetwork]...

Combining multiple signal not working using Reactive Cocoa

ios,objective-c,reactive-cocoa

Okay, two things: You can use the and helper of RACSignal to make that signal reduction a little cleaner: RACSignal *signUpActiveSignal = [[RACSignal combineLatest:@[validEmailSignal, validPasswordSignal, validConfirmPasswordSignal]] and]; You can also use the RAC macro to bind the enabled property (the only reason that the example code is using subscribeNext instead...

Receive KVO notifications for all property and changes recursively at top level

key-value-observing,reactive-cocoa

The last paragraph in your question is the key to the solution: What I want to happen is I would get a next event from initializing model.subModels to an empty array... So we'll have one signal watching the subModels property on model. one from adding a sub model to the...

Detect if at least one property of object was modified

ios,objective-c,key-value-observing,reactive-cocoa,kvc

You can try Method Swizzling, ex: http://nshipster.com/method-swizzling/. To hook whether your set method be called. You can use KVC or Delegate to notify the changing. You can use immutable object to make sure your object is not changed, then hook when it's created. ...

ReactiveCocoa - Subscribe to the second signal, if the first completes with no value

reactive-cocoa

I've just found what was the problem. The local signal used the same thread where it was created and called on: RACSignal *localSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSLog(@"Perfoming local operation"); [subscriber sendNext:@"local value"]; [subscriber sendCompleted]; return nil; }]; As I see the problem (I am not sure for...

Retry with alert using Reactive Cocoa / Inject side effect before retry

objective-c,reactive-cocoa

Just noticed you asked this on SO. I posted a reply on the GitHub repo, but for posterity I'll post my answer here too: @weakify( self ) [[[[[[self findLocation] doError:^( NSError *error ) { @strongify( self ) // There was an error fetching the location so we ask // the...

How to work with locally modified Cocoapod which don't include podspec?

objective-c,cocoapods,reactive-cocoa

I typically fork the repo, add the podspec and then make changes, here is an example. It looks like: pod 'ReactiveCocoa', :git => "https://github.com/ashfurrow/ReactiveCocoa", :branch => "podspec"...

Send error from doNext block?

ios,objective-c,design-patterns,reactive-cocoa,overcoat

You can create SSKeychain category: @interface SSKeychain (RACExtension) - (RACSignal*)rac_setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account; @end @implementation SSKeychain (RACExtension) - (RACSignal*)rac_setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account { [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { NSError *error; BOOL result = [SSKeychain setPassword:password forService:service account:account...

Toggling a view's visibility from a UIButton, in ReactiveCocoa

ios,objective-c,reactive-cocoa

Here is an example, it's probably not the best, but I think it worth noting. I use "lift" a lot to remove references to self (and therefore weakify/strongify) ... I played around with your code and got something like this working: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional...

RACObserve not working

ios,reactive-cocoa

Mark the property as dynamic, and make sure the view model inherits NSObject. class MyViewModel: NSObject { dynamic var amount: NSDecimalNumber } ...

ReactiveCocoa with MVVM

ios,mvvm,reactive-cocoa

There's a few issues in your code that your own answer has covered, but the reason that you're not getting a next signal is that you're not setting the string by using self.string, instead you're directly accessing the class' variable as _string. Properties are actually Objective-C methods that are cleverly...

Building a queue with RAC idioms

objective-c,reactive-cocoa

There are problem solutions for which ReactiveCocoa is not directly well-suited. I say "directly", because I've found that there is often plenty of opportunity to use RAC near the solution (often by wrapping it), even if it doesn't make sense to use RAC within the solution. Your situation is somewhat...

Bind UISwitch's state to NSUserDefaults with ReactiveCocoa

objective-c,nsuserdefaults,uiswitch,reactive-cocoa

You can bind them (two-way binding) by following: RACChannelTerminal *switchTerminal = self.someSwitch.rac_newOnChannel; RACChannelTerminal *defaultsTerminal = [[NSUserDefaults standardUserDefaults] rac_channelTerminalForKey:@"someBoolKey"]; [switchTerminal subscribe:defaultsTerminal]; [defaultsTerminal subscribe:switchTerminal]; The switch's on state starts with the value from the user defaults or NO....

Dynamically select property to observe with RAC

ios,objective-c,xcode,reactive-cocoa

As from documenation - RACChanelTo - is just a macro, which you can rewrite as [[RACKVOChannel alloc] initWithTarget:<#(NSObject *)#> keyPath:<#(NSString *)#> nilValue:<#(id)#>] So, instead of using RACChanelTo(,) use RACCHannelTerminal *modelTerminal = [[RACKVOChannel alloc] initWithTarget:self keyPath:@"DYNAMIC PROPERTY NAME" nilValue:nil]; WARNING From Reactive Cocoa header /// Do not use this directly. Use...

ReactiveCocoa conditional async signals

ios,objective-c,reactive-cocoa

You could monitor reachability, but it's infamously fraught with races and edge cases. It seems like you'd be much better served by catching the errors that from from not being able to complete the network call, or timing out the network call.

Reactivecocoa send new value

ios,objective-c,iphone,mvvm,reactive-cocoa

You are looking for map instead of filter: return [RACObserve(self, selectedLanguage) map:^id(NSString *value){ ... }]; Additional suggestions Also, having side affects (setting self.selectedLanguageAbbreviation) inside the signals is not very good practice and should be avoided if possible. You could change your logic like this: Explicitly bind values of selectedLanguageAbbreviation to...

RAC and cell reuse: putting deliverOn: in the right place?

ios,objective-c,reactive-cocoa

I haven't confirmed this, but here's a possible explanation: Cell X gets called into use, starts downloading an image. Cell X scrolls offscreen before the image download has completed. Cell X gets reused, prepareForReuse is called. Cell X's rac_prepareForReuseSignal sends a value. Because of deliverTo:, the value is dispatched to...

How can I convert “SignalProducer” to “SignalProducer” of ReactiveCocoa 3?

ios,swift,reactive-cocoa,reactive-cocoa-3

You can use the mapError operator. Something along the lines of: self.fooSignalProducer |> mapError { _ in NSError() } Edit: As Justin points out below, promoteErrors is specifically designed for this case: self.fooSignalProducer |> promoteErrors(NSError) ...

Objc-C: RACObserve rapidly changing values (RACSignal for AFHTTPRequestOperation)

ios,objective-c,reactive-cocoa,afhttprequestoperation

For your original question about the jumping download progress, the problem is you're creating subscriptions to two copies of the signal, which is resulting in two downloads. Namely, this bit of code: [[[DownloadMapFileOperation sharedInstance] signalForDownloadMap:self.place] subscribeNext:^(AFHTTPRequestOperation *operation) { NSString *alertMessage = @"Download complete"; [[[UIAlertView alloc] initWithTitle:@"Complete" message:alertMessage delegate:self cancelButtonTitle:@"Close" otherButtonTitles:...

MVVM with ReactiveCocoa: limit the text length of a UITextField in view model

ios,objective-c,mvvm,reactive-cocoa

As described in this answer: you can take rac_textSignal from the text field and use map to trim the string to the desired length. Then bind the mapped signal to the text field using RAC macro. As you noted, view model shouldn't have a reference to the view. But it...

UISearchResultsUpdating w/ ReactiveCocoa

ios,swift,reactive-cocoa

Actually is very good approach to solve this problem with ReactiveCocoa. You want to get the text while the user is typing or in 'Reactive' word you want “Stream” of input text, If your user is a fast typer you want to perform request to server only if the search...

Disabling UIBarButtonItem with ReactiveCocoa

ios,objective-c,mvvm,reactive-cocoa

[RACObserve(self, thresholdLimitReached) filter:^BOOL(id value) { @strongify(self); return self.thresholdLimitReached; }]; You're filtering thresholdLimitReachedSignal so that it only ever returns YES, so your button is always going to be enabled. For starters, you could rewrite that like this and avoid the @weakify/@strongify: [RACObserve(self, thresholdLimitReached) filter:^BOOL(NSNumber *thresholdLimitReached) { return thresholdLimitReached.boolValue; }]; But don't...

Signal of Signals ? Reactive Cocoa

objective-c,reactive-programming,reactive-cocoa

The code looks incorrect. You are correct in understanding that the code takes the signal of button taps and maps it to a signal of "sign-in signals". Yes, a signal of signals. While a signal of signals is common and very useful, it will do nothing without the use of...

ReactiveCocoa: rac_keywordify macros. For what purpose rac_keywordify is actually need?

macros,reactive-cocoa

All rac_keywordify does is allow the use of the @ symbol as a required prefix in front of the weakify and strongify macros. The @ is not necessary, it's a style choice to make those macros look like keywords, like other language keywords, like @try or @synchronize.

Combine and reduce but wait for each signal to complete before subscribing to next one

ios,objective-c,reactive-cocoa

FWIW, I simplified my code to this and somewhat happy with the results. I'm leaving it here for future reference. - (RACSignal *)loginWithEmail:(NSString *)email password:(NSString *)password { @weakify(self); RACSignal *authSignal = [[self requestTokensWithUsername:email password:password] doNext:^(Authentication *auth) { @strongify(self); self.authentication = auth; }]; RACSignal *profileSignal = [self fetchProfile]; RACSignal *historySignal =...

How to Convert NSError SignalProducer to NoError SignalProducer in ReactiveCocoa (Swift)

ios,swift,reactive-cocoa,reactive-cocoa-3

You can use catch() operator for that case like: let producer = ctaTopButton.rac_signalForControlEvents(.TouchUpInside).toSignalProducer() |> map { value in !self.model.enabled.value } |> catch { _ in SignalProducer<Bool, NoError>.empty } ...

Observing mouse event in ViewModel Swift (Reactive Cocoa 3.0)

swift,mvvm,reactive-cocoa,reactive-cocoa-3

MutablePropertys should be used more like properties, and not as a proxy to a signal. So it should be initialized with a sensible initial value so that anyone that observes it via the producer will get values that make sense. If you want a Signal, you can set up the...

ReactiveCocoa MVVM with UITableView

objective-c,mvvm,reactive-cocoa

1) Well, let's look at the signal: RACObserve(self.viewModel, items) When will that complete? Only when self.viewModel or self is deallocated, just like any other RACObserve. As long as those objects are around, it'll keep on nexting any time you set self.items. It appears that you want it to endRefreshing once...

DataSource methods with RACSignals

objective-c,reactive-cocoa

ReactiveCocoa, like all Reactive Extensions-based frameworks, is designed around a push-based API for operating on a series of values. That is, you have some source of values and then you use signal composition to react to the arrival of new values. On the other hand, the "data source" pattern common...

How can I subscribe to a one-time signal and conditionally initiate a secondary signal without having the original signal fired twice?

ios,objective-c,reactive-programming,reactive-cocoa

For cases where the code is in the same scope, you could go about this in by using a RACSubject to share the signal, or by using a RACMulticastConnection. Using a RACSubject, it would look like: RACSubject *webAPISubject = [RACSubject subject]; [webAPISubject subscribeNext:^(RACTuple *tuple) { @strongify(self) NSArray *foo = tuple.first;...

Merging signals of different type

reactive-cocoa

You could map to blocks instead of values, NSNumber * (^nextTrack)(NSNumber *) = ^(NSNumber *currentTrack) { return @(currentTrack.integerValue + 1); }; NSNumber * (^previousTrack)(NSNumber *) = ^(NSNumber *currentTrack) { return @(currentTrack.integerValue - 1); }; Now -mapReplace: to those instead of @1/@-1. For track selection, -map: (or here -reduceEach:) the signal...

RACSignal and an array of view models, is there a more reactive way?

ios,objective-c,mvvm,reactive-cocoa

For assembling the array of devices, check out -scanWithStart:reduce:. With this method, you could start with an empty array, and have the reduce block add each device to the array. For example: [[[self.browser rac_newDeviceSignal] map:^(RACTuple *parameters) { SDDevice *device = parameters.last; return [[DeviceViewModel alloc] initWithDevice:device]; }] scanWithStart:@[] reduce:^(NSArray models, DeviceViewModel...

ReactiveCocoa finally never be called with already completed replaySubject. Is it expected behavior?

reactive-cocoa

It's actually unrelated to the fact that the signal has already completed. Consider this: RACSubject *subject = [RACSubject subject]; [subject finally:^{ NSLog(@"never called"); }]; [subject subscribeCompleted:^{ NSLog(@"called"); }]; [subject sendCompleted]; Still never called! Why? Because finally: returns a new signal; it doesn't modify the existing signal. The new signal will...

How to use sendError in ReactiveCocoa

ios,reactive-cocoa

You can use catch: for that purpose. [[[[self.registerButton rac_signalForControlEvents:UIControlEventTouchUpInside] doNext:^(id x) { [MBProgressHUD showHUDAddedTo:self.view animated:YES]; self.registerButton.enabled = NO; }] flattenMap:^RACStream *(id value) { Login *login = [Login new]; return [[login registerSignalWithName:self.usernameTextField.text andPassword:self.passwordTextField.text] catch:^RACSignal *(NSError *error) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:error.localizedDescription...

Reactive Cocoa: subscribe only to new values

ios,cocoa,reactive-cocoa

There is a method for that, distinctUntilChanged: [[[RACObserve(self, self.testProperty) skip:1] distinctUntilChanged] subscribeNext:^(id x) { NSLog(@"Did Change: %@", x); }]; ...

How to make basic bindings in ReactiveCocoa 3

swift,reactive-cocoa,reactive-cocoa-3

So, after writing this question Colin Eberhardt made a part 3 of his RAC3 blog post series which includes a interesting and very relevant example of using MVVM and RAC3. The post can be found here and the source code here. Based on his work, I've managed to answer my...

reactive cocoa Avoid observing on flags to perform side effect

ios,reactive-cocoa

The flag property could be replaced with an empty method. The implementation of -setupHeartBeat could then use -rac_signalForSelector: on the empty method, instead of RACObserve on the flag. Calling the empty method would be semantically the same as assigning YES to the flag. - (void)resetHeartBeat { } - (RACSignal *)sendRequest:(id)request...

ReactiveCocoa 3: Map signal to value (Swift)

ios,swift,reactive-cocoa,frp

It turned out my Api.get() function should return a SignalProducer instead of a Signal. With this adjustment I ended up with a solution like this: let keywordToJson: SignalProducer<String, NSError> -> SignalProducer<JSON, NSError> = flatMap(.Concat) { keyword in Api().get("search/\(keyword)" } searchText.producer |> mapError { _ in NSError() } |> keywordToJson |>...

ReactiveCocoa, combine two signals on button enabled

ios,objective-c,mvvm,reactive-cocoa

If I'm not misunderstanding you, then the functionality should be easily achievable with combineLatest:reduce:, like so: RACSignal * enabledSignal = [RACSignal combineLatest:@[internetEnabledSignal, executingRegistrationSignal] reduce:^id(NSNumber * internetEnabled, NSNumber * isExecuting) { return @(internetEnabled.boolValue && !isExecuting.boolValue); }].distinctUntilChanged; RAC(self.button, enabled) = enabledSignal; combineLatest:reduce: won't send any next events until all signals have fired...

Removing nested subscribeNext in reactive pipeline

ios,objective-c,reactive-programming,reactive-cocoa

Check out -flattenMap:. For example: [[inputChanged flattenMap:^(id _) { @strongify(self); return [self asyncWebAPI]; }] subscribeNext:^(id x) { // Do stuff }]; ...

Auto-repeating count down timer in ReactiveCocoa

ios,objective-c,timer,reactive-cocoa

I think the missing piece of the puzzle is the very useful flattenMap operator. It essentially replaces any nexts from its incoming signal with nexts from the signal returned by it. Here's one approach to solving your problem (I replaced your newPaymentSignal method with a simple signal sending a string):...

What is the benefits of RAC schedule vs responding to subscriber immediately?

reactive-cocoa

Subscription always happens on a scheduler. If the subscription happens on a thread that has a scheduler, such as the main thread, then that block is executed immediately. If it's not immediate, it means the subscription is being trigger from a thread that doesn't have an associated scheduler. To ensure...