标签: reactive-cocoa

用副作用重新组织委托方法的方法

只是试图在某些情况下围绕ReactiveCocoa方法.

我有一种情况,即段控制器交换子视图控制器.我需要在这里做几件事:

  1. 当移动到父控制器时,我必须更新它contentInset,tableView因为iOS7没有为我自己处理自定义容器视图
  2. 启动搜索时,我需要淡化导航栏,并更新contentInset带动画
  3. 搜索结束时,我需要淡入navigationBar后退并重置contentInset动画

以下是以命令式样式完成此操作的当前代码:

- (void)didMoveToParentViewController:(UIViewController *)parent
{
    [super didMoveToParentViewController:parent];
    if (parent) {
        CGFloat top = parent.topLayoutGuide.length;
        CGFloat bottom = parent.bottomLayoutGuide.length;
        if (self.tableView.contentInset.top != top) {
            UIEdgeInsets newInsets = UIEdgeInsetsMake(top, 0, bottom, 0);
            self.tableView.contentInset =  newInsets;
            self.tableView.scrollIndicatorInsets = newInsets;
        }
    }
}

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
    [UIView animateWithDuration:.25 animations:^{
        self.navigationController.navigationBar.alpha=0;
        self.tableView.contentInset = UIEdgeInsetsMake([UIApplication sharedApplication].statusBarFrame.size.height, 0, 0, 0);
    }];
    return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
    [UIView animateWithDuration:.25 animations:^{ …
Run Code Online (Sandbox Code Playgroud)

reactive-cocoa

7
推荐指数
1
解决办法
2614
查看次数

使用ReactiveCocoa时未调用错误块

出于某种原因,我没有收到错误消息.(我在这里简化了代码以直截了当.)

// Send an error message 
_loginButton.rac_command = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
    return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendError:error]; // Pretend this is a real error
        return nil;
    }];
}];

// Subscribe to loginButton's returned signal
[_loginButton.rac_command.executionSignals subscribeNext:^(RACSignal *loginSignal) {
    [loginSignal subscribeError:^(NSError *error) {
         NSLog(@"A");
    } completed:^{
         NSLog(@"B");
    }];
}];
Run Code Online (Sandbox Code Playgroud)

这打印"B".知道为什么吗?如果-sendError:在订户上调用,为什么完成块会收到它?

objective-c ios reactive-cocoa

7
推荐指数
2
解决办法
1825
查看次数

Reactive Cocoa - 以编程方式设置文本时不会调用UITextView的rac_textSignal

我正在实现一个聊天UI,并使用Reactive Cocoa根据用户的类型调整聊天气泡的大小.目前,我正在根据textview更新UI的布局rac_textSignal.一切都很好 - 除了一点:当用户发送消息时,我以编程方式清除文本字段:

_inputTextView.text = @"";
Run Code Online (Sandbox Code Playgroud)

...但textview rac_textSignal不会激活.我听说这是ReactiveCocoa的一个功能 - 但是构建它的正确方法是什么?我是否需要拥有一个NSString currentlyTypedString,并在该字符串更新时驱动UI更改?

objective-c uitextfield ios reactive-cocoa

7
推荐指数
2
解决办法
2620
查看次数

RACChannel:没有看到我预期的双向绑定

(也可以在GitHub上公开评论来自ReactiveCocoa的人.)

我在一个非常简单的尝试ReactiveCocoa RACTest(源是在GitHub上)应用程序试图通过实际使用它坚定了我的理论认识.

,我有一个RACChannel,它提供了一个ed l值和我指定的任何参数之间的双向绑定.RAC()RACChannel

我的用法如下:

// Map the ticker's accumulationEnabled property to self.paused.
RAC(self, paused) = [RACChannelTo(_ticker, accumulateEnabled) deliverOn:[RACScheduler mainThreadScheduler]];
Run Code Online (Sandbox Code Playgroud)

我看到流动的变化的一个方向,从_ticker.accumulateEnabledself.paused,但变化self.paused不会流回_ticker.

