如何将 NSURLRequest 的结果传递回包含类 [重复]
Posted
技术标签:
【中文标题】如何将 NSURLRequest 的结果传递回包含类 [重复]【英文标题】:How to communicate result from NSURLRequest back to containing class [duplicate] 【发布时间】:2016-08-04 17:07:50 【问题描述】:我从 API 收集了JSON
数据,并且能够初始化我的数组(类实例变量),但是在块之后,数据从数组中销毁。如何从任务块返回可用于初始化数组的数据?
override func viewDidLoad()
// var movies=[Movie]()
let requestURL: NSURL = NSURL(string: "https://yts.ag/api/v2/list_movies.json")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest)
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200)
print("File downloaded successfully.")
do
let jsonYts = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)
let jsonDataTag = jsonYts["data"]
let jsonMovie = jsonDataTag!!["movies"]!
let movies = [Movie].fromJSONArray(jsonMovie as! [JSON])
// self.moviesList = movies as! [Movie] // this is my array. I want to add data to it
for data in self.moviesList
// print(data.title)
catch
task.resume()
【问题讨论】:
以我的回答为例:***.com/questions/37340967/… 【参考方案1】:异步方法不会返回到调用函数,因为它们不是一开始就被直接调用的。它们被放置在稍后调用的任务队列中(在不同的线程上!)。对于那些刚接触异步编程的人来说,这是最难掌握的。你的异步方法必须改变一个类变量。所以你会有:
class MyContainer: UIViewController
var myInstanceData: [SomeObject] // In your case moviesList
func startAsyncRequest() // In your case viewDidLoad()
// In your case NSMutableURLRequest
doSomethingAsynchronous(callback: [weak self] (result) in
// in your case JSON parsing
self?.myInstanceData = parseResult(result) // share it back to the containing class
// This method returns nothing; it is not called until well
// after startAsyncRequest() has returned
)
一旦回调完成,myInstanceData
可用于类中的所有其他方法。作为一般模式,这是否有意义?
之后你必须学习这个材料:
Swift performSegueWithIdentifier not working
从运行回调的后台线程将结果返回到 UI。
附录
为清楚起见,在编辑您的问题后再次查看,似乎您可能已经知道这一点,但是您已经注释掉了正确的行,如果您将其放回原处,事情就正常了,也就是说,电影不会销毁但会记录在类属性moviesList
中。
// self.moviesList = movies as! [Movie] // this is my array. I want to add data to it
为什么不重新启用它? 也许真正的问题是:你的意思是append
而不是覆盖,也许?那么答案可能很简单:
self.moviesList += movies as! [Movie]
【讨论】:
我认为措辞上的问题具有误导性,并且涉及两个方向,因此请根据上述答案的哪一部分实际解决它。【参考方案2】:如果返回 JSON 数据,您可以只使用“SwiftyJson”处理来自 API 的响应;如果它使用 XML,则使用“SWXMLHash”。它们都是 pod(库),旨在处理来自各自格式的响应。
Installation help for SwiftyJson。如果您仍有问题,请在下方评论。
此时你可以直接导入 SwiftyJson 并使用它。
让response
为任意对象,并假设您的 JSON 数据采用以下格式:
"text":
"data": "Click Here",
"size": 36,
"style": "bold",
"name": "text1",
"hOffset": 250,
"vOffset": 100,
"alignment": "center"
那么你就可以这样写代码了
func response(data)
let dt = JSON(data : data) // the second data is the response from api
response = dt.object // for accessing the values as object from json format
let style = response["text"]["data"]!! as? String // style = "bold"
let n = response["text"]["name"]!! as? String // n = "text1"
let size = response["text"]["hOffset"]!! as? Int // size = 250
// Done !! Easy.. if you guys need help or snapshots for the same do comment..
【讨论】:
以上是关于如何将 NSURLRequest 的结果传递回包含类 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
Angular2:如何将选定项目从 HTML 数据列表元素传递回组件?