如何为 JSON 中的 class 中的变量赋值或将此值传递给下一个函数?

How to assign a value to a variable in a class from JSON or pass this value to the next function?

大家好! 目前,我正在哈佛计算机科学 CS50 学习一门课程。 我的作业差不多准备好了,但还有一些不完整。 我无法将函数的值分配给 class 中的变量或传递 这个值到下一个函数。

导入 UIKit

class PokemonViewController: UIViewController {

var url:    String!
var name:   String!

@IBOutlet var pokemonImage:     UIImageView!
@IBOutlet var nameLabel:        UILabel!
@IBOutlet var numberLabel:      UILabel!
@IBOutlet var type1Label:       UILabel!
@IBOutlet var type2Label:       UILabel!
@IBOutlet var catchButton:      UIButton!
@IBOutlet var descriptionLabel: UILabel!

// MARK: - additional properties
var currentDescURL: String!

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    loadPokemon()
    
    showPokemonDescription()
}

//MARK: - pokemon loading
func loadPokemon() {
    guard let pokemonURL = URL(string: url) else { return }
    URLSession.shared.dataTask(with: pokemonURL) { (data, _, error) in
        guard let data = data else { return }
        do {
            let result = try JSONDecoder().decode(PokemonResult.self, from: data)
            DispatchQueue.main.async {
                self.navigationItem.title = self.capitalize(text: result.name)
                self.nameLabel.text = self.capitalize(text: result.name)
                self.numberLabel.text = String(format: "#%03d", result.id)
                
                for typeEntry in result.types {
                    if typeEntry.slot == 1 {
                        self.type1Label.text = typeEntry.type.name
                    }
                    else if typeEntry.slot == 2 {
                        self.type2Label.text = typeEntry.type.name
                    }
                }
                // Create Image and Update ImageView
                guard let imageURL = URL(string: result.sprites.front_default) else { return }
                if let data = try? Data(contentsOf: imageURL) {
                    self.pokemonImage.image = UIImage(data: data)
                }
                self.currentDescURL = result.species.url
                print(self.currentDescURL)
            }
        } catch let error { print(error) }
    }.resume()
}

// MARK: - Get the URL of a specific Pokémon
func showPokemonDescription() {
    guard let pokemonDescriptionURL = URL(string: currentDescURL) else { return }
    URLSession.shared.dataTask(with: pokemonDescriptionURL) { (data, _, error) in
        guard let data = data else { return }
        do {
            let result = try JSONDecoder().decode(PokemonDescription.self, from: data)
            DispatchQueue.main.async {
                // Check and get first pokemon description in English
                for index in 0..<result.flavor_text_entries.count {
                    if result.flavor_text_entries[index].language.name == "en" {
                        self.descriptionLabel.text = result.flavor_text_entries[index].flavor_text
                    }
                }
            }
        } catch let error { print(error) }
    }.resume()
}

}

内部的第一个函数 loadPokemon() 从 JSON 获取值并将该值打印到控制台 -> print(self.currentDescURL)。此外,如果您在 viewWillAppear 中显示此值,则控制台中将显示“nil”。我知道 loadPokemon() 函数处理最后出现的流中的值。也许正因为如此,变量 currentDescURL 无法从 loadPokemon() 函数中获取值,showPokemonDescription() 函数也无法使用该值,因为 currentDescURL 为 nil。

我请你向我解释我的错误是什么,并帮助完成作业。

currentDescURL 属性 设置后,将方法 showPokemonDescription 的调用从 viewWillAppear 移动到 loadPokemon

class PokemonViewController: UIViewController {
    //...
    var currentDescURL: String!
    //...
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        loadPokemon()
        getPreferences()
        // <- remove the call from here
    }
    //...
    func loadPokemon() {
        //...
        self.currentDescURL = result.species.url
        self.showPokemonDescription() // <- move the call here
    }
    //...
    func showPokemonDescription() {
        //...
    }
}