我误解了RACChannel吗?它有什么用,这怎么不是预期的用途?

reactive-cocoa

7
推荐指数
1
解决办法
1414
查看次数

仪器RACSignal的最佳实践

我的任务是为应用程序添加一些检测逻辑,以跟踪各种API调用的延迟.我正在努力想出一种干净的,无副作用的方法来为返回RACSignal(延迟执行API调用)的方法添加时序检测.

注意事项

  • 使用ReactiveCocoa @ 1.9.5(目前无法升级)
  • 使用Parse-RACExtensions @ 0.0.2
  • 我宁愿在ViewModel层设置时序,而不是修改Parse-RACExtensions.这是因为VM有我想记录的额外信息,比如查询参数,而且我不需要每个API调用.
  • 仅在收到completed活动时记录时间
  • 本着无痛仪器的精神,呼叫者的负担应尽可能小

试图解决方案

我唯一能想到的就是创建一个处理定时器逻辑的具体RACSubscriber子类.除了令人讨厌的子类,这显然不是理想的,因为它需要一个显式subscribe:,这反过来需要一个replay源信号.此外,调用者还有一个负担,因为他们必须至少重构以获得信号的临时句柄.

@interface SignalTimer : RACSubscriber

@property (nonatomic) NSDate *startDate;

@end

@implementation SignalTimer

- (void)didSubscribeWithDisposable:(RACDisposable *)disposable
{
    [super didSubscribeWithDisposable:disposable];

    self.startDate = [NSDate date];
}

- (void)sendCompleted
{
    NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:self.startDate];
    NSLog(@"Time elapsed: %f", duration);

    [super sendCompleted];
}

@end
Run Code Online (Sandbox Code Playgroud)

用法如下所示:

