美文网首页
URLSession创建post和get请求

URLSession创建post和get请求

作者: 上帝死了众神在堕落 | 来源:发表于2022-06-16 16:49 被阅读0次
    struct APIService: APIServiceProtocol {
        
        func fetch<T: Decodable>(_ type: T.Type, url: URL?, headerPara: [String: String], completion: @escaping(Result<T,APIError>) -> Void) {
            guard let url = url else {
                let error = APIError.badURL
                completion(Result.failure(error))
                return
            }
            var request = URLRequest(url: url)
            request.setValue("application/json", forHTTPHeaderField: "Content-Type")
            request.httpMethod = "POST"
            guard let encoded = try? JSONEncoder().encode(headerPara) else {
                print("Failed to encode order")
                return
            }
            request.httpBody = encoded
            URLSession.shared.dataTask(with: request) { (data , response, error) in
                if let error = error as? URLError {
                    completion(Result.failure(APIError.url(error)))
                }else if  let response = response as? HTTPURLResponse, !(200...299).contains(response.statusCode) {
                    completion(Result.failure(APIError.badResponse(statusCode: response.statusCode)))
                }else if let data = data {
                    let decoder = JSONDecoder()
                    do {
                        let result = try decoder.decode(type, from: data)
                        completion(Result.success(result))
                        
                    }catch {
                        completion(Result.failure(APIError.parsing(error as? DecodingError)))
                    }
    
                }
            }.resume()
    //        let task = URLSession.shared.dataTask(with: url) {(data , response, error) in
    //
    //            if let error = error as? URLError {
    //                completion(Result.failure(APIError.url(error)))
    //            }else if  let response = response as? HTTPURLResponse, !(200...299).contains(response.statusCode) {
    //                completion(Result.failure(APIError.badResponse(statusCode: response.statusCode)))
    //            }else if let data = data {
    //                let decoder = JSONDecoder()
    //                do {
    //                    let result = try decoder.decode(type, from: data)
    //                    completion(Result.success(result))
    //
    //                }catch {
    //                    completion(Result.failure(APIError.parsing(error as? DecodingError)))
    //                }
    //
    //            }
    //        }
    //
    //        task.resume()
        }
        
        
        func fetchBreeds(url: URL?, completion: @escaping(Result<[Breed], APIError>) -> Void) {
            guard let url = url else {
                let error = APIError.badURL
                completion(Result.failure(error))
                return
            }
            let task = URLSession.shared.dataTask(with: url) {(data , response, error) in
                
                if let error = error as? URLError {
                    completion(Result.failure(APIError.url(error)))
                }else if  let response = response as? HTTPURLResponse, !(200...299).contains(response.statusCode) {
                    completion(Result.failure(APIError.badResponse(statusCode: response.statusCode)))
                }else if let data = data {
                    let decoder = JSONDecoder()
                    do {
                        let breeds = try decoder.decode([Breed].self, from: data)
                        completion(Result.success(breeds))
                        
                    }catch {
                        completion(Result.failure(APIError.parsing(error as? DecodingError)))
                    }
                    
                    
                }
            }
    
            task.resume()
            
        }
    }
    
    
    protocol APIServiceProtocol {
        func fetchBreeds(url: URL?, completion: @escaping(Result<[Breed], APIError>) -> Void)
        func fetch<T: Decodable>(_ type: T.Type, url: URL?, headerPara: [String: String], completion: @escaping(Result<T,APIError>) -> Void)
    }
    
    enum APIError: Error, CustomStringConvertible {
        case badURL
        case badResponse(statusCode: Int)
        case url(URLError?)
        case parsing(DecodingError?)
        case unknown
        
        var localizedDescription: String {
            // user feedback
            switch self {
            case .badURL, .parsing, .unknown:
                return "Sorry, something went wrong."
            case .badResponse(_):
                return "Sorry, the connection to our server failed."
            case .url(let error):
                return error?.localizedDescription ?? "Something went wrong."
            }
        }
        
        var description: String {
            //info for debugging
            switch self {
            case .unknown: return "unknown error"
            case .badURL: return "invalid URL"
            case .url(let error):
                return error?.localizedDescription ?? "url session error"
            case .parsing(let error):
                return "parsing error \(error?.localizedDescription ?? "")"
            case .badResponse(statusCode: let statusCode):
                return "bad response with status code \(statusCode)"
            }
        }
    }
    
    class APIMannager: ObservableObject {
        
        @Published var isLoading: Bool = false
        @Published var errorMessage: String? = nil
        
        let service: APIServiceProtocol
        
        init(service: APIServiceProtocol = APIService()) {
            self.service = service
        }
        
        
        
        func requestPost<T: Decodable>(url: String, headerPara: [String: String], completion: @escaping(Result<T,APIError>) -> Void) {
            isLoading = true
            errorMessage = nil
            let url = URL(string: "\(url)")!
        
            service.fetch(T.self, url: url, headerPara: headerPara) { [unowned self] result in
                DispatchQueue.main.async {
                    
                    self.isLoading = false
                    switch result {
                    case .failure(let error):
                        self.errorMessage = error.localizedDescription
                        // print(error.description)
                        print(error)
                    case .success(let resultT):
                        completion(Result.success(resultT))
                    }
                }
            }
        }
        
    }
    

    相关文章

      网友评论

          本文标题:URLSession创建post和get请求

          本文链接:https://www.haomeiwen.com/subject/tvrqvrtx.html