0

我最近开始学习 swift 并且我是一个非常初学者,我试图在用户界面中输入 json 天气数据,但似乎没有任何效果,我试图将数据打印到终端中,它运行良好,任何人都可以帮助我。这是我的代码。

import UIKit

// UITableViewDelegate: is responsible for how the table is going to look like
// UITableViewDataSource: is responsible for the data that are going to be loaded in the table

class WeatherVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    
    @IBOutlet weak var dateLabel: UILabel!
    @IBOutlet weak var currentTempLabel: UILabel!
    @IBOutlet weak var locationLabel: UILabel!
    @IBOutlet weak var currentWeatherImage: UIImageView!
    @IBOutlet weak var currentWeatherTypeLabel: UILabel!
    @IBOutlet weak var tableView: UITableView!
    
    // This is going to create a generic class that behaves as if the class existed here and will call it's functions
    var currentWeather = CurrentWeather()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // After you have made the funtions down there, without setting the viewDelegate and the dataSource the program won't know what to do.
        // it will now know where to get the data from and how to represent it.
        
        tableView.delegate = self
        tableView.dataSource = self
        
        currentWeather.downloadWeatherDetails {
            // Setup the UI to download the data
            // And now we call the updating function here.
            self.updateMainUI()
        }
    }

    // Now we will add the functions of the delegate and theres 3 important ones that you need to MEMORIZE.
    
    // This function is responsible for the number of sections in the cell and we don't want more than one because we aren't going to do fancy things like titles and thing like these.
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    // This function is basically about how many cells you want in your table.
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 6
    }
    
    // Here we want to create a cell so that it know what to recreate all the way down the table.
    // You should give the prototype cell in your table view an identifier.
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // Basically what dequeueReusableCell is that it looks for a cell with the identifier of "weatherCell"
        let cell = tableView.dequeueReusableCell(withIdentifier: "weatherCell", for: indexPath)
        
        // What happens is that the cells won't be all made on the screen so that what happen's is that the contents of the cell is recycled and moved to the following cell.
        // You also need to return the cell because if you didn't return it then it won't work.
        return cell
    }
    
    // We will make a function that will upadate the UI and then call it inside (currentWeather.downloadWeatherDetails) in (viewDidLoad).
    func updateMainUI(){
        dateLabel.text = currentWeather.date
        currentTempLabel.text = "\(currentWeather.currentTemp)"
        currentWeatherTypeLabel.text = currentWeather.weatherType
        locationLabel.text = currentWeather.cityName
        // Now in order to make the pictures work correctlly when passing the picture according to the type we are going to do the following.
        currentWeatherImage.image = UIImage(named: currentWeather.weatherType)// We named the images files the way they're named in JSON and we passed it here so the image is going to be loaded from the assets.
        
    }

}

这是我的 (CurrentWeather) 课程

import UIKit
import Alamofire

class CurrentWeather{
    var _cityName: String!
    var _date: String!
    var _weatherType: String!
    var _currentTemp: Double!
    
    // Now we have to make these data hidden so we have more security
    
    var cityName: String{
        if _cityName == nil{
            _cityName = ""
        }
        return _cityName
    }
    
    // For the date it's a bit tricky since we need to make something called nsFormatter. First we will go as normal and before the return we are going to write some code.
    var date: String{
        if _date == nil{
            _date = ""
        }
        
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .long
        dateFormatter.timeStyle = .none
        let currentDate = dateFormatter.string(from: Date())
        self._date = "Today, \(currentDate)"
        
        return _date
    }
    
    var weatherType: String{
        if _weatherType == nil{
            _weatherType = ""
        }
        return _weatherType
    }
    
    var currentTemp: Double{
        if _currentTemp == nil{
            _currentTemp = 0.0
        }
        return _currentTemp
    }
    
    // We need to create a function that will download the data of the weather and change the value of the variables to the right one.
    func downloadWeatherDetails(completed: DownloadComplete){
        // We will initialze the URL that will tell the Alamofire where to download from.
        let currentWeatherURL = URL(string: CURRENT_WEATHER_URL)
        
        // response here is like the data that are going to be returned.
        AF.request("\(currentWeatherURL!)").responseJSON{ response in
            
            // Now we need to add JSON data into the variables that we have created.
            // If you remember that the JSON data are dictionaries within dictionaries, so first we are going to make a dictionary.
            /* Now return the value of the responce as a dictionary */
            if let dict = response.value as? Dictionary<String, Any>{// or instead of the Dictionary<String, Any> you can say [String: Any]
                
                if let name = dict["name"] as? String{
                    
                    self._cityName = name.capitalized // If you checked the JSON file you will find that the city name is always capitilized but we just wanna make sure that in case of something wrong happened to the API that the name of the city is always capitalized.
                    
                    print("The city name is: \(self._cityName!)")
                    
                }
                
                // Now for the weather type if you noticed something that the weather data are stored in an array that has a dictionary
                if let weather = dict["weather"] as? [Dictionary<String, AnyObject>]{
                    if let main = weather[0]["main"] as? String{ // The zero index means that I want the first element of the weather array and the "main" indicates that I want the value of the "main" key in the dictionary.
                        self._weatherType = main.capitalized
                        print("The weather type is \(self._weatherType!)")
                    }
                }
                
                // Now we want to return the temperature and it's located in the "main" dictionary.
                if let main = dict["main"] as? Dictionary<String, AnyObject>{
                    if let currentTemperature = main["temp"] as? Double{ // The temperature is going to be returned as Kelvin
                        let KelvinToCelsiusWithDecimals = (currentTemperature - 273.15)
                        // Now we want to ensure that we only have one decimal value in the temperature
                        let KelvinToCelsiusWithLessDecimals = Double(round(10 * Double(KelvinToCelsiusWithDecimals)) / 10)
                        self._currentTemp = KelvinToCelsiusWithLessDecimals
                        print("The temperature is \(self._currentTemp!)")
                        
                    }
                }
            }
            
        }
        completed()
        
    }

}

任何人都可以帮我解决这个问题!

4

0 回答 0