我已经学习 iOS 5 个月了,之前没有任何编程语言经验,所以我是一个新手。我正在学习如何在 Swift 中创建更强大且可扩展的网络层。到目前为止,我可以理解这里发生的事情,但是我正在努力重构我的代码以接受 POST 和 GET 请求。我已收到 POST 请求的授权密钥,但我不知道该怎么做。请给我一些指导
protocol HTTPDataDownloader {
func fetchData <T: Decodable>(as type: T.Type, endpoint: String) async throws -> T
}
extension HTTPDataDownloader {
func fetchData <T: Decodable>(as type: T.Type, endpoint: String) async throws -> T {
guard let url = URL(string: endpoint) else {
throw APIError.requestFailed(description: "Invalid URL")
}
let (data, response) = try await URLSession.shared.data(from: url)
guard let httpResponse = response as? HTTPURLResponse else {
throw APIError.requestFailed(description: "Request failed")
}
guard httpResponse.statusCode == 200 else {
throw APIError.invalidStatusCode(statuscode: httpResponse.statusCode)
}
do {
return try JSONDecoder().decode(type, from: data)
} catch {
throw error as? APIError ?? .unknownError(error: error)
}
}
}
class CommentsDataService: HTTPDataDownloader {
private let urlString = "https://jsonplaceholder.typicode.com/posts/1/comments"
func fetchComments() async throws -> [Comments] {
return try await fetchData(as: [Comments].self, endpoint: urlString)
}
}
@Observable
class CommentsViewModel {
var comments = [Comments]()
var errorMessage: String?
private let service: CommentsDataService
init(service: CommentsDataService) {
print("DEBUG: did init")
self.service = service
Task { await fetchComments() }
}
@MainActor
func fetchComments() async {
do {
self.comments = try await service.fetchComments()
} catch {
guard let error = error as? APIError else { return }
self.errorMessage = error.customDescription
}
}
}
struct Comments: Codable, Identifiable {
let id: Int
let name: String
let email: String
let body: String
}
enum APIError: Error {
case invalidData
case jsonParsingFailure
case requestFailed(description: String)
case invalidStatusCode(statuscode: Int)
case unknownError(error: Error)
var customDescription: String {
switch self {
case .invalidData:
return "Invalid data"
case .jsonParsingFailure:
return "Failed to parse JSON"
case .requestFailed(let description):
return "Request failed: \(description)"
case .invalidStatusCode(let statuscode):
return "Invalid status code \(statuscode)"
case .unknownError(let error):
return "An unknown error occured \(error)"
}
}
}
您选择的方法 -
URLSession.shared.data
不允许您进行太多自定义。因此,您需要使用同一对象的其他众多方法之一。与您使用的最接近的是另一种 data(for:delegate:)
方法,它接受不同的参数 - URLRequest
,您可以在其中指定方法:
var request = URLRequest(url: url)
request.method = "POST"