gpt4 book ai didi

ios - 如何在 iOS 中使用 AFNetworking 从 REST 接口(interface)定期轮询/拉取

转载 作者:塔克拉玛干 更新时间:2023-11-01 19:08:09 27 4
gpt4 key购买 nike

我正在我的 iPhone 上构建一个“监控”应用程序。我正在使用 AFNetworking-2.0。我有一个后端服务器公开一个用 Python3/tornado 编写的 RESTful 接口(interface)。

根据我所处的 ViewController 级别,我想用不同的查询轮询不同的数据(应用程序的焦点调整查询的焦点)。为了“让它工作”,我设置了以下内容:

#pragma mark - Pull Loop

- (void) forkPull {
NSString* uri = [NSString stringWithFormat: @"%@/valves", Site.current.serialID];
[[HttpConnection current]
GET: uri
parameters: @{}
success:^(NSURLSessionDataTask* task, id responseObject){
[Site.current performSelectorOnMainThread: @selector(fromDoc:) withObject:responseObject waitUntilDone:YES];
NSTimeInterval delay = 60; // default poll period
// attempt to hone in if we have valid lastTouch info
if (Site.current.touched != nil) {
NSDate *futureTick = [Site.current.touched dateByAddingTimeInterval: 65];
if ([futureTick compare: [NSDate date]] == NSOrderedDescending) {
delay = futureTick.timeIntervalSinceNow;
}
}
[self performSelector: @selector(forkPull) withObject:nil afterDelay:delay];
NSLog(@"%@ forkPull again in %f", self, delay);
}
failure:^(NSURLSessionDataTask* task, NSError* error){
NSLog(@"%@ forkPull error: %@ (uri=%@)", self, error, uri);
[self performSelector: @selector(forkPull) withObject:nil afterDelay:60];
}
];
}

- (void) stopPull {
[NSObject cancelPreviousPerformRequestsWithTarget: self];
}

#pragma mark - View Management

-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear: animated];
....
[self forkPull]; // start up polling while I'm visible
}

-(void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self stopPull]; // I'm going away, so shut down the pull loop?
...
}

基本上,当 Controller 的 View 出现时,它发送一个REST查询(当它异步返回时,它会在fromDoc:方法中更新模型; Controller 有KVO 关系设置,这将导致 UI 更改。更新完成后,它能够估计下一次拉取的时间,并使用 performSelector:withObject:afterDelay: 进行调度。当另一个 Controller 占据中心位置,viewWillDisappear: 方法尝试停止任何已排队的 forkPull

虽然这有点管用。我很确定它没有通过“正确”测试。我对所有任务和后台的工作方式一无所知,但在我看来,AFNetworking 添加了它们自己的级别,因此我的 stopPull 可能无效。我已经在我的 NSLog 输出中看到了一些证据,似乎 Controller 不再位于顶部,但仍在运行循环。

但我敢肯定其他人以前也做过这种模式。我很想知道如何更好地设计/实现它。我正在寻找可以分享他们用于执行半周期性 REST 查询的模式的人,该模式已经过审查并且运行良好。

最佳答案

使用 Grand Central Dispatch:

@property (strong, nonatomic) dispatch_source_t timer;

- (void)startTimer
{
if (!self.timer) {
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
}
if (self.timer) {
dispatch_source_set_timer(self.timer, dispatch_walltime(NULL, 0), 60ull*NSEC_PER_SEC, 10ull*NSEC_PER_SEC);
dispatch_source_set_event_handler(_timer, ^(void) {
[self tick];
});
dispatch_resume(_timer);
}
}

- (void)tick
{
// Do your REST query here
}

这将每 60 秒调用一次您的 tick 方法。

要暂停和恢复计时器,请使用 dispatch_suspend 和 dispatch_resume:

dispatch_suspend(self.timer);
dispatch_resume(self.timer);

您可以在以后的任何时间调用 dispatch_source_set_timer 来提前或延迟它们:

// Fire sooner than 60 seconds, but resume 60s fires after that
unsigned long long delaySeconds = arc4random() % 60;
dispatch_source_set_timer(self.timer, dispatch_walltime(NULL, delaySeconds * NSEC_PER_SEC), 60ull*NSEC_PER_SEC, 10ull*NSEC_PER_SEC);

查看苹果Concurrency Programming Guide有关这方面的完整文档。

关于ios - 如何在 iOS 中使用 AFNetworking 从 REST 接口(interface)定期轮询/拉取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23524927/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com