You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中基于MapKit获取地点扩展信息的方案咨询

问题:获取POI更多信息(图片、营业时间)的实现方案

我现有一段基于查询字符串搜索附近地点的Swift代码,搜索特定餐厅会得到如下MKMapItem结果:

<MKMapItem: 0x301095d00> {
    isCurrentLocation = 0;
    name = "Chick-fil-A";
    phoneNumber = "+1 (707) 421-9631";
    placemark = "Chick-fil-A, 1750 Travis Blvd, Fairfield, CA  94533, United States @ <+38.25884980,-122.05986700> +/- 0.00m, region CLCircularRegion (identifier:'<+38.25884981,-122.05986700> radius 141.17', center:<+38.25884981,-122.05986700>, radius:141.17m)";
    timeZone = "America/Los_Angeles (PDT) offset -25200 (Daylight)";
    url = "https://www.chick-fil-a.com/locations/ca/fairfield-in-line-dt";}

对应的实现代码:

import MapKit
import CoreLocation

class AddressSearchViewModel: NSObject, ObservableObject, MKLocalSearchCompleterDelegate {
    @Published var searchResults: [searchLoc] = []
    @Published var searching: Bool = false
    private var searchCompleter: MKLocalSearchCompleter!
    
    override init() {
        super.init()
        
        searchCompleter = MKLocalSearchCompleter()
        searchCompleter.delegate = self
        searchCompleter.resultTypes = [.address, .pointOfInterest]
    }
    
    func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
        getCityList(results: completer.results) { cityResults in
            DispatchQueue.main.async {
                self.searching = false
                cityResults.forEach { element in
                    if !self.searchResults.contains(where: { $0.searchName == element.searchName }) {
                        self.searchResults.insert(element, at: 0)
                    }
                }
            }
        }
    }
    
    func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) { }
    
    func performSearch(queryStr: String) {
        searching = true
        self.searchCompleter.queryFragment = queryStr
    }
    
    private func getCityList(results: [MKLocalSearchCompletion], completion: @escaping ([searchLoc]) -> Void) {
        var searchTemp: [searchLoc] = []
        let dispatchGroup = DispatchGroup()
        
        for result in results {
            dispatchGroup.enter()
            
            let request = MKLocalSearch.Request(completion: result)
            let search = MKLocalSearch(request: request)
            
            search.start { (response, error) in
                defer {
                    dispatchGroup.leave()
                }
                
                guard let response = response else { return }
                
                for item in response.mapItems {
                    if let name = item.name {
                        searchTemp.append(searchLoc(searchName: name, lat: item.placemark.coordinate.latitude, long: item.placemark.coordinate.longitude))
                    }
                }
            }
        }
        dispatchGroup.notify(queue: .main) {
            completion(searchTemp)
        }
    }
}

// 补充缺失的模型定义
struct searchLoc {
    let searchName: String
    let lat: Double
    let long: Double
}

以餐厅为例,如何获取该地点的图片、营业时间等更多信息?是否可以使用原生Swift API实现此需求?或是谷歌地图API为最优替代方案?


解决方案

一、原生MapKit的能力限制与可用功能

1. 营业时间获取

原生MKMapItem自带openingHours属性(类型为MKOpeningHours),可直接提取营业时间相关信息:

// 在遍历response.mapItems时扩展逻辑
for item in response.mapItems {
    if let name = item.name {
        // 获取营业时间对象
        let openingHours = item.openingHours
        // 判断当前是否营业
        let isOpenNow = openingHours?.isOpen() ?? false
        // 获取格式化的营业时间文本(短格式/长格式可选)
        let formattedHours = openingHours?.formattedOpeningHours(style: .short)
        
        // 更新模型存储额外信息
        let location = searchLoc(
            searchName: name,
            lat: item.placemark.coordinate.latitude,
            long: item.placemark.coordinate.longitude,
            isOpenNow: isOpenNow,
            openingHours: formattedHours
        )
        searchTemp.append(location)
    }
}

// 扩展模型结构
struct searchLoc {
    let searchName: String
    let lat: Double
    let long: Double
    let isOpenNow: Bool?
    let openingHours: String?
}

注意:部分POI可能没有录入营业时间数据,需做可选值安全处理。

2. 图片获取

原生MapKit没有直接获取POI图片的官方API,这是原生方案的核心短板,无法通过Apple提供的接口获取餐厅、景点等地点的图片资源。

二、谷歌地图Places API的优势

如果需要图片或更全面的POI数据,谷歌地图Places API是更优选择:

  • 支持通过Place ID请求POI图片(最多可获取10张不同角度的资源)
  • 营业时间数据覆盖更广,支持节假日特殊时段信息
  • 提供额外字段:用户评分、价格等级、详细分类标签等
  • 全球数据覆盖更均衡,部分地区Apple Maps数据完善度不及谷歌

三、方案选择建议

  • 若仅需营业时间、基础地点信息,优先用原生MapKit,无需额外API密钥,集成成本更低
  • 若必须获取图片或更丰富的POI数据,建议接入谷歌地图Places API,需提前申请API密钥并处理请求鉴权

内容的提问来源于stack exchange,提问作者Ahmed Zaidan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 11:50:14