简体   繁体   中英

Using ReactiveCocoa, Kiwi, and Cocoapods together, getting “is not a tuple” exception

I'm trying to get a new project set up using ReactiveCocoa and Kiwi for testing, using CocoaPods for dependency management.

I have a first test set up for a typical login screen, where the login button isn't enabled until the user has input something for the username and password. Just a simpler version of some of the example code:

- (void)viewDidLoad
{
    [super viewDidLoad];
    RAC(self.loginButton, enabled) = [RACSignal combineLatest:@[self.userNameField.rac_textSignal,
                                                            self.passwordField.rac_textSignal]
                                                       reduce:^(NSString *username, NSString *password) {
        return @(username.length > 0 && password.length > 0);
    }];
}

The problem is that when I run my tests, I get the following error:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Value from stream <RACDynamicSignal: 0xe3735a0> name: +combineLatest: (
    "<RACDynamicSignal: 0xe368c50> name: <UITextField: 0xe3707a0> -rac_textSignal",
    "<RACDynamicSignal: 0xe372d80> name: <UITextField: 0xe36aef0> -rac_textSignal"
) is not a tuple: <RACTuple: 0xe377a40> (
    "",
    ""
)'

Of course, it is a RACTuple , so that's just confusing.

My research turned up the following issue on ReactiveCocoa:

https://github.com/ReactiveCocoa/ReactiveCocoa/issues/901

The diagnosis there is that ReactiveCocoa is getting linked in twice somehow. The person who had the issue there solved it by ditching CocoaPods. That doesn't seem right. Has anyone gotten this working?

For completeness, my Podfile is:

platform :ios, '6.0'

pod 'ReactiveCocoa'

target :test do
  link_with 'PollVaultTests'
  pod 'Kiwi/XCTest'
end

Well, I get to answer my own question.

It turns out that when pods are listed at the "global" level in your Podfile , CocoaPods includes them in all targets.

The result in this case is that my main project links in CocoaPods - and so does my test target.

When my test target gets injected into my main project to run the tests - you get ReactiveCocoa linked in twice. So there are two classes named RACTuple floating around - and so when the ReactiveCocoa code internally checks to make sure its argument is a RACTuple , it checks against the wrong copy of the class and effectively has a false negative result.

The solution is to make sure that my test target in the Podfile is configured to link in only the test pods like so:

platform :ios, '6.0'

pod 'ReactiveCocoa'

target :test, :exclusive => true do
  link_with 'PollVaultTests'
  pod 'Kiwi/XCTest'
end

That :exclusive => true part is what tells Cocoapods to only include the Kiwi test framework in my test target. Problem solved!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM