2017-09-06 44 views
1

我有兩個班。班A和班B.在班A有桌子view.When我點擊A班的單元我呼籲第一個API保存數據/saveData &對第一個API的響應我打電話給另一個API getData。我在後臺調用這些API。現在,當我移動到A類時,我打電話給viewDidLoad()上的另一個API。我在前臺調用了該函數。現在我希望A類的API不應該影響B類。在swift 3中調用mutlile API的問題?

請告訴什麼是最好的方式來做到這一點。

我試圖DispatchGroup但對我沒有工作。

func saveInBackground(parameter : [String : AnyObject]?) -> Void { 

     let group = DispatchGroup() 
     group.notify(queue: DispatchQueue.global(qos: .background)){ 

      let apiManager = APIHandler(baseURL: Constants.API.baseURL, APIVersion: "") 

      apiManager.requestOfBgMethod(.post, path: Constants.API.Name.addGeneralField.completePath, parameters: parameter, encoding: .url, headers: nil, apiSuccess: { (result) in 
       //update user 
       self.copyUser = User(copyFrom: self.user) 
       self.saveCVResponse(result: result) 
       //fetch data in background 
       Utility.sharedInstance.updateCVdata(cvManager: self.cvManager) 
      }, apiFailure: { (error) in 

      }) 
     } 

//  DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async { 
//    
// 
//  } 
    } 

回答

0

使用DispatchSemaphore和Singleton實例來進行API調用一個接一個:

class ApiHelper { 
    static let shardInstance = ApiHelper() 
    private let semaphore = DispatchSemaphore(value: 1) //one task allowed at a time 
    private let apiManager = APIHandler(baseURL: Constants.API.baseURL, APIVersion: "") 

    func saveInBackground(parameter : [String : AnyObject]?) -> Void { 
     DispatchQueue.global(qos: .default).async { [unowned self] in 
      self.semaphore.wait() //lock 

      apiManager.requestOfBgMethod(.post, path: Constants.API.Name.addGeneralField.completePath, parameters: parameter, encoding: .url, headers: nil, apiSuccess: { (result) in 
       //....... 
       self.semaphore.signal() //unlock 
      }, apiFailure: { (error) in 
       self.semaphore.signal() //unlock 
      }) 
     } 
    } 
} 

使用它在A類和B類,它們將不會影響對方:

ApiHelper.shardInstance.saveInBackground(parameter: nil) 
+0

對於這種情況,我必須改變整個API結構,這是非常複雜和耗時。因爲background&forground api不使用相同的方法 – Techiee

+0

你能夠修改類「APIHandler」嗎?也許這個類應該提供一個單例來做到這一點。 –

+0

或者你可以定義'DispatchSemaphore'的全局變量,並直接在'saveInBackground'方法中使用它。 –

0

使用全球DispatchSemaphore without Singleton:

在A或c類姑娘B或某個地方,定義一個全局信號燈淘汰類:

let semaphoreGlobal = DispatchSemaphore(value: 1) //one task at a time 

//ignore following, just an example. 
class AnyClass { 
    //...... 
} 

而且你的方法成爲:

func saveInBackground(parameter : [String : AnyObject]?) -> Void { 
    DispatchQueue.global(qos: .default).async { 
     semaphoreGlobal.wait() //wait if semaphore is 0. Else, set semaphore to 0 and continue. 

     //remember: the variable 'apiManager' should not be a local one. 
     apiManager.requestOfBgMethod(.post, path: Constants.API.Name.addGeneralField.completePath, parameters: parameter, encoding: .url, headers: nil, apiSuccess: { (result) in 
      //....... 
      semaphoreGlobal.signal() //set semaphore to 1, means allowing one of other tasks stops waiting. 
     }, apiFailure: { (error) in 
      semaphoreGlobal.signal() //set semaphore to 1 
     }) 
    } 
} 
+0

在這種情況下會發生什麼?它會等待其他方法調用其他API嗎?我應該在多個班級中使用同一個semophare對象嗎?我不會隱藏如何遵循你的方法 – Techiee

+0

在這種情況下,在這個方法和其他方法中,'.wait()'和'.signal()'之間只有一個代碼塊將被執行。其他人將通過'signal()'等待上一個塊發送信號。是的,你應該在多個類中使用相同的semophare對象,這就是爲什麼它是全局的。 –

+0

我更新了回覆您的信息的評論。 –