El Tomato
El Tomato

Reputation: 6707

Swift - Using performSelectorOnMainThread

I'm trying to use – performSelectorOnMainThread:withObject:waitUntilDone: for a Cocoa application that I'm developing in Swift. I need the application to wait until the job is done. Anyway, I have the following lines of code.

func recoverData(path:String) -> Void {
    let sheetRect:NSRect = NSMakeRect(0,0,400,114)
    let progSheet:NSWindow = NSWindow.init(contentRect:sheetRect, styleMask:NSTitledWindowMask,backing:NSBackingStoreType.Buffered,`defer`:true)
    let contentView:NSView = NSView.init(frame:sheetRect)
    let progInd:NSProgressIndicator = NSProgressIndicator.init(frame:NSMakeRect(190,74,20,20))
    progInd.style = NSProgressIndicatorStyle.SpinningStyle
    let msgLabel:NSTextField = NSTextField.init(frame:NSMakeRect(20,20,240,46))
    msgLabel.stringValue = "Copying selected file..."
    msgLabel.bezeled = false
    msgLabel.drawsBackground = false
    msgLabel.editable = false
    msgLabel.selectable = false
    contentView.addSubview(msgLabel)
    contentView.addSubview(progInd)
    progSheet.contentView = contentView

    self.window.beginSheet(progSheet) {(NSModalResponse returnCode) -> Void in
        progSheet.makeKeyAndOrderFront(self)
        progInd.startAnimation(self)
        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_async(dispatch_get_global_queue(priority,0)) {

            //////////////////////////////////////////////////////////////////////////////////////////////////
            self.performSelectorOnMainThread(Selector(self.readData(path)),withObject:path,waitUntilDone:true)
            //////////////////////////////////////////////////////////////////////////////////////////////////

        }

        dispatch_async(dispatch_get_main_queue()) {
            progInd.indeterminate = true
            self.window.endSheet(progSheet)
            progSheet.orderOut(self)
        }
    }
}

func readData(path:String) -> Void {
    print("Hello!?")
}

I'm not sure how I pass path to readData. Xcode requires me to set the argument to something other than nil or nothing. In Objective-C, it would be

[self performSelectorOnMainThread:@selector(readData:) withObject:path waitUntilDone:YES];

Anyway, the application never reaches readData. What am I doing wrong?

Thanks for help.

Upvotes: 1

Views: 421

Answers (1)

vadian
vadian

Reputation: 285059

Why not

self.window.beginSheet(progSheet) {(returnCode) -> Void in
    dispatch_async(dispatch_get_main_queue()) {
        progInd.startAnimation(self)
        self.readData(path)
        progInd.indeterminate = true
    }
}

At some point you have to call self.window.endSheet(progSheet) to dismiss the sheet and call the completion handler.

Edit:

I guess you actually mean something like this

...
  self.window.beginSheet(progSheet) {(returnCode) -> Void in
    progInd.stopAnimation(self)
    progInd.indeterminate = true

  }

  progInd.startAnimation(self)
  let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
  dispatch_async(dispatch_get_global_queue(priority,0)) {
    self.readData(path) {
      dispatch_async(dispatch_get_main_queue()) {
        self.window.endSheet(progSheet)
      }
    }
  }
}

func readData(path:String, completion: (()  -> Void))  {
  print("Hello!?")
  completion()
}

Upvotes: 2

Related Questions