将字符串从JSON数据发送到函数外部的变量

时间:2018-11-24 01:40:21

标签: ios swift api jsondecoder

我正在尝试从JSON数据中提取一个字符串并将其设置为变量。我的问题是该变量显示为空。我正在使用JSONDecoder检索JSON数据并将字符串设置为函数外部的变量。然后,我想在另一个函数中使用该变量

当我打印变量时,即使函数已加载,它仍然显示为空白。在函数中,字符串正确显示。

代码:

var filmTitle = ""

override func viewDidLoad() {
    super.viewDidLoad()


loadFilms()
print(self.filmTitle) //Prints as an empty string

}

func loadFilms() {

    let id = filmId
    let apiKey = "97a0d64910120cbeae9df9cb675ad235"
    let url = URL(string: "https://api.themoviedb.org/3/movie/\(id)?api_key=\(apiKey)&language=en-US")
    let request = URLRequest(
        url: url! as URL,
        cachePolicy: URLRequest.CachePolicy.reloadIgnoringLocalCacheData,
        timeoutInterval: 10 )

    let session = URLSession (
        configuration: URLSessionConfiguration.default,
        delegate: nil,
        delegateQueue: OperationQueue.main
    )

    let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
        if let data = dataOrNil {
            do { let details = try! JSONDecoder().decode(Details.self, from: data)
        self.filmTitle = details.title
        print(self.filmTitle) //string prints correctly

                        }
                    }
                })


    task.resume()

}

我缺少将字符串正确设置为变量的什么?

3 个答案:

答案 0 :(得分:0)

从Internet加载数据是一种异步方法。 loadFilms()完成之前将调用print语句。

完成后,使用回调获取数据。

func loadFilms(completion: @escaping (Details?, Error?) -> Void) { 
    //...

 let task = session.dataTask(with: request, completionHandler: { (dataOrNil, response, error) in
    if let data = dataOrNil {
        do { let details = try JSONDecoder().decode(Details.self, from: data)
     completion(details, nil) 


           } catch { 
               completion(nil, error) 
                }
            })

}

在呼叫站点:

override func viewDidLoad() { 

   loadFilms { details, error in 

     if error { //* Handle Error */ } 

     self.filmTitle = details.title
     print(filmTitle)

    }

}

答案 1 :(得分:0)

Web请求是异步的,从CP的角度来看,需要很长时间才能完成。当您致电:

override func viewDidLoad() {
    super.viewDidLoad()

    loadFilms()
    print(self.filmTitle) // loadFilms() hasn't finished so `filmTitle` is empty
}

最好在filmTitle上设置属性观察器:

var filmTitle: String? = nil {
    didSet {
        print(filmTitle)

        Dispatch.main.async {
            // update your GUI
        }
    }
}

答案 2 :(得分:0)

此问题的解决方案是在将数据设置为数组之后,重新加载在解码器功能内将数组发送到的收集视图。