标签: reactive-cocoa

没有订阅者时停止发布,有订阅者时自动启动

如果RACSignal没有订阅者,我将如何实现停止发布?如果有订阅者则自动启动?

这是一个场景:

让我们说我有一个currentLocationSignalAppDelegate.当视图卸载时,我LocationViewController会订阅currentLocationSignal视图加载和取消订阅(dispose).由于获取当前位置需要几秒钟,我希望始终订阅currentLocationSignal应用程序打开的时间(并在几秒钟后自动取消订阅),所以当我到达时,LocationViewController我会得到一个准确的位置.因此,信号可能有多个订户.当第一个用户收听时,它需要开始呼叫startUpdatingLocation,当没有用户需要呼叫时stopUpdatingLocation.

cocoa-touch objective-c reactive-programming ios reactive-cocoa

6
推荐指数
1
解决办法
1085
查看次数

如何从ReactiveCocoa信号中获取当前值?

我有信号返回NSNumber:

RACSignal *signal = ....
Run Code Online (Sandbox Code Playgroud)

然后在某些代码处我希望在执行时得到信号的值,例如:

NSNumber *value = [code that extracts current value of signal];
Run Code Online (Sandbox Code Playgroud)

reactive-programming ios reactive-cocoa

6
推荐指数
1
解决办法
3375
查看次数

为什么在ReactiveCocoa中调用信号两次?

我正在使用https://github.com/ReactiveCocoa/ReactiveCocoa实现我的第一个代码.

用于登录用户.该行[subscriber sendNext:user];被调用两次,但我希望只有一行.并且根本没有调用地图(因此永远不会调用自动登录)

这是我的实施:

-(RACSignal *) login:(NSString *)email pwd:(NSString *)pwd
{
    DDLogInfo(@"Login user %@", email);

    RACSignal *login = [RACSignal createSignal:^ RACDisposable *(id<RACSubscriber> subscriber)
    {        
        [PFUser logInWithUsernameInBackground:email password:pwd block:^(PFUser *user, NSError *error) {

            if (error) {
                [subscriber sendError:error];
            } else {
                [subscriber sendNext:user];

                [subscriber sendCompleted];
            }
        }];

        return nil;
    }];

    [login map:^(PFUser *user) {
        return [self autoLogin:user];
    }];

    return login;
}
Run Code Online (Sandbox Code Playgroud)

这样称呼:

NSString *email = data[@"email"];
NSString *pwd = data[@"pwd"];
[SVProgressHUD showWithMaskType:SVProgressHUDMaskTypeBlack];

