QSLHomeController.swift 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. //
  2. // QSLHomeController.swift
  3. // QuickSearchLocation
  4. //
  5. // Created by mac on 2024/4/10.
  6. //
  7. import UIKit
  8. import SwiftyJSON
  9. import MAMapKit
  10. import AMapFoundationKit
  11. import AMapLocationKit
  12. import YYText
  13. class QSLHomeController: QSLBaseController {
  14. lazy var viewModel: QSLHomeViewModel = {
  15. return QSLHomeViewModel()
  16. }()
  17. var personalModel: QSLUserModel = QSLUserModel()
  18. ///判断是不是第一次定位成功
  19. var isFirstLocatScuess : Bool = true
  20. var isFirstRequestLoc : Bool = false
  21. var isEnterSearchFriend : Bool = false
  22. // var friendList: [QSLUserModel] = [QSLUserModel]()
  23. override func viewDidLoad() {
  24. super.viewDidLoad()
  25. checkDialog()
  26. QSLTools.shared.requestShortcutItem()
  27. }
  28. func checkDialog(){
  29. if UserDefaults.standard.string(forKey: "FIRST_ENTER_LOCATION_HOMEPAGE") == nil{
  30. isFirstRequestLoc = true
  31. }
  32. dealWithMap();
  33. QSLTools.shared.isOpen = true
  34. if(QSLTools.shared.urlScheme.count > 0){
  35. if(isFirstRequestLoc){
  36. isEnterSearchFriend = true
  37. }
  38. QSLTools.shared.dealwithScheme(QSLTools.shared.urlScheme)
  39. return
  40. }
  41. //会员而且没有好友才弹出来
  42. if QSLBaseManager.shared.isVip() {
  43. QSLNetwork().request(.friendList(dict: [:])) { response in
  44. let list = response.mapArray(QSLUserModel.self, modelKey: "data>list")
  45. if(list.count == 0){
  46. self.showAddFriendView()
  47. }
  48. } fail: { code, error in
  49. }
  50. }else{
  51. let vc = QSLActivityVipVC()
  52. vc.modalPresentationStyle = .fullScreen
  53. self.present(vc, animated: false)
  54. vc.dismissHandler = {[weak self] isCancel in
  55. QSLGuideusersToCommentManager.commentShare.manageWhetherTriggerPopUpWindow(.nonMember){[weak self] in
  56. self?.showAddFriendView(hideBtnClosure: {[weak self] in
  57. DispatchQueue.main.async {
  58. self?.checkLocAgain();
  59. }
  60. })
  61. }
  62. }
  63. }
  64. //试用过期弹窗
  65. // QSLTrialExpireAlertView.alert(view: currentWindow, isOneBtn: true, oneBtnText: "继续支付", oneBtnClosure: { [weak self] in
  66. // QSLCountdownManager.shared.selectGood = yearGood
  67. // self?.unlockBtnAction()
  68. // QSEventHandle.eventPush(eventName: QSLGravityConst.new_vip_retention_click, eventProps: ["button":"continue_payment"])
  69. // },closeBtnClosure: {
  70. // QSEventHandle.eventPush(eventName: QSLGravityConst.new_vip_retention_click, eventProps: ["button":"close"])
  71. // })
  72. }
  73. func checkLocAgain(){
  74. homeMapLocationM.startUpdatingLocation()
  75. homeMapView.showsUserLocation = true
  76. homeMapView.userTrackingMode = .follow
  77. self.onceLocation()
  78. firstEnterLocationHomepage()
  79. }
  80. override func viewWillAppear(_ animated: Bool) {
  81. super.viewWillAppear(animated)
  82. if(self.isFirstRequestLoc && self.isEnterSearchFriend){
  83. self.isEnterSearchFriend = false
  84. self.checkLocAgain();
  85. }
  86. }
  87. func showAddFriendView(hideBtnClosure: @escaping () -> () = {}){
  88. if let currentWindow = UIApplication.keyWindow {
  89. QSLHomeAddFriendView.alert(view: currentWindow, clickBtnClosure: {[weak self] in
  90. QSLJumpManager.shared.pushToAdd(type: .homealert)
  91. self?.isEnterSearchFriend = true
  92. },hideBtnClosure: {
  93. hideBtnClosure()
  94. })
  95. }
  96. }
  97. func dealWithMap(){
  98. viewModel.initUIData()
  99. setUpMap()
  100. setUpUI()
  101. loadData()
  102. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLLogin, object: nil)
  103. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLLogout, object: nil)
  104. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLRefreshFriend, object: nil)
  105. NotificationCenter.default.addObserver(self, selector: #selector(loadData), name: QSLNotification.QSLRefreshRequest, object: nil)
  106. NotificationCenter.default.addObserver(self, selector: #selector(requestVip), name: QSLNotification.QSLRefreshMember, object: nil)
  107. //处理第一次进入首页定位
  108. if(isFirstRequestLoc){
  109. return
  110. }
  111. firstEnterLocationHomepage()
  112. }
  113. //处理第一次进入首页定位
  114. func firstEnterLocationHomepage() {
  115. guard UserDefaults.standard.string(forKey: "FIRST_ENTER_LOCATION_HOMEPAGE") != nil else {
  116. UserDefaults.standard.set("YES", forKey: "FIRST_ENTER_LOCATION_HOMEPAGE")
  117. UserDefaults.standard.synchronize()
  118. ///第一次进入埋点
  119. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_enter_first_homepage, eventProps: ["id": 03005])
  120. return
  121. }
  122. }
  123. /// 高德地图
  124. lazy var homeMapView = {
  125. let _mapView = MAMapView()
  126. _mapView.delegate = self
  127. _mapView.minZoomLevel = 7;
  128. _mapView.maxZoomLevel = 19;
  129. _mapView.zoomLevel = 17;
  130. _mapView.showsCompass = false
  131. _mapView.showsScale = false
  132. _mapView.isRotateCameraEnabled = false
  133. if(!isFirstRequestLoc){
  134. _mapView.showsUserLocation = true
  135. _mapView.userTrackingMode = .follow
  136. }
  137. // 关闭显示精度圈
  138. let represent = MAUserLocationRepresentation()
  139. represent.showsAccuracyRing = false
  140. _mapView.update(represent)
  141. let tap = UITapGestureRecognizer(target: self, action: #selector(mapTapAction))
  142. _mapView.addGestureRecognizer(tap)
  143. return _mapView
  144. }()
  145. /// 高德地图定位
  146. lazy var homeMapLocationM = {
  147. let _homeMapLocationM = AMapLocationManager()
  148. _homeMapLocationM.delegate = self
  149. _homeMapLocationM.distanceFilter = 100
  150. _homeMapLocationM.locatingWithReGeocode = true
  151. _homeMapLocationM.desiredAccuracy = kCLLocationAccuracyHundredMeters
  152. _homeMapLocationM.locationTimeout = 2
  153. _homeMapLocationM.reGeocodeTimeout = 2
  154. _homeMapLocationM.pausesLocationUpdatesAutomatically = false
  155. _homeMapLocationM.allowsBackgroundLocationUpdates = true
  156. return _homeMapLocationM
  157. }()
  158. /// 头部定位权限弹窗
  159. lazy var homeAuthHeaderView = {
  160. let _homeAuthHeaderView = QSLHomeAuthHeaderView()
  161. _homeAuthHeaderView.addRadius(radius: 6)
  162. return _homeAuthHeaderView
  163. }()
  164. @objc func homeFriendBtnAction(){
  165. QSLJumpManager.shared.pushToAdd(type: .homesmall)
  166. }
  167. lazy var homeFriendBtn: UIView = {
  168. let _homeResortBtn = UIView(frame: CGRect(x: QSLConst.qsl_kScreenW - 40.rpx, y: QSLConst.qsl_kStatusBarFrameH + 28.rpx, width: 34.rpx, height: 44.rpx))
  169. let imgView = UIImageView.init(image: UIImage(named: "home_find_friend"))
  170. imgView.frame = CGRectMake(0, 0, 34.rpx, 40.rpx)
  171. imgView.isUserInteractionEnabled = true
  172. _homeResortBtn.addSubview(imgView)
  173. let label = YYLabel.init(frame: CGRectMake(0, 29.rpx, 34.rpx, 15.rpx))
  174. // 创建文字属性
  175. let attributedString = NSMutableAttributedString(string: QSLConfig.addFriendIconText)
  176. attributedString.yy_font = UIFont.boldSystemFont(ofSize: 13)
  177. attributedString.yy_color = UIColor.black // 文字颜色为黑色
  178. // 创建描边阴影(模拟边框效果)
  179. let shadow = YYTextShadow()
  180. shadow.color = UIColor.white // 边框颜色
  181. shadow.radius = 4 // 边框粗细
  182. shadow.offset = CGSize.zero // 偏移量为0,形成描边效果
  183. // 设置文字描边
  184. attributedString.yy_setTextShadow(shadow, range: NSRange(location: 0, length: attributedString.length))
  185. label.attributedText = attributedString
  186. label.textAlignment = .center
  187. _homeResortBtn.addSubview(label)
  188. let tapG = UITapGestureRecognizer.init(target: self, action: #selector(homeFriendBtnAction))
  189. _homeResortBtn.addGestureRecognizer(tapG)
  190. return _homeResortBtn
  191. }()
  192. /// 定位按钮
  193. lazy var homeLocateBtnView = {
  194. let _homeLocateBtnView = UIView()
  195. _homeLocateBtnView.addRadius(radius: 6)
  196. _homeLocateBtnView.effectViewWithAlpha(alpha: 1, size: CGSize(width: 40, height: 40), style: .light)
  197. return _homeLocateBtnView
  198. }()
  199. lazy var homeLocateBtn = {
  200. let _homeLocateBtn = UIButton(type: .custom)
  201. _homeLocateBtn.image(UIImage(named: "home_btn_locate"))
  202. return _homeLocateBtn
  203. }()
  204. /// 无好友和未登录时的状态
  205. lazy var homeEmptyView: QSLHomeEmptyView = {
  206. let _homeEmptyView = QSLHomeEmptyView()
  207. _homeEmptyView.delegate = self
  208. _homeEmptyView.isHidden = true
  209. return _homeEmptyView
  210. }()
  211. lazy var homeFriendView: QSLHomeFriendView = {
  212. let topHeight = QSLConst.qsl_kStatusBarFrameH
  213. let view = QSLHomeFriendView(frame: CGRect(x: 0, y: QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH, width: QSLConst.qsl_kScreenW, height: QSLConst.qsl_kScreenH - topHeight))
  214. view.scrollTopHeight = topHeight - 40
  215. view.delegate = self
  216. return view
  217. }()
  218. }
  219. // MARK: - 网络请求等
  220. extension QSLHomeController {
  221. @objc func loadData() {
  222. // viewModel.refreshDataSoure(complete: { [unowned self] in
  223. // self.homeFriendView.viewModel = self.viewModel
  224. // let friViewTopY = QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH
  225. // homeFriendView.scrollCenterHeight = friViewTopY
  226. // homeFriendView.snp.updateConstraints { make in
  227. // make.top.equalTo(friViewTopY)
  228. // }
  229. // })
  230. if(!isFirstRequestLoc){
  231. self.onceLocation()
  232. }
  233. if QSLBaseManager.shared.isLogin() {
  234. self.initSocket()
  235. } else {
  236. self.deposeSocket()
  237. }
  238. requestFriendList()
  239. requestVip()
  240. }
  241. // 请求好友列表
  242. @objc func requestFriendList() {
  243. self.homeMapView.removeAnnotations(self.homeMapView.annotations)
  244. viewModel.friendList.removeAll()
  245. viewModel.friendLocationList.removeAll()
  246. viewModel.friendList.append(QSLBaseManager.shared.userModel)
  247. QSLNetwork().request(.friendList(dict: [:])) { response in
  248. let list = response.mapArray(QSLUserModel.self, modelKey: "data>list")
  249. self.viewModel.friendList.append(contentsOf: list)
  250. self.homeFriendView.viewModel = self.viewModel
  251. for model in list {
  252. let pointAnnotation = MAPointAnnotation()
  253. let loc = CLLocationCoordinate2D(latitude: model.location.lat, longitude: model.location.lng)
  254. pointAnnotation.coordinate = loc
  255. if model.remark.count > 0 {
  256. pointAnnotation.title = model.remark
  257. } else {
  258. pointAnnotation.title = model.phone
  259. }
  260. pointAnnotation.subtitle = "300"
  261. let pointModel = QSLMapPointModel()
  262. pointModel.userId = model.userId
  263. pointModel.pointAnnotation = pointAnnotation
  264. self.viewModel.friendLocationList.append(pointModel)
  265. if QSLBaseManager.shared.isVip() && !model.blockedMe {
  266. self.homeMapView.addAnnotation(pointAnnotation)
  267. }
  268. }
  269. } fail: { code, error in
  270. self.homeFriendView.viewModel = self.viewModel
  271. }
  272. }
  273. // 请求vip信息
  274. @objc func requestVip() {
  275. QSLNetwork().request(.userMember(dict: [:])) { response in
  276. let memberModel = response.mapObject(QSLMemberModel.self, modelKey: "data")
  277. QSLBaseManager.shared.userModel.memberModel = memberModel
  278. if memberModel.expired {
  279. QSLBaseManager.shared.saveVipExpiredTime(time: 0)
  280. } else {
  281. QSLBaseManager.shared.saveVipExpiredTime(time: memberModel.endTimestamp)
  282. }
  283. QSLBaseManager.shared.saveUserId(id: memberModel.userId)
  284. QSLTools.shared.requestShortcutItem()
  285. // NotificationCenter.default.post(name: QSLNotification.QSLRefreshMember, object: nil)
  286. } fail: { code, error in
  287. }
  288. }
  289. }
  290. // MARK: - 设置地图相关方法
  291. extension QSLHomeController: MAMapViewDelegate, AMapLocationManagerDelegate {
  292. // 初始化高德地图设置
  293. func setUpMap() {
  294. AMapServices.shared().enableHTTPS = true
  295. AMapLocationManager.updatePrivacyShow(.didShow, privacyInfo: .didContain)
  296. AMapLocationManager.updatePrivacyAgree(.didAgree)
  297. homeMapLocationM.locatingWithReGeocode = true
  298. if(!isFirstRequestLoc){
  299. homeMapLocationM.startUpdatingLocation()
  300. }
  301. }
  302. // 申请地图定位权限
  303. func mapViewRequireLocationAuth(_ locationManager: CLLocationManager!) {
  304. locationManager.requestWhenInUseAuthorization()
  305. }
  306. // 地图触摸事件
  307. @objc func mapTapAction() {
  308. if self.homeFriendView.scrollLocation != .ScrollBottom {
  309. self.homeFriendView.scrollToLocation(type: .ScrollBottom)
  310. }
  311. }
  312. // 获取一次性定位
  313. func onceLocation() {
  314. // 先停止持续定位
  315. self.homeMapLocationM.stopUpdatingLocation()
  316. self.homeMapLocationM.requestLocation(withReGeocode: true) { location, regeocode, error in
  317. if error != nil {
  318. self.personalModel = QSLBaseManager.shared.userModel
  319. // 获取电话和名字
  320. // self.personalModel.phone = QSLBaseManager.shared.userModel.phone
  321. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  322. if !QSLBaseManager.shared.isLogin() {
  323. name = "自己"
  324. }
  325. name = "自己"
  326. self.personalModel.remark = name
  327. // 地址
  328. self.personalModel.location.addr = "请先开启位置权限"
  329. QSLBaseManager.shared.updateUser(model: self.personalModel)
  330. if self.viewModel.friendList.isEmpty {
  331. self.viewModel.friendList.append(self.personalModel)
  332. } else {
  333. self.viewModel.friendList[0] = self.personalModel
  334. }
  335. self.homeFriendView.viewModel = self.viewModel
  336. self.homeMapLocationM.startUpdatingLocation()
  337. return
  338. }
  339. self.personalModel = QSLBaseManager.shared.userModel
  340. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  341. if !QSLBaseManager.shared.isLogin() {
  342. name = "自己"
  343. }
  344. name = "自己"
  345. self.personalModel.remark = name
  346. self.personalModel.location.addr = regeocode?.formattedAddress ?? "未知"
  347. self.personalModel.location.timestamp = Int(Date.secondStamp) ?? 0
  348. if let location = location {
  349. // 地图居中
  350. self.homeMapView.setCenter(location.coordinate, animated: true)
  351. self.homeFriendView.scrollLocation = .ScrollCenter
  352. self.personalModel.location.lat = location.coordinate.latitude
  353. self.personalModel.location.lng = location.coordinate.longitude
  354. // 速度
  355. self.personalModel.location.speed = location.speed >= 0 ? location.speed : 0
  356. // 朝向
  357. self.personalModel.location.bearing = location.course >= 0 ? location.course : 0
  358. }
  359. QSLBaseManager.shared.updateUser(model: self.personalModel)
  360. if QSLBaseManager.shared.isLogin() {
  361. let locationData = self.personalModel.location
  362. let addr = locationData.addr
  363. if addr != "请先开启位置权限" {
  364. self.sendSocket()
  365. }
  366. }
  367. if self.viewModel.friendList.isEmpty {
  368. self.viewModel.friendList.append(self.personalModel)
  369. } else {
  370. self.viewModel.friendList[0] = self.personalModel
  371. }
  372. print("location: \(String(describing: location))")
  373. if let regeocode = regeocode {
  374. print("reGeocode: \(regeocode)")
  375. }
  376. self.homeFriendView.viewModel = self.viewModel
  377. self.homeMapLocationM.startUpdatingLocation()
  378. }
  379. }
  380. // 持续定位
  381. func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) {
  382. if self.isFirstLocatScuess {
  383. self.isFirstLocatScuess = false
  384. //始终允许定位成功
  385. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_success_always, eventProps: ["id": 03003])
  386. }
  387. // 获取电话和名字
  388. self.personalModel = QSLBaseManager.shared.userModel
  389. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  390. if !QSLBaseManager.shared.isLogin() {
  391. name = "自己"
  392. }
  393. name = "自己"
  394. self.personalModel.remark = name
  395. // 时间戳
  396. self.personalModel.location.timestamp = Int(Date.secondStamp) ?? 0
  397. // 经纬度
  398. self.personalModel.location.lat = location.coordinate.latitude
  399. self.personalModel.location.lng = location.coordinate.longitude
  400. // 速度
  401. if location.speed >= 0 {
  402. self.personalModel.location.speed = location.speed
  403. } else {
  404. self.personalModel.location.speed = 0
  405. }
  406. // 朝向
  407. if location.course >= 0 {
  408. self.personalModel.location.bearing = location.course
  409. } else {
  410. self.personalModel.location.bearing = 0
  411. }
  412. // 打印位置信息
  413. print("location: {lat: \(location.coordinate.latitude); lon: \(location.coordinate.longitude); accuracy: \(location.horizontalAccuracy)}")
  414. // 逆地理编码处理
  415. if let reGeocode = reGeocode {
  416. print("reGeocode: \(reGeocode)")
  417. self.personalModel.location.addr = reGeocode.formattedAddress
  418. } else {
  419. self.personalModel.location.addr = "请先开启位置权限"
  420. }
  421. // 保存到模块
  422. QSLBaseManager.shared.updateUser(model: self.personalModel)
  423. // 更新好友列表
  424. if self.viewModel.friendList.isEmpty {
  425. self.viewModel.friendList.append(self.personalModel)
  426. } else {
  427. self.viewModel.friendList[0] = self.personalModel
  428. }
  429. self.homeFriendView.viewModel = self.viewModel
  430. // 更新UI
  431. // self.updateHomeUI()
  432. // 如果已登录,发送定位信息
  433. if QSLBaseManager.shared.isLogin() {
  434. let locationData = self.personalModel.location
  435. let addr = locationData.addr
  436. if addr != "请先开启位置权限" {
  437. self.sendSocket()
  438. }
  439. }
  440. }
  441. func mapView(_ mapView: MAMapView!, viewFor annotation: (any MAAnnotation)!) -> MAAnnotationView! {
  442. // 处理用户位置的标注
  443. if annotation is MAUserLocation {
  444. let reuseIdentifier = "UserAnotation"
  445. var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? QSLHomeAnnotatinView
  446. if annotationView == nil {
  447. annotationView = QSLHomeAnnotatinView(annotation: annotation, reuseIdentifier: reuseIdentifier)
  448. }
  449. let name = "我"
  450. annotationView?.title = name
  451. annotationView?.isEnabled = false
  452. annotationView?.image = UIImage(named: "home_mine_anno")
  453. annotationView?.canShowCallout = false
  454. annotationView?.centerOffset = CGPoint(x: 0, y: -18)
  455. annotationView?.calloutOffset = CGPoint(x: 0, y: 0)
  456. annotationView?.zIndex = 360
  457. annotationView?.isSelected = true
  458. return annotationView
  459. }
  460. // 处理普通点标注
  461. if annotation is MAPointAnnotation {
  462. let reuseIdentifier = "OtherAnnotation"
  463. var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? QSLHomeAnnotatinView
  464. if annotationView == nil {
  465. annotationView = QSLHomeAnnotatinView(annotation: annotation, reuseIdentifier: reuseIdentifier)
  466. annotationView?.title = annotation.title
  467. }
  468. if let subtitle = annotation.subtitle as? Int {
  469. annotationView?.zIndex = subtitle
  470. }
  471. annotationView?.isEnabled = false
  472. annotationView?.image = UIImage(named: "home_mine_anno")
  473. annotationView?.canShowCallout = false
  474. annotationView?.centerOffset = CGPoint(x: 0, y: -18)
  475. annotationView?.calloutOffset = CGPoint(x: 0, y: 0)
  476. annotationView?.isSelected = true
  477. return annotationView
  478. }
  479. return nil
  480. }
  481. //@brief 定位权限状态改变时回调函数。注意:iOS13及之前版本回调
  482. // 高德地图权限变化回调
  483. func amapLocationManager(_ manager: AMapLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
  484. //print("高德地图定位权限变化: \(status.rawValue)")
  485. switch status {
  486. case .authorizedAlways, .authorizedWhenInUse:
  487. //print("定位权限已授权")
  488. //支付成功埋点
  489. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_allow_permission, eventProps: ["id": 03001])
  490. case .denied:
  491. //print("定位权限被拒绝")
  492. //拒绝定位权限
  493. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_allow_permission, eventProps: ["id": 03002])
  494. default:
  495. break
  496. }
  497. }
  498. // 系统定位权限变化回调
  499. func amapLocationManager(_ manager: AMapLocationManager, locationManagerDidChangeAuthorization locationManager: CLLocationManager) {
  500. if #available(iOS 14.0, *) {
  501. let status = locationManager.authorizationStatus
  502. // 统一处理权限变化
  503. amapLocationManager(manager, didChangeAuthorization: status)
  504. if(status != .notDetermined){
  505. QSLTools.shared.requestNotificationPermission()
  506. }
  507. //print("系统定位权限变化: \(status.rawValue)")
  508. } else {
  509. // Fallback on earlier versions
  510. }
  511. }
  512. // 定位结果回调
  513. func amapLocationManager(_ manager: AMapLocationManager, didFailWithError error: Error) {
  514. print("定位失败: \(error.localizedDescription)")
  515. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_fail_always, eventProps: ["id": 03004])
  516. }
  517. }
  518. // MARK: - 设置WebSocket
  519. extension QSLHomeController: QSLSocketManagerDelegate {
  520. // 初始化
  521. func initSocket() {
  522. QSLSocketManager.shared.urlString = "\(QSLApi.prodWSUrl)/websocket/\(QSLBaseManager.shared.userModel.authToken)"
  523. QSLSocketManager.shared.connect()
  524. QSLSocketManager.shared.delegate = self
  525. }
  526. // 关闭socket
  527. func deposeSocket() {
  528. QSLSocketManager.shared.urlString = ""
  529. QSLSocketManager.shared.close()
  530. QSLSocketManager.shared.delegate = nil
  531. }
  532. // 发送socket信息
  533. func sendSocket() {
  534. var message = QSLMapMessageModel()
  535. message.cmd = "u.location"
  536. var location = QSLMapTrackModel()
  537. location.lat = self.personalModel.location.lat
  538. location.lng = self.personalModel.location.lng
  539. location.addr = self.personalModel.location.addr
  540. location.speed = self.personalModel.location.speed
  541. location.bearing = self.personalModel.location.bearing
  542. location.timestamp = Int(Date.milliStamp) ?? 0
  543. message.body = location.toJSONString()
  544. QSLSocketManager.shared.sendMessage(message.toJSONString())
  545. }
  546. // 接收到消息
  547. func socketDidReceiveMessage(with string: String) {
  548. let locationModel = QSLMapMessageModel.mapModel(from: string)
  549. if let data = locationModel.body.data(using: .utf8), let list = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [QSLMapTrackModel] {
  550. if locationModel.cmd == "d.location.batch" {
  551. for model in list {
  552. var isBlockedMe = false
  553. for var user in viewModel.friendList {
  554. if model.userId == user.friendId {
  555. user.location = model
  556. isBlockedMe = user.blockedMe
  557. }
  558. }
  559. if !isBlockedMe && QSLBaseManager.shared.isVip() {
  560. for location in viewModel.friendLocationList {
  561. if model.userId == location.userId {
  562. let annotation = MAPointAnnotation()
  563. let cll2d = CLLocationCoordinate2D(latitude: model.lat, longitude: model.lng)
  564. annotation.coordinate = cll2d
  565. location.pointAnnotation = annotation
  566. self.homeMapView.addAnnotation(location.pointAnnotation)
  567. }
  568. }
  569. }
  570. }
  571. self.homeFriendView.viewModel = self.viewModel
  572. }
  573. }
  574. }
  575. }
  576. // MARK: - 设置界面代理方法
  577. extension QSLHomeController: QSLHomeEmptyViewDelegate, QSLHomeFriendViewDelegate {
  578. func viewDidScroll() {
  579. switch self.homeFriendView.scrollLocation {
  580. case .ScrollTop:
  581. self.homeFriendView.snp.updateConstraints { make in
  582. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH - 40.rpx)
  583. }
  584. break
  585. case .ScrollCenter:
  586. self.homeFriendView.snp.updateConstraints { make in
  587. make.top.equalTo(QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kStatusBarFrameH)
  588. }
  589. break
  590. case .ScrollBottom:
  591. self.homeFriendView.snp.updateConstraints { make in
  592. if(QSLBaseManager.shared.isVip()){
  593. make.top.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH - 56.rpx - 40.rpx)
  594. }else{
  595. make.top.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH - 56.rpx - 40.rpx - 48.rpx)
  596. }
  597. }
  598. break
  599. default:
  600. break
  601. }
  602. }
  603. func addFriendAction(isSmall: Bool) {
  604. if isSmall {
  605. QSLJumpManager.shared.pushToAdd(type: .homesmall)
  606. } else {
  607. QSLJumpManager.shared.pushToAdd(type: .homebig)
  608. }
  609. }
  610. func refreshBtnAction() {
  611. QSEventHandle.eventPush(eventName: QSLGravityConst.home_locate)
  612. self.loadData()
  613. }
  614. // 轨迹
  615. func routeBtnAction(model: QSLUserModel) {
  616. if(!QSLConfig.loginPayEnable){
  617. if !QSLBaseManager.shared.isVip() {
  618. QSLJumpManager.shared.pushToVip(type: .homeRoad)
  619. return
  620. }
  621. }else{
  622. if !QSLBaseManager.shared.isLogin() {
  623. if let view = self.tabBarController?.view {
  624. QSLAlertView.alert(view: view, title: "温馨提示", content: "登录即可体验查看轨迹记录", secondBtnClosure: {
  625. QSLJumpManager.shared.pushToLogin(type: .road)
  626. })
  627. }
  628. return
  629. }
  630. if !QSLBaseManager.shared.isVip() {
  631. QSLJumpManager.shared.pushToVip(type: .homeRoad)
  632. return
  633. }
  634. }
  635. QSLJumpManager.shared.pushToRoad(type: .home, model: model)
  636. }
  637. // 点击列表的定位按钮
  638. func locateBtnAction(model: QSLUserModel) {
  639. if !QSLBaseManager.shared.isVip() {
  640. self.view.toast(text: "请先开通会员")
  641. return
  642. }
  643. if model.blockedMe {
  644. return
  645. }
  646. let location = CLLocationCoordinate2D(latitude: model.location.lat, longitude: model.location.lng)
  647. self.homeMapView.setCenter(location, animated: true)
  648. for point in self.viewModel.friendLocationList {
  649. if point.userId == model.friendId {
  650. self.homeMapView.removeAnnotation(point.pointAnnotation)
  651. point.pointAnnotation?.subtitle = "350"
  652. self.homeMapView.addAnnotation(point.pointAnnotation)
  653. }
  654. }
  655. }
  656. func emptyFriPhoneViewClick() {
  657. if let vc = self.tabBarController {
  658. QSLFriendAddAlertView.show(vc: vc) {
  659. }
  660. }
  661. }
  662. func homeFriPhoneViewClick() {
  663. if let vc = self.tabBarController {
  664. QSLFriendAddAlertView.show(vc: vc) {
  665. }
  666. }
  667. }
  668. }
  669. // MARK: - 设置UI相关方法
  670. extension QSLHomeController {
  671. // 设置基础UI
  672. func setUpUI() {
  673. view.addSubview(homeMapView)
  674. homeMapView.snp.makeConstraints { make in
  675. make.edges.equalTo(0)
  676. }
  677. view.addSubview(homeFriendBtn)
  678. //
  679. // view.addSubview(homeLocateBtnView)
  680. // homeLocateBtnView.snp.makeConstraints { make in
  681. // make.size.equalTo(CGSize(width: 40, height: 40))
  682. // make.top.equalTo(self.homeButtonsView.snp.bottom).offset(16)
  683. // make.right.equalTo(QSLHomeViewModel.UX.viewRight)
  684. // }
  685. view.addSubview(homeFriendView)
  686. homeFriendView.snp.makeConstraints { make in
  687. make.left.right.equalTo(0)
  688. make.top.equalTo(QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH)
  689. make.height.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH)
  690. }
  691. let friViewTopY = QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH
  692. homeFriendView.scrollCenterHeight = friViewTopY
  693. homeFriendView.snp.updateConstraints { make in
  694. make.top.equalTo(friViewTopY)
  695. }
  696. }
  697. }