diff --git a/QuickLocation.xcodeproj/project.pbxproj b/QuickLocation.xcodeproj/project.pbxproj
index e0f7cc3..69ecfd8 100644
--- a/QuickLocation.xcodeproj/project.pbxproj
+++ b/QuickLocation.xcodeproj/project.pbxproj
@@ -2166,7 +2166,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 1.0;
+ MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = cn.zuomeng.jisuloca;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2218,7 +2218,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 1.0;
+ MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = cn.zuomeng.jisuloca;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
diff --git a/QuickLocation/AppDelegate.swift b/QuickLocation/AppDelegate.swift
index f54eb49..4dcf1a4 100644
--- a/QuickLocation/AppDelegate.swift
+++ b/QuickLocation/AppDelegate.swift
@@ -19,6 +19,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
+ UIFont.loadFontName("douyu.otf")
+ UIFont.loadFontName("zihunbiantaoti-r.ttf")
setupLocation()
ApiManager.shared.setup()
AppRouter.shared.setup()
diff --git a/QuickLocation/Core/Extension/UIFont+Extension.swift b/QuickLocation/Core/Extension/UIFont+Extension.swift
index 536ff3a..f0c595c 100644
--- a/QuickLocation/Core/Extension/UIFont+Extension.swift
+++ b/QuickLocation/Core/Extension/UIFont+Extension.swift
@@ -34,7 +34,7 @@ public extension UIFont {
/// 加载本地自定义字体
/// - Parameter name: 字体文件名称
- private static func loadFontName(_ fileName: String) -> String? {
+ public static func loadFontName(_ fileName: String) -> String? {
// 字体文件资源路径
guard let fontURL = Bundle.main.url(forResource: fileName, withExtension: nil),
let data = try? Data(contentsOf: fontURL),
diff --git a/QuickLocation/Info.plist b/QuickLocation/Info.plist
index ef187a1..ee972bb 100644
--- a/QuickLocation/Info.plist
+++ b/QuickLocation/Info.plist
@@ -40,6 +40,8 @@
NSAllowsArbitraryLoads
+ NSContactsUsageDescription
+ 需要访问您的通讯录以导入联系人号码
UIAppFonts
douyu.otf
diff --git a/QuickLocation/Manager/Account/UserConfigModel.swift b/QuickLocation/Manager/Account/UserConfigModel.swift
index 7360d10..48270d9 100644
--- a/QuickLocation/Manager/Account/UserConfigModel.swift
+++ b/QuickLocation/Manager/Account/UserConfigModel.swift
@@ -70,6 +70,8 @@ struct SystemConfigModel: Mappable {
var timeConfig: PopupWindowTimeModel?
/// 微信分享配置
var shareConfig: WxShareConfigModel?
+ /// 版本更新
+ var versionUpgradeModel: VersionUpgradeModel?
/// 聊天界面的警告说明
var chatWarning: String = ""
@@ -100,6 +102,7 @@ struct SystemConfigModel: Mappable {
shareConfig <- map["client.weixin.share", nested: false]
guideDisplay <- map["client.guide_display", nested: false]
globalDisplay <- map["client.global_display", nested: false]
+ versionUpgradeModel <- map["client.version.upgrade", nested: false]
}
}
@@ -173,3 +176,32 @@ struct WxShareConfigModel: Mappable {
image <- map["image"]
}
}
+
+struct VersionUpgradeModel: Mappable {
+ /// 下载地址
+ var url: String = ""
+
+ /// 标题
+ var title: String = ""
+
+ /// 内容
+ var description: String = ""
+
+ /// 版本
+ var version: String = ""
+
+ /// 强制更新
+ var force: Bool = false
+
+ init?(map: Map) {
+
+ }
+
+ mutating func mapping(map: Map) {
+ url <- map["url"]
+ title <- map["title"]
+ description <- map["description"]
+ force <- map["force"]
+ version <- map["version"]
+ }
+}
diff --git a/QuickLocation/Manager/App/ApiManager.swift b/QuickLocation/Manager/App/ApiManager.swift
index 743265b..6278af9 100644
--- a/QuickLocation/Manager/App/ApiManager.swift
+++ b/QuickLocation/Manager/App/ApiManager.swift
@@ -111,7 +111,7 @@ extension ApiManager {
case GatewayStatusCode.userLoginExpair.rawValue: // token失效
handleTokenExpired(msg: message)
case GatewayStatusCode.failure.rawValue, GatewayStatusCode.noAuthority.rawValue: // 退出当前界面
- handlePopView(message)
+ handlePopView(message, handle)
default:
// 接口没返回code的时候取success字段
if success != nil {
@@ -171,8 +171,9 @@ extension ApiManager {
}
// MARK: - 业务中断(需退出当前页面)
- private func handlePopView(_ msg: String?) {
+ private func handlePopView(_ msg: String?, _ handle: Bool) {
MainAsync {
+ guard handle else { return }
DLToast.showInfo(text: msg ?? "Error...") {
guard let viewController = UIViewController.currentViewController() else { return }
viewController.navigationController?.popViewController(animated: true)
diff --git a/QuickLocation/Manager/App/AppCacheManager.swift b/QuickLocation/Manager/App/AppCacheManager.swift
index 41165d7..e478586 100644
--- a/QuickLocation/Manager/App/AppCacheManager.swift
+++ b/QuickLocation/Manager/App/AppCacheManager.swift
@@ -23,14 +23,8 @@ final class AppCacheManager {
let fullPath = path + "/" + subPath
var isDir: ObjCBool = false
if manager.fileExists(atPath: fullPath, isDirectory: &isDir) {
- if isDir.boolValue {
- totalSize += folderSize(at: fullPath)
- } else {
- // 读取文件属性,失败则跳过
- if let attrs = try? manager.attributesOfItem(atPath: fullPath) {
- totalSize += attrs[.size] as? Int64 ?? 0
- }
- }
+ if isDir.boolValue { continue }
+ totalSize += (try? manager.attributesOfItem(atPath: fullPath))?[.size] as? Int64 ?? 0
}
}
return totalSize
diff --git a/QuickLocation/Manager/App/Authorize.swift b/QuickLocation/Manager/App/Authorize.swift
index d41d41e..1446ceb 100644
--- a/QuickLocation/Manager/App/Authorize.swift
+++ b/QuickLocation/Manager/App/Authorize.swift
@@ -13,6 +13,7 @@ import UserNotifications
import AdSupport
import AppTrackingTransparency
import URLNavigator
+import Contacts
// MARK: - AuthorizeType
@@ -112,6 +113,8 @@ public protocol AuthorizeProtocol {
return AuthorizeMicrophone()
case .tracking:
return AuthorizeTracking()
+ case .contacts:
+ return AuthorizeContacts()
default:
return nil
}
@@ -402,4 +405,26 @@ class AuthorizeTracking: NSObject, AuthorizeProtocol {
}
}
+// MARK: - AuthorizeContacts
+private class AuthorizeContacts: NSObject, AuthorizeProtocol {
+ func authorizeStatus() -> AuthorizeStatus {
+ switch CNContactStore.authorizationStatus(for: .contacts) {
+ case .restricted:
+ return .restricted
+ case .denied:
+ return .denied
+ case .authorized:
+ return .authorized
+ default:
+ return .notDetermined
+ }
+ }
+
+ func authorize(_ completion: ((AuthorizeStatus) -> Void)?) {
+ CNContactStore().requestAccess(for: .contacts) { _, _ in
+ DispatchQueue.main.async { completion?(self.authorizeStatus()) }
+ }
+ }
+}
+
diff --git a/QuickLocation/Section/Group/GroupMemberList/ItineraryTraceVC.swift b/QuickLocation/Section/Group/GroupMemberList/ItineraryTraceVC.swift
index 98b7264..fb206d3 100644
--- a/QuickLocation/Section/Group/GroupMemberList/ItineraryTraceVC.swift
+++ b/QuickLocation/Section/Group/GroupMemberList/ItineraryTraceVC.swift
@@ -20,7 +20,6 @@ class ItineraryTraceVC: BaseViewController {
private let memberModel: GroupMemberModel
private var routeOverlays: [MAPolyline] = []
private let routeSearch = AMapSearchAPI()
- private var drivingSegmentIndexes: [ObjectIdentifier: Int] = [:]
private var playbackSegments: [[CLLocationCoordinate2D]?] = []
private var playbackPath: [(coordinate: CLLocationCoordinate2D, distance: Double)] = []
private var playbackTotalDistance: Double = 0
@@ -41,10 +40,6 @@ class ItineraryTraceVC: BaseViewController {
private var playbackTargetCoordinate: CLLocationCoordinate2D?
private let minPointDistance: CLLocationDistance = 10
- private let directSegmentDistance: CLLocationDistance = 80
- private let maxDrivingSegmentDistance: CLLocationDistance = 1500
- private let maxDrivingSegmentTimeGap: Int64 = 5 * 60 * 1000
- private let maxDrivingSegmentRequests = 40
private let eventCalloutTag = 91301
override func loadView() {
@@ -146,32 +141,38 @@ class ItineraryTraceVC: BaseViewController {
let points = cleanedTracePoints(model.trajectory_path)
guard points.count >= 2 else { print("[trace] insufficient points: \(points.count)"); return }
- playbackSegments = Array(repeating: nil, count: points.count - 1)
+ playbackSegments = []
- var drivingRequestCount = 0
- for i in 0..<(points.count - 1) {
- let from = points[i]
- let to = points[i + 1]
- let fallback = [from.coordinate, to.coordinate]
- let distance = from.coordinate.distance(to: to.coordinate)
- let timeGap = abs(to.timestamp - from.timestamp)
-
- if distance < directSegmentDistance {
- addPolyline(fallback)
- playbackSegments[i] = fallback
- } else if distance <= maxDrivingSegmentDistance,
- timeGap <= maxDrivingSegmentTimeGap,
- drivingRequestCount < maxDrivingSegmentRequests {
- requestDrivingSegment(from: from.coordinate, to: to.coordinate, segmentIndex: i)
- drivingRequestCount += 1
+ var sampled: [(timestamp: Int64, coordinate: CLLocationCoordinate2D)] = []
+ for pt in points {
+ if let last = sampled.last {
+ if pt.timestamp - last.timestamp >= 5_000 {
+ sampled.append(pt)
+ }
} else {
- // 断档或距离异常的轨迹段不绘制,避免把事件点/异常点直接连到终点。
- continue
+ sampled.append(pt)
}
}
+
+ let coords = sampled.map { $0.coordinate }
+ addPolyline(coords)
+ playbackSegments = [coords]
buildPlaybackPath()
updatePlaybackAnnotation(progress: playbackProgress)
- print("[trace] cleaned=\(points.count) drivingRequests=\(drivingRequestCount)")
+
+// let middle = sampled.dropFirst().dropLast().prefix(16)
+// let waypoints = middle.map { $0.coordinate }
+//
+// let request = AMapDrivingRouteSearchRequest()
+// request.origin = AMapGeoPoint.location(withLatitude: CGFloat(points.first!.coordinate.latitude), longitude: CGFloat(points.first!.coordinate.longitude))
+// request.destination = AMapGeoPoint.location(withLatitude: CGFloat(points.last!.coordinate.latitude), longitude: CGFloat(points.last!.coordinate.longitude))
+// request.strategy = 0
+// if !waypoints.isEmpty {
+// request.waypoints = waypoints.map { AMapGeoPoint.location(withLatitude: CGFloat($0.latitude), longitude: CGFloat($0.longitude)) }
+// }
+// routeSearch?.aMapDrivingRouteSearch(request)
+
+ print("[trace] cleaned=\(points.count) sampled=\(sampled.count)")
}
private func buildPlaybackPath() {
@@ -198,7 +199,6 @@ class ItineraryTraceVC: BaseViewController {
rootView.mapView.remove(overlay)
}
routeOverlays.removeAll()
- drivingSegmentIndexes.removeAll()
}
private func cleanedTracePoints(_ points: [TrackPoint]) -> [(timestamp: Int64, coordinate: CLLocationCoordinate2D)] {
@@ -222,15 +222,6 @@ class ItineraryTraceVC: BaseViewController {
return result
}
- private func requestDrivingSegment(from: CLLocationCoordinate2D, to: CLLocationCoordinate2D, segmentIndex: Int) {
- let request = AMapDrivingRouteSearchRequest()
- request.origin = AMapGeoPoint.location(withLatitude: CGFloat(from.latitude), longitude: CGFloat(from.longitude))
- request.destination = AMapGeoPoint.location(withLatitude: CGFloat(to.latitude), longitude: CGFloat(to.longitude))
- request.strategy = 0
- drivingSegmentIndexes[ObjectIdentifier(request)] = segmentIndex
- routeSearch?.aMapDrivingRouteSearch(request)
- }
-
private func setupPlaybackControls() {
rootView.playBtn.addTarget(self, action: #selector(playButtonTapped), for: .touchUpInside)
rootView.progressSlider.addTarget(self, action: #selector(progressSliderTouchDown), for: .touchDown)
@@ -567,29 +558,18 @@ extension ItineraryTraceVC: MAMapViewDelegate {
// MARK: - AMapSearchDelegate
extension ItineraryTraceVC: AMapSearchDelegate {
func onRouteSearchDone(_ request: AMapRouteSearchBaseRequest!, response: AMapRouteSearchResponse!) {
- let requestId = ObjectIdentifier(request)
- let segmentIndex = drivingSegmentIndexes.removeValue(forKey: requestId)
-
- guard let path = response.route?.paths?.first as? AMapPath else {
- return
- }
+ guard let path = response.route?.paths?.first as? AMapPath else { return }
let coords = coordinates(from: path)
- if coords.count > 1 {
- addPolyline(coords)
- if let segmentIndex, playbackSegments.indices.contains(segmentIndex) {
- playbackSegments[segmentIndex] = coords
- buildPlaybackPath()
- updatePlaybackAnnotation(progress: playbackProgress)
- }
- }
+ guard coords.count > 1 else { return }
+
+ addPolyline(coords)
+ playbackSegments = [coords]
+ buildPlaybackPath()
+ updatePlaybackAnnotation(progress: playbackProgress)
}
func aMapSearchRequest(_ request: Any!, didFailWithError error: Error!) {
- if let request = request as? AMapRouteSearchBaseRequest {
- let requestId = ObjectIdentifier(request)
- drivingSegmentIndexes.removeValue(forKey: requestId)
- }
print("Trace route search error: \(error.localizedDescription)")
}
}
diff --git a/QuickLocation/Section/Group/GroupView.swift b/QuickLocation/Section/Group/GroupView.swift
index 3ef97ee..4ae0833 100644
--- a/QuickLocation/Section/Group/GroupView.swift
+++ b/QuickLocation/Section/Group/GroupView.swift
@@ -188,6 +188,7 @@ class GroupView: UIView {
lazy var scanBtn: UIButton = {
let btn = UIButton(type: .custom)
btn.setImage(UIImage(named: "Group/scan"), for: .normal)
+ btn.isHidden = true
return btn
}()
diff --git a/QuickLocation/Section/Home/SearchLocation/SearchLocationResultVC.swift b/QuickLocation/Section/Home/SearchLocation/SearchLocationResultVC.swift
index 50a983d..f08f081 100644
--- a/QuickLocation/Section/Home/SearchLocation/SearchLocationResultVC.swift
+++ b/QuickLocation/Section/Home/SearchLocation/SearchLocationResultVC.swift
@@ -50,6 +50,14 @@ class SearchLocationResultVC: BaseViewController {
GroupChooseView.show(groupModel: model) { _ in }
}
}).disposed(by: disposeBag)
+
+ rootView.inviteBtn.rx.tap.subscribe(onNext: { _ in
+ guard let model = self.groupModel else {
+ self.requestGroupInfo(showPicker: true)
+ return
+ }
+ GroupChooseView.show(groupModel: model) { _ in }
+ }).disposed(by: disposeBag)
}
private func handleCode() {
diff --git a/QuickLocation/Section/Home/SearchLocation/SearchLocationVC.swift b/QuickLocation/Section/Home/SearchLocation/SearchLocationVC.swift
index 0204482..c88e7b7 100644
--- a/QuickLocation/Section/Home/SearchLocation/SearchLocationVC.swift
+++ b/QuickLocation/Section/Home/SearchLocation/SearchLocationVC.swift
@@ -28,6 +28,7 @@ class SearchLocationVC: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
+ fd_interactivePopDisabled = true
searchBtn.rx.tap.subscribe(onNext: { _ in
guard let phone = self.rootView.phoneInputTF.text, phone.isPhoneNumber else {
diff --git a/QuickLocation/Section/Home/SearchLocation/SearchLocationView.swift b/QuickLocation/Section/Home/SearchLocation/SearchLocationView.swift
index 673617d..15c0aa6 100644
--- a/QuickLocation/Section/Home/SearchLocation/SearchLocationView.swift
+++ b/QuickLocation/Section/Home/SearchLocation/SearchLocationView.swift
@@ -10,6 +10,9 @@ import RxSwift
import RxCocoa
import AVFoundation
import Lottie
+import Contacts
+import ContactsUI
+import URLNavigator
class SearchLocationView: UIView {
@@ -365,8 +368,22 @@ class SearchLocationView: UIView {
contactsBtn.titleLabel?.font = .systemFont(ofSize: 12, weight: .regular)
contactsBtn.setImage(UIImage(named: "SearchLocation/contacts"), for: .normal)
contactsBtn.extendEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 15)
- contactsBtn.rx.tap.subscribe(onNext: { _ in
- //TODO: - 通讯录
+ contactsBtn.rx.tap.subscribe(onNext: { [weak self] in
+ guard let self = self else { return }
+ self.phoneInputTF.resignFirstResponder()
+ let status = CNContactStore.authorizationStatus(for: .contacts)
+ switch status {
+ case .notDetermined:
+ CNContactStore().requestAccess(for: .contacts) { granted, _ in
+ DispatchQueue.main.async { if granted { self.presentContactPicker() } }
+ }
+ case .authorized:
+ self.presentContactPicker()
+ case .denied, .restricted:
+ DLToast.show(text: "请在设置中开启通讯录权限")
+ default:
+ break
+ }
}).disposed(by: disposeBag)
inputView.addSubview(contactsBtn)
contactsBtn.layoutChain
@@ -540,4 +557,20 @@ class SearchLocationView: UIView {
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
+
+ private func presentContactPicker() {
+ let picker = CNContactPickerViewController()
+ picker.delegate = self
+ picker.displayedPropertyKeys = [CNContactPhoneNumbersKey]
+ UIViewController.topMost?.present(picker, animated: true)
+ }
+}
+
+extension SearchLocationView: CNContactPickerDelegate {
+ func contactPicker(_ picker: CNContactPickerViewController, didSelect contact: CNContact) {
+ if let phone = contact.phoneNumbers.first?.value.stringValue {
+ phoneInputTF.text = phone.filter { $0.isNumber }
+ phoneInputTF.sendActions(for: .editingChanged)
+ }
+ }
}
diff --git a/QuickLocation/Section/Launch/LaunchViewController.swift b/QuickLocation/Section/Launch/LaunchViewController.swift
index eb36c7c..925ddb5 100644
--- a/QuickLocation/Section/Launch/LaunchViewController.swift
+++ b/QuickLocation/Section/Launch/LaunchViewController.swift
@@ -59,8 +59,14 @@ class LaunchViewController: BaseViewController {
guard let model = response.model else { return }
MQTTService.shared.connect()
Defaults[\.loginToken] = model.token
+
AppContextManager.shared.systemConfig = model.config
- self.getUserIMToken()
+
+ if let upgrade = model.config?.versionUpgradeModel {
+ self.showVersionUpgrade(upgrade, model: model)
+ return
+ }
+ self.continueAfterConfig(model: model)
}, onError: { [weak self] (error) in
DLAlert.show(title: error.localizedDescription,
defaultTitle: "重试") { [weak self] in
@@ -70,6 +76,31 @@ class LaunchViewController: BaseViewController {
}).disposed(by: disposeBag)
}
+ private func continueAfterConfig(model: UserConfigModel) {
+ model.temp ? self.navigateAfterDelay() : self.getUserIMToken()
+ }
+
+ private func showVersionUpgrade(_ upgrade: VersionUpgradeModel, model: UserConfigModel) {
+ self.showConfirmPop(
+ showCloseBtn: !upgrade.force,
+ title: upgrade.title + upgrade.version,
+ message: upgrade.description,
+ confirmText: "立即更新",
+ confirmBlock: {
+ if let url = URL(string: upgrade.url) {
+ UIApplication.shared.open(url)
+ }
+ if !upgrade.force {
+ self.continueAfterConfig(model: model)
+ }
+ },
+ cancelText: upgrade.force ? nil : "稍后再说",
+ cancelBlock: upgrade.force ? nil : { [weak self] in
+ self?.continueAfterConfig(model: model)
+ }
+ )
+ }
+
/// 获取用户IM Token
func getUserIMToken() {
UserService.imToken().subscribe(onNext: { response in
@@ -77,6 +108,8 @@ class LaunchViewController: BaseViewController {
AppContextManager.shared.imToken = token
GroupIMService.shared.login { _ in }
self.navigateAfterDelay()
+ }, onError: { [weak self] (error) in
+ self?.navigateAfterDelay()
}).disposed(by: disposeBag)
}
diff --git a/QuickLocation/Section/Login/LoginView.swift b/QuickLocation/Section/Login/LoginView.swift
index 4c80781..320af4d 100644
--- a/QuickLocation/Section/Login/LoginView.swift
+++ b/QuickLocation/Section/Login/LoginView.swift
@@ -243,7 +243,7 @@ class LoginView: UIView {
lazy var welcomeLabel: UILabel = {
let label = UILabel()
label.text = "欢迎登录"
- label.font = UIFont(name: "DOUYU Font", size: 24)
+ label.font = UIFont(name: "DOUYU Font", size: 24) ?? .systemFont(ofSize: 24, weight: .medium)
label.textColor = UIColor(hexStr: "#030303")
label.textAlignment = .center
return label
diff --git a/QuickLocation/Section/Login/OneTapLoginView.swift b/QuickLocation/Section/Login/OneTapLoginView.swift
index 20cfe52..4cf27e3 100644
--- a/QuickLocation/Section/Login/OneTapLoginView.swift
+++ b/QuickLocation/Section/Login/OneTapLoginView.swift
@@ -167,7 +167,7 @@ class OneTapLoginView: UIView {
lazy var welcomeLabel: UILabel = {
let label = UILabel()
label.text = "欢迎登录"
- label.font = UIFont(name: "DOUYU Font", size: 24)
+ label.font = UIFont(name: "DOUYU Font", size: 24) ?? .systemFont(ofSize: 24, weight: .medium)
label.textColor = UIColor(hexStr: "#030303")
label.textAlignment = .center
return label
diff --git a/QuickLocation/Section/Mine/Account/AccountVC.swift b/QuickLocation/Section/Mine/Account/AccountVC.swift
index 5c0e3b2..2013311 100644
--- a/QuickLocation/Section/Mine/Account/AccountVC.swift
+++ b/QuickLocation/Section/Mine/Account/AccountVC.swift
@@ -9,8 +9,10 @@ import UIKit
import RxSwift
import RxCocoa
import RxDataSources
+import Kingfisher
#if !targetEnvironment(simulator)
import GeYanSdk
+import RxGesture
#endif
class AccountVC: BaseViewController {
@@ -55,6 +57,12 @@ class AccountVC: BaseViewController {
self.deleteAccount()
}
}).disposed(by: disposeBag)
+
+ let tap = UITapGestureRecognizer(target: self, action: #selector(handleClearCacheTap))
+ rootView.clearView.addGestureRecognizer(tap)
+
+ let versionTap = UITapGestureRecognizer(target: self, action: #selector(handleVersionViewTap))
+ rootView.versionView.addGestureRecognizer(versionTap)
}
// MARK: - API
@@ -76,4 +84,42 @@ class AccountVC: BaseViewController {
DLToast.show(text: "申请成功")
}, onError: { _ in }).disposed(by: disposeBag)
}
+
+ @objc private func handleClearCacheTap() {
+ clearCache()
+ }
+
+ @objc private func handleVersionViewTap() {
+ guard let upgrade = AppContextManager.shared.systemConfig?.versionUpgradeModel else {
+ DLToast.show(text: "已是最新版本")
+ return
+ }
+ self.showConfirmPop(
+ showCloseBtn: !upgrade.force,
+ title: upgrade.title,
+ message: upgrade.description,
+ confirmText: "立即更新",
+ confirmBlock: {
+ if let url = URL(string: upgrade.url) {
+ UIApplication.shared.open(url)
+ }
+ },
+ cancelText: upgrade.force ? nil : "稍后再说",
+ cancelBlock: nil
+ )
+ }
+
+ private func clearCache() {
+ DLToast.showLoading()
+ KingfisherManager.shared.cache.clearMemoryCache()
+ KingfisherManager.shared.cache.clearDiskCache {
+ AppCacheManager.clearCache {
+ DispatchQueue.main.async {
+ DLToast.dismiss()
+ DLToast.show(text: "缓存已清除")
+ self.rootView.cacheLab.text = "0 B"
+ }
+ }
+ }
+ }
}
diff --git a/QuickLocation/Section/Mine/Account/AccountView.swift b/QuickLocation/Section/Mine/Account/AccountView.swift
index 8074661..f7cb443 100644
--- a/QuickLocation/Section/Mine/Account/AccountView.swift
+++ b/QuickLocation/Section/Mine/Account/AccountView.swift
@@ -238,7 +238,7 @@ class AccountView: UIView {
let titleLab = UILabel()
titleLab.text = "当前版本"
titleLab.font = .systemFont(ofSize: 14, weight: .medium)
- titleLab.textColor = UIColor(hexStr: "#1A1A1A")
+ titleLab.textColor = UIColor(hexStr: "#1A1A1A ")
view.addSubview(titleLab)
titleLab.layoutChain
.left(15)
diff --git a/QuickLocation/Section/Schedule/ScheduleViewed/ScheduleViewedView.swift b/QuickLocation/Section/Schedule/ScheduleViewed/ScheduleViewedView.swift
index 69900c6..fcad42e 100644
--- a/QuickLocation/Section/Schedule/ScheduleViewed/ScheduleViewedView.swift
+++ b/QuickLocation/Section/Schedule/ScheduleViewed/ScheduleViewedView.swift
@@ -156,6 +156,7 @@ class ScheduleViewedListCell: UITableViewCell {
.top(18)
.height(50)
.widthToHeight(1)
+ .bottom(18, relation: .greaterThanOrEqual)
nameLab.layoutChain
.topToView(iconView)
diff --git a/QuickLocation/Service/UserService.swift b/QuickLocation/Service/UserService.swift
index cbf535d..62c7bd2 100644
--- a/QuickLocation/Service/UserService.swift
+++ b/QuickLocation/Service/UserService.swift
@@ -36,7 +36,7 @@ struct UserService {
static func imToken() -> Observable {
let api = UserAPI.imToken.multiTarget
- return APIProvider.request(token: api)
+ return APIProvider.request(token: api, handle: false)
.map(ResponseModel.self)
.asObservable()
}