如何将我的JSON响应(data
从getStories()
函数传递到函数之外的新变量(var stories
),之后才能使用那个新变量放到我的CollectionViewController中?
这是我的代码:
import UIKit
class StoryCollectionViewController: UICollectionViewController {
// MARK: - ***** Properties *****
private var stories: Story!
// MARK: - ***** Life Cycles *****
override func viewDidLoad() {
super.viewDidLoad()
// Register cell class
collectionView?.register(UINib.init(nibName: "StoryCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: Constants.reuseIdentifier)
// Get Stories
getStories()
print(stories.storyID) // Here should return 15 but return NIL and I don't know why
}
// MARK: ***** UICollectionView DataSource Methods *****
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Constants.reuseIdentifier, for: indexPath) as! StoryCollectionViewCell
DispatchQueue.main.async {
//cell.storyImageView.imageFromServerURL(urlString: self.posterUrl)
//cell.storyNameLabel.text = self.stories?.name
}
return cell
}
//MARK: - ***** CollectionView Delegate Methods *****
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "showStoryDetails", sender: self.stories)
}
// Get Stories from Amazon API server
func getStories(){
Spinner.show("Loading Stories")
let defaultSession = URLSession(configuration: .default)
if let urlComponents = URLComponents(string: Constants.baseURL) {
guard let url = urlComponents.url else { return }
let dataTask = defaultSession.dataTask(with: url) { (data, _, error) in
if error != nil {
self.showMessage(message: error.debugDescription)
} else if let data = data {
do {
let data = try JSONDecoder().decode(ModelJson.self, from: data)
self.stories = data.result // This object "stories" is empty outside of this function ..........
print("Story ID: \(self.stories.storyID!)") // Here return 15 which is correct
} catch {
self.showMessage(message: error.localizedDescription)
}
}
Spinner.hide()
}
dataTask.resume()
}
}
}
这是一个屏幕,向您显示我的JSON响应包含数据并在控制台中返回15:
如果您正在阅读本文,谢谢。 祝你有美好的一天!
答案 0 :(得分:0)
您可以像这样在getStories函数中使用闭包:
func getStories(CompletionHandler: @escaping (Story)->()) {
//
}
在调用数据后,像这样调用此闭包:
CompletionHandler(data.result)
然后,在调用此方法时,您可以在闭包内部处理对象并根据需要更新控制器。
getStories { [weak self] (stories) in
self?.stories = stories
}
答案 1 :(得分:0)
getStories
方法包含。异步操作。这意味着您不会立即得到响应。调用getStories
方法后无法获取故事。在设置故事属性之后执行此操作。示例:
func getStories(completion: @escaping () -> Void) {
Spinner.show("Loading Stories")
let defaultSession = URLSession(configuration: .default)
if let urlComponents = URLComponents(string: Constants.baseURL) {
guard let url = urlComponents.url else { return }
let dataTask = defaultSession.dataTask(with: url) { (data, _, error) in
if error != nil {
self.showMessage(message: error.debugDescription)
} else if let data = data {
do {
let data = try JSONDecoder().decode(ModelJson.self, from: data)
self.stories = data.result
} catch {
self.showMessage(message: error.localizedDescription)
}
}
Spinner.hide()
completion()
}
dataTask.resume()
}
}
override func viewDidLoad() {
super.viewDidLoad()
getStories(completion: { [weak self] in
self?.collectionView.reloadData()
})
}