2015-01-27 4 views
1

Проблема, с которой я столкнулся по этому запросу, - это первая функция syncRequest всегда возвращает nil, так как функция выходит до того, как возвращается (ответ, ошибка), чтобы заполнить мой возвращаемый словарь.Swift Как подождать завершения обратного вызова до выхода из функции?

Есть ли способ подождать, пока обратный вызов вернется, прежде чем вернуться из моего закрытия?

public typealias KKWatchSyncResponse = Dictionary<String, AnyObject> 

func syncRequest() -> KKWatchSyncResponse? { 
    var syncResponseDict : KKWatchSyncResponse? 
    createRequest(KKWatchRequest.Sync, parameter: nil) { reply, error in 
     if reply == nil || error != nil { 
      return 
     } else { 
      syncResponseDict = KKWatchSyncResponse() 
     } 
     if let songInfo = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["songInfo"] as NSData) as NSDictionary? { 
      syncResponseDict!["songInfo"] = songInfo 
     } 
     if let albumArtImage = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["albumArt"] as NSData) as? UIImage { 
      syncResponseDict!["albumArtImage"] = albumArtImage 
     } 
     if let isPlaying = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["isPlaying"] as NSData) as? Bool { 
      syncResponseDict!["isPlaying"] = isPlaying 
     } 
    }() 
    return syncResponseDict 
} 

    func createRequest(request:KKWatchRequest, parameter: KKWatchAPIRequestParameter?, callback:KKWatchAPICallback) -> KKWatchAPIParentRequest { 
     var requestDict : Dictionary<String, AnyObject> = [KKBOXWatchAppRequestType : request.rawValue] 
     if parameter != nil { 
     requestDict += parameter! //Combine 2 dictionaries 
    } 
     return { WKInterfaceController.openParentApplication(requestDict){ reply, error in 
       callback(reply, error) 
     } 
    } 
} 

Ваша помощь нам очень ценится!

ответ

3

Возможно, у вас есть syncRequest() сделать закрытие, которое вызывается с результатами при его готовности? Измените определение что-то вроде:

func syncRequest(callback:(KKWatchSyncResponse?)->Void) { ... } 

Затем в конце вашего createRequest() вызова, вы можете вызвать функцию обратного вызова на syncResponseDict, так как теперь она была заселена с вашими данными ... callback(syncResponseDict).

EDIT: Вот решение, которое я имел в виду.

func syncRequest(callback:(KKWatchSyncResponse?)->Void) { 
    createRequest(KKWatchRequest.Sync, parameter: nil) { reply, error in    
     if reply == nil || error != nil { 
      callback(nil) 
     } else { 
      var syncResponseDict : KKWatchSyncResponse? = KKWatchSyncResponse() 
      if let songInfo = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["songInfo"] as NSData) as NSDictionary? { 
       syncResponseDict!["songInfo"] = songInfo 
      } 
      if let albumArtImage = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["albumArt"] as NSData) as? UIImage { 
       syncResponseDict!["albumArtImage"] = albumArtImage 
      } 
      if let isPlaying = NSKeyedUnarchiver.unarchiveObjectWithData(reply!["isPlaying"] as NSData) as? Bool { 
       syncResponseDict!["isPlaying"] = isPlaying 
      } 
      callback(syncResponseDict) 
     } 
    }() 
} 
+0

ДА! это совершенно то, что я ищу. Спасибо, сэр :) –

+0

Удивительный. Нет проблем ... Рад, что это помогает. – charlierproctor

-1

Прямо вводить фиксирующую переменную. Это наиболее полезно для модульных тестов, которые выполняют некоторую асинхронную загрузку сети.

func waitingFunction() 
{ 
    //set a lock during your async function 
    var locked = true 
    RunSome.asyncFunction() {() -> Void in 

     //after your sync function remove the lock 
     locked = false 
    }) 

    //wait for the async method to complete before advancing 
    while(locked){wait()} 

    //move on from the lock 
    doMoreStuff() 
} 
func wait() 
{ 
    NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate(timeIntervalSinceNow: 1)) 
} 
+0

Я не рекомендую использовать такой шаблон: доступ к переменной (здесь «заблокирован») для разных потоков без синхронизации не является потокобезопасным. Здесь, как правило, работает на сильно упорядоченных процессорах (Intel), но он может выйти из строя на ARM. Для модульных тестов у нас есть надежный подход в XCTest с ожиданиями, которые специально сделаны для этого варианта использования. – CouchDeveloper

Смежные вопросы