RACSignal *login = [[SyncEngine server] …
Run Code Online (Sandbox Code Playgroud)

objective-c reactive-programming ios reactive-cocoa

6
推荐指数
2
解决办法
1903
查看次数

使用ReactiveCocoa跟踪远程对象的UI更新

我正在制作一个iOS应用程序,可让您远程控制桌面上播放的应用程序中的音乐.

最难的问题之一是能够正确地更新"跟踪器"的位置(其显示当前正在播放的歌曲的时间位置和持续时间).这里有几个输入源:

  • 在启动时,遥控器发送网络请求以获得当前播放歌曲的初始位置和持续时间.
  • 当用户使用遥控器调整跟踪器的位置时,它向音乐应用发送网络请求以改变歌曲的位置.
  • 如果用户使用桌面上的应用程序来更改跟踪器的位置,则应用程序会使用跟踪器的新位置向远程控制器发送网络请求.
  • 如果当前正在播放歌曲,则跟踪器的位置每0.5秒左右更新一次.

目前,跟踪器是一个UISlider,由"玩家"模型支持.每当用户更改滑块上的位置时,它都会更新模型并发送网络请求,如下所示:

在NowPlayingViewController.m中

[[slider rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(UISlider *x) {
    [playerModel seekToPosition:x.value];
}];

[RACObserve(playerModel, position) subscribeNext:^(id x) {
    slider.value = player.position;
}];
Run Code Online (Sandbox Code Playgroud)

在PlayerModel.m中:

@property (nonatomic) NSTimeInterval position;

- (void)seekToPosition:(NSTimeInterval)position
{
    self.position = position;
    [self.client newRequestWithMethod:@"seekTo" params:@[positionArg] callback:NULL];
}

- (void)receivedPlayerUpdate:(NSDictionary *)json
{
    self.position = [json objectForKey:@"position"]
}
Run Code Online (Sandbox Code Playgroud)

问题是当用户"摆弄"滑块时,会排队一些网络请求,这些请求都会在不同时间返回.当收到响应时,用户可能已经再次移动滑块,将滑块移回到先前的值.

我的问题:如何在此示例中正确使用ReactiveCocoa,确保处理来自网络的更新,但仅限于用户之后没有移动滑块?

cocoa-touch objective-c uikit ios reactive-cocoa

6
推荐指数
1
解决办法
1023
查看次数

ReactiveCocoa:处理重复信号

我试图了解如何处理计划在后台线程上运行的RACSignal.

// Start button
@weakify(self);
[[self.startButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(UIButton *sender) {
    @strongify(self);
    self.startButton.enabled = NO;
    NSDate *startDate = [NSDate date];
    RAC(self, elapsedTime) = [[[[RACSignal interval:0.1f onScheduler:
                                 [RACScheduler schedulerWithPriority:RACSchedulerPriorityDefault]]
                                startWith:[NSDate date]] map:^id(id value) {
        NSTimeInterval timeInterval = [(NSDate *)value timeIntervalSinceDate:startDate];
        return [NSNumber numberWithDouble:timeInterval];
    }] deliverOn:[RACScheduler mainThreadScheduler]];
}];

// Stop button
[[self.stopButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
    self.startButton.enabled = YES;

    // How do I stop the timer here...???

}];

RAC(self.timeLabel, text) = [RACObserve(self, elapsedTime) map:^id(NSNumber *number) {
    NSString *string = [NSString stringWithFormat:@"%.1f sec. elapsed", …
Run Code Online (Sandbox Code Playgroud)

objective-c ios reactive-cocoa

6
推荐指数
1
解决办法
3965
查看次数

ReactiveCocoa rac_valuesForKeyPath在Swift中不起作用

我正在尝试在我用Swift编写的iOS应用程序中采用ReactiveCocoa.不幸的是,看起来rac_valuesForKeyPath不能按预期工作.这是一个例子:

class Source: NSObject {
    var observable: String = "<Original>"

    override init() {
        super.init()

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), { () -> Void in
            self.observable = "<Updated>"
            println("Updated value to \(self.observable)");
        })
    }
}

class Observer: NSObject {
    init(source: Source) {
        super.init()

        source.rac_valuesForKeyPath("observable", observer: self).subscribeNext { (value: AnyObject!) -> Void in
            println(">>> Observable value changed: \(value)")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该示例生成以下输出:

>>> Observable value changed: <Original>
Updated value to <Updated>
Run Code Online (Sandbox Code Playgroud)

这意味着未调用subcribeNext块.

预期的输入是:

>>> Observable value changed: <Original>
Updated value to <Updated> …
Run Code Online (Sandbox Code Playgroud)

ios reactive-cocoa swift

6
推荐指数
1
解决办法
1410
查看次数

UISearchResultsUpdating w/ReactiveCocoa

我正在构建一个UISearchController,用户将在其中键入用户名,应用程序将从Web服务获取结果.

我想在用户输入时限制减少网络呼叫的请求.使用ReactiveCocoa如何实现这一目标?

class SearchResultsUpdater: NSObject, UISearchResultsUpdating {
    func updateSearchResultsForSearchController(searchController: UISearchController) {
        let text = searchController.searchBar.text
        let dataSource = searchResultsController.tableView.dataSource as! ...     
    }
}
Run Code Online (Sandbox Code Playgroud)

ios reactive-cocoa swift

6
推荐指数
1
解决办法
1454
查看次数

如何使RACSignal变热?

ReactiveCocoa可以通过调用它将信号转换为"热"信号-subscribeCompleted:.但我认为如果你不关心结果(即没有订阅者),这种方法就相当冗长.

RACDisposable *animationDisposable = [[self play:animation] subscribeCompleted:^{
    // just to make the animation play
}];
Run Code Online (Sandbox Code Playgroud)

而这三行并不足以表达我的意图.

有类似目的的方法吗?谢谢!

macos objective-c reactive-programming ios reactive-cocoa

5
推荐指数
1
解决办法
3582
查看次数

如何在ReactiveCocoa 4中创建自定义信号?

我有以下设置,一个GridViewGridViewCells 组成.

网格视图

class GridView : UIView {

    var gridViewCells: [GridViewCell] = []
    let tapHandler: Position -> ()

    init(frame: CGRect, tapHandler: Position -> ()) {
        self.tapHandler = tapHandler
        super.init(frame: frame)
        self.gridViewCells = createCells(self)
        addCellsToView(self.gridViewCells)
    }

    func addCellsToView(cells: [GridViewCell]) {
        for cell in cells {
            self.addSubview(cell)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

GridViewCell

class GridViewCell: UIImageView {

    let position: Position
    let tapHandler: Position -> ()

    init(frame: CGRect, position: Position, tapHandler: Position -> ()) {
        self.position = position
        self.tapHandler = tapHandler …
Run Code Online (Sandbox Code Playgroud)

ios reactive-cocoa swift

5
推荐指数
1
解决办法
2337
查看次数

Dwifft&ReactiveCocoa

我喜欢Dwifft,但我更希望将它与ReactiveCocoa一起使用,以帮助减少我的集合视图控制器中的代码复杂性.

目前,我有一个辅助类,它接受SignalProducer<[[T]]>where 的实例T: Equatable(因此它适用于不同的).每次信号产生器发出一个新值:

    self.data.producer.observeOn(UIScheduler()).on(next: { [unowned self] in
        guard let collectionView = self.collectionView else { return }
        for (index, element) in $0.enumerate() {
            if index == self.diffCalculators.count {
                let calculator = CollectionViewDiffCalculator<T>(collectionView: collectionView, initialRows: element)
                calculator.sectionIndex = index
                self.diffCalculators.append(calculator)
            } else {
                let calculator = self.diffCalculators[index]
                calculator.rows = element
            }
            for index in self.data.value.count..<(self.diffCalculators.count >= self.data.value.count ? self.diffCalculators.count : self.data.value.count) {
                self.diffCalculators.removeAtIndex(index)
            }
        }
    })
        .takeUntil(self.willDeallocSignal())
        .start()
Run Code Online (Sandbox Code Playgroud)

在这里,通过我的2d数组枚举,如果还没有存在差异计算器,则会创建一个并添加到我的存储阵列中diffCalculators.如果确实存在,rows则设置该属性.之后,我遍历其余部分并将其删除.

不幸的是,我一直难以置信地将其付诸实践.一次The number …

ios reactive-cocoa swift

5
推荐指数
1
解决办法
267
查看次数