从CoreData获取到TableView

时间:2018-04-10 18:21:02

标签: ios swift core-data nsfetchrequest

我有以下ViewController:

import UIKit    
import CoreData

class DetailedForecastViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var iconViewer: UIImageView!
    @IBOutlet weak var tempLabel: UILabel!
    var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
    var forecastInfo = [String]()
    let appDelegate = UIApplication.shared.delegate as! AppDelegate

    override func viewDidLoad() {
        super.viewDidLoad()

        // Activity Indicator config.
        activityIndicator.center = view.center
        activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
        view.addSubview(activityIndicator)

        getForecastInfo()
    }

    // Downloading forceast Data
    func getForecastInfo() {
        if currentReachabilityStatus == .notReachable {
            errorAlert(title: "", message: "The Internet connection appears to be offline")

            // Fetching Data
            let context = appDelegate.persistentContainer.viewContext
            let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Forecast")
            request.returnsObjectsAsFaults = false
            do {
                let forecastData = try context.fetch(request)
                if forecastData.count > 0 {
                    for data in forecastData as! [NSManagedObject] {
                        if let forecast = data.value(forKey: "forecastDetails") as? String {
                            forecastInfo = [forecast]
            stopAndHideActivityIndicator()

                        }
                    }
                }
            } catch {}
        } // end of reachability

        self.activityIndicator.startAnimating()
        let forecastConstants = ForecastClient(apiKey: ForecastConstants.forecastURL.forecastAPIKey)
        forecastConstants.getForecast(latitude: ForecastConstants.forecastURL.coordinates.latitude, longitude: ForecastConstants.forecastURL.coordinates.longitude) { (currentWeather) in
            if let currentWeather = currentWeather {

                let temperature = currentWeather.temperature
                let humidity = currentWeather.humidity
                let precipProbability = currentWeather.precipProbability
                let precipIntensity = currentWeather.precipIntensity
                let windSpeed = currentWeather.windSpeed
                let windGust = currentWeather.windGust
                let pressure = currentWeather.pressure
                let dewPoint = currentWeather.dewPoint

                if self.forecastInfo.count == 0 {
                    self.forecastInfo = ["Humidity: \(String(humidity!))%", "Precip. Probability: \(String( precipProbability!))%", "Precip. Intensity: \(String(precipIntensity!))%", "Wind Speed: \(String(windSpeed!))mph", "Wind Gust: \(String(windGust!))mph", "Pressure: \(String(pressure!))\"", "Dew Point: \(String(dewPoint!))°"]
                }
                DispatchQueue.main.async {
                    self.tempLabel.text = "\(Int(temperature!))°"

                    // Changing the icon based on the weather conditions
                    let icon = currentWeather.icon

                    switch icon {
                    case "clear-day"?, "clear-night"?:
                        self.iconViewer.image = UIImage(named: "clear")!
                    case "partly-cloudy-day"?, "partly-cloudy-night"?:
                        self.iconViewer.image = UIImage(named: "cloudy")!
                    case "cloudy"?:
                        self.iconViewer.image = UIImage(named: "cloudy")!
                    case "fog"?:
                        self.iconViewer.image = UIImage(named: "fog")!
                    case "rain"?:
                        self.iconViewer.image = UIImage(named: "rain")!
                    case "snow"?, "sleet"?:
                        self.iconViewer.image = UIImage(named: "snow")!
                    default:
                        self.iconViewer.image = UIImage(named: "default")!
                    }
                    self.stopAndHideActivityIndicator()

                    // MARK: Saving data into CoreData
                    let context = self.appDelegate.persistentContainer.viewContext
                    let forecast = NSEntityDescription.insertNewObject(forEntityName: "Forecast", into: context)
                    forecast.setValue("\(self.forecastInfo)", forKey: "forecastDetails")

                    if self.iconViewer.image == nil || self.tempLabel.text == nil {
                        self.iconViewer.image = UIImage(named: "iconNotFound")
                        self.errorAlert(title: "", message: "There seems to be a problem loading the weather icon and/or the temperature, please try again")
                        self.iconViewer.image = UIImage(named: "iconNotFound")
                    }
                    else {
                        let iconData = UIImagePNGRepresentation(self.iconViewer.image!) as NSData?
                        forecast.setValue(iconData, forKey: "weatherIcon")
                    }
                    do {
                        try context.save()
                    } catch {
                        print("Error saving data")
                    }
                }
            } // end of dispatch

        } // end of forecast
    }

    // Stop and hide Activity Indicator func
    func stopAndHideActivityIndicator() {
        activityIndicator.stopAnimating()
        activityIndicator.hidesWhenStopped = true
    }

    // MARK : Populating forceast data into tableView
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if forecastInfo.count == 0 {
            self.errorAlert(title: "", message: "There seems to be a problem downloading the weather forecast, please try again")
        }
        return forecastInfo.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = forecastInfo[indexPath.row]
        return cell
    }
}

除一个问题外,它工作正常。正在获取的数据未填充在tableView上。它只是在一个单元格中用引号和括号来创建所有内容,而不是单独列出项目。见图片:https://imgur.com/a/7v8aL

任何意见都会受到赞赏!

1 个答案:

答案 0 :(得分:0)

您有两个地方设置forecastInfo数组:

案例1:

// No any problem with this line

if self.forecastInfo.count == 0 {
    self.forecastInfo = ["Humidity: \(String(humidity!))%", "Precip. Probability: \(String( precipProbability!))%", "Precip. Intensity: \(String(precipIntensity!))%", "Wind Speed: \(String(windSpeed!))mph", "Wind Gust: \(String(windGust!))mph", "Pressure: \(String(pressure!))\"", "Dew Point: \(String(dewPoint!))°"]
}

案例2:

似乎每次使用数据循环更新forcastInfo数组,并将获得的字符串转换为forecastInfo = [forecast]

for data in forecastData as! [NSManagedObject] {
    if let forecast = data.value(forKey: "forecastDetails") as? String {
        forecastInfo = [forecast]
        stopAndHideActivityIndicator()
    }
}

检查来自forecast的{​​{1}}值,它应该是数组形式,每个参数的对象不同,而不是只有一个对象,显示所有参数。它将帮助您纠正问题。