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

Swift开发中如何获取经纬度数值并存储到变量中?

从MKCoordinateRegion提取经纬度的实现方法

问题场景

开发SwiftUI + MapKit的用户位置获取功能时,需要从MKCoordinateRegion类型的region实例中提取纬度、经度值存储到自定义变量。现有代码运行后可在控制台打印出包含经纬度的region信息,但未掌握正确的属性取值方式。

已编写的核心代码如下:

import SwiftUI
import MapKit
import CoreLocationUI

struct ContentView: View {
  @StateObject private var viewModel = ContentViewModel()
    @State var LongStorage : Int = 0
    @State var LangStorage : Int = 0
    var body: some View {
        ZStack(alignment: .bottom){
            Map(coordinateRegion: $viewModel.region, showsUserLocation: true)
                .ignoresSafeArea()
                .tint(Color("GreenColor"))
            
            
            LocationButton(.currentLocation){
                viewModel.requestAllowOnceLocationPermission()
            }
            .foregroundColor(.white )
            .cornerRadius(10)
            .labelStyle(.titleAndIcon)
            .symbolVariant(.fill)
            .tint(Color("GreenColor"))
            .padding(.bottom, 50)
            
            
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

final class ContentViewModel: NSObject, ObservableObject, CLLocationManagerDelegate{
    
    @Published var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude:  40, longitude: 120), span: MKCoordinateSpan(latitudeDelta: 100, longitudeDelta: 100))
    
    let locationManager = CLLocationManager()
    
    override init() {
        super.init()
        locationManager.delegate = self
    }
    
    func requestAllowOnceLocationPermission()  {
        locationManager.requestLocation()
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let latestLocation = locations.first else{
            //Show an error
            return
        }
        DispatchQueue.main.async {
            self.region = MKCoordinateRegion(center: latestLocation.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.015, longitudeDelta: 0.015))
//check region value
            print("Region --> \(self.region)")
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print(error.localizedDescription)
    }
}

运行后控制台输出日志如下:

Region --> MKCoordinateRegion(center: __C.CLLocationCoordinate2D(latitude: 37.33036067, longitude: -122.02845007), span: __C.MKCoordinateSpan(latitudeDelta: 0.015, longitudeDelta: 0.015))

具体实现步骤

1. 修正存储变量的类型与命名

  • 经纬度是CLLocationDegrees类型,本质为Double类型浮点数,原代码用Int类型存储会丢失小数位精度,需要先调整变量类型
  • 原纬度变量名存在拼写错误(LangStorage是语言的缩写,纬度对应Latitude的缩写),建议一并修正
// 替换ContentView中原有的两个@State存储变量
@State var longStorage: Double = 0
@State var latStorage: Double = 0

2. 通过结构体属性直接取值

不要尝试解析控制台打印的字符串获取经纬度,MKCoordinateRegion的center属性本身就是CLLocationCoordinate2D类型,直接访问其latitude、longitude属性即可拿到对应数值,这是官方SDK提供的标准取值方式,稳定性最高。

位置更新回调中支持两种等效的取值渠道:

  • 直接从回调返回的最新位置对象latestLocation.coordinate取值,不需要等待region赋值完成,效率更高
  • 从赋值完成后的self.region.center取值,和控制台打印的经纬度数值完全一致

修改后的didUpdateLocations方法代码如下:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let latestLocation = locations.first else{
        // 可在此处补充位置获取失败的提示逻辑
        return
    }
    DispatchQueue.main.async {
        self.region = MKCoordinateRegion(center: latestLocation.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.015, longitudeDelta: 0.015))
        
        // 提取经纬度
        let currentLat = latestLocation.coordinate.latitude
        let currentLong = latestLocation.coordinate.longitude
        
        // 如果要从region取值,替换成下面两行即可
        // let currentLat = self.region.center.latitude
        // let currentLong = self.region.center.longitude
        
        // 赋值给存储变量即可使用,控制台可打印验证
        print("提取到的纬度:\(currentLat),经度:\(currentLong)")
    }
}

3. (可选)在ViewModel层持有经纬度

如果需要全局使用经纬度,不需要在View层单独定义存储变量,直接在ContentViewModel中添加两个被@Published修饰的Double类型属性,拿到值后直接赋值,View层可以通过viewModel.latitude、viewModel.longitude直接访问,状态会自动同步。


内容的提问来源于stack exchange,提问作者Rakha Fatih

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 10:09:46