Swift-带委托的可重用URL请求

问题描述 投票:1回答:1

[嗨,我是Swift的新手,我正在尝试为URL请求创建可重用的通用下载管理器,该管理器可以在我的整个项目中的不同View Controller中重用,也可以在同一VC中为不同的URL请求调用重用。我遇到的问题是如何将数据类型从请求传递到下载管理器,然后将具有相应数据类型的已下载数据返回给VC。我可以在对downloadRequest的调用中传递数据类型,但是我不知道如何通过委托DownloadManagerDelegate将数据类型传递回VC。任何帮助将不胜感激!

通用下载管理器:

protocol DownloadManagerDelegate {
        func didUpdateData<T: Codable>(modelType: T.Type, downloadedData: T.Type)
}

struct DownloadManager {

    var delegate: DownloadManagerDelegate?

    func downloadRequest<T: Codable>(modelType: T.Type, parameters: [String: Any]) {
       guard let url = URL(string: "https://www.someAPI...") else {return}
       var request = URLRequest(url: url)
       request.httpMethod = "POST"
       request.addValue("application/json", forHTTPHeaderField: "Content-Type")
       guard let httpBodyWithParameters = try? JSONSerialization.data(withJSONObject: parameters, options: []) else 
         {
          print("error")
          return
         }

       request.httpBody = httpBodyWithParameters 
       let session = URLSession.shared
       session.dataTask(with: request) { (data, response, error) in
           if error != nil {
           print("error")
           return
           }

           if let safeData = data {
              if let downloadedData = parseDownloadedData(data: safeData) {
                  self.delegate?.didUpdateData(modelType: modelType, downloadedData: downloadedData)
               }
            }
        }.resume()

   func parseDownloadedData(data: Data) -> T?{
      let decoder = JSONDecoder()
      do {
         let decodedData = try decoder.decode(T.self, from: data)
         return decodedData
      } catch {
         print(error)
         return nil
        }
    } 

 }

在我的VC中委托:

override func viewDidLoad() {
  super.viewDidLoad()
  downloadManager.delegate = self
}


func didUpdateData(modelType: modelType,downloadedData:downloadedData){
   DispatchQueue.main.async {
     print(downloadedData)
   }
}

致电下载downloadRequest:

downloadManager.downloadrequest(modeType: Type1.self, parameters: parameters)

[数据模型定义为结构:

   struct DataModel1: Codable {
       let ItemID: String
    }

然后在同一VC中,我调用了相同的函数downloadManager,它将调用不同的API,该API应该返回不同模型类型(定义为Struct的数据)]

downloadManager.downloadRequest(modeType:Type2.self,参数:参数)

[数据模型定义为结构:

  struct DataModel2: Codable {
       let EmployeeeID: String
    }
swift delegates nsurlrequest
1个回答
0
投票
objective-c-ish。

我建议使用通用的Result类型的完成处理程序。

如果成功则返回非可选的通用类型,如果失败则返回任何错误。

data的力解开是安全的,因为如果errornil,则data具有值

struct DownloadManager { func downloadRequest<T: Decodable>(modelType: T.Type, parameters: [String: Any], completion : @escaping (Result<T, Error>) -> Void) { guard let url = URL(string: "https://www.someAPI...") else {return} var request = URLRequest(url: url) request.httpMethod = "POST" request.addValue("application/json", forHTTPHeaderField: "Content-Type") do { let httpBodyWithParameters = try JSONSerialization.data(withJSONObject: parameters) request.httpBody = httpBodyWithParameters let session = URLSession.shared session.dataTask(with: request) { (data, response, error) in if let error = error { completion(.failure(error)) } else { completion( Result { try JSONDecoder().decode(T.self, from: data!)}) } }.resume() } catch { completion(.failure(error)) } } }

© www.soinside.com 2019 - 2024. All rights reserved.