我使用适用于iOS的Google Places API,可以成功检索附近的地方并将地址显示为字符串。我想要做的是提取地址组件,例如city来存储在数据库中。
文档表明GMSPlace有一个addressComponents属性(一个数组),但我似乎无法想象如何使用这个属性。
下面的代码提供了标签文本的整个地址,但我无法超越:
编辑----添加了代码,显示了我如何尝试访问地址组件
venueLabel.isHidden = false
venueLabel.text = selectedPlace?.name
addressLabel.isHidden = false
addressLabel.text = selectedPlace?.formattedAddress
let addressComponents = selectedPlace?.addressComponents
for component in addressComponents! {
let city = component["city"] //Error Type GMSPaceAddressComponent has no subscript members
print(city)
}
答案 0 :(得分:10)
安全的Swift 4.2解决方案:
let name = place.addressComponents?.first(where: { $0.type == "city" })?.name
selectedPlace.addressComponents是 GMSAddressComponent 的数组,它有2个属性类型和名称。 在你的情况下,它将像
for component in addressComponents! {
if component.type == "city" {
print(component.name)
}
}
GMSAddressComponent是一个类,而不是您收到此错误的字典或数组。
可以从link引用其他组件类型。
答案 1 :(得分:3)
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)
答案 2 :(得分:2)
对于最新的Google Places API(2019年7月),这可以为您提供帮助。 实际上,Google现在为每个元素添加了几种类型。因此,现在不建议使用“类型”,而要提交新的“类型”。
您可以执行以下操作:
for addressComponent in (self.mySelectedPlace?.addressComponents)! {
for type in (addressComponent.types){
switch(type){
case "country":
var country = addressComponent.name
case "postal_code":
var postCode = addressComponent.name
default:
break
}
}
}
答案 3 :(得分:1)
对于那些追随我的人来说,我无法在Objective-C的任何地方找到它:
for (int i = 0; i < [place.addressComponents count]; i++)
{
NSLog(@"name %@ = type %@", place.addressComponents[i].name, place.addressComponents[i].type);
}
答案 4 :(得分:1)
我正在使用此扩展程序:
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
}
}
用法:
let place: GMSPlace
// ...
place.addressComponents?.valueFor(placeType: kGMSPlaceTypeRoute, shortName: true)
答案 5 :(得分:1)
我将扩展@Ramis答案,在任何情况下,如果您想检查多种类型(例如其中一种),您都想检查
addressComponents?.valueFor(placeTypes: kGMSPlaceTypePostalTown, kGMSPlaceTypeLocality)
实现
extension Array where Element == GMSAddressComponent {
func valueFor(placeTypes: String..., shortName: Bool = false) -> String? {
let array = self as NSArray
let result = array
.compactMap { $0 as? GMSAddressComponent }
.first(where: {
placeTypes.contains($0.types.first(where: { placeTypes.contains($0) }) ?? "")
})
return shortName ? result?.shortName : result?.name
}
}
答案 6 :(得分:1)
它可以在Swift 5和iOS 13.3中运行
1。创建一个用于显示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。在任何需要的地方调用该函数,例如:-
override func viewDidLoad() {
super.viewDidLoad()
googlePlacesSearchVC()
}
3。调用GMSAutoCompleteViewControllerDelegates方法。 这里将从GMSPlace地址组件获取所有详细信息,例如街道,城市等
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)
}
}
答案 7 :(得分:0)
for ( GMSAddressComponent * component in place.addressComponents) {
if ( [component.type isEqual: @"locality"] )
{
NSLog(@"Current city %@ ", component.name);
}
}
答案 8 :(得分:0)
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("All component type \(component.type)")
if component.type == "locality"{
print("This is city name \(component.name)")
}
})
print(values)
答案 9 :(得分:-1)
我找到了,希望对你有帮助
let arrays : NSArray = place.addressComponents! as NSArray
for i in 0..<arrays.count {
let dics : GMSAddressComponent = arrays[i] as! GMSAddressComponent
let str : NSString = dics.type as NSString
if (str == "country") {
print("Country: \(dics.name)")
self.pais = dics.name
}
else if (str == "administrative_area_level_2") {
print("City: \(dics.name)")
self.ciudad = dics.name
}