dsafa
dsafa

Reputation: 793

NSBlockOperation not executing

As I'm currently dealing with web service calls and database retrieval, I've stumbled upon the issue of an NSBlockOperation not starting.

But, to explain things a little bit at first. The main goal is to have an operation queue which consists of the following operations:

  1. Operation #1 - send a request to the web service to start creating the database .zip file
  2. Operation #2 - upon completion of #1, repeatedly call the web service for the progress of the .zip file compression process
  3. Operation #3 - upon completion of #2, download the database using NSURLSessionDownloadTask.

To do so, I've defined the following class:

class DatabaseServerDownload {
typealias Callback = (storedLocation : NSURL) -> ()
typealias Failure = ((error : NSError) -> Void)

let callback : Callback
let failure : Failure

let operationQueue : NSOperationQueue

required init(callback : Callback, failure : Failure) {
    operationQueue = NSOperationQueue()
    operationQueue.maxConcurrentOperationCount = 1

    self.callback = callback
    self.failure = failure
}

func start() {
    let databaseCreationOperation = createDatabaseOnServer()
    let databaseCheckOperation = repeatedlyCheckForDatabaseReadiness()
    let databaseDownloadOperation = downloadDatabaseFromServer()

    databaseCheckOperation.addDependency(databaseCreationOperation)
    databaseDownloadOperation.addDependency(databaseCheckOperation)

    operationQueue.addOperations([databaseCreationOperation, databaseCheckOperation, databaseDownloadOperation], waitUntilFinished: true)
}

func createDatabaseOnServer() -> BlockOperation {
    let operation : BlockOperation = BlockOperation()
    operation.addExecutionBlock({SVMRSendTask(method: BeginCreatingDatabase(), onSuccess: {operation.finish()}, onFailure: {e in}).apply()})
    return operation
}

func repeatedlyCheckForDatabaseReadiness() -> NSBlockOperation {
    return NSBlockOperation(block: {SVMRRequestTask(method: DatabaseZipReady()).apply(5, c: {s in s == "OK"}, f: {s in String(s)}, onSuccess: {r in}, onFailure: {e in})})
}

func downloadDatabaseFromServer() -> NSBlockOperation {
    let sourceURL : NSURL = RequestDatabaseIdentitiesForDownload.sharedInstance.databaseURL
    return NSBlockOperation(block: {DownloadTask(url: sourceURL, progressCallback: {p in}, successCallback: {l in}, failureCallback: {e in }).start()})
}
}

Where the SVMRRequestTask takes a web service method as an argument (while the method is an instance of the abstract class SVMR), upon which, it executes the web service request using NSURLSessionTasks.

While the BlockOperation is as follows:

class BlockOperation : NSBlockOperation {

private var _isFinished : Bool = false
private var _isExecuting : Bool = false

override var finished : Bool {
    return _isFinished
}

override var executing : Bool {
    return _isExecuting
}

func finish() {
    if cancelled {
        return
    }

    self.willChangeValueForKey("ready")
    _isReady = false
    self.didChangeValueForKey("ready")

    self.willChangeValueForKey("executing")
    _isExecuting = false
    self.didChangeValueForKey("executing")

    self.willChangeValueForKey("finished")
    _isFinished = true
    self.didChangeValueForKey("finished")
}
}

Can anyone explain what exactly am I doing wrong - since I'm using the NSOperation class for the very first time. Before that, I went of course throughout the entire documentation by Apple and some other references, but unfortunately, couldn't find anything.

Upvotes: 1

Views: 462

Answers (1)

Prajwal S Prakash
Prajwal S Prakash

Reputation: 131

You can solve this by NSBlockOperation which is best way to do serialise operation queue by adding dependency,

@dsafa I've created a sample for you in gist: https://gist.github.com/prajwalabove/66eecbf6b6aa096d5e18b04bd0cc18e8

Upvotes: 3

Related Questions