- (RACSignal*)saveFoo:(Foo*)fooParseObj {
    RACSignal *save = [[fooParseObj rac_save] replay]; // Don't forget replay!
    [save subscribe:[[SignalTimer alloc] initWithName@"Saving the user's foo …
Run Code Online (Sandbox Code Playgroud)

objective-c reactive-programming ios reactive-cocoa

7
推荐指数
1
解决办法
526
查看次数

使用ReactiveCocoa重试异步操作

我正在使用ReactiveCocoa信号来表示对我们系统中RESTful后端的调用.每个RESTful调用都应该接收一个令牌作为参数之一.令牌本身是从身份验证API调用接收的.

所有工作正常,我们现在介绍令牌到期,所以后端接入类可能需要如果API调用失败,HTTP代码403我想使这个操作的调用者完全透明的重新授权本身,这是我来最好起来:

- (RACSignal *)apiCallWithSession:(Session *)session base:(NSString *)base params:(NSDictionary *)params get:(BOOL)get {
    NSMutableDictionary* p = [params mutableCopy];
    p[@"token"] = session.token;

    RACSubject *subject = [RACReplaySubject subject];

    RACSignal *first = [self apiCall:base params:p get:get];  // this returns the signal representing the asynchronous HTTP operation

    @weakify(self);
    [first subscribeNext:^(id x) {
        [subject sendNext:x];   // if it works, all is fine
    } error:^(NSError *error) {
        @strongify(self);

        // if it doesn't work, try re-requesting a token
        RACSignal *f = [[self action:@"logon" email:session.user.email password:session.user.password]
                         flattenMap:^RACStream *(NSDictionary *json) …
Run Code Online (Sandbox Code Playgroud)

frp ios reactive-cocoa

7
推荐指数
1
解决办法
2560
查看次数

RACObserve不工作

我正在尝试观察我的ViewModel中的属性,然后使用ReactiveCocoa更新带有它的值的标签,但它没有更新.

这是我得到的:

视图模型

var amount: NSDecimalNumber
Run Code Online (Sandbox Code Playgroud)

视图控制器

RAC(self.amountLabel, "text") <~ RACObserve(self.viewModel, "amount").map({
            (value) -> AnyObject! in
                let numberFormatter = NSNumberFormatter()
                numberFormatter.numberStyle = .CurrencyStyle

                return numberFormatter.stringFromNumber(value as NSDecimalNumber)
        })
Run Code Online (Sandbox Code Playgroud)

我检查过,ViewModel正在更新'amount'属性.这里有什么我想念的吗?

我也试过这个测试:

RACObserve(self.viewModel, "amount").subscribeNext { 
    (value) -> Void in
        println(value)
}
Run Code Online (Sandbox Code Playgroud)

也不起作用.

我正在使用ReactiveCocoa 2.4.7,因为我的应用程序支持iOS 7. Swift [1,2]和此版本中的宏替换之间是否存在任何不兼容性?

[1] - https://github.com/ashfurrow/Swift-RAC-Macros

[2] - http://blog.scottlogic.com/2014/07/24/mvvm-reactivecocoa-swift.html

ios reactive-cocoa

7
推荐指数
1
解决办法
1961
查看次数

在Reactive Cocoa 4中点击UIButton获取信号

如何通过Signal点击来创建UIButton

到目前为止,我试图使用目标/行动,但已经开始认为可能有一种更简单的方法.

Colin Eberhardt一篇文章中,声明Signals适用于UI操作.但是当我尝试使用目标/动作时,我需要创建一个CocoaAction最终初始化为SignalProducer.

我想要的是一些在每个用户点击时Signal发出它的next事件.然后,我想要将此信号转换为读取UITextFields并继续执行这些值以在我的应用程序中使用它们.

ios reactive-cocoa swift

7
推荐指数
1
解决办法
1718
查看次数

为什么SignalProducer不返回信号?

我觉得我理解ReactiveCocoa的所有基本组件(从概念上讲),通过了解如何将所有组件连接在一起仍然有点令人困惑.

例如,在阅读了有关Signal之后,我完全希望SignalProducer只有一个start()方法返回一个Signal,你可以这样使用它:

mySignalProducer.start().observe(myObserver)
Run Code Online (Sandbox Code Playgroud)

相反,你必须将观察者传递给start(),SignalProducer为你调用observe():

mySignalProducer.start(myObserver)
Run Code Online (Sandbox Code Playgroud)

这意味着SignalProducer的接口要大得多(更需要理解),因为observe()的所有变量都必须在start()上重复(例如startNext()等).

我认为这里有两种可能性:

  1. 有技术原因,为什么start()不能简单地返回一个信号
  2. 我在概念上误解了SignalProducer,导致对其界面的不满

如果是1,我猜这与内存管理和一次性用品有关,我还不完全了解.

我更担心2是这样的.在内部,我对SignalProducer的理解基本上映射到Factory的概念,例如:

mySignalFactory.createSignal().observe(myObserver)
Run Code Online (Sandbox Code Playgroud)

这就是为什么我很惊讶我们没有找到返回Signal的start().

如果社区可以在这里阐明一点,我将非常感激.

谢谢!

ios reactive-cocoa swift reactive-cocoa-4

7
推荐指数
1
解决办法
1892
查看次数

如何获取UIAlertController observable(ReactiveCocoa或RxSwift)?

我实施了"反应",UIAlertController所以我可以Observable<Int>按下按钮.(见下面的代码).

我的问题或疑问是:

  • 这个实现是否正确?我不喜欢存放观察者; 我想知道是否有更好的解决方案.
  • 或者...... ReactiveCocoa或RxSwift中是否已实现此功能?

这是实施.我删除了与te问题无关的部分.

class AlertBuilder {

    typealias AlertAction = (Int) -> ()

    private let alert: UIAlertController

    /** If observable() is called, we keep here the observers to notify them */
    private var observers: [AnyObserver<Int>] = []

    init(alert: UIAlertController) {
        self.alert = alert
    }

    /** When using observable(), the action is not needed. */
    func button(_ title: String, style: UIAlertActionStyle = .default, action: AlertAction? = nil) -> AlertBuilder {

        let buttonIndex = alert.actions.count …
Run Code Online (Sandbox Code Playgroud)

ios reactive-cocoa rx-swift

7
推荐指数
1
解决办法
2523
查看次数