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

Posted

技术标签:

【中文标题】使用 Core Data 在 Swift 中通过 UIProgressView 异步插入数据【英文标题】:Use Core Data to Insert data asynchronously in Swift with UIProgressView 【发布时间】:2015-11-19 10:46:22 【问题描述】:

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

这个数组的结果有 8000 项。

如何在 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()
        
        
    

编辑

自定义类正在插入数据。我试图创建一个协议和委托,但我不知道错误在哪里(说真的,我不知道如何使用协议和委托。我尝试按照Howto Update a gui (progressview) from a download delegate in swift 中的示例进行操作)

我的 ViewController 类:

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 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)
        
    

【问题讨论】:

您是如何尝试的,出了什么问题? @Wain :我刚刚添加了更多代码来更好地解释我想要的。基本上,我从其他类调用方法 AddData。此方法在自定义类中。谢谢! 【参考方案1】:

您似乎对关系有点误解。

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

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 然后做一些工作并调用UpdateProgressBarMyViewController 然后更新 UI。

此时您会遇到崩溃,因为您从未设置委托。这一行:

DB.delegate?.UpdateProgressBar(progressView.progress)

应该是

DB.delegate = self

旁白:

如果它实际上没有创建某些东西,请不要调用 CreateContext。另外,函数的第一个字母应该小写。

【讨论】:

非常感谢@Wain!现在可以了! (我来自 ASP.Net/VB,这就是为什么我的方法的第一个字母是大写的,但我会从现在开始更改它)。【参考方案2】:

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

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。

【讨论】:

以上是关于使用 Core Data 在 Swift 中通过 UIProgressView 异步插入数据的主要内容,如果未能解决你的问题,请参考以下文章

SWIFTUI Core Data 传递数字

如何使用 Multipeer Connectivity (Swift 3) 在会话中通过 didReceiveData() 调用 table.reloadData

Swift 3 Core Data Migration with Progress Indicator 或 Activity Spinner

在swift中通过inout参数编写一个var

如何在 Swift 中将 Core Data 与 Cloudkit 和许多设备同步

如何在 EF Core 中通过 Fluent Api 创建加密列