【问题标题】:Google Maps Autocomplete谷歌地图自动完成
【发布时间】:2018-01-08 20:59:53
【问题描述】:

在我的 Swift iOS 应用中,我使用这个库来显示 Google Place 自动完成:https://github.com/watsonbox/ios_google_places_autocomplete

这是我的主视图控制器中的内容:

let gpaViewController = GooglePlacesAutocomplete(
  apiKey: "myapikey",
  placeType: .Address
)

gpaViewController.placeDelegate = self // Conforms to GooglePlacesAutocompleteDelegate

presentViewController(gpaViewController, animated: true, completion: nil)

这很好用,但它让我有了新的看法。如何在我的主视图控制器中的搜索字段上应用自动完成功能,而无需切换到另一个视图?

【问题讨论】:

  • 您还需要自动完成方法吗?如果您需要,我可以为您提供答案。

标签: ios swift


【解决方案1】:

嘿,使用来自 GitHub 的快速代码

https://github.com/vijayvir/LeoGoogle/blob/master/AutoCompeteWithSearchBar/LeoGoogleAutoCompleteSearch.swift

@IBOutlet var leoGoogleAutoCompleteSearch: LeoGoogleAutoCompleteSearch!
override func viewDidLoad() {
super.viewDidLoad()
leoGoogleAutoCompleteSearch.closureDidUpdateSearchBarWithPredictions = { predictions in

predictions.map({ (prediction ) -> Void in

print(prediction.placeId ?? "NG" , "     ??   " , prediction.description ?? "NG" )

})

}

这里我创建了 autocomplete api 的对象,它将通过closure返回 place_id 和搜索的描述。进一步开发者可以修改代码。对于请求,我使用 Almofire 来获取请求,这在当今很常见。

更多关于代码

mport Foundation
import GooglePlaces
import Alamofire
import UIKit
typealias LeoGoogleMapACompletionBlock = (AnyObject, AnyObject) -> Void

typealias LeoGoogleMapAFailureBlock = (AnyObject, AnyObject) -> Void

struct LeoGoogleMapsApiPlaceAutocomplete {
    static func get(url: URL,
                   completionHandler: LeoGoogleMapACompletionBlock? = nil,
                   failureHandler: LeoGoogleMapAFailureBlock? = nil) {
        print("??????? get :", url)

        Alamofire.request(url,
                          method: .get
            )
            .responseJSON { response in

                print(" get ??????? " )

                if let json = response.result.value {

                    //  print("WebServices : - ", json)
                    completionHandler!(json as AnyObject, response.result as AnyObject)

                } else {

                    failureHandler?("" as AnyObject, "" as AnyObject)

                }

            }
            .responseString { _ in

                failureHandler?("" as AnyObject, "" as AnyObject)

                //  print("responseString Success: \(responseString)")
            }
            .responseData { _ in
        }
    }



    struct Prediction {
        var description : String?
        var id : String?
        var placeId : String?
        init(dictionary : NSDictionary) {
            description = dictionary["description"] as? String
            id = dictionary["id"] as? String
            placeId = dictionary["place_id"] as? String
        }
    }
    var predictions: [Prediction] = []
    init(response: AnyObject) {
        if let searchList = response["predictions"] as? [Any] {
            for object in searchList {
                let tempPrediction = Prediction(dictionary: (object as? NSDictionary)!)
                predictions.append(tempPrediction)
            }
        }
    }
}
class LeoGoogleAutoCompleteSearch: NSObject {
    @IBOutlet weak var searchBar: UISearchBar!
    var closureDidUpdateSearchBar : ((LeoGoogleMapsApiPlaceAutocomplete)-> Void)?
    var closureDidUpdateSearchBarWithPredictions : (([LeoGoogleMapsApiPlaceAutocomplete.Prediction])-> Void)?

}
extension LeoGoogleAutoCompleteSearch : UISearchBarDelegate  {
    func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
        return true
    }
    func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool {

        return true }
    func searchBar(_ searchBar: UISearchBar, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
        return true
    }
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { // called when text changes (including clear)
        webserviceSearchBy(text: searchBar.text!)
    }
    func webserviceSearchBy(text : String) {

        let newString = text.replacingOccurrences(of: " ", with: "+")

        let url : URL = URL(string: "https://maps.googleapis.com/maps/api/place/autocomplete/json?input=\(newString)&key=AIzaSyAVrXmSPxYourApiPK_ceurWlZJgrpWY")!

        LeoGoogleMapsApiPlaceAutocomplete.get(url: url, completionHandler: { (response, _) in
            let some  : LeoGoogleMapsApiPlaceAutocomplete = LeoGoogleMapsApiPlaceAutocomplete(response: response)
            self.closureDidUpdateSearchBar?(some)
            self.closureDidUpdateSearchBarWithPredictions?(some.predictions)

        }) { (response, _) in

        }

    }

}

【讨论】:

    【解决方案2】:

    添加这两个变量...

    let autoPlaceURLString : String = "https://maps.googleapis.com/maps/api/place/autocomplete/json"

    let apiKey = "your api key"

    现在将您的 UITextfield 委托设置为 self。并在文本字段更改方法上调用以下方法...

    fetchAutocompletePlaces(keyword: textField.text!)

    您将收到一组地址...

    func fetchAutocompletePlaces(keyword: String) {
    
        let urlString = "\(autoPlaceURLString)?key=\(apiKey)&input=\(keyword)"
        let s = (CharacterSet.urlQueryAllowed as NSCharacterSet).mutableCopy() as! NSMutableCharacterSet
        s.addCharacters(in: "+&")
        let encodedURL = urlString.addingPercentEncoding(withAllowedCharacters: s as CharacterSet)
    
        Alamofire.request(encodedURL!).responseJSON { (response) in
    
            if response.result.isSuccess {
                if let json = response.result.value as? [String: Any] {
                    let predictions = json["predictions"]
                    var locations = [String]()
                    for dict in predictions as! [NSDictionary]{
                        locations.append(dict["description"] as! String)
                    }
                    DispatchQueue.main.async(execute: { () -> Void in
                        self.strAddressByGoogle = locations
                        if (self.strAddressByGoogle.count == 0){
                            self.tblAddress.isHidden = true
                        }else {
                            self.tblAddress.isHidden = false
                        }
                        self.tblAddress.reloadData()
                    })
                }
            }
        }
    }
    

    现在在同一视图的 UITableView 中显示此列表。

    【讨论】:

      【解决方案3】:

      为什么不使用适用于 iOS 的 Google Places API?并按照步骤使用 fetcher 以编程方式执行此操作。链接:https://developers.google.com/places/ios-api/autocomplete#get_place_predictions_programmatically

      【讨论】:

        猜你喜欢
        • 2016-11-17
        • 2018-01-26
        • 1970-01-01
        • 1970-01-01
        • 2018-06-01
        • 2015-03-22
        • 2012-10-14
        • 2019-04-21
        相关资源
        最近更新 更多