MKLocalPointsOfInterestRequest等API返回结果不一致问题咨询
Core Location三个POI相关API结果差异问题
我在使用Core Location获取用户附近兴趣点(POI)时,采用苹果提供的三个API:MKLocalPointsOfInterestRequest、MKLocalSearch.Request和MKLocalSearchCompleter,尽管请求配置相似,但返回结果差异极大:
MKLocalPointsOfInterestRequest返回地点极少,有时还会报错:The operation couldn’t be completed. (MKErrorDomain error 4.)- 另外两个API返回结果更多,且彼此结果也不相同
以下是各请求代码及对应结果:
MKLocalPointsOfInterestRequest
// 注:代码存在变量名笔误,center应改为coordinate let coordinate = CLLocationCoordinate2DMake(41.38891, 9.16205) let poiRequest = MKLocalPointsOfInterestRequest(center: coordinate, radius: 3_000) poiRequest.pointOfInterestFilter = MKPointOfInterestFilter(including: [.beach, .marina]) let poiSearch = MKLocalSearch(request: poiRequest) let resultsPOI = try await poiSearch.start() print(resultsPOI.mapItems.compactMap(\.name))
返回结果:
["Plage de Stagnolu"]
MKLocalSearch.Request
// 注:代码存在变量名笔误,center应改为coordinate let coordinate = CLLocationCoordinate2DMake(41.38891, 9.16205) let searchRequest = MKLocalSearch.Request() searchRequest.region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 4_000, longitudinalMeters: 4_000) searchRequest.pointOfInterestFilter = MKPointOfInterestFilter(including: [.beach, .marina]) searchRequest.resultTypes = .pointOfInterest searchRequest.naturalLanguageQuery = "beach" let search = MKLocalSearch(request: searchRequest) let results = try? await search.start() print(results?.mapItems.compactMap(\.name) ?? [])
返回结果:
["Plage du Petit Sperone", "Plage de 3 Pointes", "Plage de Saint-Antoine Bonifacio", "Plage de Fazzio", "Piantarella Beach", "Plage du Grand Sperone", "Capu Testagro", "Plage de Balistra", "Plage de Stagnolo", "Plage de Cala Longa", "Plage de La Tonnara", "Plage Porto Novo", "Plage de Sant'Amanza", "Rena Majori", "Plage de Rondinara", "Plage de Santa Giulia", "Spiaggia Rena Bianca", "Plage De Roccapina", "Cala Spinosa", "Naracu Nieddu Beach", "Porto Cervo Beach", "Lido Dog Beach", "Plage de Figari", "Capocchia Du Purpu", "Spiaggia Zia Culumba"]
MKLocalSearchCompleter
func search(coordinate: CLLocationCoordinate2D) { completer.region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 4_000, longitudinalMeters: 4_000) completer.pointOfInterestFilter = MKPointOfInterestFilter(including: [.beach, .marina]) completer.resultTypes = .pointOfInterest completer.queryFragment = "beach" } func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) { print(completer.results.map(\.title)) }
返回结果:
["Porto Istana Beach", "Sandbanks Beach", "Spiaggia La Cinta", "Piantarella Beach", "Platja de la Barceloneta", "Whitstable Beach", "West Wittering Beach", "Cala Millor", "Maora B'ch Sailing Club"]
问题咨询
- 这种结果差异是预期行为吗?
- 若不是,是否存在配置遗漏?
- 这是否属于Bug?
测试环境:Xcode 14.3,iOS 16.0
解答
1. 结果差异属于预期行为
三个API的设计定位和数据源完全不同,结果差异是正常逻辑:
MKLocalPointsOfInterestRequest:仅调用苹果地图内置的官方标记POI数据库,严格匹配设置的MKPointOfInterestFilter类别,且返回结果数量有严格限制(通常仅返回最相关的少量结果)。报错MKErrorDomain error 4对应MKError.pointOfInterestNotFound,当请求区域内匹配的官方POI数量极少或没有时触发,符合API设计逻辑。MKLocalSearch.Request:是基于自然语言的综合搜索API,数据源更广泛,涵盖官方POI、用户提交地点、商家信息等。它会结合区域、关键词(naturalLanguageQuery)和过滤条件返回所有相关匹配结果,因此数量远多于前者。MKLocalSearchCompleter:专为输入补全场景设计,优先返回热门、高搜索量的地点,即使部分结果可能超出设置的区域范围(补全逻辑优先满足用户常见输入需求),因此结果和前两者差异明显。
2. 不存在配置遗漏
检查代码后,三个API的核心配置均已正确设置:
MKLocalPointsOfInterestRequest:已指定中心点、搜索半径和POI过滤类别,无遗漏配置(变量名笔误不影响功能执行)。MKLocalSearch.Request:已设置搜索区域、POI过滤、结果类型和自然语言查询关键词,配置完整。MKLocalSearchCompleter:已设置区域、过滤条件、结果类型和查询片段,配置符合要求。
3. 不属于Bug
结果差异由三个API的设计目标、数据源和搜索逻辑不同导致,完全符合苹果官方API的设计预期。偶尔出现的MKErrorDomain error 4也属于API正常的错误反馈场景,并非Bug。
内容的提问来源于stack exchange,提问作者alpennec
相关产品推荐
相关产品推荐

