Hello,I'm learning CoreData but my Tutorial is about one year old so not everything is up to date and I don't understand where the problem is. My Project includes an TableViewController with an bar button item. Here is the codeCoreDataResource.swift:import UIKit
import CoreData
class CoreDataResource {
// /Document
var documentDir : URL {
let allUrls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return allUrls[0]
}
let appDelegate = UIApplication.shared.delegate as! AppDelegate
private var managedObjectModel: NSManagedObjectModel {
guard let url = Bundle.main.url(forResource: "Listen", withExtension: "momd") else {
fatalError("fix me: not found?")
}
guard let model = NSManagedObjectModel(contentsOf: url) else {
fatalError("error in the model?")
}
return model
}
private var storeCoordinator: NSPersistentStoreCoordinator {
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.documentDir.appendingPathComponent("Listen.sqlite")
do {
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
} catch {
print(error)
}
return coordinator
}
var managedContext: NSManagedObjectContext {
let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
context.persistentStoreCoordinator = self.storeCoordinator
return context
}
func saveContext() {
if managedContext.hasChanges {
do {
try managedContext.save()
} catch {
print(error)
}
}
}
func loadLists() -> [Liste] {
let request: NSFetchRequest = Liste.fetchRequest()
var listen = [Liste]()
do{
listen = try managedContext.fetch(request)
} catch {
print(error)
}
return listen
}
func newList(_ name: String) {
let newList = NSEntityDescription.insertNewObject(forEntityName: "Liste", into: managedContext) as! Liste
newList.name = name
saveContext()
}
}ListTableViewController.swift:import UIKit
class ListTableViewController: UITableViewController {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
var listen = [Liste]()
override func viewDidLoad() {
super.viewDidLoad()
reloadList()
}
private func reloadList() {
listen = appDelegate.coreDataResource.loadLists()
}
@IBAction func addDummyData(_ sender: Any) {
appDelegate.coreDataResource.newList("Test entry")
appDelegate.coreDataResource.saveContext()
reloadList()
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "listCell", for: indexPath)
let liste = listen[indexPath.row]
cell.textLabel?.text = liste.name
return cell
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return listen.count
}
}If I press in Simulator on the addDummyData button the following error occurs:CoreData: error: Mutating a managed object 0x6000026b25c0 <x-coredata:///Liste/t8A4529E8-BD3B-4157-B3AF-E8B011B6C46E2> (0x6000005b6300) after it has been removed from its context.I can't find the mistake. Please help me it's frustrating 😀
Post
Replies
Boosts
Views
Activity
Hey,I'm a beginner hobby dev who tried cloud storage for first time using SwiftUI.I wanted to make a simple app which only needs to retrieve some values of a Database.I'm using Firebase RealTime Database.My Database structure looks like this:monsterhunter-e8167 Velkhana
HP: 12000element: IceRath
HP: 8000element: FireMy Code looks like this:import SwiftUI
import FirebaseDatabase
struct ContentView: View {
var ref: DatabaseReference = Database.database().reference()
var body: some View {
Button(action: {
self.ref.child("monsterhunter-e8167").child("Velkhana")
.observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let hp = value?["HP"] as? Int ?? 0
print(hp)
// ...
}) { (error) in
print(error.localizedDescription)
}
}) {
Text("print")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}However it is printing out0the expected output should be:12000I figured out "value" is nil but I don't know why."childpath" should be correctCan anyone tell me what I'm doing wrong?
I'm new to swiftUI.There must be a way to make this better.For example if I add an Item (for example: "name5") to names I have to add a new HStack Block in my Code.How can I do this more efficient?import SwiftUI
struct name: View {
let names = ["name1", "name2", "name3", "name4"]
var body: some View {
List {
VStack {
HStack {
Image(names[0])
Text(names[0])
}
HStack {
Image(names[1])
Text(names[1])
}
HStack {
Image(names[2])
Text(names[2])
}
HStack {
Image(names[3])
Text(names[3])
}
}
}
}
}
struct monsterList_Previews: PreviewProvider {
static var previews: some View {
name()
}
}Maybe something like this.Pseudocode: foreach i in names.count:
HStack {
Image(names[i])
Text(names[i])
}if I add an Item to names it should automatically increase the list by the new element.thanks in advance
I'm new to SwiftUI and tried my first project on it.So I want to make an iOS app which is showing some data from Firestore in a list. The list is empty because MonsterT is empty. How can I call the init of Class MonsterC?In my SceneDelegate I added following line in func scene and added this variable:class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var monsterT = MonsterC()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionIf using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView().environmentObject(monsterT)
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}...My Listimport SwiftUI
struct ContentView: View {
@EnvironmentObject var monsterT: MonsterC
var body: some View {
List(monsterT.monsters, id: \.self) { monster in
Text(monster.name)
}
}
}My MonsterC Class with MonsterObjimport SwiftUI
import FirebaseFirestore
import FirebaseFirestoreSwift
struct MonsterObj: Identifiable, Equatable, Hashable {
var id = UUID()
var name: String
var element: String
var immune: String
var size: String
var twoStarWeakness: String
var threeStarWeakness: String
#if DEBUG
static let exampleMonster = MonsterObj(id: UUID(), name: "Test Monster", element: "Test Element", immun: "Test immune", groesse: "Test size", twoStarWeakness: "Test 2 Weakness", threeStarWeakness: "Test3 Weakness")
#endif
}
class MonsterC: ObservableObject {
var db = Firestore.firestore()
@Published var monsters = [MonsterObj]()
init() {
var monsterCount: [String] = [""]
monsterCount.remove(at: 0)
db.collection("Monster").getDocuments() { (querySnapshot, err) in
if let err = err {
print(err)
} else {
for document in querySnapshot!.documents {
monsterCount.append(document.documentID)
}
}
}
for monsterName in monsterCount {
print(monsterName)
db.collection("Monster").document(monsterName).getDocument { (document, error) in
if let document = document, document.exists {
let elementGetter = document.get("element") as! String
let immuneGetter = document.get("immune") as! String
let sizeGetter = document.get("size") as! String
let twoStarWeaknessGetter = document.get("2 Star Weakness") as! String
let threeStarWeaknessGetter = document.get("3 Star Weakness")as! String
self.monsters.append(MonsterObj.init(name: monsterName, element: elementGetter, immune: immuneGetter, size: sizeGetter, twoStarWeakness: twoStarWeaknessGetter, threeStarWeakness: threeStarWeaknessGetter))
}
}
}
}What am I doing wrong or missing?Thanks in advance 🙂
My listView is simplestruct ListView: View {
var body: some View {
NavigationView {
List(myList) { element in
NavigationLink(destination: NextView()) {
Text(element.name)
}
}
}
}
}Thought I could set a background Image for the whole View with.background(Image("ImageName"))modifier. But the lists background is still white. I don't want to set an image for each row only once for the whole view.Can anyone help?