核心数据问题

时间:2018-03-23 03:45:49

标签: swift uitableview core-data

我正在尝试在Core Data中保存两个数组titlesbodys。我在代码中找不到错误。我认为下面的代码非常明显。我也无法判断我的问题是数据是否未正确保存,因此,下次无法加载。或者它保存得当,加载永远不会有效。

最后,每次打开应用程序时都会调用函数loadAPIData。

我首先想到的错误是它是一个线程问题

func loadCoreData() {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Saved")
    request.returnsObjectsAsFaults = false

    do {
        let results = try context.fetch(request)
        for result in results as! [NSManagedObject]{
            if let title = result.value(forKey: "title") as? String {
                titles.append(title)
            } else if let body = result.value(forKey: "body") as? String {
                bodys.append(body)
            }
        }
    } catch {
        print("failed")
    }
}

func saveCoreData() {
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext


    let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "Saved")
    let request = NSBatchDeleteRequest(fetchRequest: fetch)
    do {
        _ = try context.execute(request)
    } catch {
        print("we could not delete")
    }
    //delete first ^^^


    //save everything
    let newValue = NSEntityDescription.insertNewObject(forEntityName: "Saved", into: context)
    for a in 0..<bodys.count {
        newValue.setValue(titles[a], forKey: "title")
        newValue.setValue(bodys[a], forKey: "body")
        do {
            try context.save()
        }
        catch {
            print("Did not save")
        }
    }
}

另一种可能有用的方法:

var titles: [String] = []
var bodys: [String] = []


    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {

        titles.remove(at: indexPath.item)
        bodys.remove(at: indexPath.item)
        table.reloadData()
        saveCoreData()

    }
}


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    loadCoreData()
    if (bodys.count == 0) {
        loadAPIData()
        saveCoreData()
    }

    //some ommited because irrelevant
}

Scheme for Core Data

2 个答案:

答案 0 :(得分:0)

您必须在批量删除请求后合并更改。

我就是这样做的

let moc = context

    let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Members")
    request.returnsObjectsAsFaults = false

    moc.perform {



        // create deletion request.
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
        deleteRequest.resultType = .resultTypeObjectIDs

        do {

            let resultBox = try moc.execute(deleteRequest) as! NSBatchDeleteResult
            let objectIdArray = resultBox.result as? [NSManagedObjectID]
            let changes = [NSDeletedObjectsKey : objectIdArray]
            NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [moc])

            do {
                try context.save()
            }
            catch {

            }

            // save after deletion

            for objectToSave in self.objectArray {
                let object = NSEntityDescription.insertNewObject(forEntityName: "YourEntity", into: context)

                objectToSave.setValue(member.duration, forKey: "duration")

                do {
                    try context.save()
                }
                catch {

                }

            }

            do {
                let results = try context.fetch(request)
                print(results.count)
            }

            catch {
                print("Error")
            }

        }
        catch {
            print("error encountered")
            abort()
        }
    }

Source: Apple documentation

答案 1 :(得分:0)

我认为你这一切都错了,在你的代码中使用Saved实体作为一个类,并跳过这个删除全部/插入你拥有的所有逻辑。

替换标题和正文数组
var savedItems: [Saved]()

并将loadCoreData()中的do {}替换为

do {
    savedItems() = try context.fetch(request)
}

只需执行

,就可以在tableView(... commit ...)方法中删除
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext

let saved = savedItems[indexPath.row]
context.delete(saved)

在saveCoreData()函数中,删除提取逻辑和删除逻辑,然后只保存上下文。

do {
    try context.save()
} catch {
    print("Did not save")
}

我没有指出你的代码有什么问题,但是这应该会使代码变得更简单,并且在我看来更容易找到任何错误。