diff --git a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift index 6283446dc..6b2415e07 100644 --- a/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift +++ b/local_plugins/agent_service/ios/agent_service/Sources/agent_service/AgentServiceImpl.swift @@ -1,4 +1,5 @@ import Foundation +import UIKit import AVFoundation import ble_service import location_service @@ -856,7 +857,8 @@ private func handleJSONDictionary(_ jsonDict: [String: Any], toolName: String) - if let cardMusiclist = jsonDict["data"] as? [[String: Any]], toolName == "music_searchandplay_songs" { processMusicListCard(cardMusiclist) } else if let cardNavigation = jsonDict["card_navigation"] as? [String: Any] { - processNavigationCard(cardNavigation) + let isinternal = processNavigationCard(cardNavigation) + metadata["isinternal"] = isinternal } else if let cardQQMusiclist = jsonDict["data"] as? [[String: Any]], toolName == "qqmusic_searchandplay_songs" { processQQMusicPlayList(cardQQMusiclist) } else if toolName == "maps_weather" { @@ -982,11 +984,293 @@ private func jsonToString(_ json: [String: Any]) -> String? { } // 处理导航卡片 - private func processNavigationCard(_ cardNavigation: [String: Any]) { + private func processNavigationCard(_ cardNavigation: [String: Any]) -> Bool { let start = cardNavigation["start"] as? String ?? "" - let end = cardNavigation["end"] as? String ?? "" - // 实际处理导航逻辑 - print("启动导航: 从 \(start) 到 \(end)") + let destination = cardNavigation["end"] as? String ?? "" + let endlatitude = cardNavigation["endlatitude"] as? String ?? "" + let endlongitude = cardNavigation["endlongitude"] as? String ?? "" + let mode = cardNavigation["mode"] as? String ?? "driving" + + print("启动导航: 从 \(start) 到 \(destination), 坐标: \(endlatitude),\(endlongitude), 模式: \(mode)") + + // 根据导航模式选择不同的导航方式 + switch mode { + case "internal_gaode": + // 使用内置高德导航 + // startInternalNavigation(start: start, destination: destination, + // latitude: endlatitude, longitude: endlongitude, mode: mode) + return true + case "external_baidu": + // 使用外部百度地图 + openBaiduMap(destination: destination, latitude: endlatitude, + longitude: endlongitude, mode: mode) + return false + case "external_gaode": + // 使用外部高德地图 + openGaodeMap(destination: destination, latitude: endlatitude, + longitude: endlongitude, mode: mode) + return false + case "external_google": + // 使用外部谷歌地图 + openGoogleMap(destination: destination, mode: mode) + return false + default: + // 默认使用自动选择 + return autoSelectNavigation(start: start, destination: destination, + latitude: endlatitude, longitude: endlongitude, mode: mode) + } + } + + // 启动内置高德导航 + private func startInternalNavigation(start: String, destination: String, + latitude: String, longitude: String, mode: String) { + // 发送导航事件通知 + NotificationCenter.default.post(name: .navigationdEvent, object: nil, userInfo: [ + "start": start, + "destination": destination, + "latitude": latitude, + "longitude": longitude, + "mode": mode + ]) + print("启动内置导航: 从 \(start) 到 \(destination)") + } + + // 打开百度地图 + private func openBaiduMap(destination: String, latitude: String, longitude: String, mode: String) { + guard let bundleId = Bundle.main.bundleIdentifier else { + print("无法获取应用包名") + return + } + + let src = "ios.\(bundleId)" + + // 百度地图导航模式映射 + let baiduMode: String + switch mode { + case "transit": + baiduMode = "transit" // 公交 + case "walking": + baiduMode = "walking" // 步行 + case "cycling": + baiduMode = "riding" // 骑行 + case "driving": + fallthrough + default: + baiduMode = "driving" // 驾车 + } + + var components = URLComponents() + components.scheme = "baidumap" + components.host = "map" + components.path = "/direction" + components.queryItems = [ + URLQueryItem(name: "destination", value: "name:\(destination)|latlng:\(latitude),\(longitude)"), + URLQueryItem(name: "coord_type", value: "gcj02"), + URLQueryItem(name: "mode", value: baiduMode), + URLQueryItem(name: "src", value: src) + ] + + guard let url = components.url else { + print("构建百度地图URL失败") + return + } + + print("百度导航链接: \(url.absoluteString)") + + if UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url, options: [:]) { success in + if success { + print("成功打开百度地图") + } else { + print("打开百度地图失败") + } + } + } else { + print("百度地图未安装") + // 可以在这里添加提示用户安装百度地图的逻辑 + } + } + + // 打开高德地图 + private func openGaodeMap(destination: String, latitude: String, longitude: String, mode: String) { + guard let bundleId = Bundle.main.bundleIdentifier else { + print("无法获取应用包名") + return + } + + let src = "ios.\(bundleId)" + + // 导航模式映射 + let gaodeMode: String + switch mode { + case "transit": + gaodeMode = "1" // 公交 + case "walking": + gaodeMode = "2" // 步行 + case "cycling": + gaodeMode = "3" // 骑行 + case "driving": + fallthrough + default: + gaodeMode = "0" // 驾车 + } + + var components = URLComponents() + components.scheme = "amapuri" + components.host = "route" + components.path = "/plan" + components.queryItems = [ + URLQueryItem(name: "dlat", value: latitude), + URLQueryItem(name: "dlon", value: longitude), + URLQueryItem(name: "dname", value: destination), + URLQueryItem(name: "dev", value: "0"), // 0: gcj02 + URLQueryItem(name: "t", value: gaodeMode), + URLQueryItem(name: "sourceApplication", value: src) + ] + + guard let url = components.url else { + print("构建高德地图URL失败") + return + } + + print("高德导航链接: \(url.absoluteString)") + + if UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url, options: [:]) { success in + if success { + print("成功打开高德地图") + } else { + print("打开高德地图失败") + } + } + } else { + print("高德地图未安装") + // 可以在这里添加提示用户安装高德地图的逻辑 + } + } + + // 打开谷歌地图 + private func openGoogleMap(destination: String, mode: String) { + // 方案1: 尝试使用Google Maps应用的URL scheme + var components = URLComponents() + components.scheme = "comgooglemaps" + components.queryItems = [ + URLQueryItem(name: "saddr", value: "Current Location"), + URLQueryItem(name: "daddr", value: destination), + URLQueryItem(name: "directionsmode", value: mode) + ] + + if let appUrl = components.url, UIApplication.shared.canOpenURL(appUrl) { + UIApplication.shared.open(appUrl, options: [:]) { success in + if success { + print("成功打开谷歌地图应用") + } else { + print("打开谷歌地图应用失败") + } + } + return + } + + // 方案2: 使用网页版谷歌地图 + let webUrlString = "https://www.google.com/maps/dir/?api=1&origin=Current+Location&destination=\(destination)&travelmode=\(mode)" + if let webUrl = URL(string: webUrlString) { + UIApplication.shared.open(webUrl, options: [:]) { success in + if success { + print("成功打开谷歌地图网页版") + } else { + print("打开谷歌地图网页版失败") + } + } + } + } + + // 打开苹果地图 + private func openAppleMap(destination: String, mode: String) { + var components = URLComponents() + components.scheme = "maps" + components.queryItems = [ + URLQueryItem(name: "daddr", value: destination), + URLQueryItem(name: "dirflg", value: mode == "driving" ? "d" : "r") // d=驾车, r=公交 + ] + + guard let url = components.url else { + print("构建苹果地图URL失败") + return + } + + if UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url, options: [:]) { success in + if success { + print("成功打开苹果地图") + } else { + print("打开苹果地图失败") + } + } + } else { + print("苹果地图不可用") + } + } + + // 自动选择导航应用 + private func autoSelectNavigation(start: String, destination: String, + latitude: String, longitude: String, mode: String) -> Bool { + // 1. 优先尝试百度地图 + if canOpenBaiduMap() { + print("自动选择:使用百度地图") + openBaiduMap(destination: destination, latitude: latitude, longitude: longitude, mode: mode) + return false + } + + // 2. 其次尝试高德地图 + if canOpenGaodeMap() { + print("自动选择:使用高德地图") + openGaodeMap(destination: destination, latitude: latitude, longitude: longitude, mode: mode) + return false + } + + // 3. 然后尝试谷歌地图 + if canOpenGoogleMap() { + print("自动选择:使用谷歌地图") + openGoogleMap(destination: destination, mode: mode) + return false + } + + // 4. 尝试苹果地图 + if canOpenAppleMap() { + print("自动选择:使用苹果地图") + openAppleMap(destination: destination, mode: mode) + return false + } + + // 5. 最后尝试内置高德导航 + print("自动选择:使用内置导航") + // startInternalNavigation(start: start, destination: destination, + // latitude: latitude, longitude: longitude, mode: mode) + return true + } + + // 检查是否可以打开百度地图 + private func canOpenBaiduMap() -> Bool { + guard let url = URL(string: "baidumap://") else { return false } + return UIApplication.shared.canOpenURL(url) + } + + // 检查是否可以打开高德地图 + private func canOpenGaodeMap() -> Bool { + guard let url = URL(string: "amapuri://") else { return false } + return UIApplication.shared.canOpenURL(url) + } + + // 检查是否可以打开谷歌地图 + private func canOpenGoogleMap() -> Bool { + guard let url = URL(string: "comgooglemaps://") else { return false } + return UIApplication.shared.canOpenURL(url) + } + + // 检查是否可以打开苹果地图 + private func canOpenAppleMap() -> Bool { + guard let url = URL(string: "maps://") else { return false } + return UIApplication.shared.canOpenURL(url) } // 后台播放单曲 @@ -1294,6 +1578,7 @@ class ChatApiStreamCallback: StreamCallback { private var responseBuilder = "" private var metadata = "" private var userMetadata:[String: Any] = [:] + private var iscard = false; private var reply = true; //是否回复 private var broadcast = true //是否播发 @@ -1443,15 +1728,19 @@ class ChatApiStreamCallback: StreamCallback { metadata = resultmap["meta"] as? String ?? "" broadcast = resultmap["broadcast"] as? Bool ?? true reply = !(resultmap["notreply"] as? Bool ?? true) - agentService.sendEvent(name: "function_call_result", data: [ - "function_call": functionCall, - "result": functionCallResult, - "meta":metadata, - ]) - os_log("收到函数调用结果! broadcast: %{public}@ reply: %{public}@ %{metadata}@", - log: agentService.logger, - type: .info, - "\(broadcast)", "\(reply)", "\(metadata)") + iscard = !(resultmap["iscard"] as? Bool ?? false) + if (iscard){ + agentService.sendEvent(name: "function_call_result", data: [ + "function_call": functionCall, + "result": functionCallResult, + "meta":metadata, + ]) + os_log("收到函数调用结果! broadcast: %{public}@ reply: %{public}@ %{metadata}@", + log: agentService.logger, + type: .info, + "\(broadcast)", "\(reply)", "\(metadata)") + } + }catch{ print("liwei--------------- AI Call onFunctionCallResult 异常: \(error)") }