In my code below the variable number is increased by 10 every time when button is pressed. I want to overwrite number to the old one then save, fetch and display it on the View. Unfortunately I get the following error message in func fetchStats() How can I assign a type of optional to a type entity? Or easier to say: How can I overwrite the existing variable "number" with the old one, then save, fetch it with Core Data (to entity (Statsohs) with attribute (value)) and finally display it?
import UIKit
import CoreData
class ViewController: UIViewController {
var number : Double = 0
//Reference to Managed Object Context
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
//Data for the Stats
var average : Statsohs?
@IBOutlet weak var LabelStats: UILabel!
//--------------------------------------------------------------------------------------
override func viewDidLoad() {
super.viewDidLoad()
fetchStats()
}
//--------------------------------------------------------------------------------------
@IBAction func ActionButton(_ sender: UIButton) {
number = number + 10
average = Statsohs(context: context)
average?.value = number
LabelStats.text = String(format: "%.2f", average!.value)
//Save the data
do {
try context.save()
}
catch {
}
}
//--------------------------------------------------------------------------------------
func fetchStats() {
//Fetch the data from CoreData to display in the View
do {
average = try context.fetch(Statsohs.fetchRequest())
//Cannot assign value of type '[Statsohs]' to type 'Statsohs'
}
catch {
}
}
}
I tried different declarations of average in the beginning, e.g.: average : [Statsohs]? But then I will get the same error message in Action at average = Statsohs(conext: context) And also member of type '[Statsohs]' has no member 'value'
I hope its possible in that way to assign value to Statsohs, save, fetch, display every time the updated value.
fetch
returns always an array of records (multiple items) even if there is only one.
To overwrite an attribute of a record you have to fetch the record, modify the attribute and save it back.
In fetchStats
fetch the (single) record which is the first in the array. Assign it to average
and its value
to number
. If it doesn't exist create one and assign zero to value
func fetchStats() {
//Fetch the data from CoreData to display in the View
do {
if let found = try context.fetch(Statsohs.fetchRequest()).first {
average = found
number = found.value
} else {
average = Statsohs(context: context)
average?.value = 0
saveData()
}
displayData()
} catch {
print(error)
}
}
In actionButton
increment number
by 10, assign the result to value
, display and save the data
@IBAction func actionButton(_ sender: UIButton) {
number += 10.0
average?.value = number
saveData()
displayData()
}
Finally add the helper methods displayData
and saveData
func saveData() {
do {
try context.save()
} catch {
print(error)
}
}
func displayData() {
labelStats.text = String(format: "%.2f", number)
}