在 iOS Swift 中使用 Delegated 和 Protocols 从 dataTaskWithRequest 返回数据
Posted
技术标签:
【中文标题】在 iOS Swift 中使用 Delegated 和 Protocols 从 dataTaskWithRequest 返回数据【英文标题】:Using Delegated and Protocols to return data from dataTaskWithRequest in iOS Swift 【发布时间】:2016-03-22 04:48:55 【问题描述】:我有一个框架,它调用一个返回 JSON 给我的 API。问题是我的 SDK 中有一个函数,它使用 NSURLSession 并调用 DataTaskWithRequest 来获取数据。问题是我的函数甚至在正确获取数据之前就返回了值。我曾尝试将 Completion Handler 与 DataTaskWithRequest 一起使用,目前正在使用 while 循环来等待接收数据。有没有其他可能的方法来做到这一点
代码
public func getDetails() -> AnyObject
if Reachability.isConnectedToNetwork()
received = false
let baseUrl = "API_URL Here"
let url = NSURL(string: baseUrl)
let request = NSURLRequest(URL: url!)
let session = NSURLSession.sharedSession()
print("Starting the connection")
let task = session.dataTaskWithRequest(request, completionHandler :
(data, response, error ) in
//Proper JSON Form
do
self.JSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
catch
print("Error")
return
self.received = true
)
task.resume()
print("Going through the loop")
while(!received)
print("Searching")
print(JSON)
return JSON
else
let alert = UIAlertView(title: "No Internet Connection", message: "Make sure your device is connected to the internet.", delegate: nil, cancelButtonTitle: "OK")
alert.show()
return 0
【问题讨论】:
发布您的代码... 【参考方案1】:您的问题是您试图将异步的东西变成同步的东西。用伪代码总结一下,你正在这样做:-
let myData = getDetails(blah)
doSomeAction(myData)
处理它的方法是使用完成块作为指示器本身并使一切异步。 此代码未经测试
public typealias CompletionHandler = (success: Bool, message: String, json: JSON?, error: NSError?) -> Void
func getDetailsAsync(completion: CompletionHandler)
if Reachability.isConnectedToNetwork()
received = false
let baseUrl = "API_URL Here"
let url = NSURL(string: baseUrl)
let request = NSURLRequest(URL: url!)
let session = NSURLSession.sharedSession()
print("Starting the connection")
let task = session.dataTaskWithRequest(request, completionHandler :
(data, response, error ) in
//Proper JSON Form
if error != nil
completion(false, "error", nil, error)
else
do
self.JSON = try NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments)
completion(true, "OK", self.JSON, nil)
catch
print("Error")
completion(false, "JSON parsing failed", nil, nil)
)
task.resume()
else
completion(false, "No network", nil, nil)
这样称呼它:
getDetailsAsync()
(success, message, json, error) in
if success == true
print(json)
else
// Do your alert here
print(message)
print(error)
This 的回答可能会有所帮助。
【讨论】:
谢谢!解决了我的问题【参考方案2】:是的,使用另一个线程来监视进程并让它通过您的协议发送消息。
newQueue = NSOperationQueue()
let operation2 = NSBlockOperation(block:
)
operation2.completionBlock =
print("Operation 2 completed")
let operation1 = NSBlockOperation(block:
)
operation1.completionBlock =
self.newQueue.addOperation(operation2)
operation1.qualityOfService = .UserInitiated
newQueue.addOperation(operation1)
这里是代码的概要。简而言之,您使用块 1 启动会话,并在完成时使用块 2 启动您对下载的验证。 block1 在完成时会触发 block2 [几乎像你说的那样立即],但是在下载块 1 中正在完成的数据结构之前,块 2 不会触发。
【讨论】:
对swift中的线程不熟悉的能不能再解释一下 辛格非常直截了当。我在这里所做的只是编写不再从上到下流动的代码,而是从 op1 到 op2。所以 addOperation 启动 op1,当它完成时,它会触发它的完成块,然后添加 operation2 运行,然后触发它的完成块。您可以在操作 1 中启动会话,并在您知道会话在操作 2 中运行时监控其完成情况。 这里的服务质量是 swift 2.0 的一个特性,可以告诉你的 ios 所述进程的优先级是什么。因此,如果您只是监控和操作 1 提高一到两个等级,我会尽可能降低操作 2,检查服务质量是否为 NSOperations。 我喜欢这种方法,将对其进行测试以上是关于在 iOS Swift 中使用 Delegated 和 Protocols 从 dataTaskWithRequest 返回数据的主要内容,如果未能解决你的问题,请参考以下文章
jQuery Direct and delegated events 直接事件与委托事件
“无效的 Swift 支持”在 Xamarin.iOS 中使用本机 Swift 库
iOS - 如何在 swift 中使用`NSMutableString`
iOS 图表子类 Markerview 使用 Swift 总是在“xxx-Swift.h”中构建错误