Swift调用Restcountries API出现NSURLErrorDomain -999错误如何解决
问题根因
你遇到的NSURLErrorDomain Code=-999 "cancelled"错误由两个低级错误直接导致:
- 你在
fetchCountries方法中把sink返回的AnyCancellable订阅对象声明为局部变量,方法执行完成后该对象会被自动回收,Combine框架会主动终止未完成的订阅流,对应网络请求直接被取消 - 你在订阅创建完成后主动调用了
cancel()方法,手动终止了请求
另外补充一个额外问题:你用的restcountries.eu是旧的退役域名,目前官方接口域名已经更换为restcountries.com,即使修复了订阅问题,旧接口也会返回404错误。
修复方案
修改ListViewModel代码,添加订阅持有容器、移除手动取消逻辑、更换正确的接口地址即可,修改后完整代码如下:
import SwiftUI import Combine class ListViewModel: ObservableObject { private let apiService: APIServiceProtocol @Published var countries = [Country]() // 新增:持有订阅的容器,防止订阅被提前释放 private var cancellables = Set<AnyCancellable>() init(apiService: APIServiceProtocol = APIService()) { self.apiService = apiService } func fetchCountries() { // 修改:更换为新的官方接口地址 guard let url = URL(string: "https://restcountries.com/v2/all") else { return } apiService.fetchAllCountries(url: url) .receive(on: DispatchQueue.main) .sink(receiveCompletion: { completion in switch completion { case .finished: break case .failure(let error): print(error.localizedDescription) } }, receiveValue: { data in self.countries = data print(data) }) // 修改:把订阅存入持有容器,移除原来的cancel()调用 .store(in: &cancellables) } }
内容的提问来源于stack exchange,提问作者beginner992
相关产品推荐
相关产品推荐

