如何将 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 数据列表元素传递回组件?

React 功能组件 - 当组件返回元素数组时,如何将 refs 传递回父级?

NSURLRequest : 发布数据并读取发布的页面

将数组传递回javascript

如何将值从子窗体传递回父窗体?

如何将值从 JS 传递回 Python