2017-09-06 7 views
1

私は、私は私が別のAPI getDataを呼び出す最初のAPIの応答にデータを/saveData &を保存するための最初のAPIを呼び出すクラスAのセルをタップview.When表があり、クラスAでは2 classes.Class AとクラスBを持っています。私はこれらの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とシングルトンインスタンス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シングルトンなし:

クラス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()'の間のコードのうちの1ブロックだけが一度に実行されます。他は 'signal()'で前のブロック送信信号を待つでしょう。はい、複数のクラスで同じセミファアオブジェクトを使用する必要があります。そのため、グローバルになっています。 –

+0

そして、私はあなたの情報の答えのコメントを更新しました。 –

関連する問題