2015-01-27 2 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)로 채워 됐어요.

편집 : 여기에 제가 생각한 해결책이 있습니다.

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

나는 그런 패턴을 사용하지 않는 편이 좋다. 동기화하지 않고 다른 쓰레드에서 변수에 접근하는 것은 스레드로부터 안전하지 않다. 여기에서는 강력하게 주문한 CPU (Intel)에서 작동하지만 ARM에서는 실패 할 수 있습니다. 유닛 테스트의 경우 XCTest에서 특히이 사용 사례에 대해 기대되는 강력한 접근 방식을 사용합니다. – CouchDeveloper

관련 문제