我的目标是创建一个模块化的网络服务层,可以很容易地进行单元测试。
为了实现这一目标,我简单地从以下协议开始:
protocol NetworkService {
associatedtype Response
func fetchData() async throws -> Response
}
然后,我继续创建一个服务来获取新闻提要,如下所示:
struct FetchNewsService: NetworkService {
typealias Response = [NewsAssetModel]
func fetchData() async throws -> Response {
guard let fetchNewsURL = URL(string: SystemConstants.NetworkConstants.fetchNewsEndpoint) else {
throw NetworkError.invalidURL
}
let urlRequest = URLRequest(url: fetchNewsURL)
let session = URLSession(configuration: .default)
guard let (data, response) = try? await session.data(for: urlRequest) else {
// Would need to handle no internet error as well
throw NetworkError.server
}
if let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode > 400 {
throw NetworkError.server
}
guard let newsResponse = try? JSONDecoder().decode(NewsResponseModel.self,
from: data) else {
throw NetworkError.decode
}
return newsResponse.assets
}
}
在我的视图模型中,我希望请求获取新闻提要项,因此我希望将NetworkService
类型注入到视图模型中。
class NewsAssetManager {
private(set) var newsAssets: [NewsAssetModel] = []
private var newsService: NetworkService // 1 - error on this line
// 2 - and this line below
init(withNewsService newsService: NetworkService = FetchNewsService()) {
}
}
在属性声明中得到的第一个错误是Protocol 'NetworkService' can only be used as a generic constraint because it has Self or associated type requirements
我在初始化器中得到的第二个错误也是相同的Protocol 'NetworkService' can only be used as a generic constraint because it has Self or associated type requirements
我做错了什么?我如何修复/改进?
更新泛型
一个三个三个一个
最后一行Cannot convert return expression of type '[NewsAssetModel]' to return type 'T'
出现错误
根据评论和答复更新
将Any & Some的组合添加到属性或初始化器中仍然无法消除所面临的编译错误。
我还通过终端和此代码确认,我至少在运行Swift 5.6:
#if swift(>=5.6)
print("swift 5.6")
#endif
2条答案
按热度按时间vltsax251#
这就是我在不使用关联类型时定义协议的方式。将函数改为泛型,类型应该符合
Decodable
然后将符合类型的实现更改为
现在,该实现并没有被硬编码为一个解决方案,实际上它是如此通用,以至于我们可以将其移动到协议的扩展中
这意味着在本例中不再需要
FetchNewsService
,可以将其删除。然后可以将
NewsAssetManager
更改为下面的代码,其中特定于此特定API和响应类型的所有代码现在都驻留在下面。5ssjco0h2#
当我把你的代码放进Xcode时,编译器告诉我如何修复它:
变更
到
并改变
到
唯一的区别是关键字
any
。