MKLocalSearch
와 start(completionHandler:)
를 활용해 장소를 검색하고, 결과를 [MKMapItem] 형태로 받아올 수 있다.
아래는 공식문서에 소개되어있는 검색 예제
let searchRequest = MKLocalSearch.Request()
searchRequest.naturalLanguageQuery = "coffee"
// Set the region to an associated map view's region.
searchRequest.region = myMapView.region
let search = MKLocalSearch(request: searchRequest)
search.start { (response, error) in
guard let response = response else {
// Handle the error.
}
for item in response.mapItems {
if let name = item.name,
let location = item.placemark.location {
print("\\(name): \\(location.coordinate.latitude),\\(location.coordinate.longitude)")
}
}
}
async throws
형태의 메서드도 지원하지만 네트워크 관련해서 아직은 팀에서 async 도입에 대해 논의해보지 않았으므로 completion handler가 있는 메서드로 “회귀”했다.
장소 검색의 근간이 되는 맵뷰가 존재하고, 해당 범위에서만 검색하고 싶을 때 지역을 설정한다..는 것 같다. 처음엔 무조건 region도 설정해줘야 동작하는 줄 알고 사용하지도 않는 맵뷰를 만들어서 해당 맵뷰의 region으로 일단 설정했는데 아래와 같은 경고가 떴다.
[Memory] Resetting zone allocator with allocations still alive
Resetting zone allocator with allocations still alive
처음에는 위의 글처럼 removeAnnotations를 해서 맵뷰 내에서 필요 없는 annotation들을 제거해주는 방식을 썼지만 이것도 근본적인 해결책은 안됐고 오히려 왜 이거랑 메모리가 관련이 있단 걸까 하는 궁금증만 추가됨
⇒ 줌 또는 패닝된 annotations가 있다면 뷰가 사라지더라도 계속 남아 있어 메모리 릭을 일으키는 것이 맞지만 이번 케이스에서는 해당되지 않는다.
⇒ 우선은 MKMapView를 사용하게 될 때 메모리 릭이 발생한다면 뷰컨이 deinit 될 때 설정된 델리게이트나 annotations를 모두 제거해줘야 한다.. 정도로 이해하고 마무리했다.
두번째는 region을 반드시 지정해줘야할 필요가 있나 싶어 생성했던 MKMapView 생성 부분과 region 설정을 바꿔줬더니 더 이상 워닝이 나지 않았다.. 역시 맵뷰 문제가 맞았던 듯.
request.region = MKMapView().region // 이런 느낌으로 되어 있던 걸
request.region = MKCoordinateRegion(MKMapRect.world) // 이렇게 수정함