19 changed files with 976 additions and 779 deletions
@ -1,38 +0,0 @@ |
|||
.idea/ |
|||
.vagrant/ |
|||
.sconsign.dblite |
|||
.svn/ |
|||
|
|||
.DS_Store |
|||
*.swp |
|||
profile |
|||
|
|||
DerivedData/ |
|||
build/ |
|||
GeneratedPluginRegistrant.h |
|||
GeneratedPluginRegistrant.m |
|||
|
|||
.generated/ |
|||
|
|||
*.pbxuser |
|||
*.mode1v3 |
|||
*.mode2v3 |
|||
*.perspectivev3 |
|||
|
|||
!default.pbxuser |
|||
!default.mode1v3 |
|||
!default.mode2v3 |
|||
!default.perspectivev3 |
|||
|
|||
xcuserdata |
|||
|
|||
*.moved-aside |
|||
|
|||
*.pyc |
|||
*sync/ |
|||
Icon? |
|||
.tags* |
|||
|
|||
/Flutter/Generated.xcconfig |
|||
/Flutter/ephemeral/ |
|||
/Flutter/flutter_export_environment.sh |
|||
@ -1,131 +0,0 @@ |
|||
import Foundation |
|||
import AMapLocationKit |
|||
|
|||
extension Notification.Name { |
|||
static let locationstartEvent = Notification.Name("locationstartEvent") //启动定位 |
|||
static let updatelocationEvent = Notification.Name("updatelocationEvent") //更新位置事件 |
|||
} |
|||
class LocationService: NSObject { |
|||
static let shared = LocationService() |
|||
private let TAG = "LocationService" |
|||
|
|||
private var locationManager: AMapLocationManager! |
|||
private var currentLocation: CLLocation? |
|||
private var currentReGeocode: AMapLocationReGeocode? |
|||
private var initialized = false |
|||
|
|||
private override init() { |
|||
super.init() |
|||
} |
|||
|
|||
// 初始化定位服务 |
|||
func initialize() { |
|||
if initialized { return } |
|||
print("\(TAG)--------- 初始化高德定位服务") |
|||
|
|||
locationManager = AMapLocationManager() |
|||
locationManager.delegate = self |
|||
|
|||
locationManager.desiredAccuracy = kCLLocationAccuracyBest // 定位精度 |
|||
locationManager.distanceFilter = 10.0 // 移动距离阈值(单位:米) |
|||
locationManager.locatingWithReGeocode = true // 是否返回逆地理编码信息 |
|||
locationManager.allowsBackgroundLocationUpdates = true // 是否允许后台定位 |
|||
locationManager.locationTimeout = 10 // 定位超时时间(秒) |
|||
locationManager.reGeocodeTimeout = 5 // 逆地理编码超时时间(秒) |
|||
|
|||
locationManager.startUpdatingLocation() |
|||
|
|||
initialized = true |
|||
} |
|||
|
|||
// 获取缓存的位置信息 |
|||
func getCachedLocation() -> [String: String]? { |
|||
guard let location = currentLocation else { return nil } |
|||
|
|||
var locationInfo: [String: String] = [ |
|||
"user_lat": "\(location.coordinate.latitude)", |
|||
"user_lng": "\(location.coordinate.longitude)" |
|||
] |
|||
|
|||
if let regeocode = currentReGeocode { |
|||
let address = [ |
|||
regeocode.province, // 省 |
|||
regeocode.city, // 市 |
|||
regeocode.district, // 区 |
|||
regeocode.street, // 街道 |
|||
regeocode.number // 门牌号 |
|||
].compactMap { $0 }.joined(separator: "") |
|||
|
|||
locationInfo["user_location"] = address |
|||
} |
|||
|
|||
return locationInfo |
|||
} |
|||
|
|||
// 获取当前位置(带回调) |
|||
func getCurrentLocation(completion: @escaping ([String: String]?, Error?) -> Void) { |
|||
if let cached = getCachedLocation() { |
|||
completion(cached, nil) |
|||
} else { |
|||
let error = NSError( |
|||
domain: "LocationService", |
|||
code: -1, |
|||
userInfo: [NSLocalizedDescriptionKey: "当前位置还未获取"] |
|||
) |
|||
completion(nil, error) |
|||
} |
|||
} |
|||
|
|||
// 停止定位服务 |
|||
func stop() { |
|||
locationManager.stopUpdatingLocation() |
|||
locationManager = nil |
|||
currentLocation = nil |
|||
currentReGeocode = nil |
|||
initialized = false |
|||
} |
|||
} |
|||
|
|||
// MARK: - AMapLocationManagerDelegate |
|||
extension LocationService: AMapLocationManagerDelegate { |
|||
// 定位更新回调 |
|||
func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) { |
|||
currentLocation = location |
|||
currentReGeocode = reGeocode |
|||
|
|||
print("\(TAG)--------- 定位更新: \(location.coordinate.latitude), \(location.coordinate.longitude)") |
|||
|
|||
var locationInfo: [String: String] = [ |
|||
"user_lat": "\(location.coordinate.latitude)", |
|||
"user_lng": "\(location.coordinate.longitude)" |
|||
] |
|||
if let regeocode = currentReGeocode { |
|||
let address = [ |
|||
reGeocode.province, // 省 |
|||
reGeocode.city, // 市 |
|||
reGeocode.district, // 区 |
|||
reGeocode.street, // 街道 |
|||
reGeocode.number // 门牌号 |
|||
].compactMap { $0 }.joined(separator: "") |
|||
print("\(TAG)--------- 定位地址: \(address)") |
|||
locationInfo["user_location"] = address |
|||
} |
|||
|
|||
|
|||
NotificationCenter.default.post( |
|||
name: .updatelocationEvent, |
|||
object: nil, |
|||
userInfo: locationInfo |
|||
) |
|||
} |
|||
|
|||
// 定位失败回调 |
|||
func amapLocationManager(_ manager: AMapLocationManager!, didFailWithError error: Error!) { |
|||
print("\(TAG)--------- 定位失败: \(error.localizedDescription)") |
|||
} |
|||
|
|||
// 权限变更回调 |
|||
func amapLocationManager(_ manager: AMapLocationManager!, doRequireLocationAuth locationManager: CLLocationManager!) { |
|||
locationManager.requestWhenInUseAuthorization() |
|||
} |
|||
} |
|||
@ -1,44 +0,0 @@ |
|||
import Flutter |
|||
import UIKit |
|||
import AMapLocationKit |
|||
|
|||
public class LocationServicePlugin: NSObject, FlutterPlugin { |
|||
private static var channel: FlutterMethodChannel? |
|||
|
|||
public static func register(with registrar: FlutterPluginRegistrar) { |
|||
let channel = FlutterMethodChannel(name: "com.yunqiinnovation.location_service", binaryMessenger: registrar.messenger()) |
|||
let instance = LocationServicePlugin() |
|||
// 必须先设置隐私合规 |
|||
DispatchQueue.main.async { |
|||
// 2. API Key |
|||
AMapServices.shared()?.apiKey = "aa60a03be9f6531bcc64029e60f95d03" |
|||
AMapServices.shared().enableHTTPS = true |
|||
// 3. 打印验证(调试用) |
|||
print("高德SDK初始化完成") |
|||
} |
|||
registrar.addMethodCallDelegate(instance, channel: channel) |
|||
self.channel = channel |
|||
instance.addstartlocationmonitor() |
|||
} |
|||
|
|||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { |
|||
switch call.method { |
|||
case "location": |
|||
result(nil) |
|||
default: |
|||
result(FlutterMethodNotImplemented) |
|||
} |
|||
} |
|||
|
|||
private func addstartlocationmonitor(){ |
|||
// 通常放在启动后或模块初始化时 |
|||
NotificationCenter.default.addObserver( |
|||
forName: .locationstartEvent, |
|||
object: nil, |
|||
queue: .main |
|||
) { notification in |
|||
print("📥 收到 启动定位服务事件") |
|||
LocationService.shared.initialize() |
|||
} |
|||
} |
|||
} |
|||
@ -1,27 +0,0 @@ |
|||
# |
|||
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. |
|||
# Run `pod lib lint location_service.podspec` to validate before publishing. |
|||
# |
|||
Pod::Spec.new do |s| |
|||
s.name = 'location_service' |
|||
s.version = '0.0.1' |
|||
s.summary = 'A new Flutter project.' |
|||
s.description = <<-DESC |
|||
A new Flutter project. |
|||
DESC |
|||
s.homepage = 'http://example.com' |
|||
s.license = { :file => '../LICENSE' } |
|||
s.author = { 'Your Company' => 'email@example.com' } |
|||
s.source = { :path => '.' } |
|||
s.source_files = 'Classes/**/*' |
|||
s.dependency 'Flutter' |
|||
s.dependency 'AMapLocation', '~> 2.10.0' |
|||
|
|||
s.static_framework = true |
|||
s.pod_target_xcconfig = { |
|||
'DEFINES_MODULE' => 'YES', |
|||
'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' |
|||
} |
|||
s.platform = :ios, '12.0' |
|||
s.swift_version = '5.0' |
|||
end |
|||
@ -0,0 +1,21 @@ |
|||
// swift-tools-version: 5.9 |
|||
import PackageDescription |
|||
|
|||
let package = Package( |
|||
name: "location_service", |
|||
platforms: [ |
|||
.iOS(.v16), |
|||
.macOS(.v13) |
|||
], |
|||
products: [ |
|||
.library(name: "location-service", targets: ["location_service"]) |
|||
], |
|||
dependencies: [ ], |
|||
targets: [ |
|||
.target( |
|||
name: "location_service", |
|||
dependencies: [], |
|||
path: "Sources/location_service" |
|||
) |
|||
] |
|||
) |
|||
@ -0,0 +1,7 @@ |
|||
import Foundation |
|||
|
|||
/// 定位回调协议 |
|||
public protocol LocationCallback: AnyObject { |
|||
func onLocationSuccess(latitude: Double, longitude: Double, address: String) |
|||
func onLocationError(errorCode: Int, errorMessage: String) |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
import Foundation |
|||
|
|||
/// 位置数据结构 |
|||
public struct LocationData: Codable { |
|||
public let latitude: Double |
|||
public let longitude: Double |
|||
public let address: String |
|||
public let timestamp: TimeInterval |
|||
|
|||
public init(latitude: Double, longitude: Double, address: String, timestamp: TimeInterval) { |
|||
self.latitude = latitude |
|||
self.longitude = longitude |
|||
self.address = address |
|||
self.timestamp = timestamp |
|||
} |
|||
} |
|||
@ -0,0 +1,357 @@ |
|||
import Foundation |
|||
import CoreLocation |
|||
import UIKit |
|||
|
|||
public extension Notification.Name { |
|||
static let locationStartEvent = Notification.Name("locationStartEvent") |
|||
static let updateLocationEvent = Notification.Name("updateLocationEvent") |
|||
} |
|||
|
|||
public class LocationService: NSObject { |
|||
private static let TAG = "LocationService" |
|||
private static let CACHE_PREFS_NAME = "location_cache" |
|||
private static let PERMISSION_REQUEST_CODE = 1001 |
|||
|
|||
public static let shared = LocationService() |
|||
|
|||
private var locationManager: CLLocationManager? |
|||
private var initialized = false |
|||
private var permissionRetryTimer: Timer? |
|||
|
|||
// 存储当前的定位请求回调(Flutter用) |
|||
private var currentLocationCallback: ((Result<[String: Any], Error>) -> Void)? |
|||
// 存储权限请求回调(Flutter用) |
|||
private var permissionRequestCallback: ((Result<[String: Bool], Error>) -> Void)? |
|||
|
|||
// 存储服务间调用的回调 |
|||
private var serviceCallbacks: [LocationCallback] = [] |
|||
|
|||
// 缓存的位置数据 |
|||
private var cachedLocationData: LocationData? |
|||
|
|||
private override init() { |
|||
super.init() |
|||
} |
|||
|
|||
/// 检查应用是否在前台运行 |
|||
public func isAppInForeground() -> Bool { |
|||
return UIApplication.shared.applicationState == .active |
|||
} |
|||
|
|||
/// 初始化定位服务 |
|||
public func initialize() { |
|||
if initialized { return } |
|||
|
|||
if !checkPermissions() { |
|||
print("\(LocationService.TAG): 没有定位权限,等待用户授权中...") |
|||
startPermissionMonitor() |
|||
return |
|||
} |
|||
|
|||
setupLocationManager() |
|||
initialized = true |
|||
print("\(LocationService.TAG): 定位服务初始化完成") |
|||
} |
|||
|
|||
private func setupLocationManager() { |
|||
locationManager = CLLocationManager() |
|||
locationManager?.delegate = self |
|||
locationManager?.desiredAccuracy = kCLLocationAccuracyBest |
|||
locationManager?.distanceFilter = 10 |
|||
} |
|||
|
|||
private func startPermissionMonitor() { |
|||
permissionRetryTimer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { [weak self] _ in |
|||
guard let self = self else { return } |
|||
let hasPermission = self.checkPermissions() |
|||
if hasPermission && !self.initialized { |
|||
print("\(LocationService.TAG): 权限已授予,重新初始化定位服务") |
|||
self.initialize() |
|||
self.stopPermissionMonitor() |
|||
} |
|||
} |
|||
} |
|||
|
|||
private func stopPermissionMonitor() { |
|||
permissionRetryTimer?.invalidate() |
|||
permissionRetryTimer = nil |
|||
} |
|||
|
|||
/// 检查定位权限 |
|||
private func checkPermissions() -> Bool { |
|||
return hasForegroundLocationPermission() |
|||
} |
|||
|
|||
private func hasForegroundLocationPermission() -> Bool { |
|||
let status = CLLocationManager.authorizationStatus() |
|||
return status == .authorizedWhenInUse || status == .authorizedAlways |
|||
} |
|||
|
|||
private func hasBackgroundLocationPermission() -> Bool { |
|||
return CLLocationManager.authorizationStatus() == .authorizedAlways |
|||
} |
|||
|
|||
/// 检查定位权限状态(Flutter用) |
|||
public func checkLocationPermission(completion: @escaping (Result<[String: Bool], Error>) -> Void) { |
|||
let hasPermission = checkPermissions() |
|||
let result: [String: Bool] = [ |
|||
"hasPermission": hasPermission, |
|||
"hasForegroundPermission": hasForegroundLocationPermission(), |
|||
"hasBackgroundPermission": hasBackgroundLocationPermission() |
|||
] |
|||
completion(.success(result)) |
|||
} |
|||
|
|||
/// 请求定位权限(Flutter用) |
|||
public func requestLocationPermission(completion: @escaping (Result<[String: Bool], Error>) -> Void) { |
|||
if checkPermissions() { |
|||
completion(.success(["granted": true])) |
|||
return |
|||
} |
|||
|
|||
permissionRequestCallback = completion |
|||
locationManager?.requestWhenInUseAuthorization() |
|||
} |
|||
|
|||
/// 按需获取当前位置(Flutter用) |
|||
public func getCurrentLocation(completion: @escaping (Result<[String: Any], Error>) -> Void) { |
|||
if !checkPermissions() { |
|||
completion(.failure(NSError(domain: "LocationService", code: -2, userInfo: [NSLocalizedDescriptionKey: "需要定位权限"]))) |
|||
return |
|||
} |
|||
|
|||
if !initialized { |
|||
completion(.failure(NSError(domain: "LocationService", code: -3, userInfo: [NSLocalizedDescriptionKey: "定位服务未初始化"]))) |
|||
return |
|||
} |
|||
|
|||
if currentLocationCallback != nil { |
|||
completion(.failure(NSError(domain: "LocationService", code: -4, userInfo: [NSLocalizedDescriptionKey: "正在定位中,请稍后再试"]))) |
|||
return |
|||
} |
|||
|
|||
// 保存回调,开始定位 |
|||
currentLocationCallback = completion |
|||
locationManager?.requestLocation() |
|||
} |
|||
|
|||
// MARK: - 供其他iOS服务使用的接口 |
|||
|
|||
/// 检查是否有定位权限(供其他服务使用) |
|||
public func hasLocationPermission() -> Bool { |
|||
return checkPermissions() |
|||
} |
|||
|
|||
/// 异步获取当前位置(供其他iOS服务使用) |
|||
public func getCurrentLocation() async throws -> LocationData { |
|||
return try await withCheckedThrowingContinuation { continuation in |
|||
getCurrentLocation { result in |
|||
switch result { |
|||
case .success(let locationInfo): |
|||
// 从返回的字典中提取位置信息 |
|||
if let latStr = locationInfo["user_lat"] as? String, |
|||
let lngStr = locationInfo["user_lng"] as? String, |
|||
let latitude = Double(latStr), |
|||
let longitude = Double(lngStr), |
|||
let address = locationInfo["user_location"] as? String { |
|||
|
|||
let locationData = LocationData( |
|||
latitude: latitude, |
|||
longitude: longitude, |
|||
address: address, |
|||
timestamp: Date().timeIntervalSince1970 * 1000 |
|||
) |
|||
continuation.resume(returning: locationData) |
|||
} else { |
|||
continuation.resume(throwing: NSError(domain: "LocationService", code: -5, userInfo: [NSLocalizedDescriptionKey: "位置数据格式错误"])) |
|||
} |
|||
case .failure(let error): |
|||
continuation.resume(throwing: error) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// 获取当前位置(供其他iOS服务使用) |
|||
public func requestLocation(callback: LocationCallback) { |
|||
if !checkPermissions() { |
|||
callback.onLocationError(errorCode: -2, errorMessage: "没有定位权限") |
|||
return |
|||
} |
|||
|
|||
if !initialized { |
|||
callback.onLocationError(errorCode: -3, errorMessage: "定位服务未初始化") |
|||
return |
|||
} |
|||
|
|||
// 添加到回调列表 |
|||
serviceCallbacks.append(callback) |
|||
|
|||
// 如果没有正在进行的定位请求,开始定位 |
|||
if currentLocationCallback == nil && serviceCallbacks.count == 1 { |
|||
locationManager?.requestLocation() |
|||
} |
|||
} |
|||
|
|||
/// 同步获取缓存的位置信息(供其他服务使用) |
|||
/// 注意:这个方法返回的可能是过期的位置信息 |
|||
public func getCachedLocationData() -> LocationData? { |
|||
// 优先返回内存中的缓存 |
|||
if let cached = cachedLocationData { |
|||
return cached |
|||
} |
|||
|
|||
// 从UserDefaults中读取缓存 |
|||
return loadCachedLocationFromUserDefaults() |
|||
} |
|||
|
|||
private func saveCachedLocationToUserDefaults(_ locationData: LocationData) { |
|||
do { |
|||
let encoder = JSONEncoder() |
|||
let data = try encoder.encode(locationData) |
|||
UserDefaults.standard.set(data, forKey: "latitude") |
|||
UserDefaults.standard.set(String(locationData.latitude), forKey: "latitude") |
|||
UserDefaults.standard.set(String(locationData.longitude), forKey: "longitude") |
|||
UserDefaults.standard.set(locationData.address, forKey: "address") |
|||
UserDefaults.standard.set(Double(locationData.timestamp), forKey: "timestamp") |
|||
UserDefaults.standard.synchronize() |
|||
} catch { |
|||
print("\(LocationService.TAG): 保存位置缓存失败: \(error.localizedDescription)") |
|||
} |
|||
} |
|||
|
|||
private func loadCachedLocationFromUserDefaults() -> LocationData? { |
|||
do { |
|||
guard let latitudeStr = UserDefaults.standard.string(forKey: "latitude"), |
|||
let longitudeStr = UserDefaults.standard.string(forKey: "longitude"), |
|||
let latitude = Double(latitudeStr), |
|||
let longitude = Double(longitudeStr) else { |
|||
return nil |
|||
} |
|||
|
|||
let address = UserDefaults.standard.string(forKey: "address") ?? "未知地址" |
|||
let timestampDouble = UserDefaults.standard.double(forKey: "timestamp") |
|||
|
|||
if timestampDouble == 0 { return nil } |
|||
|
|||
return LocationData( |
|||
latitude: latitude, |
|||
longitude: longitude, |
|||
address: address, |
|||
timestamp: TimeInterval(timestampDouble) |
|||
) |
|||
} catch { |
|||
print("\(LocationService.TAG): 读取位置缓存失败: \(error.localizedDescription)") |
|||
return nil |
|||
} |
|||
} |
|||
|
|||
/// 停止定位服务 |
|||
public func stop() { |
|||
locationManager?.stopUpdatingLocation() |
|||
locationManager = nil |
|||
currentLocationCallback = nil |
|||
permissionRequestCallback = nil |
|||
serviceCallbacks.removeAll() |
|||
initialized = false |
|||
stopPermissionMonitor() |
|||
} |
|||
|
|||
private func handleLocationResult(_ location: CLLocation?, error: Error?) { |
|||
// 处理Flutter回调 |
|||
let flutterCallback = currentLocationCallback |
|||
currentLocationCallback = nil |
|||
|
|||
if let location = location, error == nil { |
|||
print("\(LocationService.TAG): 定位成功: \(location.coordinate.latitude), \(location.coordinate.longitude)") |
|||
|
|||
// 进行逆地理编码获取地址 |
|||
let geocoder = CLGeocoder() |
|||
geocoder.reverseGeocodeLocation(location) { [weak self] placemarks, geocodeError in |
|||
guard let self = self else { return } |
|||
|
|||
let address = placemarks?.first?.name ?? "未知地址" |
|||
|
|||
// 缓存位置数据 |
|||
let locationData = LocationData( |
|||
latitude: location.coordinate.latitude, |
|||
longitude: location.coordinate.longitude, |
|||
address: address, |
|||
timestamp: TimeInterval(Date().timeIntervalSince1970) * 1000 |
|||
) |
|||
self.cachedLocationData = locationData |
|||
self.saveCachedLocationToUserDefaults(locationData) |
|||
|
|||
// 通知Flutter |
|||
if let callback = flutterCallback { |
|||
let result: [String: Any] = [ |
|||
"user_location": address, |
|||
"user_lat": String(location.coordinate.latitude), |
|||
"user_lng": String(location.coordinate.longitude) |
|||
] |
|||
callback(.success(result)) |
|||
} |
|||
|
|||
// 通知其他iOS服务 |
|||
self.serviceCallbacks.forEach { callback in |
|||
callback.onLocationSuccess( |
|||
latitude: location.coordinate.latitude, |
|||
longitude: location.coordinate.longitude, |
|||
address: address |
|||
) |
|||
} |
|||
|
|||
// 清空服务回调列表(单次定位) |
|||
self.serviceCallbacks.removeAll() |
|||
} |
|||
} else { |
|||
let errorMessage = error?.localizedDescription ?? "未知错误" |
|||
print("\(LocationService.TAG): 定位失败: \(errorMessage)") |
|||
|
|||
// 通知Flutter |
|||
if let callback = flutterCallback { |
|||
callback(.failure(NSError(domain: "LocationService", code: -1, userInfo: [NSLocalizedDescriptionKey: "定位失败: \(errorMessage)"]))) |
|||
} |
|||
|
|||
// 通知其他iOS服务 |
|||
serviceCallbacks.forEach { callback in |
|||
callback.onLocationError(errorCode: -1, errorMessage: errorMessage) |
|||
} |
|||
|
|||
// 清空服务回调列表 |
|||
serviceCallbacks.removeAll() |
|||
} |
|||
} |
|||
} |
|||
|
|||
// MARK: - CLLocationManagerDelegate |
|||
extension LocationService: CLLocationManagerDelegate { |
|||
public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { |
|||
guard let location = locations.last else { return } |
|||
handleLocationResult(location, error: nil) |
|||
} |
|||
|
|||
public func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { |
|||
handleLocationResult(nil, error: error) |
|||
} |
|||
|
|||
public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { |
|||
print("\(LocationService.TAG): 定位权限状态变更: \(status.rawValue)") |
|||
|
|||
switch status { |
|||
case .authorizedWhenInUse, .authorizedAlways: |
|||
if !initialized { |
|||
initialize() |
|||
} |
|||
permissionRequestCallback?(.success(["granted": true])) |
|||
permissionRequestCallback = nil |
|||
case .denied, .restricted: |
|||
permissionRequestCallback?(.success(["granted": false])) |
|||
permissionRequestCallback = nil |
|||
case .notDetermined: |
|||
break |
|||
@unknown default: |
|||
break |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,72 @@ |
|||
import Foundation |
|||
|
|||
#if canImport(Flutter) |
|||
import Flutter |
|||
import UIKit |
|||
|
|||
public class LocationServicePlugin: NSObject, FlutterPlugin { |
|||
private static var channel: FlutterMethodChannel? |
|||
|
|||
public static func register(with registrar: FlutterPluginRegistrar) { |
|||
let channel = FlutterMethodChannel(name: "com.yunqiinnovation.location_service", binaryMessenger: registrar.messenger()) |
|||
let instance = LocationServicePlugin() |
|||
|
|||
registrar.addMethodCallDelegate(instance, channel: channel) |
|||
self.channel = channel |
|||
instance.addStartLocationMonitor() |
|||
} |
|||
|
|||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { |
|||
switch call.method { |
|||
case "location": |
|||
result(nil) |
|||
case "initialize": |
|||
LocationService.shared.initialize() |
|||
result(nil) |
|||
case "getCurrentLocation": |
|||
LocationService.shared.getCurrentLocation { locationResult in |
|||
switch locationResult { |
|||
case .success(let locationInfo): |
|||
result(locationInfo) |
|||
case .failure(let error): |
|||
result(FlutterError(code: "LOCATION_ERROR", message: error.localizedDescription, details: nil)) |
|||
} |
|||
} |
|||
case "checkPermission": |
|||
LocationService.shared.checkLocationPermission { permissionResult in |
|||
switch permissionResult { |
|||
case .success(let permissions): |
|||
result(permissions) |
|||
case .failure(let error): |
|||
result(FlutterError(code: "PERMISSION_ERROR", message: error.localizedDescription, details: nil)) |
|||
} |
|||
} |
|||
case "requestPermission": |
|||
LocationService.shared.requestLocationPermission { permissionResult in |
|||
switch permissionResult { |
|||
case .success(let permissions): |
|||
result(permissions) |
|||
case .failure(let error): |
|||
result(FlutterError(code: "PERMISSION_ERROR", message: error.localizedDescription, details: nil)) |
|||
} |
|||
} |
|||
case "stop": |
|||
LocationService.shared.stop() |
|||
result(nil) |
|||
default: |
|||
result(FlutterMethodNotImplemented) |
|||
} |
|||
} |
|||
|
|||
private func addStartLocationMonitor() { |
|||
NotificationCenter.default.addObserver( |
|||
forName: .locationStartEvent, |
|||
object: nil, |
|||
queue: .main |
|||
) { notification in |
|||
print("📥 收到启动定位服务事件") |
|||
LocationService.shared.initialize() |
|||
} |
|||
} |
|||
} |
|||
#endif |
|||
Loading…
Reference in new issue