[英]Cannot save and display data in table view correctly with Core Data and Swift
Goal:目标:
My goal is to pass the current minimum, average and maximum value data to table view and present them to the user.我的目标是将当前的最小值、平均值和最大值数据传递给表视图并将它们呈现给用户。
Error:错误:
When I hit the "Save" button "nan" value is passed with the current minimum, average and maximum value data.当我点击“保存”按钮时,“nan”值与当前的最小值、平均值和最大值数据一起传递。
UI screenshot界面截图
Here is the table view before pressing the Save button这是按下“保存”按钮之前的表格视图
Here is the table view after pressing the Save button这是按下保存按钮后的表格视图
Here is the current code:这是当前的代码:
Record.swift记录.swift
import Foundation
import CoreData
class Record: NSManagedObject {
var minimumValue: Float = .nan
var averageValue: Float = .nan
var maximumValue: Float = .nan
}
RecordTableViewController.swift RecordTableViewController.swift
class RecordCell: UITableViewCell {
@IBOutlet weak var maximumValueLabel: UILabel!
@IBOutlet weak var averageValueLabel: UILabel!
@IBOutlet weak var minimumValueLabel: UILabel!
}
class RecordTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
private lazy var fetchedResultsController: NSFetchedResultsController = { () -> NSFetchedResultsController<NSFetchRequestResult> in
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "History")
let sortDescriptor: [NSSortDescriptor] = []
fetchRequest.sortDescriptors = sortDescriptor
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = appDelegate.persistentContainer.viewContext
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
return fetchedResultsController
}()
let cellIdentifier: String = "cellID"
var recordsArray = [Record]()
override func viewDidLoad() {
super.viewDidLoad()
let swipe = UISwipeGestureRecognizer(target: self, action: #selector(swipeRight(_:)))
swipe.direction = .right
self.view.addGestureRecognizer(swipe)
recordsArray = fetchAllRecords()
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
switch editingStyle {
case .delete:
let removedRecord = fetchedResultsController.object(at: indexPath) as! NSManagedObject
let context = fetchedResultsController.managedObjectContext
context.delete(removedRecord)
do {
try context.save()
self.recordsArray.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
} catch _ {
}
default:
break
}
}
}
extension RecordTableViewController {
public func fetchAllRecords() -> [Record] {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "History")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
return result as! [Record]
} catch let error {
fatalError(error.localizedDescription)
}
}
}
MainViewController.swift主视图控制器.swift
import UIKit
import Dispatch
import CoreData
import Accelerate
import Foundation
import UserNotifications
class MainViewController: UIViewController {
var minimum: Float = .nan
var average: Float = .nan
var maximum: Float = .nan
var decibel: Float = .nan
/// MARK: Segue functions
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "saveRecord" {
let recordVC = segue.destination as! RecordTableViewController
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let record = Record.init(entity: NSEntityDescription.entity(forEntityName: "History", in: context)!, insertInto: context)
record.minimumValue = Float(minDbLabel.text!) ?? 0.0
record.averageValue = Float(averageDbLabel.text!) ?? 0.0
record.maximumValue = Float(maximumDbLabel.text!) ?? 0.0
saveNewRecord(record: record)
self.recordsArray.append(record)
recordVC.recordsArray = self.recordsArray
}
}
@IBAction func save(_ sender: UIButton){
self.performSegue(withIdentifier: "saveRecord", sender: nil)
}
// MARK: Core Data functions
private func saveNewRecord(record: Record) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
var index: Int = 0
let entity = NSEntityDescription.entity(forEntityName: "History", in: context)
let newRecord = [NSManagedObject(entity: entity!, insertInto: context)] as [NSManagedObject]
newRecord[index].setValue(record.minimumValue, forKey: "minimumValue")
newRecord[index].setValue(record.averageValue, forKey: "averageValue")
newRecord[index].setValue(record.maximumValue, forKey: "maximumValue")
index += 1
do {
try context.save()
} catch let error {
print("\(error.localizedDescription)")
}
}
}
Any help is appreciated.任何帮助表示赞赏。
The code you provided is kinda confusing, however, here's how I setup my CoreData applications.您提供的代码有点令人困惑,但是,这是我设置 CoreData 应用程序的方法。
First: I create a CoreDataManager model第一:我创建了一个 CoreDataManager 模型
This will handle all of my Model functions like fetching viewing and context etc...这将处理我所有的模型功能,如获取查看和上下文等...
struct CoreDataManager {
static let shared = CoreDataManager()
let persistentContainer: NSPersistentContainer = {
let perCon = NSPersistentContainer(name: "EntityName")
perCon.loadPersistentStores { (storeDescription, err) in
if let err = err {
fatalError("\(err)")
}
}
return perCon
}()
func fetchEntitys() -> [Entity] {
let context = persistentContainer.viewContext
let fetchRequest = NSFetchRequest<Entity>(entityName: "EntityName")
do {
let entity = try context.fetch(fetchRequest)
return entity
} catch let err {
print("\(err)")
return []
}
}
func resetEntitys() {
let context = persistentContainer.viewContext
let batchRequest = NSBatchDeleteRequest(fetchRequest: Entity.fetchRequest())
do {
try context.execute(batchRequest)
} catch let err {
print("\(err)")
}
}
}
Second: Setup your secondViewController the viewController in which you create the objects in第二:设置你的 secondViewController 你在其中创建对象的 viewController
protocol CreateControllerDelegate: class {
func didAdd(entity: Entity)
}
weak var delegate: CreateControllerDelegate?
func createEntity() {
let context = CoreDataManager.shared.persistentContainer.viewContext
let entity = NSEntityDescription.insertNewObject(forEntityName: "EntityName", into: context)
entity.setValue(nameTextField.text, forKey: "name")
// set all of your values that you want to be saved.
do {
try context.save()
dismiss(animated: true) {
self.delegate?.didAdd(entity: entity as! Entity)
}
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
Finally, setup your firstViewController the one in which you will display all of your Core Data objects.最后,设置您的 firstViewController ,您将在其中显示所有 Core Data 对象。
var objectsArray = [Entity]()
override func viewDidLoad() {
super.viewDidLoad()
self.objectsArray = CoreDataManager.shared.fetchEntitys()
}
extension MainController: CreateControllerDelegate {
func didAdd(entity: Entity) {
objectsArray.append(entity)
let indexPath = IndexPath(row: objectsArray.count - 1, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)
}
}
@IBAction func handleAdd(_ sender: Any) {
let createController = storyboard?.instantiateViewController(withIdentifier: "CreateController") as! CreateController
createController.delegate = self
let navController = UINavigationController(rootViewController: createController)
navController.modalPresentationStyle = .fullScreen
present(navController, animated: true)
}
I hope this is helpful and if there's something that's not working let me know!我希望这是有帮助的,如果有什么不工作让我知道!
Good Luck!祝你好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.