2014-11-06 121 views
5

我工作的iOS應用,凡在我appDelegate我:等待,直到異步API調用完成 - 斯威夫特/ IOS

func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {  
    self.api.signInWithToken(emailstring, token: authtokenstring) { 
     (object: AnyObject?, error:String?) in    
      if(object != nil){ 
       self.user = object as? User 
       // go straight to the home view if auth succeeded 
       var rootViewController = self.window!.rootViewController as UINavigationController 
       let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil) 
       var homeViewController = mainStoryboard.instantiateViewControllerWithIdentifier("HomeViewController") as HomeViewControllerenter 
       // code here 
       rootViewController.pushViewController(homeViewController, animated: true) 
      } 
     } 
    return true 
} 

api.signInWithToken是Alamofire由異步調用,我會喜歡在func應用程序的最後端返回true之前等待它完成。

+2

Swift沒有這種功能。您需要在'didFinishLaunching'主體中設置窗口和根視圖控制器,可能需要使用加載圖形,然後導航到API登錄完成處理程序中的新視圖控制器。 – 2014-11-06 20:10:12

+0

didFinishLaunching已棄用,但聽起來像個好主意 – 2014-11-07 21:51:45

回答

11

注意:您應該不是這樣做,因爲它阻止線程。請參閱Nate上面的評論以獲得更好的方法。

有一種方法可以等待使用GCD完成異步調用。該代碼看起來像下面

var semaphore = dispatch_semaphore_create(0) 

performSomeAsyncTask { 
    ... 
    dispatch_semaphore_signal(semaphore) 
} 

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) 
dispatch_release(semaphore) 

維基百科的情況下,確定article你一無所知信號燈。

+0

我嘗試了上面的方法; dispatch_release(信號量)已被Apple刪除。 – 2014-11-07 21:52:20

+2

所以我刪除了dispatch_release(信號量),但是semaphore_wait似乎阻塞了整個線程。看起來像執行停滯在我的異步封閉。 – 2014-11-07 22:12:02

+1

本着學習的精神,你能解釋爲什麼我的評論是一個壞主意嗎? – 2014-11-07 23:33:27

1

這是Swift 3中的解決方案。這再次阻塞線程,直到異步任務完成,因此應僅在特定情況下考慮它。

let semaphore = DispatchSemaphore(value: 0) 

performAsyncTask { 
    semaphore.signal() 
} 

// Thread will wait here until async task closure is complete 
semaphore.wait(timeout: DispatchTime.distantFuture)