在 iPhone 应用程序初始化时进行多个服务调用

发布于 2024-09-17 23:55:17 字数 675 浏览 7 评论 0原文

我需要在 application:didFinishLaunchingWithOptions: 方法中从我的应用程序委托进行多个异步服务调用,以便从服务中检索一些数据以在我的应用程序中的各个控制器上使用。我可以控制该服务,并且我已将 API 设计为尽可能 RESTful,因此我需要在应用程序初始化期间进行多次调用。

我想要做的是显示一个带有进度指示器的加载视图 - 类似于 Default.png 中的默认启动屏幕 - 并在服务调用完成并且获得所需的初始值后删除该视图。如果只有一个服务调用,这很容易做到,因为我可以通过隐藏加载视图并显示根控制器,简单地将逻辑挂接到 NSURLConnection 的 connectionDidFinishLoading: 委托方法中。

然而,如果有多个服务调用,事情就变得很棘手。我可以将所有内容“链接”在一起并触发一个请求,等待它完成/失败,然后触发第二个请求,依此类推,直到到达最后一个请求。在最后一个请求中,我隐藏加载视图并显示普通视图。然而,如果有多个服务调用,这可能会变得很笨拙,并且代码变得难以理解和遵循。

关于最佳方法有什么建议吗?

我认为一种解决方案是让一个单例类负责进​​行服务调用和应用程序初始化。单例对象将在启动时并行触发所有必要的请求,每个失败/完成回调将检查每个请求是否已完成。如果所有请求都已完成,那么它可以调用应用程序委托中的某些方法并告诉它隐藏加载视图、显示根控制器等。

有什么想法?

I need to make multiple asynchronous service calls in the application:didFinishLaunchingWithOptions: method from my application delegate in order to retrieve some data from a service to be used across various controllers in my app. I have control over the service, and I've designed the API to be as RESTful as possible, so I need to make multiple calls during app initialization.

What I want to do is to show a loading view with a progress indicator - similar to the default splash screen from Default.png - and remove that view once the service calls have completed and I have the initial values I need. This is pretty easy to do if there's only one service call, since I can simply hook that logic into the connectionDidFinishLoading: delegate method of NSURLConnection by hiding the loading view and displaying the root controller.

However, with multiple service calls, it becomes tricky. I can "chain" everything together and fire off one request, wait for it to finish/fail, then fire off the second request, and so on until I get to the last request. In the last request, I then hide the loading view and display the normal view. However, this can get unwieldy with multiple service calls, and the code becomes hard to understand and follow.

Any suggestions on the best approach for this?

I'm thinking one solution is to have a singleton class responsible for making service calls and app initialization. The singleton object will fire off all necessary requests in parallel on start, and each fail/finish callback will check if every request has finished. If all requests have finished, then it can call some method in the application delegate and tell it to hide the loading view, show the root controller, etc.

Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滥情稳全场 2024-09-24 23:55:17

另一种可能性是让每个服务完成回调通知 (NSNotification) 控制器进度指示器已取得进展。您还可以告诉进度指示器的控制器您计划发出多少个请求,并让它记录分数,并在它认为一切都已完成时执行回调。

Another possibility is to have each service completion callback notify (NSNotification) the controller of the progress indicator that progress has been made. You could also tell the controller of the progress indicator of how many request you were planning to make, and let it keep score, and itself do a callback when it thinks everything is done.

时间海 2024-09-24 23:55:17

我正在使用 NSOperationQueue 执行类似的操作,该队列配置为一次仅运行 1 个操作。例如,请参阅 WeaveEngine.m ,它是 synchronizewithServer :credentials: 方法。我将所有单独的操作排队,其中大部分是异步网络调用。

I am doing something similar with an NSOperationQueue that is configured to just run 1 operation at a time. See for example WeaveEngine.m and it's synchronizewithServer:credentials: method. I queue up all the separate operations, which are mostly async network calls.

不离久伴 2024-09-24 23:55:17

您可以使用 NSThreading 并在单独的线程中为您需要获得的每件事进行同步调用,

[NSThread detachNewThreadSelector:@selector(getDataRequest1:) toTarget:self withObject:urlRequest];
[NSThread detachNewThreadSelector:@selector(getDataRequest2:) toTarget:self withObject:urlRequest];
[NSThread detachNewThreadSelector:@selector(getDataRequest3:) toTarget:self withObject:urlRequest];

然后在每个线程的选择器中执行类似的操作

- (void) getDataRequest1:(NSURLRequest*)urlRequest {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSHTTPURLResponse *urlResponse;
    NSError *error;
    NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&urlResponse error:&error];
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    if ([urlResponse statusCode] < 200 || [urlResponse statusCode] > 299) {
        //request probably failed
    }else{
        [self performSelectorOnMainThread:@selector(completeRequest1:) withObject:responseData waitUntilDone:NO];           
    }
    [pool drain];
    [responseString release];
    [urlRequest release];   
}

,当然这实际上取决于您想要生成多少个请求/线程。
并且您需要跟踪生成的数量和完成的数量,以便您可以正确地停止旋转器。

you could use NSThreading and make synchronous calls in separate threads for each thing you need to get like

[NSThread detachNewThreadSelector:@selector(getDataRequest1:) toTarget:self withObject:urlRequest];
[NSThread detachNewThreadSelector:@selector(getDataRequest2:) toTarget:self withObject:urlRequest];
[NSThread detachNewThreadSelector:@selector(getDataRequest3:) toTarget:self withObject:urlRequest];

then in the selector for each thread do something like

- (void) getDataRequest1:(NSURLRequest*)urlRequest {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSHTTPURLResponse *urlResponse;
    NSError *error;
    NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&urlResponse error:&error];
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    if ([urlResponse statusCode] < 200 || [urlResponse statusCode] > 299) {
        //request probably failed
    }else{
        [self performSelectorOnMainThread:@selector(completeRequest1:) withObject:responseData waitUntilDone:NO];           
    }
    [pool drain];
    [responseString release];
    [urlRequest release];   
}

of course it really depends on how many requests/threads you are wanting to spawn.
and you will need to keep track of how many you spawn vs how many finish so you can properly stop your spinner.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文