首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PromiseKit w/ URLSession

PromiseKit w/ URLSession
EN

Stack Overflow用户
提问于 2019-10-08 11:12:09
回答 2查看 828关注 0票数 3

在远程服务返回401时,我试图根据响应状态代码添加一个检查。

我正在尝试使用PromiseKit URLSession扩展。

想象一下我有一些基本的东西,比如

代码语言:javascript
复制
        return firstly {
            URLSession.shared.dataTask(.promise, with: request)
        }.compactMap {
            try JSONDecoder().decode(T.self, from: $0.data)
        }

我想要做的是根据响应状态代码添加一个检查,这样我就可以抛出一个错误并执行一些进一步的步骤。

有点像

代码语言:javascript
复制
        return firstly {
            URLSession.shared.dataTask(.promise, with: request)
        }.map { session  in
            if (session.response as? HTTPURLResponse)?.statusCode == 401 {
                // throw a custom error here
                // something like
                // throw TokenProviderError.unauthorized
            }

            return session.data

        }.compactMap {
            try JSONDecoder().decode(T.self, from: $0)
        }.catch { error in
            // check the error thrown here and do something
        }

这有一个例外

无法将“PMKFinalizer”类型的返回表达式转换为返回类型“承诺”

是否有可能引入像retryWhen这样的东西来捕获错误并进行检查?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-08 11:26:07

因为.catch不返回任何东西,但是您想返回一个Promise<T>,所以您必须在这里删除.catch

代码语言:javascript
复制
return firstly {
    URLSession.shared.dataTask(.promise, with: request)
}.map { session  in
    if (session.response as? HTTPURLResponse)?.statusCode == 401 {
        // throw a custom error here
        // something like
        // throw TokenProviderError.unauthorized
    }

    return session.data

}.compactMap {
    try JSONDecoder().decode(T.self, from: $0)
}

.catch将由被调用方实现。

或者,也许你看起来像,

代码语言:javascript
复制
func test() -> Promise<Any> {
    return firstly(execute: { () -> Promise<String> in
        return .value("bhai")
    }).map({ string -> Promise<Double?> in
        return .value(0.1)
    }).compactMap({ double -> NSError in
        return NSError(domain: "", code: 0, userInfo: nil)
    })
}
票数 0
EN

Stack Overflow用户

发布于 2020-03-31 18:29:07

我试图实现和您完全一样的功能,我认为您正在寻找的retrywhen特性是recover,您可以在GitHub PromiseKit文档中找到它。

  • 请注意,下面的代码没有通过编辑器,可能无法编译,我只是用它来演示一下流程.
代码语言:javascript
复制
return firstly {
            URLSession.shared.dataTask(.promise, with: request)
        }.map { session  in
            if (session.response as? HTTPURLResponse)?.statusCode == 401 {
                throw TokenProviderError.unauthorized
            }
            return session.data
        }.compactMap {
            try JSONDecoder().decode(T.self, from: $0)
        }
        // above is a copy of your code
        .recover { error in // instead of .catch, use .recover here
            guard let err = error as? TokenProviderError,
                  err == .unauthorized 
                  else { throw error } // we only care 401 error here, other error will be handled in caller's .catch

            // in my case, the reason for 401 error is due to an expired access token, so I will try to use refresh token to get a valid access token and make the same request again
            return firstly {
                loginWithRefreshToken(token: myRefreshToken)
            }.then { loginRes -> Promise<(data: Data, response: URLResponse)> in
                // loginRes contains new access token, set it to request "Authorization" header, and make the same request again
                request.setValue(loginRes.accessToken, forHTTPHeaderField: "Authorization")
                return URLSession.shared.dataTask(.promise, with: request)
            }.map { session -> Data in
                return session.data
            }.compactMap { data -> Promise<T> in
                try JSONDecoder().decode(T.self, from: data)
            }
        }

也许现在回答起来有点晚了,但我希望它能帮助一些像我这样新加入PromiseKit的程序员。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58285240

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档