Swift中如何在闭包中返回一个外部函数值?

我现在需要做一个UITextField的Autocomplete自动匹配的功能,大概就是在输入框中输入一个地名开头的一个或几个字符,服务器返回相关的地名和邮编作为一个列表,从而不需要用户把所有字母都输入了。

我在网上找了一个Autocomplete的库,https://github.com/cjcoax/Aut..., 它其中有一个Delegate的方法

func autoCompleteItemsForSearchTerm(term: String) -> [AutocompletableOption]

用来处理用户输入的字符term 返回一个AutocompletableOption作为自动匹配列表的输入数据。

现在问题来了,我需要把用户输入的term发到服务器然后等待服务器的返回的JSON,网络层我用的是Moya,大概的方法如
CredentialProvider.request(.Autocomplete(term, 10)) { (result) -> () in .... }

那么我怎么才能当异步的从服务器端得到数据之后再生成一个[AutocompletableOption] 作为 func autoCompleteItemsForSearchTerm(term: String) 的返回值呢?

这是我尝试写的方法,搞不懂的地方已经写了注释

    func autoCompleteItemsForSearchTerm(term: String) -> [AutocompletableOption] {
        
        var cityArray: [AutocompleteCellData] = [] // 是不是应该写个闭包?
        
        CredentialProvider.request(.Autocomplete(term, 10)) { (result) -> () in
            print(result)
            switch result {
            case let .Success(response):
                let json = JSON(data: response.data)
    
                // 在这里应该怎么处理得到的json值? 这个闭包的返回值类型是Moya定好的,我没办法处理
                
            case let .Failure(error):
                print(error)
                break
            }
        }
    
        // 怎么才能把json赋值给cityArray后再让它最为外部函数的返回值呢
        
        return cityArray.map( {$0 as AutocompletableOption })
    }

==========我是郁闷的分割线==========

附上这个库自带的例子,不过例子里匹配列表是本地储存的数据,不存在等待服务器返回数据的问题

func autoCompleteItemsForSearchTerm(term: String) -> [AutocompletableOption] {

        let filteredCountries = self.countriesList.filter { (country) -> Bool in
            return country.lowercaseString.containsString(term.lowercaseString)
        }

        let countriesAndFlags: [AutocompletableOption] = filteredCountries.map { ( country) -> AutocompleteCellData in
            var country = country
            
            country.replaceRange(country.startIndex...country.startIndex, with: String(country.characters[country.startIndex]).capitalizedString)
            
            return AutocompleteCellData(text: country, image: UIImage(named: country)) 
            }.map( { $0 as AutocompletableOption })

        return countriesAndFlags
    }
阅读 2.9k
1 个回答

答案是你不能,那个库的实现方式并不支持这样的异步加载数据,你可以参考一下自己实现一个异步的版本。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进