Search code examples
iosobjective-ciphonemvvmreactive-cocoa

Reactivecocoa send new value


I'm new to reactivecocoa and I need help. I was searching and I couldn't figure it out. Let assume that I have UIPickerView. In that pickerView there are 4 options, for each language one for example german, english, spanish, french. On selected language I need to send back abbreviation english - en, french - fr... I'm using MVVM architecture and this is my method in my ViewController. In that method I bind ViewModel and selected properties.

- (void)bindeViewModel
{
  RAC(self, selectedLanguageAbbreviation) = self.languageViewModel.observeSelectedLanguage;
}

"observeSelectedLanguage" is my signal and its implementation is:

-(RACSignal *) observeSelectedLanguage
{
    @weakify(self);
    return [RACObserve(self, selectedLanguage) filter:^BOOL(NSString *value){
    @strongify(self);

    if (value == LocalizedString(myValueString(English)))
    {
        self.selectedLanguageAbbreviation = @"en";
        return self.selectedLanguageAbbreviation;
    }
    else if (value == LocalizedString(myValueString(German)))
    {
        self.selectedLanguageAbbreviation = @"ge";
        return self.selectedLanguageAbbreviation;
    }
    else if (value == LocalizedString(myValueString(French)))
    {
        self.selectedLanguageAbbreviation = @"fr";
        return self.selectedLanguageAbbreviation;

    }
    else if (value == LocalizedString(myValueString(Spanish)))
    {
        self.selectedLanguageAbbreviation = @"sp";
        return self.selectedLanguageAbbreviation;
    }
    else
    {
        self.selectedLanguageAbbreviation = @"en";
        return self.selectedLanguageAbbreviation;
    }
 }];
}

"myValueString" is macro for returning string from enum, so English, French etc are part of enum. Can you help me and explain how to send abbreviation for selected language? Thank you


Solution

  • 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 selectedLanguage (in the view model's -init):

    RAC(self, selectedLanguageAbbreviation) = [RACObserve(self, selectedLanguage) map:^id(NSString* language) {
        // do your mapping here
    }];
    

    And then you can remove -observeSelectedLanguage method and bind view controller's selectedLanguageAbbreviation directly to view model's selectedLanguageAbbreviation (if it is still necessary):

    - (void)bindeViewModel
    {
      RAC(self, selectedLanguageAbbreviation) = RACObserve(self.languageViewModel, selectedLanguageAbbreviation);
    }