如何从Swift / Objective C中的HTTP请求返回数据 [英] How return data from an HTTP request in Swift/Objective C

查看:94
本文介绍了如何从Swift / Objective C中的HTTP请求返回数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Coinbase的API来获取有关我的在线比特币钱包的信息,而我正在尝试使用Swift的NSURLSession对象来实现这一点。也许我在Apple文档中遗漏了一些明显的东西,但在阅读了有关NSURLSession和NSURLSessionTask的信息后,我仍然不明白如何发出HTTP请求然后返回响应的主体,以便身体可以在整个生命中持续存在我的应用程序截至目前,我只看到能够使用返回void的完成块,或者自己返回void或使用也返回void的完成块的委托。我想使用稍后在应用程序中从响应中获得的数据,但由于我使用完成块,我必须在响应到达后立即处理响应数据。

I'm trying to use Coinbase's API to get information about my online bitcoin wallet, and I'm trying to use Swift's NSURLSession object to do so. Perhaps I'm missing something obvious in the Apple docs, but after reading through the information about NSURLSession and NSURLSessionTask I still do not understand how to make an HTTP request and then return the body of the response so that the body can persist throughout the life of my app. As of now I only see the ability to use completion blocks which return void, or delegates which either return void themselves or use completion blocks which also return void. I want to use the data I get from the response later in the app, but because I'm using completion blocks I must handle the response data immediately after the response arrives.

为了说清楚,我想在下面的伪代码函数中做一些事情:

To make it clear, I want to do something along the lines of the pseudocode function below:

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
}

然后,我可以这样打电话:

Then later, I could call something like this:

let myObject : MyObject = MyObject()
let respData : String = myObject.makeHTTPCall("https://coinbase.com/api/v1/account/balance")

此数据返回一个JSON对象string,这是我想要在响应及其完成块的生命周期之后保留的字符串。我怎样才能在Swift或Objective C中执行此操作,因为我可以在Xcode 6中使用它?

This data is returning a JSON Object string, which is the String I want to persist beyond the life of the response and its completion block. How can I do this in either Swift or Objective C, since I'll be able to use either in Xcode 6?

编辑:已经发布了两个答案,但是错过了这个问题的基本点。我需要返回从响应中收到的数据。这两个答案(以及我在SO上看到的所有其他答案)只是打印收到的数据。我希望代码不使用返回void的完成处理程序,而是返回数据,以便以后可以在应用程序的生命周期中使用它。如果我的问题有任何不清楚的地方,请告诉我,虽然我不知道如何更清楚。

Two answers have been posted, but they miss the fundamental point of this question. I need to RETURN the data which I receive from the response. Both answers (and all other answers I've seen on SO) simply print the data received. I would like code that doesn't use a void-returning completion handler, but instead returns the data so that it can be used later in the lifecycle of the app. If there is anything unclear about my question, please tell me, though I don't see how this can be made clearer.

推荐答案

在编辑问题时,您说:


我需要返回从响应中收到的数据。这两个答案(以及我在SO上看到的所有其他答案)只是打印收到的数据。我希望代码不使用返回void的完成处理程序,而是返回数据,以便以后可以在应用程序的生命周期中使用它。如果我的问题有任何不清楚的地方,请告诉我,虽然我不知道如何做得更清楚。

I need to RETURN the data which I receive from the response. Both answers (and all other answers I've seen on SO) simply print the data received. I would like code that doesn't use a void-returning completion handler, but instead returns the data so that it can be used later in the lifecycle of the app. If there is anything unclear about my question, please tell me, though I don't see how this can be made clearer.

I理解这种策略的吸引力,因为它感觉非常符合逻辑。问题是您的网络请求应始终异步运行(例如,使用您提到的完成处理程序模式)。

I understand the appeal of this strategy, because it feels so intuitively logical. The problem is that your networking requests should always run asynchronously (e.g. use that completion handler pattern to which you allude).

虽然有一些技术使函数等待异步请求完成(即使异步 NSURLSession 方法同步运行或使用旧的同步网络请求方法之一),出于以下几个原因,这是一个非常糟糕的主意:

While there are techniques making a function "wait" for the asynchronous request to complete (i.e. to make the asynchronous NSURLSession method behave synchronously or use one of the old synchronous network request methods), this is a really bad idea for a number of reasons:


  • 如果你从主线程执行此操作,则会导致糟糕的用户体验(当请求正在进行时,应用程序将无响应,用户将无法知道应用程序是否正忙于执行某些操作或是否已将其冻结一些不明原因)。

  • If you do this from the main thread, it results in a horrible user experience (the app will be unresponsive while the request is in progress and the user won't know if the app is busy doing something or whether it's frozen for some unknown reason).

同样,如果你从主线程执行此操作,你也有可能让iOS看门狗进程杀死你的应用程序(因为如果你阻止主要在错误的时间排队超过几秒钟,特别是当应用程序到达前台时,操作系统将毫不客气地终止您的应用程序)。有关问题的讨论,请参见技术问答#1693 做同步网络请求。

Again, if you do this from the main thread, you also risk having the iOS "watch dog" process kill your app (because if you block the main queue for more than a few seconds at the wrong time, particularly as the app comes to foreground, the OS will unceremoniously terminate your app). See Technical Q&A #1693 for a discussion on the problems of doing synchronous network requests.

我们通常更喜欢异步网络技术,因为它们提供了更多不可用于同步技术的功能(例如,使请求可取消,提供进度更新时使用基于委托的网络请求等。)。

We generally prefer the asynchronous network techniques because they offer more features unavailable with synchronous techniques (e.g. making requests cancelable, offer progress updates when using delegate-based network requests, etc.).

你真的应该使用完成处理程序模式那些其他问题建议,并管理这些处理程序中应用程序的变化状态。在那些绝对不能让用户继续进行某些网络请求的情况下(例如,在你确认他们的比特币余额之前你不能让用户购买东西,并且在他们登录之前你不能这样做),然后改变用于指示此类请求正在进行的UI。例如,调暗UI,禁用控件,弹出活动指示器视图(例如,旋转器)等。只有这样才能启动请求。完成请求后,您将恢复UI。我知道它似乎很多,但是当用户完全无法继续前一个请求时,这是正确的方法。

You really should use the completion handler pattern that those other questions suggest, and manage the changing state of the app in those handlers. In those situations where you absolutely cannot let the user proceed until some network request is done (e.g. you can't let the user buy something until you confirm their bitcoin balance, and you can't do that until they log in), then change the UI to indicate that such a request is in progress. For example, dim the UI, disable the controls, pop up an activity indicator view (a.k.a., a "spinner"), etc. Only then would you initiate the request. And upon completion of the request, you would restore the UI. I know it seems like a lot, but it's the right way to do it when the user absolutely cannot proceed until the prior request is done.

我也认为很长并且很难确定是否真的必须迫使用户等待先前的网络请求完成。有时,在网络请求正在进行时,您可以让用户执行/查看其他内容。是的,有时这是不可能的,但如果你能在你的应用程序中找到那些机会,你最终会得到一个更优雅的用户体验。

I'd also think long and hard as to whether it's truly the case that you absolutely have to force the user to wait for the prior network request to complete. Sometimes there are situations where you can let the user do/review something else while the network request is in progress. Yes, sometimes that isn't possible, but if you can find those sorts of opportunities in your app, you'll end up with a more elegant UX.

这篇关于如何从Swift / Objective C中的HTTP请求返回数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