gpt4 book ai didi

ios - UIKit 中的 Swift 组合。某些用户的 URLSession dataTaskPublisher NSURLErrorDomain -1

转载 作者:行者123 更新时间:2023-12-04 17:09:53 28 4
gpt4 key购买 nike

将我们的 API 客户端切换到组合后,我们开始收到用户关于错误“操作无法完成 (NSURLErrorDomain -1.)”的报告,即 error.localizedDescription从我们的 API 客户端转发到 UI。
顶级 api 调用如下所示:

class SomeViewModel {
private let serviceCategories: ICategoriesService
private var cancellables = [AnyCancellable]()

init(service: ICategoriesService) {
self.serviceCategories = service
}

// ...

// Yes, the block is ugly. We are only on the half way of the migration to Combine
func syncData(force: Bool = false, _ block: @escaping VoidBlock) {
serviceCategories
.fetch(force: force)
.combineLatest(syncOrders(ignoreCache: force))
.receive(on: DispatchQueue.main)
.sink { [unowned self] completion in
// bla-bla-bla
// show alert on error
}
.store(in: &cancellables)
}
}
低级 API 客户端调用如下所示:
func fetch<R>(_ type: R.Type, at endpoint: Endpoint, page: Int, force: Bool) -> AnyPublisher<R, TheError> where R : Decodable {
guard let request = request(for: endpoint, page: page, force: force) else {
return Deferred { Future { $0(.failure(TheError.Network.cantEncodeParameters)) } }.eraseToAnyPublisher()
}

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

return URLSession.shared
.dataTaskPublisher(for: request)
.subscribe(on: DispatchQueue.background)
.tryMap { element in
guard
let httpResponse = element.response as? HTTPURLResponse,
httpResponse.statusCode == 200 else
{ throw URLError(.badServerResponse) }

return element.data
}
.decode(type: type, decoder: decoder)
.mapError { error in
// We map error to present in UI
switch error {
case is Swift.DecodingError:
return TheError.Network.cantDecodeResponse

default:
return TheError(title: nil, description: error.localizedDescription, status: -2)
}
}
.eraseToAnyPublisher()
}
在我们的分析中,我们可以清楚地看到事件链:
  • 应用更新
  • 申请开通
  • 显示主屏幕
  • 显示警报 (NSURLErrorDomain -1)
  • 应用程序背景
    然后用户陷入循环“打开,警报,后台”试图重新启动或重新安装应用程序但没有成功。

  • 首先寻求的是它可能是一些从后端发送到客户端的垃圾,但我们的服务器日志有 api 调用的记录,这些 api 调用按日期和时间与 相关的分析日志相关联。 http 状态码 499 .
    所以我们可以清楚地确定这不是服务器问题。
    在此更新之前,我们也没有来自用户的报告或分析记录。
    所有指向新 API 客户端的点都切换到了组合。
    看起来 session 由于某种原因被客户端丢弃,但同时它与内存释放周期无关,因为如果可取消,则释放 sink关闭将永远不会执行,并且不会显示警报消息。
    问题:
  • 这个 URLSession 设置有什么问题?
  • 您是否遇到过类似的行为并设法解决了它?
  • 您是否有想法如何使用 URLSession 重现或至少模拟此类错误?

  • 笔记:
  • 我们不使用 SwiftUI
  • iOS 版本从 14.8 到 15.0
  • 5% 到 10% 的用户受到影响
  • 我们在开发或测试过程中从未遇到过这样的错误
  • 最佳答案

    我不确定,但我在你提供的代码中看到了几个问题......我在下面评论了。
    499 意味着您的 Cancelable 在网络请求完成之前被删除。也许这会帮助你追踪它。
    此外,您不需要 subscribe(on:)它可能不会做你认为它做的事情。它可能是导致问题的原因,但无法确定。
    使用 subscribe(on:)就像这样做:

    DispatchQueue.background.async {
    URLSession.shared.dataTask(with: request) { data, response, error in
    <#code#>
    }
    }
    如果您了解 URLSession 的工作原理,您会发现 dispatch 完全没有必要,并且不会影响数据任务将在哪个线程上发出。
    func fetch<R>(_ type: R.Type, at endpoint: Endpoint, page: Int, force: Bool) -> AnyPublisher<R, TheError> where R : Decodable {
    guard let request = request(for: endpoint, page: page, force: force) else {
    return Fail(error: TheError.Network.cantEncodeParameters).eraseToAnyPublisher() // your failure here is way more complex than it needs to be. A simple Fail will do what you need here.
    }

    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase

    return URLSession.shared
    .dataTaskPublisher(for: request)
    // you don't need the `subscribe(on:)` here.
    .tryMap { element in
    guard
    let httpResponse = element.response as? HTTPURLResponse,
    httpResponse.statusCode == 200 else
    { throw URLError(.badServerResponse) }

    return element.data
    }
    .decode(type: type, decoder: decoder)
    .mapError { error in
    // We map error to present in UI
    switch error {
    case is Swift.DecodingError:
    return TheError.Network.cantDecodeResponse

    default:
    return TheError(title: nil, description: error.localizedDescription, status: -2)
    }
    }
    .eraseToAnyPublisher()
    }

    关于ios - UIKit 中的 Swift 组合。某些用户的 URLSession dataTaskPublisher NSURLErrorDomain -1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69725699/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com