Giter VIP home page Giter VIP logo

reactiveobjc's Introduction

ReactiveCocoa

Reactive extensions to Cocoa frameworks, built on top of ReactiveSwift.

Join the ReactiveSwift Slack community.


Carthage compatible CocoaPods compatible SwiftPM compatible GitHub release Swift 5.1 platforms

⚠️ Looking for the Objective-C API?

🎉 Migrating from RAC 4.x?

🚄 Release Roadmap

What is ReactiveSwift?

ReactiveSwift offers composable, declarative and flexible primitives that are built around the grand concept of streams of values over time. These primitives can be used to uniformly represent common Cocoa and generic programming patterns that are fundamentally an act of observation.

For more information about the core primitives, see ReactiveSwift.

What is ReactiveCocoa?

ReactiveCocoa wraps various aspects of Cocoa frameworks with the declarative ReactiveSwift primitives.

  1. UI Bindings

    UI components expose BindingTargets, which accept bindings from any kind of streams of values via the <~ operator.

    // Bind the `name` property of `person` to the text value of an `UILabel`.
    nameLabel.reactive.text <~ person.name

    Note: You'll need to import ReactiveSwift as well to make use of the <~ operator.

  2. Controls and User Interactions

    Interactive UI components expose Signals for control events and updates in the control value upon user interactions.

    A selected set of controls provide a convenience, expressive binding API for Actions.

    // Update `allowsCookies` whenever the toggle is flipped.
    preferences.allowsCookies <~ toggle.reactive.isOnValues
    
    // Compute live character counts from the continuous stream of user initiated
    // changes in the text.
    textField.reactive.continuousTextValues.map { $0.characters.count }
    
    // Trigger `commit` whenever the button is pressed.
    button.reactive.pressed = CocoaAction(viewModel.commit)
  3. Declarative Objective-C Dynamism

    Create signals that are sourced by intercepting Objective-C objects, e.g. method call interception and object deinitialization.

    // Notify after every time `viewWillAppear(_:)` is called.
    let appearing = viewController.reactive.trigger(for: #selector(UIViewController.viewWillAppear(_:)))
    
    // Observe the lifetime of `object`.
    object.reactive.lifetime.ended.observeCompleted(doCleanup)
  4. Expressive, Safe Key Path Observation

    Establish key-value observations in the form of SignalProducers and DynamicPropertys, and enjoy the inherited composability.

    // A producer that sends the current value of `keyPath`, followed by
    // subsequent changes.
    //
    // Terminate the KVO observation if the lifetime of `self` ends.
    let producer = object.reactive.producer(forKeyPath: #keyPath(key))
    	.take(during: self.reactive.lifetime)
    
    // A parameterized property that represents the supplied key path of the
    // wrapped object. It holds a weak reference to the wrapped object.
    let property = DynamicProperty<String>(object: person,
                                           keyPath: #keyPath(person.name))

But there are still more to be discovered and introduced. Read our in-code documentations and release notes to find out more.

Getting started

ReactiveCocoa supports macOS 10.9+, iOS 8.0+, watchOS 2.0+, and tvOS 9.0+.

Carthage

If you use Carthage to manage your dependencies, simply add ReactiveCocoa to your Cartfile:

github "ReactiveCocoa/ReactiveCocoa" ~> 10.1

If you use Carthage to build your dependencies, make sure you have added ReactiveCocoa.framework and ReactiveSwift.framework to the "Linked Frameworks and Libraries" section of your target, and have included them in your Carthage framework copying build phase.

CocoaPods

If you use CocoaPods to manage your dependencies, simply add ReactiveCocoa to your Podfile:

pod 'ReactiveCocoa', '~> 10.1'

Swift Package Manager

If you use Swift Package Manager, simply add ReactiveCocoa as a dependency of your package in Package.swift:

.package(url: "https://github.com/ReactiveCocoa/ReactiveCocoa.git", branch: "master")

Git submodule

  1. Add the ReactiveCocoa repository as a submodule of your application’s repository.
  2. Run git submodule update --init --recursive from within the ReactiveCocoa folder.
  3. Drag and drop ReactiveCocoa.xcodeproj and Carthage/Checkouts/ReactiveSwift/ReactiveSwift.xcodeproj into your application’s Xcode project or workspace.
  4. On the “General” tab of your application target’s settings, add ReactiveCocoa.framework and ReactiveSwift.framework to the “Embedded Binaries” section.
  5. If your application target does not contain Swift code at all, you should also set the EMBEDDED_CONTENT_CONTAINS_SWIFT build setting to “Yes”.

Have a question?

If you need any help, please visit our GitHub issues or Stack Overflow. Feel free to file an issue if you do not manage to find any solution from the archives.

Release Roadmap

Current Stable Release:
GitHub release

In Development

Plan of Record

ABI stability release

ReactiveCocoa is expected to declare library ABI stability when Swift rolls out resilience support in Swift 5. Until then, ReactiveCocoa will incrementally adopt new language features.

reactiveobjc's People

Contributors

335g avatar adlai-holler avatar aitskovi avatar alanjrogers avatar almassapargali avatar andersio avatar bigboybad avatar brow avatar erichoracek avatar ikesyo avatar javisoto avatar jlawton avatar jonsterling avatar joshaber avatar joshvera avatar jspahrsummers avatar kastiglione avatar kkazuo avatar lawrencelomax avatar lbrndnr avatar mattjgalloway avatar mdiep avatar nachosoto avatar natestedman avatar neilpa avatar robrix avatar ruiaaperes avatar sharplet avatar thenikso avatar tomj avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

reactiveobjc's Issues

RACCommand's executing property abnormal

The RACCommand's RACSignal *immediateExecuting logic has been refactored in recent RAC version which makes me a little bit curiously.

The signalBlock of a command may become complexly sometimes..
One scenario that will cause executing signal stuck on @yES if the command received a disposed signal.

The test case I pasted here can re-produce this bug:

qck_it(@"should update executing signal status with a disposed source signal", ^{
	__block NSUInteger executingStage = 0;
	RACCommand<RACSignal *> *command = [[RACCommand alloc] initWithSignalBlock:^(RACSignal *signal) {
		return signal;
	}];
	
	// disposed source signal
	RACSubject *subject = [RACSubject.subject takeUntilBlock:^BOOL(id x) {
		return YES;
	}];
	
	// trigger executing to @YES
	[command execute:subject];
	
	// Stage 0: not started
	// Stage 1: start executing <= we are stucking at here
	// Stage 2: stop executing  <= the stage we were expected
	[command.executing subscribeNext:^(NSNumber* executingValue) {
		if (executingValue.boolValue) {
			if (0 == executingStage) {
				executingStage = 1;
			}
		} else {
			if (1 == executingStage) {
				executingStage = 2;
			}
		}
	}];
	expect(@(executingStage)).toEventually(equal(@2));
});

Ummm... I cannot figure it out the reason with debugging (for awhile).

Codes used in RACSignal *immediateExecuting:

- (instancetype)startWith:(id)value {
	return [[[self.class return:value]
		concat:self]
		setNameWithFormat:@"[%@] -startWith: %@", self.name, RACDescription(value)];
}

It looks like a signal concat a disposed source signal will lead no any further subscribtion.

Am I misleading anything on it?

feature request: RACTuple with generics

Is it possible to implement statically typed RACTuple with lightweight generics, e.g. RACTuple2<NSString, NSNumber>, RACTuple3<NSString, NSValue, NSNumber>?

Trouble with throttle operator

Hi, is anyone getting some trouble with throttle when creating a signal with +createSignal method:

RACSignal* signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        NSLog(@"%@", [NSThread currentThread]);
        
        [subscriber sendNext:@"1"];
        
        [subscriber sendNext:@"2"];
        
        [NSThread sleepForTimeInterval:4];
        
        [subscriber sendNext:@"3"];
        
        [subscriber sendNext:@"4"];
        
        [subscriber sendCompleted];
        return nil;
    }];
    
    [[[signal subscribeOn:[RACScheduler scheduler]] throttle:3] subscribeNext:^(id data) {
        NSLog(@"onNext: %@", data);
    } completed:^{
        NSLog(@"Completed");
    }];

Expected: 2
Actual Result: 4

Am i missing something ?

Make it possible to pass RACSignalAsynchronousWaitTimeout

Hi,

RACSignalAsynchronousWaitTimeout is used in - (id)asynchronousFirstOrDefault:(id)defaultValue success:(BOOL *)success error:(NSError **)error but it is not possible to change that value. If test is expected to take longer then defined value, it will fail.

Would it be possible to create alternative method that accepts this value as well?

RACSubject explicit generic

RACSubject currently not a generic type, despite that it inherited from RACSignal. Explicit generic type declaration required.

UIImagePickerController+RAC and AppStore submission

Due to new iTunesConnect rules, new uploaded builds would be rejected for privacy-sensitive data access, if these are not specified in app's info.plist.

ReactiveObjC users would be rejected because of missing NSPhotoLibraryUsageDescription.
This happens due to UIImagePickerController+RACSignalSupport.h, which uses UIImagePickerController.
This happens even if this category isn't used in project, only existence of files is enough.

It's important because developers should not be forced to include privacy descriptions which they don't use.

Simple removing
#import <ReactiveObjC/UIImagePickerController+RACSignalSupport.h>
from ReactiveObjC.h file doesn't fixes the issue.

Other frameworks examples:
https://forums.developer.apple.com/thread/62229
https://groups.google.com/forum/#!topic/google-admob-ads-sdk/UmeVUDrcDaw

-[RACMulticastConnection connect] not working as expected.

When calling connect it connects and subscribes correctly to the underlying signal.
Then, disposing the returned RACDisposable unsubscribe correctly from the underlying signal.
Then, reconnecting no longer subscribe to the underlying signal when it should to.

Here is a code you can paste in a sample project to verify.

- (void)testRx
{
    NSLog(@"Current Time: %@", NSDate.date);
    RACSignal *source = [RACSignal interval:1 onScheduler:[RACScheduler scheduler]]; //creates a sequence
    
    RACMulticastConnection *hot = [source publish]; // convert the sequence into a hot sequence
    
    RACDisposable *subscription1 = [hot.signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"1: Next(%@)", x);
    } error:^(NSError * _Nullable error) {
        NSLog(@"1: Error(%@)", error);
    } completed:^{
        NSLog(@"1: Completed");
    }];
    
    NSLog(@"Current Time after 1st subscription: %@", NSDate.date);
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        __block RACDisposable *connectionDisposable = [hot connect]; // hot is connected to source and starts pushing value to subscribers
        NSLog(@"Current Time after Connect: %@", NSDate.date);
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"Current Time just before 2nd subscription: %@", NSDate.date);
            
            RACDisposable *subscription2 = [hot.signal subscribeNext:^(id  _Nullable x) {
                NSLog(@"2: Next(%@)", x);
            } error:^(NSError * _Nullable error) {
                NSLog(@"2: Error(%@)", error);
            } completed:^{
                NSLog(@"2: Completed");
            }];
            
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                NSLog(@"Disconnecting");
                [connectionDisposable dispose];
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    NSLog(@"Reconnecting");
                    connectionDisposable = [hot connect]; // this should resubscribe and broadcast values !
                    
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                        NSLog(@"Ending");
                        [subscription1 dispose];
                        [subscription2 dispose];
                        [connectionDisposable dispose];
                    });
                });
            });
        });
    });
}

