Swift 闭包:无法将类型“()”的 return 表达式转换为 return 类型 'LiveSearchResponse?'

Swift Closures: Cannot convert return expression of type '()' to return type 'LiveSearchResponse?'

我有两个控制器。

  1. Maincontroller
  2. Dropdown

Maincontroller允许用户打开下拉菜单。 Dropdown 允许用户 select 列表中的一行。 selected 行值将传递给 Maincontroller。在 Dropdown 控制器中有 searchBar。当用户搜索某些内容时,它会要求 Maincontroller 获取搜索查询的数据。 Maincontroller 将从 Web API 和 return 结果中获取数据到 Dropdown

我在使用闭包 return 将数据从 Maincontroller 传输到 Dropdown 时遇到了问题。

我从 Maincontroller 模态地呈现 Dropdown,如下所示。

            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)

以下是我在 Maincontroller 中从 Web API 获取搜索数据的函数。它 return 类型为 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)
    }
}

当我从闭包中 returning 对象时,下面的块出现编译时错误。

Cannot convert return expression of type '()' to return type 'LiveSearchResponse?'

search: { (query, spaging) -> LiveSearchResponse? in

            let res  = self.fetchPatients(query: query, forPaging: spaging, response: { (response) in

            })
            return res

我不知道如何在从异步函数获取数据后 return 将值赋给闭包。

编辑 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 {

    }
}

你能建议我存档目标的正确方法吗?

如果你正在调用异步方法,那么 search 不应该 return,你应该传递一个完成块,我认为它看起来像这样:

search: {[weak self] (query, spaging, completion) in

    self?.fetchPatients(query: query, forPaging: spaging, response: { (response) in
        completion(response)
    })

编辑 1

我对添加的信息有了更多的了解,您应该可以这样做:

public let searchQuery: LiveSearchQuery
typealias LiveSearchQuery = (String, Paging, @escaping (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()
        searchQuery(query, self.paging) { [weak self] response in
            DispatchQueue.main.async {
                if response?.error == nil {
                    self?.dataModels = response?.data as? [AnyObject]
                } else {
                }
                self?.tableView.reloadData()
                searchBar.resignFirstResponder()
            }
        }
    } else {

    }
}