// // StartLocationHandler.swift // ylgamehall // // H5 → Native handler:startlocation — 定位(Phase 5 接入高德 SDK 后激活真实路径) // 契约:docs/H5-Native-Contract.md §3.1 [20] + §3.2 [6] // // 完整链路: // 1. LocationService.shared.requestOnce()(actor,包 AMapLocationManager 异步) // 2. bridge.call("getlocationinfo", 9 字段) 反向 callback // - latitude / longitude 是 **string**(`String(format: "%f")`) // - province 小写 p(与 sharelogin.Province 大写不同) // 3. 失败 → getlocationinfo({errorCode:12, errorMsg:"缺少定位权限"}) // // ⚠️ canImport(AMapLocationKit) 守卫:SDK 未链接时 LocationService 抛 sdkNotLinked, // 此处兜底走 stub(与 Phase 2 一致),仅响应 callback 不触发反向 getlocationinfo。 // import Foundation public enum StartLocationHandler { public static func register(on bridge: any BridgeProtocol) { bridge.register("startlocation") { _, callback in // 与 msext 行为一致:先回 cb 字面,不等定位完成 callback?(.string("startlocation")) #if canImport(AMapLocationKit) // SDK 已链接:拉起一次性定位 → 反向 callback 9 字段 // (持续定位 data == 1 暂未实现,业务实际只调一次性 — Phase 5.4 再扩展) Task { @MainActor in do { let payload = try await LocationService.shared.requestOnce() bridge.call("getlocationinfo", data: .object([ "address": .string(payload.address), "city": .string(payload.city), "cityCode": .string(payload.cityCode), "country": .string(payload.country), "district": .string(payload.district), "latitude": .string(payload.latitude), // ← string "longitude": .string(payload.longitude), // ← string "province": .string(payload.province), // ← 小写 p "street": .string(payload.street) ]), callback: nil) } catch LocationError.authorizationDenied { // 契约失败回包(msext gameController.m:2507 等价) bridge.call("getlocationinfo", data: .object([ "errorCode": .number(12), "errorMsg": .string("缺少定位权限") ]), callback: nil) } catch { // 其它失败也归一到 12(msext 行为) bridge.call("getlocationinfo", data: .object([ "errorCode": .number(12), "errorMsg": .string("缺少定位权限") ]), callback: nil) } } #endif } } }