У меня два контроллера.
Maincontroller
Dropdown
Maincontroller
позволяет пользователям открывать выпадающий список.Dropdown
позволяет пользователям выбирать строку из списка.значение выбранной строки будет передано Maincontroller
.В Dropdown
контроллере есть панель поиска.Когда пользователь что-то ищет, он просит Maincontroller
получить данные для поискового запроса.Maincontroller
будет извлекать данные из Web API и возвращать результат в Dropdown
.
Я столкнулся с проблемой при возврате данных из Maincontroller
в Dropdown
с использованием замыкания.
я представляю Dropdown
модально из Maincontroller
, как показано ниже.
let searchVC = LiveSearchDropDown<DropDownTitleTCell>.init(configureCell: { (cell ,object) -> DropDownTitleTCell in
cell.lblTitle.text = "Dummy"
return cell
}, selection: { (selectedObject) in
print(selectedObject)
self.dismiss(animated: false, completion: nil)
}, search: { (query, spaging) -> LiveSearchResponse? in
let res = self.fetchPatients(query: query, forPaging: spaging, response: { (response) in
})
return res
})
self.present(searchVC, animated: true)
Ниже приводится функция, в которой я получаю данные поиска из Web API в Maincontroller
.Возвращает объект типа LiveSearchResponse
.
func fetchPatients(query searchText: String, forPaging : Paging, response: @escaping(LiveSearchResponse) -> ()) {
let params = Prefs.getAPICallParameters()
var responseData = LiveSearchResponse()
APIManager.shared.jsonRequest(url: AppConstant.Patient.getPatientList, parameters: params, method: .post, encoding: JSONEncoding.default, onSuccess: { (resposeJSON) in
if let patientList = resposeJSON["data"].array {
if patientList.count > 0 {
var data = [Patient]()
//success retreived
for patient in patientList {
data.append(Patient(json: patient))
}
if patientList.count < 20 {
forPaging.shouldLoadMore = false
} else {
forPaging.shouldLoadMore = true
}
responseData.data = data
responseData.error = nil
} else {
forPaging.status = .failed
}
response(responseData)
} else {
forPaging.status = .failed
self.presentAlertWithTitle(title: "Error", message: "AppConstant.Patient.getPatientList data Key not found", options: "Ok", completion: { (option) in
})
response(responseData)
}
}) { (error) in
forPaging.status = .failed
self.presentAlertWithTitle(title: "Error", message: error.message, options: "Ok", completion: { (option) in
})
response(responseData)
}
}
Я получаю ошибку времени компиляции в блоке ниже, когда возвращаю объект из замыкания.
Невозможно преобразовать возвращаемое выражение типа '()' в возвращаемый тип 'LiveSearchResponse?'
search: { (query, spaging) -> LiveSearchResponse? in
let res = self.fetchPatients(query: query, forPaging: spaging, response: { (response) in
})
return res
Я не знаю, как вернуть значение в Closures послеизвлечение данных из асинхронной функции.
РЕДАКТИРОВАТЬ 2
В Dropdown
я объявил как
public let searchQuery: LiveSearchQuery
typealias LiveSearchQuery = (String, Paging) -> LiveSearchResponse?
Инициализация
required init(configureCell: @escaping CellConfiguration, selection: @escaping Selection, search: @escaping LiveSearchQuery) {
self.configureCell = configureCell
self.selection = selection
self.searchQuery = search
super.init(nibName: nil, bundle: nil)
self.modalPresentationStyle = .formSheet
self.modalTransitionStyle = .crossDissolve
self.preferredContentSize = CGSize(width: 400, height: 400)
}
и Вызовэто как
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
if let query = searchBar.text, !query.isEmpty {
self.paging.status = .loading
self.tableView.reloadData()
let response = searchQuery(query, self.paging)
if response?.error == nil {
self.dataModels = response?.data as? [AnyObject]
} else {
}
self.tableView.reloadData()
searchBar.resignFirstResponder()
} else {
}
}
Можете ли вы предложить мне правильный способ архивирования цели?