QSLHomeController.swift 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  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. _homeResortBtn.addSubview(imgView)
  172. let label = YYLabel.init(frame: CGRectMake(0, 29.rpx, 34.rpx, 15.rpx))
  173. // 创建文字属性
  174. let attributedString = NSMutableAttributedString(string: QSLConfig.addFriendIconText)
  175. attributedString.yy_font = UIFont.boldSystemFont(ofSize: 13)
  176. attributedString.yy_color = UIColor.black // 文字颜色为黑色
  177. // 创建描边阴影(模拟边框效果)
  178. let shadow = YYTextShadow()
  179. shadow.color = UIColor.white // 边框颜色
  180. shadow.radius = 4 // 边框粗细
  181. shadow.offset = CGSize.zero // 偏移量为0,形成描边效果
  182. // 设置文字描边
  183. attributedString.yy_setTextShadow(shadow, range: NSRange(location: 0, length: attributedString.length))
  184. label.attributedText = attributedString
  185. label.textAlignment = .center
  186. _homeResortBtn.addSubview(label)
  187. let tapG = UIGestureRecognizer.init(target: self, action: #selector(homeFriendBtnAction))
  188. _homeResortBtn.addGestureRecognizer(tapG)
  189. return _homeResortBtn
  190. }()
  191. /// 定位按钮
  192. lazy var homeLocateBtnView = {
  193. let _homeLocateBtnView = UIView()
  194. _homeLocateBtnView.addRadius(radius: 6)
  195. _homeLocateBtnView.effectViewWithAlpha(alpha: 1, size: CGSize(width: 40, height: 40), style: .light)
  196. return _homeLocateBtnView
  197. }()
  198. lazy var homeLocateBtn = {
  199. let _homeLocateBtn = UIButton(type: .custom)
  200. _homeLocateBtn.image(UIImage(named: "home_btn_locate"))
  201. return _homeLocateBtn
  202. }()
  203. /// 无好友和未登录时的状态
  204. lazy var homeEmptyView: QSLHomeEmptyView = {
  205. let _homeEmptyView = QSLHomeEmptyView()
  206. _homeEmptyView.delegate = self
  207. _homeEmptyView.isHidden = true
  208. return _homeEmptyView
  209. }()
  210. lazy var homeFriendView: QSLHomeFriendView = {
  211. let topHeight = QSLConst.qsl_kStatusBarFrameH
  212. 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))
  213. view.scrollTopHeight = topHeight - 40
  214. view.delegate = self
  215. return view
  216. }()
  217. }
  218. // MARK: - 网络请求等
  219. extension QSLHomeController {
  220. @objc func loadData() {
  221. // viewModel.refreshDataSoure(complete: { [unowned self] in
  222. // self.homeFriendView.viewModel = self.viewModel
  223. // let friViewTopY = QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH
  224. // homeFriendView.scrollCenterHeight = friViewTopY
  225. // homeFriendView.snp.updateConstraints { make in
  226. // make.top.equalTo(friViewTopY)
  227. // }
  228. // })
  229. if(!isFirstRequestLoc){
  230. self.onceLocation()
  231. }
  232. if QSLBaseManager.shared.isLogin() {
  233. self.initSocket()
  234. } else {
  235. self.deposeSocket()
  236. }
  237. requestFriendList()
  238. requestVip()
  239. }
  240. // 请求好友列表
  241. @objc func requestFriendList() {
  242. self.homeMapView.removeAnnotations(self.homeMapView.annotations)
  243. viewModel.friendList.removeAll()
  244. viewModel.friendLocationList.removeAll()
  245. viewModel.friendList.append(QSLBaseManager.shared.userModel)
  246. QSLNetwork().request(.friendList(dict: [:])) { response in
  247. let list = response.mapArray(QSLUserModel.self, modelKey: "data>list")
  248. self.viewModel.friendList.append(contentsOf: list)
  249. self.homeFriendView.viewModel = self.viewModel
  250. for model in list {
  251. let pointAnnotation = MAPointAnnotation()
  252. let loc = CLLocationCoordinate2D(latitude: model.location.lat, longitude: model.location.lng)
  253. pointAnnotation.coordinate = loc
  254. if model.remark.count > 0 {
  255. pointAnnotation.title = model.remark
  256. } else {
  257. pointAnnotation.title = model.phone
  258. }
  259. pointAnnotation.subtitle = "300"
  260. let pointModel = QSLMapPointModel()
  261. pointModel.userId = model.userId
  262. pointModel.pointAnnotation = pointAnnotation
  263. self.viewModel.friendLocationList.append(pointModel)
  264. if QSLBaseManager.shared.isVip() && !model.blockedMe {
  265. self.homeMapView.addAnnotation(pointAnnotation)
  266. }
  267. }
  268. } fail: { code, error in
  269. self.homeFriendView.viewModel = self.viewModel
  270. }
  271. }
  272. // 请求vip信息
  273. @objc func requestVip() {
  274. QSLNetwork().request(.userMember(dict: [:])) { response in
  275. let memberModel = response.mapObject(QSLMemberModel.self, modelKey: "data")
  276. QSLBaseManager.shared.userModel.memberModel = memberModel
  277. if memberModel.expired {
  278. QSLBaseManager.shared.saveVipExpiredTime(time: 0)
  279. } else {
  280. QSLBaseManager.shared.saveVipExpiredTime(time: memberModel.endTimestamp)
  281. }
  282. QSLBaseManager.shared.saveUserId(id: memberModel.userId)
  283. QSLTools.shared.requestShortcutItem()
  284. // NotificationCenter.default.post(name: QSLNotification.QSLRefreshMember, object: nil)
  285. } fail: { code, error in
  286. }
  287. }
  288. }
  289. // MARK: - 设置地图相关方法
  290. extension QSLHomeController: MAMapViewDelegate, AMapLocationManagerDelegate {
  291. // 初始化高德地图设置
  292. func setUpMap() {
  293. AMapServices.shared().enableHTTPS = true
  294. AMapLocationManager.updatePrivacyShow(.didShow, privacyInfo: .didContain)
  295. AMapLocationManager.updatePrivacyAgree(.didAgree)
  296. homeMapLocationM.locatingWithReGeocode = true
  297. if(!isFirstRequestLoc){
  298. homeMapLocationM.startUpdatingLocation()
  299. }
  300. }
  301. // 申请地图定位权限
  302. func mapViewRequireLocationAuth(_ locationManager: CLLocationManager!) {
  303. locationManager.requestWhenInUseAuthorization()
  304. }
  305. // 地图触摸事件
  306. @objc func mapTapAction() {
  307. if self.homeFriendView.scrollLocation != .ScrollBottom {
  308. self.homeFriendView.scrollToLocation(type: .ScrollBottom)
  309. }
  310. }
  311. // 获取一次性定位
  312. func onceLocation() {
  313. // 先停止持续定位
  314. self.homeMapLocationM.stopUpdatingLocation()
  315. self.homeMapLocationM.requestLocation(withReGeocode: true) { location, regeocode, error in
  316. if error != nil {
  317. self.personalModel = QSLBaseManager.shared.userModel
  318. // 获取电话和名字
  319. // self.personalModel.phone = QSLBaseManager.shared.userModel.phone
  320. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  321. if !QSLBaseManager.shared.isLogin() {
  322. name = "自己"
  323. }
  324. name = "自己"
  325. self.personalModel.remark = name
  326. // 地址
  327. self.personalModel.location.addr = "请先开启位置权限"
  328. QSLBaseManager.shared.updateUser(model: self.personalModel)
  329. if self.viewModel.friendList.isEmpty {
  330. self.viewModel.friendList.append(self.personalModel)
  331. } else {
  332. self.viewModel.friendList[0] = self.personalModel
  333. }
  334. self.homeFriendView.viewModel = self.viewModel
  335. self.homeMapLocationM.startUpdatingLocation()
  336. return
  337. }
  338. self.personalModel = QSLBaseManager.shared.userModel
  339. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  340. if !QSLBaseManager.shared.isLogin() {
  341. name = "自己"
  342. }
  343. name = "自己"
  344. self.personalModel.remark = name
  345. self.personalModel.location.addr = regeocode?.formattedAddress ?? "未知"
  346. self.personalModel.location.timestamp = Int(Date.secondStamp) ?? 0
  347. if let location = location {
  348. // 地图居中
  349. self.homeMapView.setCenter(location.coordinate, animated: true)
  350. self.homeFriendView.scrollLocation = .ScrollCenter
  351. self.personalModel.location.lat = location.coordinate.latitude
  352. self.personalModel.location.lng = location.coordinate.longitude
  353. // 速度
  354. self.personalModel.location.speed = location.speed >= 0 ? location.speed : 0
  355. // 朝向
  356. self.personalModel.location.bearing = location.course >= 0 ? location.course : 0
  357. }
  358. QSLBaseManager.shared.updateUser(model: self.personalModel)
  359. if QSLBaseManager.shared.isLogin() {
  360. let locationData = self.personalModel.location
  361. let addr = locationData.addr
  362. if addr != "请先开启位置权限" {
  363. self.sendSocket()
  364. }
  365. }
  366. if self.viewModel.friendList.isEmpty {
  367. self.viewModel.friendList.append(self.personalModel)
  368. } else {
  369. self.viewModel.friendList[0] = self.personalModel
  370. }
  371. print("location: \(String(describing: location))")
  372. if let regeocode = regeocode {
  373. print("reGeocode: \(regeocode)")
  374. }
  375. self.homeFriendView.viewModel = self.viewModel
  376. self.homeMapLocationM.startUpdatingLocation()
  377. }
  378. }
  379. // 持续定位
  380. func amapLocationManager(_ manager: AMapLocationManager!, didUpdate location: CLLocation!, reGeocode: AMapLocationReGeocode!) {
  381. if self.isFirstLocatScuess {
  382. self.isFirstLocatScuess = false
  383. //始终允许定位成功
  384. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_success_always, eventProps: ["id": 03003])
  385. }
  386. // 获取电话和名字
  387. self.personalModel = QSLBaseManager.shared.userModel
  388. var name = "用户\(QSLBaseManager.shared.userModel.phone.suffix(4))"
  389. if !QSLBaseManager.shared.isLogin() {
  390. name = "自己"
  391. }
  392. name = "自己"
  393. self.personalModel.remark = name
  394. // 时间戳
  395. self.personalModel.location.timestamp = Int(Date.secondStamp) ?? 0
  396. // 经纬度
  397. self.personalModel.location.lat = location.coordinate.latitude
  398. self.personalModel.location.lng = location.coordinate.longitude
  399. // 速度
  400. if location.speed >= 0 {
  401. self.personalModel.location.speed = location.speed
  402. } else {
  403. self.personalModel.location.speed = 0
  404. }
  405. // 朝向
  406. if location.course >= 0 {
  407. self.personalModel.location.bearing = location.course
  408. } else {
  409. self.personalModel.location.bearing = 0
  410. }
  411. // 打印位置信息
  412. print("location: {lat: \(location.coordinate.latitude); lon: \(location.coordinate.longitude); accuracy: \(location.horizontalAccuracy)}")
  413. // 逆地理编码处理
  414. if let reGeocode = reGeocode {
  415. print("reGeocode: \(reGeocode)")
  416. self.personalModel.location.addr = reGeocode.formattedAddress
  417. } else {
  418. self.personalModel.location.addr = "请先开启位置权限"
  419. }
  420. // 保存到模块
  421. QSLBaseManager.shared.updateUser(model: self.personalModel)
  422. // 更新好友列表
  423. if self.viewModel.friendList.isEmpty {
  424. self.viewModel.friendList.append(self.personalModel)
  425. } else {
  426. self.viewModel.friendList[0] = self.personalModel
  427. }
  428. self.homeFriendView.viewModel = self.viewModel
  429. // 更新UI
  430. // self.updateHomeUI()
  431. // 如果已登录,发送定位信息
  432. if QSLBaseManager.shared.isLogin() {
  433. let locationData = self.personalModel.location
  434. let addr = locationData.addr
  435. if addr != "请先开启位置权限" {
  436. self.sendSocket()
  437. }
  438. }
  439. }
  440. func mapView(_ mapView: MAMapView!, viewFor annotation: (any MAAnnotation)!) -> MAAnnotationView! {
  441. // 处理用户位置的标注
  442. if annotation is MAUserLocation {
  443. let reuseIdentifier = "UserAnotation"
  444. var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? QSLHomeAnnotatinView
  445. if annotationView == nil {
  446. annotationView = QSLHomeAnnotatinView(annotation: annotation, reuseIdentifier: reuseIdentifier)
  447. }
  448. let name = "我"
  449. annotationView?.title = name
  450. annotationView?.isEnabled = false
  451. annotationView?.image = UIImage(named: "home_mine_anno")
  452. annotationView?.canShowCallout = false
  453. annotationView?.centerOffset = CGPoint(x: 0, y: -18)
  454. annotationView?.calloutOffset = CGPoint(x: 0, y: 0)
  455. annotationView?.zIndex = 360
  456. annotationView?.isSelected = true
  457. return annotationView
  458. }
  459. // 处理普通点标注
  460. if annotation is MAPointAnnotation {
  461. let reuseIdentifier = "OtherAnnotation"
  462. var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? QSLHomeAnnotatinView
  463. if annotationView == nil {
  464. annotationView = QSLHomeAnnotatinView(annotation: annotation, reuseIdentifier: reuseIdentifier)
  465. annotationView?.title = annotation.title
  466. }
  467. if let subtitle = annotation.subtitle as? Int {
  468. annotationView?.zIndex = subtitle
  469. }
  470. annotationView?.isEnabled = false
  471. annotationView?.image = UIImage(named: "home_mine_anno")
  472. annotationView?.canShowCallout = false
  473. annotationView?.centerOffset = CGPoint(x: 0, y: -18)
  474. annotationView?.calloutOffset = CGPoint(x: 0, y: 0)
  475. annotationView?.isSelected = true
  476. return annotationView
  477. }
  478. return nil
  479. }
  480. //@brief 定位权限状态改变时回调函数。注意:iOS13及之前版本回调
  481. // 高德地图权限变化回调
  482. func amapLocationManager(_ manager: AMapLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
  483. //print("高德地图定位权限变化: \(status.rawValue)")
  484. switch status {
  485. case .authorizedAlways, .authorizedWhenInUse:
  486. //print("定位权限已授权")
  487. //支付成功埋点
  488. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_allow_permission, eventProps: ["id": 03001])
  489. case .denied:
  490. //print("定位权限被拒绝")
  491. //拒绝定位权限
  492. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_allow_permission, eventProps: ["id": 03002])
  493. default:
  494. break
  495. }
  496. }
  497. // 系统定位权限变化回调
  498. func amapLocationManager(_ manager: AMapLocationManager, locationManagerDidChangeAuthorization locationManager: CLLocationManager) {
  499. if #available(iOS 14.0, *) {
  500. let status = locationManager.authorizationStatus
  501. // 统一处理权限变化
  502. amapLocationManager(manager, didChangeAuthorization: status)
  503. if(status != .notDetermined){
  504. QSLTools.shared.requestNotificationPermission()
  505. }
  506. //print("系统定位权限变化: \(status.rawValue)")
  507. } else {
  508. // Fallback on earlier versions
  509. }
  510. }
  511. // 定位结果回调
  512. func amapLocationManager(_ manager: AMapLocationManager, didFailWithError error: Error) {
  513. print("定位失败: \(error.localizedDescription)")
  514. QSEventHandle.gravityPush(eventName: QSLGravityConst.location_fail_always, eventProps: ["id": 03004])
  515. }
  516. }
  517. // MARK: - 设置WebSocket
  518. extension QSLHomeController: QSLSocketManagerDelegate {
  519. // 初始化
  520. func initSocket() {
  521. QSLSocketManager.shared.urlString = "\(QSLApi.prodWSUrl)/websocket/\(QSLBaseManager.shared.userModel.authToken)"
  522. QSLSocketManager.shared.connect()
  523. QSLSocketManager.shared.delegate = self
  524. }
  525. // 关闭socket
  526. func deposeSocket() {
  527. QSLSocketManager.shared.urlString = ""
  528. QSLSocketManager.shared.close()
  529. QSLSocketManager.shared.delegate = nil
  530. }
  531. // 发送socket信息
  532. func sendSocket() {
  533. var message = QSLMapMessageModel()
  534. message.cmd = "u.location"
  535. var location = QSLMapTrackModel()
  536. location.lat = self.personalModel.location.lat
  537. location.lng = self.personalModel.location.lng
  538. location.addr = self.personalModel.location.addr
  539. location.speed = self.personalModel.location.speed
  540. location.bearing = self.personalModel.location.bearing
  541. location.timestamp = Int(Date.milliStamp) ?? 0
  542. message.body = location.toJSONString()
  543. QSLSocketManager.shared.sendMessage(message.toJSONString())
  544. }
  545. // 接收到消息
  546. func socketDidReceiveMessage(with string: String) {
  547. let locationModel = QSLMapMessageModel.mapModel(from: string)
  548. if let data = locationModel.body.data(using: .utf8), let list = try? JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [QSLMapTrackModel] {
  549. if locationModel.cmd == "d.location.batch" {
  550. for model in list {
  551. var isBlockedMe = false
  552. for var user in viewModel.friendList {
  553. if model.userId == user.friendId {
  554. user.location = model
  555. isBlockedMe = user.blockedMe
  556. }
  557. }
  558. if !isBlockedMe && QSLBaseManager.shared.isVip() {
  559. for location in viewModel.friendLocationList {
  560. if model.userId == location.userId {
  561. let annotation = MAPointAnnotation()
  562. let cll2d = CLLocationCoordinate2D(latitude: model.lat, longitude: model.lng)
  563. annotation.coordinate = cll2d
  564. location.pointAnnotation = annotation
  565. self.homeMapView.addAnnotation(location.pointAnnotation)
  566. }
  567. }
  568. }
  569. }
  570. self.homeFriendView.viewModel = self.viewModel
  571. }
  572. }
  573. }
  574. }
  575. // MARK: - 设置界面代理方法
  576. extension QSLHomeController: QSLHomeEmptyViewDelegate, QSLHomeFriendViewDelegate {
  577. func viewDidScroll() {
  578. switch self.homeFriendView.scrollLocation {
  579. case .ScrollTop:
  580. self.homeFriendView.snp.updateConstraints { make in
  581. make.top.equalTo(QSLConst.qsl_kStatusBarFrameH - 40.rpx)
  582. }
  583. break
  584. case .ScrollCenter:
  585. self.homeFriendView.snp.updateConstraints { make in
  586. make.top.equalTo(QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kStatusBarFrameH)
  587. }
  588. break
  589. case .ScrollBottom:
  590. self.homeFriendView.snp.updateConstraints { make in
  591. if(QSLBaseManager.shared.isVip()){
  592. make.top.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH - 56.rpx - 40.rpx)
  593. }else{
  594. make.top.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH - 56.rpx - 40.rpx - 48.rpx)
  595. }
  596. }
  597. break
  598. default:
  599. break
  600. }
  601. }
  602. func addFriendAction(isSmall: Bool) {
  603. if isSmall {
  604. QSLJumpManager.shared.pushToAdd(type: .homesmall)
  605. } else {
  606. QSLJumpManager.shared.pushToAdd(type: .homebig)
  607. }
  608. }
  609. func refreshBtnAction() {
  610. QSEventHandle.eventPush(eventName: QSLGravityConst.home_locate)
  611. self.loadData()
  612. }
  613. // 轨迹
  614. func routeBtnAction(model: QSLUserModel) {
  615. if(!QSLConfig.loginPayEnable){
  616. if !QSLBaseManager.shared.isVip() {
  617. QSLJumpManager.shared.pushToVip(type: .homeRoad)
  618. return
  619. }
  620. }else{
  621. if !QSLBaseManager.shared.isLogin() {
  622. if let view = self.tabBarController?.view {
  623. QSLAlertView.alert(view: view, title: "温馨提示", content: "登录即可体验查看轨迹记录", secondBtnClosure: {
  624. QSLJumpManager.shared.pushToLogin(type: .road)
  625. })
  626. }
  627. return
  628. }
  629. if !QSLBaseManager.shared.isVip() {
  630. QSLJumpManager.shared.pushToVip(type: .homeRoad)
  631. return
  632. }
  633. }
  634. QSLJumpManager.shared.pushToRoad(type: .home, model: model)
  635. }
  636. // 点击列表的定位按钮
  637. func locateBtnAction(model: QSLUserModel) {
  638. if !QSLBaseManager.shared.isVip() {
  639. self.view.toast(text: "请先开通会员")
  640. return
  641. }
  642. if model.blockedMe {
  643. return
  644. }
  645. let location = CLLocationCoordinate2D(latitude: model.location.lat, longitude: model.location.lng)
  646. self.homeMapView.setCenter(location, animated: true)
  647. for point in self.viewModel.friendLocationList {
  648. if point.userId == model.friendId {
  649. self.homeMapView.removeAnnotation(point.pointAnnotation)
  650. point.pointAnnotation?.subtitle = "350"
  651. self.homeMapView.addAnnotation(point.pointAnnotation)
  652. }
  653. }
  654. }
  655. func emptyFriPhoneViewClick() {
  656. if let vc = self.tabBarController {
  657. QSLFriendAddAlertView.show(vc: vc) {
  658. }
  659. }
  660. }
  661. func homeFriPhoneViewClick() {
  662. if let vc = self.tabBarController {
  663. QSLFriendAddAlertView.show(vc: vc) {
  664. }
  665. }
  666. }
  667. }
  668. // MARK: - 设置UI相关方法
  669. extension QSLHomeController {
  670. // 设置基础UI
  671. func setUpUI() {
  672. view.addSubview(homeMapView)
  673. homeMapView.snp.makeConstraints { make in
  674. make.edges.equalTo(0)
  675. }
  676. view.addSubview(homeFriendBtn)
  677. //
  678. // view.addSubview(homeLocateBtnView)
  679. // homeLocateBtnView.snp.makeConstraints { make in
  680. // make.size.equalTo(CGSize(width: 40, height: 40))
  681. // make.top.equalTo(self.homeButtonsView.snp.bottom).offset(16)
  682. // make.right.equalTo(QSLHomeViewModel.UX.viewRight)
  683. // }
  684. view.addSubview(homeFriendView)
  685. homeFriendView.snp.makeConstraints { make in
  686. make.left.right.equalTo(0)
  687. make.top.equalTo(QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH)
  688. make.height.equalTo(QSLConst.qsl_kScreenH - QSLConst.qsl_kTabbarFrameH)
  689. }
  690. let friViewTopY = QSLConst.qsl_kScreenH - viewModel.friendViewHeight - QSLConst.qsl_kTabbarFrameH
  691. homeFriendView.scrollCenterHeight = friViewTopY
  692. homeFriendView.snp.updateConstraints { make in
  693. make.top.equalTo(friViewTopY)
  694. }
  695. }
  696. }