同步相册云盘界面并完善相关交互
This commit is contained in:
@ -10,6 +10,8 @@ import UIKit
|
||||
|
||||
/// 附近风险地图页面,展示当前位置、疑似打野、处理中线索和内部摄影师标记。
|
||||
final class WildReportRiskMapViewController: BaseViewController {
|
||||
private static let cachedNavigationAppKey = "wildReportRiskMap.cachedNavigationApp"
|
||||
|
||||
private let viewModel: WildReportRiskMapViewModel
|
||||
private let api: any WildPhotographerReportServing
|
||||
private let locationProvider: any LocationProviding
|
||||
@ -907,6 +909,10 @@ final class WildReportRiskMapViewController: BaseViewController {
|
||||
return
|
||||
}
|
||||
guard let target = viewModel.navigateToSelectedMarker() else { return }
|
||||
if let cachedOption = cachedNavigationOption(for: target) {
|
||||
openNavigation(cachedOption, cacheSelection: false)
|
||||
return
|
||||
}
|
||||
presentNavigationOptions(for: target)
|
||||
}
|
||||
|
||||
@ -930,7 +936,7 @@ final class WildReportRiskMapViewController: BaseViewController {
|
||||
let alert = UIAlertController(title: "选择导航软件", message: target.title, preferredStyle: .actionSheet)
|
||||
options.forEach { option in
|
||||
alert.addAction(UIAlertAction(title: option.title, style: .default) { [weak self] _ in
|
||||
self?.openNavigation(option)
|
||||
self?.openNavigation(option, cacheSelection: true)
|
||||
})
|
||||
}
|
||||
alert.addAction(UIAlertAction(title: "取消", style: .cancel))
|
||||
@ -942,43 +948,71 @@ final class WildReportRiskMapViewController: BaseViewController {
|
||||
}
|
||||
|
||||
private func availableNavigationOptions(for target: WildReportMapMarker) -> [WildReportNavigationOption] {
|
||||
[
|
||||
WildReportNavigationOption(title: "Apple 地图", url: navigationURL(for: .apple, target: target)),
|
||||
WildReportNavigationOption(title: "高德地图", url: navigationURL(for: .amap, target: target)),
|
||||
WildReportNavigationOption(title: "百度地图", url: navigationURL(for: .baidu, target: target)),
|
||||
WildReportNavigationOption(title: "腾讯地图", url: navigationURL(for: .tencent, target: target)),
|
||||
WildReportNavigationOption(title: "Google Maps", url: navigationURL(for: .google, target: target))
|
||||
].compactMap { option in
|
||||
guard option.url != nil else { return nil }
|
||||
WildReportNavigationApp.allCases.compactMap { app in
|
||||
guard let option = navigationOption(for: app, target: target) else { return nil }
|
||||
guard isNavigationOptionAvailable(option) else { return nil }
|
||||
return option
|
||||
}
|
||||
}
|
||||
|
||||
private func openNavigation(_ option: WildReportNavigationOption) {
|
||||
private func cachedNavigationOption(for target: WildReportMapMarker) -> WildReportNavigationOption? {
|
||||
guard let rawValue = UserDefaults.standard.string(forKey: Self.cachedNavigationAppKey),
|
||||
let app = WildReportNavigationApp(rawValue: rawValue),
|
||||
let option = navigationOption(for: app, target: target),
|
||||
isNavigationOptionAvailable(option)
|
||||
else {
|
||||
UserDefaults.standard.removeObject(forKey: Self.cachedNavigationAppKey)
|
||||
return nil
|
||||
}
|
||||
return option
|
||||
}
|
||||
|
||||
private func navigationOption(for app: WildReportNavigationApp, target: WildReportMapMarker) -> WildReportNavigationOption? {
|
||||
WildReportNavigationOption(
|
||||
app: app,
|
||||
title: app.title,
|
||||
url: navigationURL(for: app, target: target),
|
||||
requiresAvailabilityCheck: app.requiresAvailabilityCheck
|
||||
)
|
||||
}
|
||||
|
||||
private func isNavigationOptionAvailable(_ option: WildReportNavigationOption) -> Bool {
|
||||
guard let url = option.url else { return false }
|
||||
return !option.requiresAvailabilityCheck || UIApplication.shared.canOpenURL(url)
|
||||
}
|
||||
|
||||
private func openNavigation(_ option: WildReportNavigationOption, cacheSelection: Bool) {
|
||||
guard let url = option.url else { return }
|
||||
UIApplication.shared.open(url) { [weak self] success in
|
||||
guard !success else { return }
|
||||
guard success else {
|
||||
UserDefaults.standard.removeObject(forKey: Self.cachedNavigationAppKey)
|
||||
Task { @MainActor in
|
||||
self?.showToast("无法打开\(option.title)")
|
||||
}
|
||||
return
|
||||
}
|
||||
guard cacheSelection else { return }
|
||||
Task { @MainActor in
|
||||
self?.showToast("未安装\(option.title)或无法打开")
|
||||
UserDefaults.standard.set(option.app.rawValue, forKey: Self.cachedNavigationAppKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func navigationURL(for app: WildReportNavigationApp, target: WildReportMapMarker) -> URL? {
|
||||
let latitude = target.coordinate.latitude
|
||||
let longitude = target.coordinate.longitude
|
||||
let destLat = target.coordinate.latitude
|
||||
let destLon = target.coordinate.longitude
|
||||
let name = encodedNavigationText(target.title)
|
||||
switch app {
|
||||
case .apple:
|
||||
return URL(string: "http://maps.apple.com/?daddr=\(latitude),\(longitude)&dirflg=d&q=\(name)")
|
||||
return URL(string: "http://maps.apple.com/?daddr=\(destLat),\(destLon)&dirflg=d")
|
||||
case .amap:
|
||||
return URL(string: "iosamap://path?sourceApplication=suixinkan&dlat=\(latitude)&dlon=\(longitude)&dname=\(name)&dev=0&t=0")
|
||||
return URL(string: "iosamap://path?sourceApplication=suixinkan&dlat=\(destLat)&dlon=\(destLon)&dname=\(name)&dev=0&t=0")
|
||||
case .baidu:
|
||||
return URL(string: "baidumap://map/direction?destination=latlng:\(latitude),\(longitude)|name:\(name)&mode=driving&coord_type=wgs84")
|
||||
return URL(string: "baidumap://map/direction?destination=latlng:\(destLat),\(destLon)|name:\(name)&mode=driving&coord_type=wgs84")
|
||||
case .tencent:
|
||||
return URL(string: "qqmap://map/routeplan?type=drive&tocoord=\(latitude),\(longitude)&to=\(name)&referer=suixinkan")
|
||||
return URL(string: "qqmap://map/routeplan?type=drive&tocoord=\(destLat),\(destLon)&to=\(name)&referer=suixinkan")
|
||||
case .google:
|
||||
return URL(string: "comgooglemaps://?daddr=\(latitude),\(longitude)&directionsmode=driving")
|
||||
return URL(string: "comgooglemaps://?daddr=\(destLat),\(destLon)&directionsmode=driving")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1022,17 +1056,40 @@ final class WildReportRiskMapViewController: BaseViewController {
|
||||
}
|
||||
}
|
||||
|
||||
/// 风险地图导航软件选项。
|
||||
private struct WildReportNavigationOption {
|
||||
let app: WildReportNavigationApp
|
||||
let title: String
|
||||
let url: URL?
|
||||
let requiresAvailabilityCheck: Bool
|
||||
}
|
||||
|
||||
private enum WildReportNavigationApp {
|
||||
/// 风险地图支持打开的导航软件。
|
||||
private enum WildReportNavigationApp: String, CaseIterable {
|
||||
case apple
|
||||
case amap
|
||||
case baidu
|
||||
case tencent
|
||||
case google
|
||||
|
||||
var title: String {
|
||||
switch self {
|
||||
case .apple:
|
||||
return "Apple 地图"
|
||||
case .amap:
|
||||
return "高德地图"
|
||||
case .baidu:
|
||||
return "百度地图"
|
||||
case .tencent:
|
||||
return "腾讯地图"
|
||||
case .google:
|
||||
return "Google Maps"
|
||||
}
|
||||
}
|
||||
|
||||
var requiresAvailabilityCheck: Bool {
|
||||
self != .apple
|
||||
}
|
||||
}
|
||||
|
||||
extension WildReportRiskMapViewController: MKMapViewDelegate {
|
||||
|
||||
Reference in New Issue
Block a user