You can test the equivalent in C# using the code sample from here.

I will work on a PR to fix this.

Generic type resolving error (forward class declaration with lightweight generic RACSignal type)

ReactiveObjC (2.1.0)

Have ConfigurationViewModel.h

#import "RootViewModel.h"


@class RACSignal<ObjectType>;
@class Configuration;


@interface ConfigurationViewModel : RootViewModel

- (RACSignal<Configuration *> *_Nonnull)updateConfiguration;

@end

And with SomeViewModel.m

#import "SomeViewModel.h"
#import "RootViewModel_Internal.h"
#import <ReactiveObjC/ReactiveObjC.h>
#import "ConfigurationViewModel.h"


@implementation SomeViewModel

- (void)setupConfiguration
{
    self.configurationViewModel = [self.flow configurationViewModel:self];
    [[self.configurationViewModel updateConfiguration] reply];
_______________________________________________________^
}

@end

Got error:

ARC Semantic issue
/**/SomeViewModel.m:107:56: No visible @interface for 'RACSignal<Configuration *>' declares the selector 'reply'

Generic type constraint not working with map operator

I've admittedly not looked deeply into lightweight generics in Objective-C, but I'm seeing an issue when changing type in a signal chain using the map operator.

image

ReactiveObjC expects the output type of the original signal rather than the mapped one, and due to the presence of the generic refuses to allow type coercion. The following results in a build error:

