Swift结合Mapbox实现向联系人发送实时位置追踪功能咨询
iOS实时位置共享短信发送实现方案
整体实现逻辑
- 搭建轻量后端作为中间层,承担共享会话管理、位置存储、有效期控制的能力
- 用户触发SOS时,iOS端先向后端申请创建唯一的位置共享会话,拿到对应的访问URL
- iOS端开启后台定位权限,定时将最新位置上报到后端,直到预设的共享时长结束
- 家人点开短信里的URL后,H5页面会定时从后端拉取最新位置并在地图上展示,超时后自动停止更新
前提配置
首先需要在Xcode中完成两项配置,保证APP退后台后仍能正常上报位置:
- 项目
Signing & Capabilities中添加Background Modes能力,勾选Location updates选项 - 在
Info.plist中添加NSLocationAlwaysAndWhenInUseUsageDescription权限声明,向用户说明后台定位的用途
iOS端代码改造
新增属性定义
import CoreLocation // 对应类的内部属性 private var locationManager: CLLocationManager = CLLocationManager() private var currentShareId: String? private let shareDuration: TimeInterval = 3600 // 自定义共享时长,示例为1小时 private var uploadTimer: Timer?
改造SOS按钮点击逻辑
@IBAction func SOS_Pressed(_ sender: Any) { // 申请后台定位权限 locationManager.requestAlwaysAuthorization() locationManager.allowsBackgroundLocationUpdates = true locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation locationManager.startUpdatingLocation() // 1. 请求后端创建共享会话 createShareSession { [weak self] shareId, shareUrl in guard let self = self, let shareId = shareId, let shareUrl = shareUrl else { return } self.currentShareId = shareId // 2. 启动定时位置上报 self.startUploadLocation() // 3. 发送带共享链接的短信 if MFMessageComposeViewController.canSendText() { let controller = MFMessageComposeViewController() controller.body = "紧急求助!这是我的实时位置链接,1小时内可查看:\(shareUrl)" controller.recipients = ContactsPHArray controller.messageComposeDelegate = self self.present(controller, animated: true) } // 4. 共享时长到后自动停止 DispatchQueue.main.asyncAfter(deadline: .now() + self.shareDuration) { [weak self] in self?.stopShare() } } } // 原有短信回调逻辑无需修改 func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) { self.dismiss(animated: true, completion: nil) }
新增辅助方法
// 对接后端创建共享会话接口 private func createShareSession(completion: @escaping (String?, String?) -> Void) { guard let url = URL(string: "你的后端创建会话接口地址") else { completion(nil, nil) return } var request = URLRequest(url: url) request.httpMethod = "POST" // 可根据需要自定义传参,比如共享时长、用户标识等 URLSession.shared.dataTask(with: request) { data, _, error in guard let data = data, error == nil, let json = try? JSONSerialization.jsonObject(with: data) as? [String: String], let shareId = json["share_id"], let shareUrl = json["share_url"] else { completion(nil, nil) return } DispatchQueue.main.async { completion(shareId, shareUrl) } }.resume() } // 定时上报最新位置到后端 private func startUploadLocation() { // 每5秒上报一次,可自行调整频率 uploadTimer = Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { [weak self] _ in guard let self = self, let shareId = self.currentShareId, let userLoc = self.locationManager.location else { return } let lat = userLoc.coordinate.latitude let lon = userLoc.coordinate.longitude guard let url = URL(string: "你的后端位置上报接口地址") else { return } var request = URLRequest(url: url) request.httpMethod = "POST" let params = ["share_id": shareId, "lat": lat, "lon": lon] as [String : Any] request.httpBody = try? JSONSerialization.data(withJSONObject: params) request.setValue("application/json", forHTTPHeaderField: "Content-Type") URLSession.shared.dataTask(with: request).resume() } } // 停止位置共享 private func stopShare() { locationManager.stopUpdatingLocation() uploadTimer?.invalidate() uploadTimer = nil currentShareId = nil // 可添加本地通知提醒用户共享已结束 }
后端&前端逻辑说明
后端只需提供3个基础接口:
- 共享会话创建接口:生成全局唯一的
share_id,绑定会话过期时间,返回share_id和对应的访问URL - 位置上报接口:接收iOS端传入的
share_id和经纬度,更新该会话的最新位置 - 位置查询接口:接收前端请求,返回对应
share_id的最新位置,会话过期则返回过期标识
前端H5页面逻辑:
URL对应页面内置地图组件,每隔3秒调用后端位置查询接口拉取最新坐标,更新地图上的用户标记,收到过期标识后提示「位置共享已结束」。
注意事项
- APP被用户手动杀掉后共享会自动中断,可添加本地通知告知用户
- 后端可给每个共享会话加访问频次限制,避免链接泄露后位置被无关人员获取
- 可额外增加手动停止共享的按钮,支持用户提前结束位置共享
内容的提问来源于stack exchange,提问作者M. pittard
相关产品推荐
相关产品推荐

