[英]Fetching from CoreData into TableView
I have the following ViewController: 我有以下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
}
}
It works fine, except for one problem. 它工作正常,除了一个问题。 The data being fetched is not populated on the tableView as it should. 提取的数据未按原样填充在tableView上。 It just crams everything with quotes and brackets in one cell instead of listing the items separately. 它只是在一个单元格中用引号和方括号填充所有内容,而不是单独列出项目。 See images: https://imgur.com/a/7v8aL 查看图片: https : //imgur.com/a/7v8aL
Any input would be appreciated! 任何输入将不胜感激!
There are 2 places where you are setting forecastInfo
array: 您可以在2个地方设置forecastInfo
数组:
Case 1: 情况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!))°"]
}
Case 2: 情况2:
Seems like for loop updating the forcastInfo
array each time with data, and cast the obtained string in forecastInfo = [forecast]
. 好像是每次使用数据循环循环更新forcastInfo
数组,然后将获得的字符串forcastInfo
为forecastInfo = [forecast]
。
for data in forecastData as! [NSManagedObject] {
if let forecast = data.value(forKey: "forecastDetails") as? String {
forecastInfo = [forecast]
stopAndHideActivityIndicator()
}
}
Check the forecast
value from if let forecast = data.value(forKey: "forecastDetails") as? String
检查forecast
值是否来自if let forecast = data.value(forKey: "forecastDetails") as? String
if let forecast = data.value(forKey: "forecastDetails") as? String
, it should be in array form with different objects of each parameter rather than just one object with all parameter you are showing. if let forecast = data.value(forKey: "forecastDetails") as? String
,它应该是数组形式,每个参数具有不同的对象,而不是只有一个带有所有参数的对象。 it will help you to rectify issue. 它将帮助您纠正问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.