When I'm trying to delete an item in list I'm getting the following error:
Swift/ContiguousArrayBuffer.swift:580: Fatal error: Index out of range 2021-05-07 09:59:38.171277+0200 Section[4462:220358] Swift/ContiguousArrayBuffer.swift:580: Fatal error: Index out of range
I have been searching for a solution but none of the once I'v found seems to work on my code.
FIY this is my first app in SwiftUI or Swift for that matter so I'm totally new to this.
So if someone could help me out and explain what I need to change and why I would be so grateful :)
Here is some code I hope will help get to the bottom of the problem.
My model:
//
// Item.swift
// Section
//
// Created by Niklas Peterson on 2021-03-11.
//
import Foundation
struct Item: Identifiable, Hashable, Codable {
var id = UUID().uuidString
var name: String
}
extension Item {
static func getAll() -> [Item] {
let key = UserDefaults.Keys.items.rawValue
guard let items: [Item] = UserDefaults.appGroup.getArray(forKey: key) else {
let items: [Item] = [.section1]
UserDefaults.appGroup.setArray(items, forKey: key)
return items
}
return items
}
static let section1: Item = {
return Item(name: "Section")
}()
}
extension Item {
static func fromId(_ id: String) -> Item? {
getAll().first { $0.id == id }
}
}
UserDefaults:
//
// UserDefaults+Ext.swift
// Section
//
// Created by Niklas Peterson on 2021-03-11.
//
import Foundation
extension UserDefaults {
static let appGroup = UserDefaults(suiteName: "************ hidden ;) ")!
}
extension UserDefaults {
enum Keys: String {
case items
}
}
extension UserDefaults {
func setArray<Element>(_ array: [Element], forKey key: String) where Element: Encodable {
let data = try? JSONEncoder().encode(array)
set(data, forKey: key)
}
func getArray<Element>(forKey key: String) -> [Element]? where Element: Decodable {
guard let data = data(forKey: key) else { return nil }
return try? JSONDecoder().decode([Element].self, from: data)
}
}
ContentView:
//
// ContentView.swift
// Section
//
// Created by Niklas Peterson on 2021-03-11.
//
import SwiftUI
struct ContentView: View {
@State private var items = Item.getAll()
func saveItems() {
let key = UserDefaults.Keys.items.rawValue
UserDefaults.appGroup.setArray(items, forKey: key)
}
func move(from source: IndexSet, to destination: Int) {
items.move(fromOffsets: source, toOffset: destination)
saveItems()
}
func delete(at offsets: IndexSet) {
items.remove(atOffsets: offsets)
saveItems()
}
var body: some View {
NavigationView {
List {
ForEach(items.indices, id: \.self) { index in
TextField("", text: $items[index].name, onCommit: {
saveItems()
})
}
.onDelete(perform: delete)
.onMove(perform: move)
}
.toolbar {
ToolbarItemGroup(placement: .primaryAction) {
HStack {
Button(action: {
self.items.insert(Item(name: ""), at: 0)
}) {
Image(systemName: "plus.circle.fill")
}
EditButton()
}
}
}
.navigationBarTitle("Sections")
.listStyle(InsetGroupedListStyle())
}
}
}