Swift 如何在退出函数之前等待回调完成?
Swift How to wait for callback to finish before exiting function?
我在这个请求上遇到的问题是第一个函数 syncRequest 总是 returns nil 因为函数在(回复,错误)返回之前退出填写我的 return 词典。
有没有办法让它在 return 退出我的闭包之前等待 return 的回调?
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)
}
}
}
非常感谢您的帮助!
您能否让 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)
}
}()
}
实现锁定变量很简单。这对于进行一些异步网络加载的单元测试最有帮助。
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))
}
我在这个请求上遇到的问题是第一个函数 syncRequest 总是 returns nil 因为函数在(回复,错误)返回之前退出填写我的 return 词典。
有没有办法让它在 return 退出我的闭包之前等待 return 的回调?
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)
}
}
}
非常感谢您的帮助!
您能否让 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)
}
}()
}
实现锁定变量很简单。这对于进行一些异步网络加载的单元测试最有帮助。
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))
}