简介
在本文中,我们查看了通过iOS应用中的地址实现位置搜索的有趣过程。如果您重新开发具有地图或位置相关功能的应用程序,则本指南将帮助您根据用户进入搜索栏中的地址获得特定的坐标。
1。导入您的文件
导入的连续分配
导入mapkit
冠状和mapkit有什么区别?
旋转定位是位置数据的处理。它使用所有可用的设备组件,包括蜂窝设备,Wi-Fi,蓝牙,GPS,晴雨表和磁力计。
MAPKIT涉及视觉操作,例如地图渲染,路线方向,地址查找和用户友好的操作。无论如何,谁想输入纬度,而不是可读地址?
2。将需要的属性
私人懒惰var完整器= mklocalsearchcompleter()
私人懒惰的var searchResults:[(title:string?,subtitle:string?,坐标:cllocation coortion2d?)] = []
私人var searchcompletion:(([[((标题:string?,subtitle:string?,坐标:cllocation coortion2d?))]) - > void)?
私人var usergeionionCoordion:cllocation coortion2d?
3。来自clgeocoder的GeoCodeDeadDressstring的问题
在开发开始时,我决定在SearchAddressEftext方法中使用ClgeoCoder的GeocodeDeadDressString方法。但是,我遇到了一个问题。此方法总是只返回一个带有坐标的地址,而不是提供供您选择的完整地址列表。例如,在某些国家 /地区可能有很多街道上有相同的名字。如果我将这样的字符串传递给方法,我只收到一个代表随机城市街道的clplacemark。此限制不适合我的应用,因此我需要找到替代解决方案。
func searchAddressesForText(_ text: String, completion: @escaping ([String]) -> Void) {
let region = CLCircularRegion(center: userRegionCoordinate, radius: 30000, identifier: "SearchRegion")
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(text, in: region, completionHandler: { (placemarks, error) in
var addresses: [String] = []
if let placemarks = placemarks {
for placemark in placemarks {
if let thoroughfare = placemark.thoroughfare, let subThoroughfare = placemark.subThoroughfare {
let address = "\(thoroughfare), \(subThoroughfare)"
addresses.append(address)
} else if let thoroughfare = placemark.thoroughfare {
let address = "\(thoroughfare)"
addresses.append(address)
}
}
}
completion(addresses)
})
}
}
4。使用mklocalsearchcompleter
后来,我发现MklocalsearchCompleter可以解决此问题。它通过最近的匹配提供了多个地址,从而使用户可以从列表中选择正确的地址。但是,该解决方案的缺点是它不为每个地址提供坐标。相反,用户必须选择一个地址之一,然后调用SearchCoordinatesForadDress方法以获取所选地址的坐标。
func searchAddressesForText(_ text: String,
completion: @escaping ([(title: String?,
subtitle: String?,
coordinate: CLLocationCoordinate2D?)]) -> Void) {
completer.delegate = self
completer.queryFragment = text
if let userRegionCoordinate = self.userRegionCoordinate {
let region = MKCoordinateRegion(center: userRegionCoordinate, latitudinalMeters: 5000, longitudinalMeters: 5000)
completer.region = region
}
searchCompletion = completion
}
要使用MklocalsearchCompleter,我创建了一个MklocalsearchCompleter的实例并设置其委托。然后,我设置搜索文本和区域以获取适当的结果。更新搜索结果后,我检索地址列表并将其传递到完成单元以进行进一步处理或显示。
5。 mklocalsearchcompleterdelegate
为了克服使用MKlocalsearchCompleter获得的地址的限制,我使用MklocalsearchCompleter获取地址列表,然后使用MKlocalsearch列出了所选地址的坐标。
extension SomeViewController: MKLocalSearchCompleterDelegate {
public func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
searchResults = completer.results.compactMap { result in
let street = result.title
let subtitle = result.subtitle
let searchRequest = MKLocalSearch.Request(completion: result)
let coordinate = searchRequest.region.center
//If you want to exclude any result
let isRelevant = number != "find near me"
guard isRelevant else {
return nil
}
return (title: street, subtitle: number, coordinate: coordinate)
}
searchCompletion?(searchResults)
}
public func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
searchResults = []
searchCompletion?(searchResults)
}
}
6。获得坐标
为用户提供了使用MKLocalsearchCompleter获得的地址列表,并可以选择其中一个。当用户选择地址时,我将其传递到searchCoordinatesForaddress方法,以使用MKlocalsearch检索相应的坐标。这样,我结合了两种方法的优势,并通过地址获得位置搜索的完整功能。
func searchCoordinatesForAddress(_ address: [(title: String?, subtitle: String?)],
completion: @escaping ([(title: String?,
subtitle: String?,
coordinate: CLLocationCoordinate2D?)]?) -> Void) {
let searchRequest = MKLocalSearch.Request()
let entireAddress = address.title + " " + address.subtitle
searchRequest.naturalLanguageQuery = entireAddress
let search = MKLocalSearch(request: searchRequest)
search.start { response, error in
if let response = response,
let firstPlacemark = response.mapItems.first?.placemark {
let coordinate = firstPlacemark.coordinate
completion(title: address.title, subtitle: address.subtitle, coordinate: coordinate)
} else {
completion(nil)
}
}
}
7。如果不再需要
取消搜索
例如,如果用户键入地址并决定立即关闭屏幕。
或将每个新字符输入方法中的搜索栏时:
功能搜索( em> sertarcar,sexirect,sexcarchart sexdint:string)_bring
您必须使用此方法取消搜索。
func cancelSearchAddresses() {
if completer.isSearching {
completer.cancel()
}
}
结论
在本文中,我们研究了通过iOS应用程序中的地址实现位置搜索功能的过程。我们使用Clgeocoder的GeoCodeadDressString方法发现了一个问题,该方法仅返回一个地址,并使用MklocalsearchCompleter解决了该问题,该方法提供了多个地址,但没有坐标。我们还研究了一种合并的方法,该方法使我们能够获得地址列表和所选地址的相应坐标。
我希望本指南对您有用,并帮助您解决了通过iOS应用中的地址找到位置的问题。
如果您还有其他问题,请随时提出。