在不同的API主机之间切换

时间:2013-07-15 15:05:18

标签: ios objective-c cocoa-touch block afnetworking

我正在开发一款主要与将安装在内部系统中的API配合使用的应用。 API也可通过公共互联网访问。客户希望允许用户输入内部和外部(公共互联网)URL,然后应用程序将根据内部和外部URL的可用性连接到该URL。

该应用程序基本上已完成,但它目前仅为所有API调用连接到内部URL。我正在为每个API调用使用AFNetworking和基于块的完成/失败调用。

根据我们设计的逻辑,应用程序将始终通过查询服务器的当前时间来检查API的可用性。这是通过调用http://internal_url/api/time来完成的。如果此API无法返回相应的响应,我们将切换到外部网址http://external_url/api/time并在该网址上调用相同的API。如果两者都失败,则应用程序将相应地通知用户,并且不对API执行任何其他查询。

如果没有透露太多,这里有一些关于我如何设置API调用的代码:

- (void)someAPIMethodCall:(NSDictionary *)parameters completionBlock:block failure:block {
// query /api/time and return the URL (internal/external) that is currently up

AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:<url returned from above query>];
[client operationWithSuccess:block failure:block];
}

所以我的问题是:上面的查询/api/time方法工作的最佳方法是什么?显然,此方法需要完成并返回内部/外部URL,以便后续的实际API查询可以使用。 AFAIK,AFNetworking调用是基于块的,因此它将在上述/api/time返回之前返回。我还想到了一个单独的类,它同步使用NSURLConnection,它会在等待/api/time返回时阻塞主线程。

1 个答案:

答案 0 :(得分:1)

我想告诉你只需在内部和外部使用相同的URL(通过DNS),但这不是你想要的。

我想你在问如何有条件地打电话给另一个网址。

你希望someAPIMethodCall是异步的...所以你不想阻止调用以检查正确的api来调用。

除了缓存结果,所以你不必每次都这样做,你只需要调用你自己的另一个基于块的方法,它有一个完成块,它传入一个URL的参数来调用你的真实查询。

- (void)someAPIMethodCall:(NSDictionary *)parameters completionBlock:(void (^)(void))succesBlock failure((^)(void)):failureBlock {
    [self callBlockWithMyApiUrl:^(NSString *apiUrl){
        AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:apiUrl];
        [client operationWithSuccess:successBlock failure:failureBlock];
    } onFailure:^{
        failureBlock
    }
}

- (NSString *)callBlockWithMyApiUrl:(NSString * (^)(void))success (void (^)(void))failure
{
    // Your code to test for the working URI
    // If you're doing it this way, I'd suggest caching the result.
    // Subscribe to networking interface changes to dump the cache.
}