У меня проблема, которую я пытаюсь осмыслить, связанная с использованием обработчиков завершения. У меня есть 3 слоя в моей программе iOS: ViewController-> Service-> Networking. Мне нужно загрузить некоторые данные через вызов API из контроллера представления.
Я определил функции (завершенияHandlers) в ViewController, которые должны выполняться после завершения запроса данных, и мне комфортно при реализации обработчиков завершения, когда существует только два уровня, но сбивает с толку, когда в следующем сценарии:
DashboardViewController.swift
import UIKit
@IBDesignable class DashboardViewController: UIViewController {
@IBOutlet weak var stepCountController: ExpandedCardView!
var articles:[Article]?
let requestHandler = RequestHandler()
let dashboardService = DashboardService()
override func viewDidLoad() {
super.viewDidLoad()
dashboardService.getDashboardData(completionHandler: getDashboardDataCompletionHandler)
}
func getDashboardDataCompletionHandler(withData: DashboardDataRequest) {
print(withData)
}
}
DashboardService.swift
import Foundation
class DashboardService: GeneralService {
var requestHandler: DashboardRequestHandler
override init() {
requestHandler = DashboardRequestHandler()
super.init()
}
//this function should execute requestHandler.requestDashboardData(), and then execute convertDashboardData() with the result of previous get request
func getDashboardData(completionHandler: @escaping (DashboardDataRequest) -> Void) {
//on network call return
guard let url = URL(string: apiResourceList?.value(forKey: "GetDashboard") as! String) else { return }
requestHandler.requestDashboardData(url: url, completionHandler: convertDashboardData(completionHandler: completionHandler))
}
func convertDashboardData(completionHandler: (DashboardDataRequest) -> Void) {
//convert object to format acceptable by view
}
}
DashboardRequestHandler.swift
import Foundation
class DashboardRequestHandler: RequestHandler {
var dataTask: URLSessionDataTask?
func requestDashboardData(url: URL, completionHandler: @escaping (DashboardDataRequest) -> Void) {
dataTask?.cancel()
defaultSession.dataTask(with: url, completionHandler: {(data, response, error) in
if error != nil {
print(error!.localizedDescription)
}
guard let data = data else {
return
}
do {
let decodedJson = try JSONDecoder().decode(DashboardDataRequest.self, from: data)
completionHandler(decodedJson)
} catch let jsonError {
print(jsonError)
}
}).resume()
}
}
Если вы посмотрите комментарий в DashboardService.swift, моя проблема очевидна. Я передаю обработчик завершения из ViewController в службу, и у службы есть собственный обработчик завершения, который он передает в RequestHandler, где обработчик завершения контроллера представления (getDashboardDataCompletionHandler) должен выполняться после обработчика завершения службы (convertDashboardData ())
Пожалуйста, помогите мне прояснить, как это реализовать. Допускаю ли я ошибку в дизайне, пытаясь связать такие обработчики завершения, или я упускаю что-то очевидное.
Спасибо
- РЕДАКТИРОВАТЬ - Моя реализация обработчика запросов выглядит следующим образом:
import Foundation
class RequestHandler {
// let defaultSession = URLSession(configuration: .default)
var defaultSession: URLSession!
init() {
guard let path = Bundle.main.path(forResource: "Api", ofType: "plist") else {
print("Api.plist not found")
return
}
let apiResourceList = NSDictionary(contentsOfFile: path)
let config = URLSessionConfiguration.default
if let authToken = apiResourceList?.value(forKey: "AuthToken") {
config.httpAdditionalHeaders = ["Authorization": authToken]
}
defaultSession = URLSession(configuration: config)
}
}
RequestHandler
? - person user3581248   schedule 12.03.2018convertDashboardData(completionHandler: completionHandler)
наcompletionHandler
вDashboardService.swift
- person user3581248   schedule 12.03.2018//convert object to format acceptable by view
- если вы хотите этого добиться, вашDashboardService
также должен выполнять роль адаптера, поэтому объявление методаgetDashboardData
должно выглядеть так:func getDashboardData(completionHandler: @escaping (SomeTypeThatAdjustsDashboardDataToFormatAcceptableByView) -> Void)
. И тогда вам нужно будет выполнить это преобразование вDashboardService
- person user3581248   schedule 12.03.2018SomeTypeThatAdjustsDashboardDataToFormatAcceptableByView
- это тип;(SomeTypeThatAdjustsDashboardDataToFormatAcceptableByView) -> Void
будет закрытием - person user3581248   schedule 12.03.2018