我正在尝试使用Coinbase的API来获取有关我的在线比特币钱包的信息,并且正在尝试使用Swift的NSURLSession对象来执行此操作。也许我在Apple文档中缺少明显的内容,但是在阅读了有关NSURLSession和NSURLSessionTask的信息之后,我仍然不了解如何发出HTTP请求,然后返回响应的主体,以便主体可以在整个生命周期中持久存在我的应用程序。到目前为止,我仅看到使用返回空值的完成块或使用本身返回空值的委托或使用也返回空值的完成块的委托的功能。我想稍后在应用程序中使用从响应中获取的数据,但是由于使用的是完成块,因此必须在响应到达后立即处理响应数据。
为了清楚起见,我想按照以下伪代码函数的方式做一些事情:
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上看到的所有其他答案)都只是打印接收到的数据。我想要的代码不使用返回空值的完成处理程序,而是返回数据,以便可以在应用程序的生命周期中稍后使用。如果我的问题有任何不清楚的地方,请告诉我,尽管我不知道如何将其弄清楚。
在对问题的编辑中,您说:
我需要返回从响应中收到的数据。这两个答案(以及我在SO上看到的所有其他答案)都只是打印接收到的数据。我想要的代码不使用返回空值的完成处理程序,而是返回数据,以便可以在应用程序的生命周期中稍后使用。如果我的问题有任何不清楚的地方,请告诉我,尽管我不知道如何将其弄清楚。
我理解此策略的吸引力,因为它在直觉上感觉很合理。问题在于您的网络请求应始终异步运行(例如,使用您提到的完成处理程序模式)。
尽管有一些使函数“等待”异步请求完成的技术(例如,使异步NSURLSession
方法同步运行或使用旧的同步网络请求方法之一),但是由于许多原因,这确实是个坏主意:
如果从主线程执行此操作,则会导致可怕的用户体验(在请求进行过程中,应用程序将无响应,并且用户将不知道该应用程序是否正在忙于做某事,或者由于某种未知原因而被冻结) )。
同样,如果您是从主线程执行此操作,则还冒着让iOS“看门狗”进程杀死您的应用程序的风险(因为如果您在错误的时间将主队列阻塞了几秒钟,尤其是当应用程序进入前台,操作系统会毫不客气地终止您的应用程序)。有关执行同步网络请求的问题的讨论,请参见技术问答1693。
我们通常更喜欢异步网络技术,因为它们提供了同步技术无法提供的更多功能(例如,使请求可取消,在使用基于委托的网络请求时提供进度更新等)。
您确实应该使用其他问题建议的完成处理程序模式,并在这些处理程序中管理应用程序的更改状态。在某些情况下,您绝对不能让用户继续进行直到完成一些网络请求为止(例如,您不能让用户在确认其比特币余额之前买东西,直到他们登录后才能这样做),然后进行更改用户界面,以指示此类请求正在进行中。例如,使UI变暗,禁用控件,弹出活动指示器视图(又称“旋转器”)等。只有这样,您才可以发起请求。完成请求后,您将还原用户界面。我知道这看起来很多,但是当用户在事先完成请求之前绝对无法继续进行操作时,这是正确的方法。
对于是否确实必须强制用户等待先前的网络请求完成,我也要进行漫长而艰难的思考。有时在某些情况下,您可以在网络请求进行时让用户执行/查看其他操作。是的,有时候这是不可能的,但是如果您可以在应用程序中找到这些机会,那么您将获得更加优雅的UX。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句