Swift Closures:无法将类型'()'的返回表达式转换为返回类型'LiveSearchResponse?'

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

我有两个控制器。

  1. Maincontroller
  2. Dropdown

Maincontrollerallows用户打开下拉列表。 Dropdown允许用户从列表中选择一行。选定的行值将传递给Maincontroller。在Dropdown控制器中有searchBar。当用户搜索某些内容时,它会要求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)

以下是我在Maincontroller从Web API获取搜索数据的功能。它返回类型为LiveSearchResponse的Object。

    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 {

    }
}

你能告诉我存档目标的正确方法吗?

ios swift swift4.2
1个回答
2
投票

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

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 {

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