2014-11-06 2 views
5

Я работаю над приложением Иос, где в моем appDelegate у меня есть:Подождите, пока асинхронный вызов апи не завершен - Swift/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, и я бы как дождаться его завершения, прежде чем вернуть true в конце приложения func.

+2

Swift не имеет таких функциональных возможностей. Вы хотите настроить свой контроллер окон и корневого представления в теле 'didFinishLaunching', возможно, с графикой загрузки, а затем перейти к новому контроллеру представления в обработчике завершения входа API. –

+0

didFinishLaunching устарел, но это звучит неплохо. –

ответ

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. –

+2

Итак, я удалил dispatch_release (семафор), но semaphore_wait, похоже, блокирует весь поток. Похоже, что исполнение застряло в моем асинхронном закрытии. –

+1

В духе обучения, не могли бы вы объяснить, почему мой комментарий - плохая идея? –

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) 
Смежные вопросы