How to extract street, city, etc. from GMSPlace Address Components

后端 未结 10 1901
栀梦
栀梦 2021-02-20 02:51

I\'m using Google Places API for iOS and can successfully retrieve nearby places and present the address as a string. What I\'m trying to do is extract address components such

相关标签:
10条回答
  • 2021-02-20 03:44

    A safe Swift 4.2 solution:

    let name = place.addressComponents?.first(where: { $0.type == "city" })?.name
    

    selectedPlace.addressComponents is a array of GMSAddressComponent which have 2 properties type and name. In you case it will be like

        for component in addressComponents! {
        if component.type == "city" {
        print(component.name)
        }
       }
    

    GMSAddressComponent is a class not a dictionary or array that's you are getting this error.

    Additional component types can be referred from the link.

    0 讨论(0)
  • 2021-02-20 03:44

    Swift 4

        var keys = [String]()
        place.addressComponents?.forEach{keys.append($0.type)}
        var values = [String]()
        place.addressComponents?.forEach({ (component) in
            keys.forEach{ component.type == $0 ? values.append(component.name): nil}
        })
        print(values) 
    
    0 讨论(0)
  • 2021-02-20 03:46

    I am using this extension:

    extension Array where Element == GMSAddressComponent {
        func valueFor(placeType: String, shortName: Bool = false) -> String? {
            // bug in the google or apple framework. This cast must stay.
            // Withou it crashing.
            guard let array = self as? NSArray else { return nil }
            let result = array
                .compactMap { $0 as? GMSAddressComponent }
                .first(where: {
                    $0.types
                        .first(where: { $0 == placeType }) == placeType
                })
            return shortName ? result?.shortName : result?.name
        }
    }
    

    Usage:

    let place: GMSPlace
    // ...
    place.addressComponents?.valueFor(placeType: kGMSPlaceTypeRoute, shortName: true)
    
    0 讨论(0)
  • 2021-02-20 03:54

    It's working in Swift 5 and iOS 13.3

    1. Create a function for showing GMSAutocompleteViewController

        func googlePlacesSearchVC() {
        
            let acController = GMSAutocompleteViewController()
            acController.delegate = self
            // Specify the place data types to return.
            let fields: GMSPlaceField = GMSPlaceField(rawValue: UInt(GMSPlaceField.name.rawValue) |
          UInt(GMSPlaceField.formattedAddress.rawValue)  |
                   UInt(GMSPlaceField.addressComponents.rawValue))!
        
            acController.placeFields = fields
            // Specify a filter.
            let filter = GMSAutocompleteFilter()
            filter.country = "IN"
            acController.autocompleteFilter = filter
    
            acController.secondaryTextColor = .darkGray
            acController.primaryTextColor = .lightGray
            acController.primaryTextHighlightColor = .black
            acController.tableCellBackgroundColor = .whiteThree
            acController.tableCellSeparatorColor = .lightGray
            // Display the autocomplete view controller.
            present(acController, animated: true) {
    
                let views = acController.view.subviews
                let subviewsOfSubview = views.first!.subviews
                let subOfNavTransitionView = subviewsOfSubview[1].subviews
                let subOfContentView = subOfNavTransitionView[1].subviews
                let searchBar = subOfContentView[0] as! UISearchBar
                searchBar.searchTextField.placeholder = "places_picker_hint_add_address".localized
                searchBar.searchBarStyle = .minimal
                searchBar.searchTextField.font = UIFont.screenTitle16Pt
                searchBar.searchTextField.backgroundColor = UIColor.white
                searchBar.searchTextField.leftView?.tintColor = .darkGray
                searchBar.delegate?.searchBar?(searchBar, textDidChange: "")
            }
       }
    

    2. Call that function where ever you need, for ex:-

       override func viewDidLoad() {
          super.viewDidLoad()
    
          googlePlacesSearchVC()
       }
    

    3. Call GMSAutoCompleteViewControllerDelegates Methods. Here will get all details like Street, City, etc. from GMSPlace Address Components

    extension ViewController {
    
          // Handle the user's selection.
          func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace) {
            
                // Show HouseAndFlat
                if place.name?.description != nil {
                    
                    yourTxtField.text = place.name?.description ?? ""
                }
    
                // Show latitude
                if place.coordinate.latitude.description.count != 0 {
                    var latitude = place.coordinate.latitude
                }
                // Show longitude
                if place.coordinate.longitude.description.count != 0 {
                    selectedLongitude = place.coordinate.longitude
                }
    
                // Show AddressComponents
                if place.addressComponents != nil {
                    
                    for addressComponent in (place.addressComponents)! {
                       for type in (addressComponent.types){
    
                           switch(type){
                               case "sublocality_level_2":
                                   yourTxtField.text = addressComponent.name
                               case "sublocality_level_1":
                                    yourTxtField.text = addressComponent.name
                                case "administrative_area_level_2":
                                    yourTxtField.text = addressComponent.name
    
                                case "administrative_area_level_1":
                                     yourTxtField.text = addressComponent.name
                                case "country":
                                    yourTxtField.text = addressComponent.name
    
                                case "postal_code":
                                     yourTxtField.text = addressComponent.name
                           default:
                               break
                           }
                       }
                   }
                }
                dismiss(animated: true, completion: nil)
          }
    
          func viewController(_ viewController: GMSAutocompleteViewController, didFailAutocompleteWithError error: Error) {
                // TODO: handle the error.
                print("Error: ", error.localizedDescription)
          }
    
          // User canceled the operation.
          func wasCancelled(_ viewController: GMSAutocompleteViewController) {
                dismiss(animated: true, completion: nil)
          }
    }
    

    I have found an answer from this link

    0 讨论(0)
提交回复
热议问题