- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是 ReactiveCocoa 的新手,有一个问题我还没有找到解决的方法。我的应用程序中有一个网络请求,它返回要编码为二维码的数据,该二维码的有效期仅为 30 秒。网络请求返回一个 RACSignal
,我将要在该信号中编码的数据发送到我的 View 模型。在 View 模型中,我将该数据映射到 QR 图像,并将其作为属性公开在我的 View 模型界面中。创建 QR 图像后,我想更新一个 timeLeftString
属性,上面写着“此代码仅在 30 秒内有效”,但秒数会随着时间的推移而改变,在 30 秒完成后,我想要发出另一个请求以获取另一个有效期为 30 秒的 QR 码数据,然后完成另一个请求以获取有效期为 30 秒的数据......直到屏幕被关闭。我该如何实现?
目前我有这个来获取数据:
- (RACSignal *)newPaymentSignal
{
@weakify(self);
return [[[[APIManager sharedManager] newPayment] map:^id(NSString *paymentToken) {
ZXMultiFormatWriter *writer = [ZXMultiFormatWriter writer];
ZXBitMatrix *result =
[writer encode:paymentToken format:kBarcodeFormatQRCode width:250 height:250 error:nil];
if (!result) {
return nil;
}
CGImageRef cgImage = [[ZXImage imageWithMatrix:result] cgimage];
UIImage *image = [UIImage imageWithCGImage:cgImage];
return UIImagePNGRepresentation(image);
}] doNext:^(NSData *data) {
@strongify(self);
self.qrImageData = data;
}];
}
这个是定时器
- (RACSignal *)timeRemainingSignal
{
@weakify(self);
return [[[RACSignal interval:0.5 onScheduler:[RACScheduler scheduler]] //
startWith:[NSDate date]] //
initially:^{
@strongify(self);
self.expiryDate = [[NSDate date] dateByAddingTimeInterval:30];
}];
}
流程是:从 api 获取数据,启动计时器,当时间到了时发出新请求以获取新数据并再次启动计时器......并永远重复此过程。
1- 从 API 获取数据后如何启动计时器?
2- 我如何让这个流程永远重复?
3- 如果用户点击用户界面上的按钮,如何在 30 秒完成之前停止计时器并从头开始流程?
4- 我有一个 expiryDate
属性,它被添加到当前日期 30 秒,因为我想我会取 expiryDate
和 [NSDate date] 的区别
来决定时间是否到了 - 有没有更好的方法来实现这个?
5- 当它永远重复时如何中断流程并在屏幕关闭时(或者说,当用户点击另一个按钮时)取消订阅所有内容?
非常感谢您的回答。
最佳答案
我认为缺少的一 block 拼图是非常有用的 flattenMap
运算符。它实质上是用它返回的信号中的下一个替换其传入信号中的任何下一个。
这是解决您的问题的一种方法(我用发送字符串的简单信号替换了您的 newPaymentSignal 方法):
- (RACSignal *)newPaymentSignal
{
return [[RACSignal return:@"token"] delay:2];
}
- (void)start
{
NSInteger refreshInterval = 30;
RACSignal *refreshTokenTimerSignal =
[[RACSignal interval:refreshInterval onScheduler:[RACScheduler mainThreadScheduler]]
startWith:[NSDate date]];
[[[[refreshTokenTimerSignal
flattenMap:^RACStream *(id _)
{
return [self newPaymentSignal];
}]
map:^NSDate *(NSString *paymentToken)
{
// display paymentToken here
NSLog(@"%@", paymentToken);
return [[NSDate date] dateByAddingTimeInterval:refreshInterval];
}]
flattenMap:^RACStream *(NSDate *expiryDate)
{
return [[[[RACSignal interval:1 onScheduler:[RACScheduler mainThreadScheduler]]
startWith:[NSDate date]]
takeUntil:[refreshTokenTimerSignal skip:1]]
map:^NSNumber *(NSDate *now)
{
return @([expiryDate timeIntervalSinceDate:now]);
}];
}]
subscribeNext:^(NSNumber *remaining)
{
// update timer readout here
NSLog(@"%@", remaining);
}];
}
每次外部 refreshTokenTimerSignal
触发时,它都会映射到一个新的 newPaymentSignal
,而当它返回一个值时,它又映射到一个到期日期,该日期被使用创建一个每秒触发的新“内部”定时器信号。
一旦外部刷新计时器发送下一个信号,内部计时器上的 takeUntil
运算符就会完成该信号。
(这里有一个奇怪的事情是我必须向 refreshTokenTimerSignal
添加一个 skip:1
,否则内部定时器永远不会启动。我本以为它会即使没有 skip:1
也能正常工作,也许更精通 RAC 内部结构的人可以解释这是为什么。)
要中断响应各种事件的外部信号流,您也可以尝试使用 takeUntil
和 takeUntilBlock
。
关于ios - ReactiveCocoa 中的自动重复倒数计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30245302/
我正在尝试构建一个 Cocoapod xcode 项目。我按照以下步骤在我的 mac 机器上配置 cocoapods(MAC OS yosemite 10.10.2,xcode 6.1.1 版本) s
假设我有一个返回 SignalProducer 的函数我想将生产者绑定(bind)到多个 MutableProperty .所以,像这样: let foo = SignalProducer(value
我编写了一个非常简单的 ReactiveCocoa 测试应用程序来尝试在 RAC 中编码(而不是无休止地阅读它)。在 Github 上,我想得到一些关于它的具体问题的答案。我将链接到代码组件。 首先,
我已经接管了一个实现 ReactiveCocoa 2.4.7 的 iOS 项目使用 CocoaPods。该应用程序是用 Swift 1.2 编写的,但后来进行了升级,现在是 Swift 2.3。然而R
当我创建一个信号并将其带入函数范围时,根据 Cocoa 约定,其有效保留计数为 0: RACSignal *signal = [self createSignal]; 当我订阅信号时,它会保留订阅者并
我想并行启动多个独立的网络请求,并在所有请求完成后订阅(我不在乎它们是否完成或出错)。 现在,我使用 combineLatest 。因此,这些请求是并行进行的(如我所愿),但是当信号发送error时,
我正在使用 MVVM 架构,我有两个信号: RACSignal *internetEnabledSignal = RACObserve(self.regWizardVehicleViewModel,
我有一个关于 ReactiveCocoa (v5) 与 Swift 3 的问题。在我的项目中,我有不同的服务。例如,API 或用于从磁盘保存或获取内容的 API。这些服务正在返回 SignalProd
我有一个搜索文本字段,当用户开始输入时,它会向用户提供自动完成建议的列表。用户也可以点击建议或按键盘的搜索按钮以使用输入文本执行搜索。 如果用户开始输入内容,然后在等待建议出现之前按下搜索,则可能会出
我正在编写一个库,它有一个返回 RACSignal 的方法,但只订阅 Complete 和 Error,而不订阅 Next。 我有一个 RACSignal,我想进一步传播,但忽略所有值。我从网络调用中
我在 View 模型中有以下代码: @weakify(self); [RACAbleWithStart(self.visitStartDate) subscribeNext:^(NSDate *vis
我正在测试 ReactiveCocoa 。在下面的代码中,我希望输出为: name : Item 1 arr : a1 arr : a2 name : Item 2 arr : b1 arr : b2
我成功地通过 CocoaPods 集成了 ReactiveCocoa。 该项目也会构建并运行。 在一个文件中我有这段代码: #import #import UITextField *fld = [
我正在尝试与登录服务通信并以 react 方式更新 UI。问题是我的登录服务与委托(delegate)一起工作,而且我发现的几乎每个示例都与 block 一起工作。 我写了一个可行的解决方案,但它似乎
我是 ReactiveCocoa 的新手,有一个问题我还没有找到解决的方法。我的应用程序中有一个网络请求,它返回要编码为二维码的数据,该二维码的有效期仅为 30 秒。网络请求返回一个 RACSigna
这里是 ReactiveCocoa 的新手。我有一个 (MVVM) View 模型,代表一个类似新闻源的页面,什么是监听数据模型属性变化的正确方法?在下面的示例中,startUpdate() 不断更新
我已经将 RAC 与 objective-c 一起使用,但现在无法与 swift 一起使用。 我下载了 ReactiveCocoaBindings.swift 并将其包含在我的项目中。 Here 临
我使用 ReactiveCocoa 有一段时间了,但我一直在这样做: // Assume match.status is an enum [RACAble(self.match.status) sub
我有一个 merge 操作,它依赖于两个异步操作的结果。一是网络操作,二是位置授权成败。我不关心这些操作的值,只关心它们都已完成。 这是它的样子: RACSignal *networkCallRetu
我正在使用 ReactiveCocoa 4.0.4 alpha 1 和 Swift 2.1。我正在尝试编写一个扩展,在 UITextField 上创建最大文本限制。 extension RACStre
我是一名优秀的程序员,十分优秀!