使用 Core Data 在 Swift 中使用 UIProgressView 异步插入数据

Use Core Data to Insert data asynchronously in Swift with UIProgressView

我收到一个 JSon,我将其转换为字典数组并将该数组插入到 Core Data。

这个数组的结果有 8.000 项。

如何在 Core Data 使用以下代码时插入 UIProgressView?

谢谢!

func CreateContext() -> NSManagedObjectContext {
    let AppDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let Context: NSManagedObjectContext = AppDel.managedObjectContext
    return Context
}

static func AddData(arrayDictionary: [[String : AnyObject]]) {
    for Item in arrayDictionary {
        let Context = CreateContext()
        let DAO = NSEntityDescription.insertNewObjectForEntityForName("Customers", inManagedObjectContext: Context)

        // Insert at Core Data
        if let item = Item["UserID"] as? Int {
            DAO.setValue(item, forKey: "userID")
        }
        if let item = Item["Name"] as? String {
            DAO.setValue(item, forKey: "name")
        }
        if let item = Item["Email"] as? String {
            DAO.setValue(item, forKey: "email")
        }

        do {
            try Contexto.save()
        } catch {
            let nserror = error as NSError
            //abort()
        }
        }
    }
}

编辑

正在通过自定义 class 插入数据。我试图创建一个协议和委托,但我不知道错误在哪里(真的,我不知道如何使用协议和委托。我试着按照 中的示例)

我的ViewControllerclass:

import UIKit

protocol ProgressBarDelegate: class {
    func UpdateProgressBar(progress: Float)
}

class MyViewController: UIViewController {

    @IBOutlet var progressView: UIProgressView!

    func AddDataFromArray() {
        let DB = MyCustomClass()
        DB.delegate?.UpdateProgressBar(progressView.progress)
        DB.AddData(getArrayDictionaryData())
    }

}

我的习惯class:

class MyCustomClass {

    var delegate: ProgressBarDelegate?

    func initWithDelegate(delegate: ProgressBarDelegate) {
        self.delegate = delegate
    }

    func CreateContext() -> NSManagedObjectContext {
        let AppDel: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        let Context: NSManagedObjectContext = AppDel.managedObjectContext
        return Context
    }

    func AddData(arrayDictionary: [[String : AnyObject]]) {
        var addedItems: Int = 0
        var Progress = Float()

        for Item in arrayDictionary {
        addedItems += 1
        Progress = ((Float(100.0) / Float(arrayDictionary.count)) * Float(addedItems)) / Float(100)

            let Context = CreateContext()
            let DAO = NSEntityDescription.insertNewObjectForEntityForName("Customers", inManagedObjectContext: Context)

            // Insert at Core Data
            if let item = Item["UserID"] as? Int {
                DAO.setValue(item, forKey: "userID")
            }
            if let item = Item["Name"] as? String {
                DAO.setValue(item, forKey: "name")
            }
            if let item = Item["Email"] as? String {
                DAO.setValue(item, forKey: "email")
            }

            do {
                try Contexto.save()
            } catch {
                let nserror = error as NSError
                //abort()
            }

            delegate!.UpdateProgressBar(Progress)
        }
    }
}

假设进度视图已经存在,您可以执行如下操作:

self.progressView.progress = 0

for (index, item) in arrayDictionary.enumerate() {
    // Do all the work of importing the data...

    let progress = CGFloat(index) / CGFloat(arrayDictionary.count)
    self.progressView.progress = progress
}

随着循环的不断执行,progress 的值将逐渐从接近零上升到 1.0。

你好像对关系有点误解。

如果 class 需要提供一些信息或想要进行回调以让某人知道发生了某些事情,则它可以接受委托。委托实现委托协议中指定的方法并处理通知:

Delegate (observer)
  -> conforms to the delegate protocol
  -> registers itself
  -> handles notifications

Interesting class
  -> holds a reference to a delegate
  -> notifies the delegate when things happen

在你的情况下。 MyViewController 应该符合委托协议,所以它应该实现 UpdateProgressBar。它创建了一个 MyCustomClass 的实例来为它做一些工作,并将自己设置为委托。 MyCustomClass 然后做一些工作并调用 UpdateProgressBar,其中 MyViewController 然后更新 UI.

您现在遇到了崩溃,因为您从未设置委托。这一行:

DB.delegate?.UpdateProgressBar(progressView.progress)

应该是

DB.delegate = self

旁白:

如果它实际上不是在创建某些东西,请不要调用它 CreateContext。另外,函数首字母要小写