我正在尝试使用 Coinbase 的 API 来获取有关我的在线比特币钱包的信息,并且我正在尝试使用 Swift 的 NSURLSession 对象来执行此操作。也许我在苹果文档中遗漏了一些明显的东西,但是在阅读了有关 NSURLSession 和 NSURLSessionTask 的信息后,我仍然不明白如何发出 HTTP 请求,然后返回响应的正文,以便正文可以在整个生命周期中持续存在我的应用程序。到目前为止,我只看到能够使用返回 void 的完成块,或者本身返回 void 的委托或使用也返回 void 的完成块。我想稍后在应用程序中使用从响应中获得的数据,但因为我使用的是完成块,所以我必须在响应到达后立即处理响应数据。
为了清楚起见,我想按照下面的伪代码函数做一些事情:
func makeHTTPCall(urlString : String) -> String? {
create NSURLSession object
create request with proper headers and using the passed-in urlString
use the session object to send out the request
get the response object, extract the response body as a string, and return it
}
然后,我可以这样称呼:
let myObject : MyObject = MyObject()
let respData : String = myObject.makeHTTPCall("https://coinbase.com/api/v1/account/balance")
该数据返回一个 JSON 对象字符串,这是我想要在响应及其完成块的生命周期之外保留的字符串。既然我可以在 Xcode 6 中使用,我该如何在 Swift 或 Objective C 中执行此操作?
编辑:已经发布了两个答案,但他们错过了这个问题的基本要点。我需要返回从响应中收到的数据。这两个答案(以及我在 SO 上看到的所有其他答案)都只是打印收到的数据。我想要的代码不使用返回 void 的完成处理程序,而是返回数据,以便稍后在应用程序的生命周期中使用它。如果我的问题有任何不清楚的地方,请告诉我,尽管我不知道如何才能更清楚地说明这一点。
在编辑您的问题时,您说:
我需要返回从响应中收到的数据。这两个答案(以及我在 SO 上看到的所有其他答案)都只是打印收到的数据。我想要的代码不使用返回 void 的完成处理程序,而是返回数据,以便稍后在应用程序的生命周期中使用它。如果我的问题有任何不清楚的地方,请告诉我,尽管我不知道如何才能更清楚地说明这一点。
我理解这个策略的吸引力,因为它感觉非常直观合乎逻辑。问题是您的网络请求应该始终异步运行(例如,使用您提到的完成处理程序模式)。
虽然有一些技术可以使函数“等待”异步请求完成(即使异步请求NSURLSession
方法同步运行或使用旧的同步网络请求方法之一),由于多种原因,这是一个非常糟糕的主意:
如果您从主线程执行此操作,则会导致糟糕的用户体验(在请求正在进行时应用程序将无响应,并且用户不知道应用程序是否正忙于执行某些操作或是否因某种未知原因而被冻结) )。
同样,如果您从主线程执行此操作,您还可能面临 iOS“看门狗”进程杀死您的应用程序的风险(因为如果您在错误的时间阻塞主队列超过几秒钟,特别是当应用程序进入前台,操作系统将毫不客气地终止您的应用程序)。看技术问答#1693有关同步网络请求问题的讨论。
我们通常更喜欢异步网络技术,因为它们提供了同步技术无法提供的更多功能(例如,使请求可取消、在使用基于委托的网络请求时提供进度更新等)。
您确实应该使用其他问题建议的完成处理程序模式,并在这些处理程序中管理应用程序的更改状态。在某些情况下,在某些网络请求完成之前,您绝对不能让用户继续进行(例如,在您确认用户的比特币余额之前,您不能让用户购买东西,并且在他们登录之前您不能这样做),然后更改UI 指示此类请求正在进行中。例如,调暗 UI、禁用控件、弹出活动指示器视图(也称为“旋转器”)等。只有这样,您才会发起请求。请求完成后,您将恢复 UI。我知道这看起来很多,但当用户在之前的请求完成之前绝对无法继续时,这是正确的方法。
我还仔细思考是否真的必须强迫用户等待先前的网络请求完成。有时,在某些情况下,您可以让用户在网络请求正在进行时执行/查看其他操作。是的,有时这是不可能的,但如果您可以在应用程序中找到此类机会,您最终将获得更优雅的用户体验。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)