Hi I have a strange situation here :
OverView:
I am working on an app where user can initiate multiple operations and all these operations will run on a background thread hence will not block the UI. Some of these operations are dependent on each other and some are not.
So in order to ensure that operation will execute only after all the necessary dependencies operations finished executing am using the dependency property of Operation. I am making use of Asynchronous operations.
Here is my implementation :
import UIKit
import CoreData
import SwiftyJSON
class VMBaseOperation: NSOperation {
var finishedStatus : Bool = false
var executionStatus : Bool = false
var retryCount : Int = 0
private (set) var requestToQueue : BaseRequest? = nil
var vmOperationCompletionBlock: ((JSON?) -> Void)?
var vmOperationFailureBlock: ((WebResponseError?) -> Void)?
override init() {
super.init()
}
convenience init(withVMRequest request : BaseRequest) {
self.init()
requestToQueue = request
}
override func start() {
if self.cancelled {
self.finished = true
return
}
NSThread.detachNewThreadSelector(#selector(main), toTarget: self, withObject: nil)
self.executionStatus = true
}
override func main() {
if self.cancelled {
return
}
self.hitWebService()
}
func hitWebService(){
let webserviceManager = WebServiceManager()
webserviceManager.getResponseFromRequest(requestToQueue!) { (requset, response, data, error) in
let error = WebResponseError.checkResponse(response, request: requset, error: error)
if error != nil {
if error == WebResponseError.NO_INTERNET {
if self.vmOperationFailureBlock != nil {
self.vmOperationFailureBlock!(error)
}
self.operationFailed()
}
else{
self.retryCount += 1
if self.retryCount == 3 {
if self.vmOperationFailureBlock != nil {
self.vmOperationFailureBlock!(error)
}
self.operationFailed()
}
else{
self.hitWebService()
}
}
}
else{
if data == nil {
self.retryCount += 1
if self.retryCount == 3 {
if self.vmOperationFailureBlock != nil {
self.vmOperationFailureBlock!(nil)
}
self.operationFailed()
}
else{
self.hitWebService()
}
}
else{
let json = JSON(data: data!)
if self.vmOperationCompletionBlock != nil {
self.vmOperationCompletionBlock!(json)
}
self.operationCompleted()
}
}
}
}
override var finished: Bool {
get{
return finishedStatus
}
set{
self.willChangeValueForKey("isFinished")
finishedStatus = newValue
self.didChangeValueForKey("isFinished")
}
}
override var executing: Bool {
get{
return executionStatus
}
set{
self.willChangeValueForKey("isExecuting")
executionStatus = newValue
self.didChangeValueForKey("isExecuting")
}
}
override var asynchronous: Bool{
get{
return true
}
set{
self.willChangeValueForKey("isAsynchronous")
self.asynchronous = true
self.didChangeValueForKey("isAsynchronous")
}
}
func operationCompleted(){
self.executing = false
self.finished = true
}
func operationFailed(){
self.executing = false
self.finished = false
}
}
What It Does :
each operation takes a web request and attempts to get the data from server and if it fails, it tries 3 times before finally setting its finished status to false by calling operationFailed
method and there by stopping all the dependent operation from executing forever.On the other hand if it succeeds it changes its finished status to true by calling operationCompleted
hence triggers the execution of remaining dependent operations.
What is the Issue:
Dependency works like a charm. No issue with that. Now I need to sync the data from server when all the operations in the operation queue finished executing no matter whether they finished successfully or not.
Easiest way to do it is to create a Operation to sync the data from server and add it as dependent operation to all the operations added to operationQueue.
But because of the above mentioned nature of the operation, even if one operation fails all its stops the execution of all the dependent operations (as expected) but because my sync data from server operation is also a dependent operation it will never execute even if one operation fails :(
What I need :
While maintaining the dependency I mentioned above I need to know how to execute an operation to sync the data from server when all the operations in operation queue finishes executing no matter whether they succeed or fail.
Is that even possible :( Please help me out . Thanks in advance.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…