同步获取数据 NSOperationQueue 或 NSURLSession



在我的应用程序中,当我们单击登录按钮时,我们必须进行 3 次服务器调用。

1) will make a server call to get an OAuth token for user credentials
2) with the token from (1) we will get user privileges
3) with the token from (1) and with the valid privilege from (2) we will get the data to be displayed on the page after login in a tableview. 

我对采取的方法感到困惑。使用操作队列添加依赖项或使用 NSURLSession 任务是否是一种好方法?

根据为此的堆栈溢出解决方案之一 - 创建NSURLSessionTasks队列的最佳实践,NSURLSession 没有任何关于对请求进行排序的逻辑,即使将每个主机的最大连接数设置为 1,它也只会调用首先完成的任何内容的 completionBlock

如果有其他更好的方法,请告诉我..

您可以使用NSURLSession任务。 首先调用第一个 API 方法,您将在完成处理程序(块)中获得响应。 现在将其存储在完成处理程序中的任何公共属性中(因为您想再次使用它)。从该完成处理程序调用第二个 api 方法,从该第二个方法的完成处理程序中,通过传递响应并使用存储了第一个 api 方法对象的公共属性来调用第三个 api 方法。

完成处理程序或块仅在响应到达时被调用,因此您可以通过这种方式管理 api 调用。

希望这对:)有所帮助

归根结底,使用传统"完成处理程序"方法的代码简化版本可能如下所示:

fetchOAuthToken() { (token, error) in
    if let token = token {
        fetchPrivileges(token: token) { (privileges, error) in
            if let privileges = privileges {
               fetchData(token: token, privileges: privileges) { (data, error) in 
                   if let data = data {
                       // ... 
                   }
               }
            }
        }
    }
}

请注意,为简洁起见,代码不包含错误处理,也不包含取消方法。

依赖项是通过延续(即完成处理程序)建立的。

另一种利用"类似Scala"期货的方法如下所示(使用Promises的方法非常相似):

fetchOAuthToken().flatMap { token in
    fetchPrivileges(token: token).flatMap { privileges in
        fetchData(token: token, privileges).map { data in
            // ...
        }
    }
}.onFailure { error in
    print("Error: (error)")
}

上面的语句创建了一个由三个任务组成的任务。

此方法包含完整的错误处理,即使它可能并不明显。生产版本与上面的这个片段没有太大区别 - 它可能只会添加一种取消方式。

有一些第三方库实现了类似 Scala 的未来或承诺。

一种添加取消的方法可能如下所示:

let cr = CancellationRequest()
fetchOAuthToken(ct: cr.token).flatMap { token in
    fetchPrivileges(token: token, ct: cr.token).flatMap { privileges in
        fetchData(token: token, privileges, ct: cr.token).map { data in
            // ...
        }
    }
}.onFailure { error in
    print("Error: (error)")
}

稍后,您可以取消组合任务(当前正在执行的任何任务):

cr.cancel()

注意:

这个问题也可以NSOperations来解决。但是,它需要三个NSOperation子类,以及一个或两个线程安全的辅助类,这些类将用于将Op1的结果"传输"到Op2的输入,并将Op2的结果"传输"到Op3的输入。我估计这将需要大约 500 行代码——对于 SO ;) 的答案来说太多

"类似 Scala"的未来方法需要第三方库。取消需要另一个 - 或您自己的实现(这并不难),或者一个提供多合一的库。

最新更新