将任务延迟到完成

时间:2018-06-25 18:45:13

标签: ios swift

人们经常问“如何延迟功能或代码块?”是一个非常常见的问题。但这不是我所需要的。

我需要我的代码等待某个任务完成,否则我的函数会收到一个错误,提示我没有access_token(因为该代码不会等待从Spotify服务器获取数据)。

到目前为止,这是我的代码,尝试添加DispatchGroup

func getAccessToken() throws -> Spotify.JSONStandard {
    var accessToken: Spotify.JSONStandard!

    let group = DispatchGroup() // <- Create group
    group.enter() // <- Enter group

    Alamofire.request("https://accounts.spotify.com/api/token", method: .post, parameters: spotify.parameters, headers: nil).responseJSON(completionHandler: {
        response in
        // Check if response is valid
        if let newValue = response.result.value as? Spotify.JSONStandard {
            accessToken = newValue
        }

        group.leave() // <- Leave group
    })

    group.wait() // <- Wait until task is completed

    // \/ Delay this code until complete \/
    if accessToken != nil {
        return accessToken
    }
    else {
        throw SpotifyError.failedToGetAccessToken
    }
    // /\                                /\
}

没有分组,我的代码将抛出SpotifyError.failedToGetAccessToken(access_token为nil)。

但是,添加组后,我的代码只是挂起并永远等待。如何延迟此代码的完成时间?

我知道获取令牌没有问题,就像我删除return并在请求中放置打印内容一样,我得到了预期的结果。

如有任何疑问,请询问

1 个答案:

答案 0 :(得分:3)

不要尝试使异步任务同步

这是一个带有完成处理程序和自定义枚举的解决方案

enum Result {
    case success(Spotify.JSONStandard), failure(Error)
}

func getAccessToken(completion: @escaping (Result)->()) {
    Alamofire.request("https://accounts.spotify.com/api/token", method: .post, parameters: spotify.parameters, headers: nil).responseJSON(completionHandler: {
        response in
        // Check if response is valid
        if let newValue = response.result.value as? Spotify.JSONStandard {
            completion(.success(newValue)
        } else {
            completion(.failure(SpotifyError.failedToGetAccessToken))
        }
    })
}

并调用它

getAccessToken { result in
   switch result {
     case .success(let token) : // do something with the token
     case .failure(let error) : // do something with the error
   }
}