通过地址实现位置搜索到iOS应用程序中。分步指南
#ios #swift #maps

简介
在本文中,我们查看了通过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。如果不再需要
取消搜索 例如,如果用户键入地址并决定立即关闭屏幕。
或将每个新字符输入方法中的搜索栏时:
功能搜索( sertarcar,sexirect,sexcarchart sexdint:string)_bring 您必须使用此方法取消搜索。

func cancelSearchAddresses() {
     if completer.isSearching {
         completer.cancel()
     }
}

结论
在本文中,我们研究了通过iOS应用程序中的地址实现位置搜索功能的过程。我们使用Clgeocoder的GeoCodeadDressString方法发现了一个问题,该方法仅返回一个地址,并使用MklocalsearchCompleter解决了该问题,该方法提供了多个地址,但没有坐标。我们还研究了一种合并的方法,该方法使我们能够获得地址列表和所选地址的相应坐标。

我希望本指南对您有用,并帮助您解决了通过iOS应用中的地址找到位置的问题。
如果您还有其他问题,请随时提出。