index.uts 7.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
import { CLLocationManager, CLAuthorizationStatus } from "CoreLocation"
import { TencentLBSLocationManager, TencentLBSLocation, TencentLBSRequestLevel, TencentLBSLocationManagerDelegate } from "TencentLBS"
import { NSError, Bundle } from "Foundation"
import { GetLocationOptions, GetLocationSuccess } from "../interface.uts"

/**
 * 判断当前是否是自定义基座
 */
export function checkHasIntegration() : boolean {
  // todo
  return true
}

/**
 * 定位 LBSLocation 类,封装定位相关方法
 */
class LBSLocation implements TencentLBSLocationManagerDelegate {

  // 定义 locationManager 属性,类型为 TencentLBSLocationManager
  locationManager! : TencentLBSLocationManager

  locationOptions ?: GetLocationOptions

  // 初始化 locationManager 方法
  configLocationManager() : boolean {

    if (this.locationManager == null) {
      // 从 info.plist 中读取 apiKey
      const apiKey = Bundle.main.infoDictionary?.["TencentLBSAPIKey"]

      // infoDictionary 获取的值类型为 any?
      if (apiKey == null) {
        // 如果 apiKey 为 null 返回 false
        console.log("apiKey 未配置")
        return false
      }
      // 调用API前需要设置同意用户隐私协议
      TencentLBSLocationManager.setUserAgreePrivacy(true)
      // 初始化 locationManager 实例对象
      this.locationManager = new TencentLBSLocationManager()
      // 设置 apiKey (因为 apiKey 是 any?类型,需要转成 string 类型赋值)
      this.locationManager.apiKey = apiKey! as string;
      this.locationManager.delegate = this
    }

    return true
  }

  // 请求定位权限
  requestPremission() {
    if (this.configLocationManager()) {
      const status = CLLocationManager.authorizationStatus()
      // 如果未获取过定位权限,则发起权限请求
      if (status == CLAuthorizationStatus.notDetermined) {
        this.locationManager.requestWhenInUseAuthorization()
      } else if (status == CLAuthorizationStatus.denied || status == CLAuthorizationStatus.restricted) {
        let ret = new UniError("uni-getLocation-tencent", -30, "permission missed.");
        options.fail?.(ret)
        options.complete?.(ret)
      }
    }
  }

  // 获取单次位置信息
  getLocation(locationOptions : GetLocationOptions) : boolean {

    // 初始化 locationManager
    if (!this.configLocationManager()) {
      // 初始化失败返回 false
      return false
    }

    this.locationOptions = locationOptions

    const status = CLLocationManager.authorizationStatus()
    if (status == CLAuthorizationStatus.authorizedAlways || status == CLAuthorizationStatus.authorizedWhenInUse) {
      // 是否需要返回逆地理编码
      let requestLevel = TencentLBSRequestLevel.geo
      if (locationOptions.geocode) {
        requestLevel = TencentLBSRequestLevel.name
      }

      // 请求单次定位信息
      this.locationManager.requestLocation(with = requestLevel, locationTimeout = 10, completionBlock = (location ?: TencentLBSLocation, err ?: NSError) : void => {
        if (location != null) {
          // 判断 address 是否有值
          var address = ""
          if (location!.address != null) {
            address = location!.address!
          }

          let response : GetLocationSuccess = {
            latitude: Number(location!.location.coordinate.latitude),
            longitude: Number(location!.location.coordinate.longitude),
            speed: Number(location!.location.speed),
            altitude: Number(location!.location.altitude),
            accuracy: Number(location!.location.horizontalAccuracy),
            verticalAccuracy: Number(location!.location.verticalAccuracy),
            horizontalAccuracy: Number(location!.location.horizontalAccuracy),
            address: address
          }

          locationOptions.success?.(response)
          locationOptions.complete?.(response);
        } else {
          let ret = new UniError("uni-getLocation-tencent", -10, err!.localizedDescription);
          locationOptions.fail?.(ret)
          locationOptions.complete?.(ret)
        }
      })
    } else {
      this.requestPremission()
    }
    return true
  }

  // 监听位置变化
  watchPosition(locationOptions : GetLocationOptions) {
    // 初始化 locationManager
    if (!this.configLocationManager()) {
      return
    }
    if (locationOptions.geocode) {
      this.locationManager.requestLevel = TencentLBSRequestLevel.name
    } else {
      this.locationManager.requestLevel = TencentLBSRequestLevel.geo
    }
    this.locationOptions = locationOptions
    this.locationManager.startUpdatingLocation()
  }

  // 清除监听
  clearWatch() {
    // 初始化 locationManager
    if (!this.configLocationManager()) {
      return
    }
    this.locationManager.stopUpdatingLocation()
  }

  // 实现定位出错的 delegate 方法

  tencentLBSDidChangeAuthorization(manager : TencentLBSLocationManager) {
    const status = this.getAuthorizationStatus()
    if (status == CLAuthorizationStatus.denied || status == CLAuthorizationStatus.restricted) {
      let ret = new UniError("uni-getLocation-tencent", -30, "permission missed.");
      options.fail?.(ret)
      options.complete?.(ret)
    } else if (status == CLAuthorizationStatus.authorizedAlways || status == CLAuthorizationStatus.authorizedWhenInUse) {
      this.getLocation(this.locationOptions)
    }
  }

  tencentLBSLocationManager(manager : TencentLBSLocationManager, @argumentLabel("didFailWithError") error : NSError) {
    let ret = new UniError("uni-getLocation-tencent", -10, error.localizedDescription);
    this.locationOptions?.fail?.(ret)
    this.locationOptions?.complete?.(ret)
  }

  // 实现位置更新的 delegate 方法
  tencentLBSLocationManager(manager : TencentLBSLocationManager, @argumentLabel("didUpdate") location : TencentLBSLocation) {

    // 判断 address 是否有值
    var address = ""
    if (location.address != null) {
      address = location.address!
    }

    let response : GetLocationSuccess = {
      latitude: Number(location.location.coordinate.latitude),
      longitude: Number(location.location.coordinate.longitude),
      speed: Number(location.location.speed),
      altitude: Number(location.location.altitude),
      accuracy: Number(location.location.horizontalAccuracy),
      verticalAccuracy: Number(location.location.verticalAccuracy),
      horizontalAccuracy: Number(location.location.horizontalAccuracy),
      address: address
    }
    this.locationOptions?.success?.(response)
    this.locationOptions?.complete?.(response)
  }

}

const LBSLocationTool : LBSLocation = new LBSLocation()

/**
 * 请求定位权限方法
 */
export function requestPremission() {
  LBSLocationTool.requestPremission()
}

/*
 * 获取位置信息方法(单次定位)
 */
export function getLocation(locationOptions : GetLocationOptions) : boolean {
  return LBSLocationTool.getLocation(locationOptions)
}

/**
 * 持续监听位置变化
 */
export function watchPosition(locationOptions : GetLocationOptions) {
  LBSLocationTool.watchPosition(locationOptions)
}

/**
 * 关闭监听位置变化
 */
export function clearWatch() {
  LBSLocationTool.clearWatch()
}