ios - 从 CoreData 获取到 TableView

标签 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

如有任何意见,我们将不胜感激!

最佳答案

有 2 个地方可以设置 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:

看起来就像for循环每次用数据更新forcastInfo数组,并将获得的字符串转换为forecastInfo = [forecast]

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

检查 forecastif let Forecast = data.value(forKey: "forecastDetails") as? String,它应该采用数组形式,每个参数都有不同的对象,而不是只有一个包含您显示的所有参数的对象。它将帮助您纠正问题。

关于ios - 从 CoreData 获取到 TableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49760548/

相关文章:

在我添加另一个 .map(ping) 子句之前,Swift 编译器一直有效

objective-c - CoreData自定义映射模型

ios - iPhone 如何在按下音量键时隐藏音量覆盖

ios - 空部分的 UITableView 策略并在自定义单元格中添加行

ios - 选择或突出显示 UITableViewCell 时调用哪个方法

iphone - UITableView 无限滚动

swift - RxSwift Driver 第一次调用两次

ios - prepareForSegue 不能快速工作。我该如何解决?

ios - 使用 Coredata 和 NSFetchRequest 进行 "IN"搜索时如何格式化 NSPredicate

ios - 无法保存或正确调用电话号码,ios 太大