image

My thought is this may be related to #34 as instancetype is picking up on the generic Signal, and that generic isn't updated with map.

[RACStream(Operations) reduceEach:]_block_invoke

1:testLoginViewModel.m

(RACSignal *)isValidUsernameAndPasswordSignal
{
return [RACSignal combineLatest:@[RACObserve(self, username), RACObserve(self, password)] reduce:^(NSString *username, NSString *password) {
return @([self isValidEmail:username] && [self isValidPassword:password]);
}];
}
//验证

(BOOL)isValidEmail:(NSString )data
{
NSString emailPattern =
@"(?:[a-z0-9!#$%&'+/=?^{|}~-]+(?:\.[a-z0-9!#$%\&'*+/=?\^{|}"
@"~-]+)|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-"
@"x7f]|\[\x01-\x09\x0b\x0c\x0e-\x7f])")@(?:(?:[a-z0-9](?:[a-"
@"z0-9-][a-z0-9])?.)+a-z0-9?|[(?:(?:25[0-5"
@"]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-"
@"9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21"
@"-\x5a\x53-\x7f]|\[\x01-\x09\x0b\x0c\x0e-\x7f])+)])";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:emailPattern options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:data options:0 range:NSMakeRange(0, [data length])];
return match != nil;
}

(BOOL)isValidPassword:(NSString *)password
{
return password.length >= 6;
}

2:I do unit testing on the above file,But it has been reporting the problem above;[RACStream(Operations) reduceEach:]_block_invoke

#import <Kiwi/Kiwi.h>

#import <ReactiveCocoa/ReactiveCocoa.h>
#import "testLoginViewModel.h"

SPEC_BEGIN(testLoginViewModelSpec)

describe(@"testLoginViewModel", ^{
__block testLoginViewModel* viewModel = nil;

beforeEach(^{
viewModel = [testLoginViewModel new];
});

afterEach(^{
viewModel = nil;
});

context(@"when username is wujunyang and password is freedom", ^{
__block BOOL result = NO;

it(@"should return signal that value is YES", ^{
    viewModel.username = @"[email protected]";
    viewModel.password = @"123456";
    
    [[viewModel isValidUsernameAndPasswordSignal] subscribeNext:^(id x) {
        result = [x boolValue];
    }];
    
     [[theValue(result) should] beYes];
});

});
});

SPEC_END

Where is the problem?

你好 我使用命令报错了

Failed to check out repository into /Users/huabinhu/Library/Caches/org.carthage.CarthageKit/dependencies/Quick: No object named "swift-3.0" exists

'metamacros.h' file not found

I have ReactObjC installed via Cocoapods, when I try to build my project I get:
RACTuple.h:10:9: 'metamacros.h' file not found

Any idea on how I can fix this issue?

Purpose of this project

Hi,

I've been using ReactiveCocoa locked to the last Objective C version

Only today I became aware of this project.

Is this meant to be a "replacement" for ReactiveCocoa version 2.5?

Can I safely assume that I can replace ReactiveCocoa in my podfile to ReactiveObjC?

Will this project have future updates?

RAC key-value validation feature request

As a programmer,
I want to have ability to use KVV (key-value validation) when do KVC via RAC
to reduce duplication
and avoid model properties key-path hard-coding each time.


Do something like this

    RACSignal *usernameSignal = [RACObserve(self, username) map:^RACTuple *_Nonnull(id _Nullable value) {
        NSError *error;
        return
        RACTuplePack(
        @([self.credentials validateValue:&value
                               forKeyPath:@"username"
                                    error:&error]),
                     error);
    }];

    self.usernameValidation = [usernameSignal map:^NSError *_Nullable(RACTuple *_Nonnull tuple) {
        return tuple.second;
    }];
    RAC(self.credentials, username) = [[RACObserve(self, username) zipWith:usernameSignal]
                                       filter:^BOOL(RACTuple *_Nonnull tuple) {
                                           return tuple.second;
                                       }];

In way like

    [RAC(self.credentials, username)
     validateTo:self.usernameValidation] = RACObserve(self, username);

Where

  • self - view modeller
  • self.credentials - model
  • self.username - data to validate
  • self.credentials.username - validating property
  • self.usernameValidation - signal with results of validation.

Lightweight generics on Signal purely for bridging and type annotations

Now that Obj-C lightweight generics can be bridged to swift, its seems like it could be quite useful to have lightweight generics on the values sent by RACSignal. This would be extremely helpful to those that are either planning or undergoing a piecemeal migration of a codebase from ReactiveObjC to ReactiveSwift.

From playing around with it a little bit, generic type annotations added to RACSignal now appear to be fully accessible in Swift 3. By using the lightweight generics from RACSignal, the pain of bridging between the two could be reduced significantly. However, it appears that this would cause a breaking change in the way that signals are bridged to Swift, since Swift extensions of Obj-C classes do not have access to the Obj-C lightweight generic annotations. A set of free functions for RACSignal → Signal/SignalProducer conversion should work for this though.

While there was previously a discussion about adding lightweight generics to RACSignal, that approach seemed to break down in two ways:

  • When you attempted to create generic signal chains, the compiler couldn't handle an method changing the generic type of the returned signal from the generic type of the signal that the operator was performed on. I don't think this type of functionality should be included as part of this addition. Instead, I'm suggesting that the generic types should not be included in any of the signal operators so that we can define away this class of issues entirely.
  • Issues with the inheritance hierarchy of RACSignal : RACStream when both have generic types. My suggestion is that we don't make RACStream generic whatsoever as part of this, since in practice RACStream is almost never exposed in interfaces, and tends to be used as an implementation detail only.

As such, the only places where the ValueType generic type would be used in a method would be in RACSignal methods where the return type is not a RACSignal. For example, the in the -[RACSignal subscribe...] family of methods:

@interface RACSignal<__covariant ValueType> (Subscription)

- (RACDisposable *)subscribeNext:(void (^)(ValueType _Nullable x))nextBlock;

@end

This would also encompass adding a second generic type to RACCommand:

@interface RACCommand<__contravariant InputType, __covariant ValueType> : NSObject

- (RACSignal<ValueType> *)execute:(nullable InputType)input;

@end

This change would expressly not be for improving the compiler checks on existing RACSignal chains written in Objective-C. As such, existing Objective-C RACSignal usage would be largely unaffected.

This migration could also involve adding type annotations to most of the UIKit/AppKit/Foundation categories that expose a RACSignal. While this wouldn't be very helpful for existing consumers of these categories since they have mostly been ported to native Swift 3 with REX, it would serve as a better form of documentation than the existing documentation comments.

Let me know what your thoughts are. I can take a shot at implementing this if it seems like something worth doing. Thanks!

First release?

Since ReactiveObjC is just what was releasable-ReactiveCocoa, minus a bunch of stuff, it's unsurprisingly in a working/releasable state. Might it be appropriate to.. do that? :)

RACSubject flattenMap to long running signal break subscribing.

   RACSubject *subject = [RACSubject subject];

   RACSignal *resultSignal = [[[subject filter:^BOOL(NSNumber *item) {

        return [item isKindOfClass:[NSNumber class]];
    }] flattenMap:^RACSignal *(NSNumber *item) {

        return [RACSignal createSignal:
                ^RACDisposable *(id<RACSubscriber> subscriber) {
                    __block TheTask *veryLongRunningTask =
                    [self doVeryLongRunningTaskForItem:item
                                        withCompletion:
                     ^(id result, NSError *error) {

                         if (!error) {
                             [subscriber sendNext:result];
                             [subscriber sendCompleted];
                         } else {
                             [subscriber sendError:error];
                         }
                     }];

                    return [RACDisposable disposableWithBlock:^{
                        [veryLongRunningTask cancel];
                    }];
        }];
   [subject sendNext:@1];
   [subject sendNext:@2];

I need to receive both results for @1 and @2 values in resultSignal, but sending second time next signal to subject very soon after first one, until veryLongRunningTask not completed yet, break expected behaviour: resultSignal do not return neither values, and will ignore all next values after that.

Is it bug, or what exactly did I do wrong, and how should so?


version:

 $ grep ReactiveObjC Podfile.lock
    - ReactiveObjC (~> 2.1)
  - ReactiveObjC (2.1.0)
    - ReactiveObjC (~> 2.1)
  - ReactiveObjC (~> 2.1)
  ReactiveObjC: 2edae120982d8e6d5407503a10edcfdd87eb8639

flattenMap new return type

I am in the process of migrating from ReactiveCocoa 2.5 to ReactiveObjC 2.1.2

I've noticed that flattenMap's return type changed from RACStream to __kindOf RACSignal

Shouldn't have changed to __kindOf RACStream as RACSignal continues to be a subclass of RACStream?

A "navigationItem.rightBarButtonItem" Exception"

I define an enable RACSignal ,which is bind to RAC(RAC(self.navigationItem.rightBarButtonItem,enabled), at same time , its also be a enableSignal of "self.navigationItem.rightBarButtonItem.rac_command".
Then the excetpion is thrown:

OG: error: session_id=3EFB33D463E8F6453C31794E3A35EECA, context=Signal name: is already bound to key path "enabled" on object , adding signal name: is undefined behavior
(null)
((
0 CoreFoundation 0x0000000182126dc8 + 148
1 libobjc.A.dylib 0x000000018178bf80 objc_exception_throw + 56
2 CoreFoundation 0x0000000182126c80 + 0
3 Foundation 0x0000000182aac1c0 + 88
4 ReactiveCocoa 0x00000001006d2684 -[RACSignal(Operations) setKeyPath:onObject:nilValue:] + 2216
5 ReactiveCocoa 0x00000001006d1da4 -[RACSignal(Operations) setKeyPath:onObject:] + 116
6 ReactiveCocoa 0x00000001006fa4d8 -[UIBarButtonItem(RACCommandSupport) setRac_command:] + 308
7 Neighbours 0x000000010003f834 -[FillMobileVC bindRac2ThisVC] + 800
8 Neighbours 0x000000010003f3b8 -[FillMobileVC viewDidLoad] + 368

The Code throw Exception is listed below, if "RAC(self.navigationItem.rightBarButtonItem,enabled) = enablSginal" is removed , it works fine.

RACSignal* enablSginal = [self.mobileTextField.rac_textSignal map:^id(id value) {
NSString* mobile = (NSString*)value;
BOOL nextEnabled = [MobileFormatUtil isValideMobile:mobile];
return @(nextEnabled);
}];

RAC(self.navigationItem.rightBarButtonItem,enabled) = enablSginal; //The bug Line//

__weak FillMobileVC* weakSelf = (FillMobileVC*)self;
self.navigationItem.rightBarButtonItem.rac_command = [[RACCommand alloc]initWithEnabled:enablSginal signalBlock:^RACSignal *(id input) {
return [weakSelf requestVeiryCodeSignal:weakSelf.mobileTextField.text];
}];

Bootstrap?

Should a bootstrap script exist in the scripts folder based on step two of the setup?

Sort call sequence for subscribers.

Hi guys, i'm have a question about RAC2.5
I have 3 subscribers on my signal, i'm don't know when they will be subscribed, but know one of it signals must called before other all. How can i do that on RAC2.5?

Now solve this feature with adding delay:.1 for another subscribers.

RACMulticastConnection and error handling

Hello,
Using RACMulticastConnection it's quite easy to cache the result of a network request. However I'm having trouble in handling gracefully the following scenario:
If the signal completes with error the first new subscription should trigger again the signal, all this in a thread safe manner.

Thanks.

RAC UITextField big bug

copy: ReactiveCocoa/ReactiveCocoa#3179 (comment)

RACSignal *signal1 = self.textField.rac_textSignal;
RACSignal *cSignal1 = [signal1 distinctUntilChanged];
[cSignal1 subscribeNext:^(NSString *number) {

    NSInteger length = number.length;
    NSString *text = weakself.textField.text;
    DEBUGG(@"111Text: %@, number: %@", text, number);
    if (length >= 20)
    {
        NSString *subText = [number substringToIndex:20];
        DEBUGG(@"subText: %@, number: %@", subText, number);
        weakself.textField.text = subText;
    }
}];

first input text: 1234567891234567
second input text: 12345678912345678; show subtext: 1234567891234567
third input text: 12345678912345678; show subtext: 12345678912345678
because the subscribeNext block is not called;

Unknown type name RACSubject, RACSignal

Hi,

I am in dire need of help, I am working on a project started by somebody else. I just did a pod update and I have:

Installing ReactiveCocoa (5.0.1)
Installing ReactiveSwift (1.1.0)
Installing Result (3.2.1)

When I build the project i get:

screen shot 2017-03-08 at 13 34 30

Any input is much appreciated.

Adrian

RACObserve Expected ';' after expression

So I am trying to create a new email signal, but getting error: "Expected ';' after expression".

- (instancetype)init {
    self = [super init];
    if (self) {
        RACSignal *emailSignal = RACObserve(self, email);
    }
    return self;
}

RACCommand - dispose executing signal

I have a little confused about dispose mechanism of RACCommand. I want to dispose subscription of executing signal manually, but disposableBlock invokes only after sendCompleted event. It's a problem of my real task, hope someone can help me.

- (void)test {
    RACCommand *rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
        return [self signal];
    }];

    RACDisposable *rac_dispose = [[rac_command execute:nil] subscribeNext:^(id x) {}];
    [rac_dispose dispose];
}

- (RACSignal *)signal {
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [subscriber sendNext:nil];
            [subscriber sendCompleted];
        });
        return [RACDisposable disposableWithBlock:^{
            NSLog(@"dispose block");
        }];
    }];
}

First in interval

Hi, we're looking for a way to get the first value sent in an interval, all other values sent in that interval should be ignored, and then this should repeat.

So for example (with an interval of 1 second):

4-(wait 0.4 second)-5-(wait 0.4 second)-6-(wait 0.4 second)-7-(wait 0.4 second)-|
would become:
4-7-|

This differs from throttle or buffer, because the first value should be sent right away rather than waiting for the end of the interval.

I've found a Stackoverflow answer that addresses a similar problem, although it uses a Window operator. It seems that ReactiveObjc used to have such an operator but it was deprecated here.

With the currently existing operators, is there a nice way to accomplish what we're trying to do? We've managed to do it by copying and slightly modifying the implementation of throttle, but that seems like a very messy way to do this.

Any help would be greatly appreciate, thank you!

Swift compiler crash

Hi,

While porting the project to Swift 3 I cannot get around some segmentation faults. The scenario is the following. I have an Objective-C protocol:

#import "ViewModelProtocol.h"

@class RACCommand;
@class RACSignal;

@protocol ListViewModelProtocol <ViewModelProtocol>

@property (nonatomic, strong) RACCommand *listItemSelectedCommand;
@property (nonatomic, strong, readonly) RACCommand *reloadDataCommand;
@property (nonatomic, strong) NSArray    *datasource;

@end

Which is implemented in Swift as:

    lazy var reloadDataCommand: RACCommand<AnyObject, AnyObject>! = {
        return RACCommand { (argument) -> RACSignal<AnyObject> in
            return self.reloadDataAction(argument: argument)
        }
    }()

In the end I always get the same error:

1. While emitting SIL for getter for reloadDataCommand at /Users/vmagalhaes/work/ios/nlife/nlife/ViewModels/ParkingViewModel.swift:28:14

Probably this has nothing to do with ReactiveObjc but any help would be appreciated.

There is a reference to something similar but my property is not optional https://bugs.swift.org/browse/SR-1825

Thanks in advance,

RACCommand's executionSignals's subscribeNext block or error's block execute more times?

i use RACCommand to send a network request in a sendController, you can click this controller right barbuttomitem, then will execute a command; if success, this sendController will be dismissed;
but when fail, you know i add the log in the errors's subscribeNext block; i click barbuttomitem first time, the log will be show one time; but when i click at the second time, the log will be show two times; and it will always added one times if i continue click;
so, i want to know is there some solution to settle this problem? thanks!

readme link 404

The link of "Escape from Callback Hell" in readme is 404.

Generics in `map:`

@erichoracek, @mdiep Can ReactiveObjC use generics for map:-like operators as well, in way described here (use additional mapper wrapper for strict type checking)? Disadvantage of that approach -- it can't be done implicitly.

Tagged release and a prebuilt binary for Carthage?

Not sure about the versioning schema you'd like to use (e.g. is this ReactiveObjC 1.0, or 2.6), but it would be nice to be able to include this repo via Carthage alongside a prebuilt framework.

Thanks for separating this out!

Could not extend RACSignal with generic in Swift 3

Most of the code in my app is ObjC, and my Unit Test code is pure Swift. After switch from ReactiveCocoa repo to ReactiveObjC, the extension for RACSignal no longer compile. The code is something like this

extension RACSignal {
    
    fileprivate func foo() -> RACSignal
        //...
    }
}

and I get error msg below:

Extension of a generic Objective-C class cannot access the class's generic parameters at runtime

The issue has been discussed this proposal

I wonder is there any way to work around this other than explicitly checkout commit before this ?
Thx in advance😝

Improve performance of `setNameWithFormat:`

Close this issue at will. I felt it was cleaner to continue the discussion in a new thread instead of discussing in a closed thread from 2014 ReactiveCocoa/ReactiveCocoa#1083 on the swift repo.

I think I found a way to improve the performance of setNameWithFormat using blocks. Memory and performance could potentially be improved when setNameWithFormat is active (typically debug builds). I haven't had any problems with this my self, but reading that issue thread ReactiveCocoa/ReactiveCocoa#1083 made me think it's a problem for some people.

Well, instead of creating the strings directly we can defer (and cache) this operation:
https://gist.github.com/hfossli/3682cd8769bd4d167f6e05ee4b34af8c

I wrote this test. And my prototype passes that test fine. This should mean better performance and lower memory usage.

@interface Foo : NSObject
@property (nonatomic, assign) int descriptionRequestedCount;
@end

@implementation Foo

- (NSString *)description
{
    self.descriptionRequestedCount++;
    return @"<Foo 0xFOOBAR>";
}

@end

@interface RACSignalTest : XCTestCase
@end
@implementation RACSignalTest

- (void)testWithSignal
{
    Foo *foo = [Foo new];
    RACSignal *signal = [[RACSignal new] someOperatorWithObject:foo];
    XCTAssertTrue(foo.descriptionRequestedCount == 0, @"");
    XCTAssertEqualObjects([signal name], @"transformed using `someOperatorWithObject` with object <Foo 0xFOOBAR>");
    XCTAssertTrue(foo.descriptionRequestedCount == 1, @"");
    XCTAssertEqualObjects([signal name], @"transformed using `someOperatorWithObject` with object <Foo 0xFOOBAR>");
    XCTAssertTrue(foo.descriptionRequestedCount == 1, @"");
}

@end

Ambiguous use of distinctUntilChanged

Hi,

The following code is causing an ambiguous error:

let observableProducts: RACSignal<AnyObject> = RACObserve(licensingService as! NSObject, "products")
let productChanges = observableProducts.distinctUntilChanged()
Ambiguous use of 'distinctUntilChanged()'
- Found this candidate (ReactiveObjC.RACSignal<ValueType>)
- Found this candidate (ReactiveObjC.RACStream)

The utility class I'm using to bridge RACObserve is:

import Foundation

struct RAC  {
    var target : NSObject!
    var keyPath : String!
    var nilValue : AnyObject!
    
    init(_ target: NSObject!, _ keyPath: String, nilValue: AnyObject? = nil) {
        self.target = target
        self.keyPath = keyPath
        self.nilValue = nilValue
    }
    
    func assignSignal(signal : RACSignal<AnyObject>) {
        signal.setKeyPath(self.keyPath, on: self.target, nilValue: self.nilValue)
    }
}

extension NSObject {
    func RACObserve(_ target: NSObject!,_ keyPath: String) -> RACSignal<AnyObject>! {
        return target.rac_values(forKeyPath: keyPath, observer: self)
    }
}


infix operator <~
func <~ (rac: RAC, signal: RACSignal<AnyObject>!) {
    rac.assignSignal(signal: signal)
}

infix operator ~>
func ~> (signal: RACSignal<AnyObject>!, rac: RAC) {
    rac.assignSignal(signal: signal)
}

Is there any way to workaround this ? I cannot use the pure Swift version for now.

Thanks in advance,

RACObserve: Expected ';' after expression

I use RACObserve macro, I'm also getting the error: "Expected ';' after expression" in Xcode7.3. And ReactiveObjC v2.1.0 installed using cocoapod.But in Xcode8 is not.
image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.