Swift 创建csv文件时的活动指示器

Swift 创建csv文件时的活动指示器,swift,csv,uiactivityindicatorview,Swift,Csv,Uiactivityindicatorview,我试图在创建csv文件时显示活动指示器,但它不显示。我猜我应该以某种方式使用dispatch\u async,但我不知道如何在swift 3中实现这一点 var activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray) override func viewDidLoad() { super.viewDidLoad() // act

我试图在创建csv文件时显示活动指示器,但它不显示。我猜我应该以某种方式使用dispatch\u async,但我不知道如何在swift 3中实现这一点

var activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)

override func viewDidLoad() {
    super.viewDidLoad()

    // activity indicator
    activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 100 ,y: 200,width:  50,height:  50)) as UIActivityIndicatorView
    activityIndicator.hidesWhenStopped = true
    activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
    activityIndicator.center = self.view.center
    self.view.addSubview(activityIndicator)
}

func writeToCsv() {

    self.activityIndicator.startAnimating()  // start the animation

    let fileName = "events.csv"
    let path = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName)

    var csvText = self.name! + "\n"
    csvText += "Date,Start time,End time\n"

    // create rest of comma-separated string
    for event in self.events! {

        let newLine = "\(event.date),\(event.startTime),\(event.endTime)\n"
        csvText.append(newLine)
    }

    // write to csv
    do {
        try csvText.write(to: path!, atomically: true, encoding: String.Encoding.utf8)
    } catch {
        print("Failed to create file")
        print(error)
    }

    // create and present view controller with send options
    let vc = UIActivityViewController(activityItems: [path as Any], applicationActivities: [])
    self.present(vc, animated: true, completion: nil)
    self.activityIndicator.stopAnimating()  // stop the animation
}

呃,好吧,如果没有更多关于视图设置的上下文,回答这个问题有点困难。首先,确保活动指示器在不调用writeCsv方法的情况下可见,这样您就知道视图层次结构是正确的。(即,它可能隐藏在其他子视图后面)

接下来,在Swift3中,调度已更改为更新的API。我不确定他们是否在OSX上使用,但在任何情况下,您都可以这样访问它:

后台默认队列:

DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { /* code */ }
DispatchQueue.main.async { /* Mainthread code ( UIKit stuff ) */ }
let queue = DispatchQueue(label: "csvgenerator.queue")
queue.async { /* code */ }
主线程:

DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { /* code */ }
DispatchQueue.main.async { /* Mainthread code ( UIKit stuff ) */ }
let queue = DispatchQueue(label: "csvgenerator.queue")
queue.async { /* code */ }
您自己的CSV生成块自定义队列:

DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { /* code */ }
DispatchQueue.main.async { /* Mainthread code ( UIKit stuff ) */ }
let queue = DispatchQueue(label: "csvgenerator.queue")
queue.async { /* code */ }
现在,对于动画制作/停止动画,请确保从主线程调用与UIKit相关的代码,以防止出现奇怪的Glitech和/或崩溃

即:

DispatchQueue.main.async {
   self.activityIndicator?.startAnimating()
}
另一个好主意可能是改用NSOperationQueue。我相信它在内部使用了GCD,但它确实很好地集成到了iOS中,并且可能使一些调度更容易实现。我自己总是用GCD来代替,但我从来没有真正有过长时间的工作需要做。NSOperationQueue的一个优点是,在取消调度块方面,它对用户更加友好

Dave Delong编写的关于WWDC应用程序中NSOperationQueue的有趣会话视频:

我将对您的writeCSV方法做一个小改动:

guard let path = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName) else {
     // Should throw an error here, or whatever is handy for your app
     return
 }
尽可能避免在所有阶段强制展开。
在具有此功能的方法中,例如,您可以在函数定义的末尾添加“throws”,这样您就可以在不使用do和catch块的情况下使用try,同时还可以在guard语句中抛出错误,这样writeCsv的任何调用都可以捕获错误并更容易地将其显示给用户。

Err,好的,如果没有更多关于视图设置的上下文,回答这个问题有点困难。首先,确保活动指示器在不调用writeCsv方法的情况下可见,这样您就知道视图层次结构是正确的。(即,它可能隐藏在其他子视图后面)

接下来,在Swift3中,调度已更改为更新的API。我不确定他们是否在OSX上使用,但在任何情况下,您都可以这样访问它:

后台默认队列:

DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { /* code */ }
DispatchQueue.main.async { /* Mainthread code ( UIKit stuff ) */ }
let queue = DispatchQueue(label: "csvgenerator.queue")
queue.async { /* code */ }
主线程:

DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { /* code */ }
DispatchQueue.main.async { /* Mainthread code ( UIKit stuff ) */ }
let queue = DispatchQueue(label: "csvgenerator.queue")
queue.async { /* code */ }
您自己的CSV生成块自定义队列:

DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { /* code */ }
DispatchQueue.main.async { /* Mainthread code ( UIKit stuff ) */ }
let queue = DispatchQueue(label: "csvgenerator.queue")
queue.async { /* code */ }
现在,对于动画制作/停止动画,请确保从主线程调用与UIKit相关的代码,以防止出现奇怪的Glitech和/或崩溃

即:

DispatchQueue.main.async {
   self.activityIndicator?.startAnimating()
}
另一个好主意可能是改用NSOperationQueue。我相信它在内部使用了GCD,但它确实很好地集成到了iOS中,并且可能使一些调度更容易实现。我自己总是用GCD来代替,但我从来没有真正有过长时间的工作需要做。NSOperationQueue的一个优点是,在取消调度块方面,它对用户更加友好

Dave Delong编写的关于WWDC应用程序中NSOperationQueue的有趣会话视频:

我将对您的writeCSV方法做一个小改动:

guard let path = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName) else {
     // Should throw an error here, or whatever is handy for your app
     return
 }
尽可能避免在所有阶段强制展开。 在具有此功能的方法中,例如,您可以在函数定义的末尾添加“throws”,这样您就可以在不使用do和catch块的情况下使用try,同时还可以在guard语句中抛出错误,这样writeCsv的任何调用都可以捕获错误,并更容易地将其显示给用户