一个用于多个 ViewController 的网络处理程序类

Posted

技术标签:

【中文标题】一个用于多个 ViewController 的网络处理程序类【英文标题】:One network handler class for multiple ViewControllers 【发布时间】:2020-05-04 10:27:43 【问题描述】:

我有一个应用程序,它有 5 个不同的视图控制器,可通过 UITabBar 访问。

这些 ViewController 中的每一个都将通过取自同一 API 源的 5 个不同 URL 访问 API 数据。

我怎样才能重复使用下面的 API 请求代码,这样我就不必在我的代码中重新键入这个块 5 次了?下面的代码是我当前的设置,委托是第一个视图控制器。

protocol ClubFixturesManagerDelegate 

    func didUpdateTable (club: [ClubData])
    func didFailWithError(error: Error) 



struct MyClubFixturesManager

    let getclubListURL = "someURL"
    var delegate: ClubFixturesManagerDelegate?

    func getClubID(clubID: String)

        let getClubResultsURL = "someURL"
        performRequest(with: getClubResultsURL)

    


    func performRequest(with urlString: String)

        if let url = URL(string: urlString)

            var request = URLRequest(url: url)
            request.httpMethod = "GET"
            request.setValue("APIToken", forHTTPHeaderField: "Authorization")

            //create URL session
            let task = URLSession.shared.dataTask(with: request)  (data: Data?, response: URLResponse?, error: Error?) in

                if error != nil
                    self.delegate?.didFailWithError(error: error!)
                    return
                

                if let safeData = data 

                    if let clubResults = self.parseJSON(safeData)

                        self.delegate?.didUpdateTable(club: clubResults)

                    

                

            

            task.resume()

        

    

    func parseJSON(_ teamData: Data) -> [ClubData]?

        let decoder = JSONDecoder()

        do

            var clubInfo: [ClubData] = []
            let decodedData = try decoder.decode(ClubSeasonData.self, from: teamData)
            for entry in decodedData.matches

                let updatedDate = ISO8601Converter.converter(for: entry.utcDate)

                let clubInstance = ClubData(utcDate: updatedDate, homeTeam: entry.homeTeam.name, awayTeam: entry.awayTeam.name, homeTeamScore: entry.score.fullTime.homeTeam ?? nil, awayTeamScore: entry.score.fullTime.awayTeam ?? nil)
                clubInfo.append(clubInstance)

            

            return clubInfo

        

        catch

              print(error)

            

            return nil

        


【问题讨论】:

【参考方案1】:

您可以简单地在 viewDidLoad 中创建 api 管理器的新实例,然后分配委托并执行请求。 像这样的:

var apiManager: MyClubFixturesManager?

func viewDidLoad() 
  super.viewDidLoad()
  apiManager = MyClubFixturesManager()
  apiManager.delegate = self // Assuming self conforms to ClubFixturesManagerDelegate protocol
  apiManager?.performRequest(with: "yourUrl")



作为旁注,我会让委托变得弱,以避免保留周期和内存泄漏。 你只需要这样做:

weak var delegate: ClubFixturesManagerDelegate?

为此,您需要绑定协议类:

protocol ClubFixturesManagerDelegate: class 

    func didUpdateTable (club: [ClubData])
    func didFailWithError(error: Error) 

【讨论】:

【参考方案2】:

我不知道您的完整设置,但如果您还没有,我建议您将此 MyClubFixturesManager 结构保存在其自己的文件中。

然后将“静态”添加到它的每个属性和函数中。

static func performRequest(with urlString: String)

然后尝试从您设置的每个 VC 中调用它

MyClubFixturesManager.performRequest(with urlString: urlString)

但不确定它如何与您的代表一起工作。另一种选择是在每个 VC 中创建此结构的实例。希望这会引导您走上正确的道路。

【讨论】:

感谢您的回复,我尝试使用静态但它不适用于代表。我设法让它与上述的新结构实例一起工作,并根据通过新函数选择的 VC 分配 URL。

以上是关于一个用于多个 ViewController 的网络处理程序类的主要内容,如果未能解决你的问题,请参考以下文章

如何在一个 viewController 上使用多个搜索栏来访问 Swift 中的不同 JSON 数据?

RxSwift 从一个创建多个 Observable

同一个 ViewController 的 2 个视图

同时调用多个 ViewController 实例会导致应用在 AppDelegate 中崩溃

一个 UIImagePickerController 用于多个 ImageVIews

用于设置多步骤注册页面的最佳ViewController是什么?