JXLocation.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. //
  2. // JXLocation.m
  3. // shiku_im
  4. //
  5. // Created by p on 2017/4/1.
  6. // Copyright © 2017年 Reese. All rights reserved.
  7. //
  8. #import "JXLocation.h"
  9. @interface JXLocation ()<CLLocationManagerDelegate>
  10. @property (nonatomic, strong) CLLocationManager *location;
  11. @property (nonatomic, strong) CLGeocoder *geocoder;
  12. @property (nonatomic, copy) NSString *cityName;
  13. @property (nonatomic, copy) NSString *cityId;
  14. @property (nonatomic, copy) NSString *countryCode;
  15. @property (nonatomic, copy) NSString *address;
  16. @end
  17. @implementation JXLocation
  18. - (instancetype)init {
  19. if ([super init]) {
  20. _location = [[CLLocationManager alloc] init] ;
  21. _location.delegate = self;
  22. if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
  23. // [_location requestAlwaysAuthorization];//始终允许访问位置信息,必须关闭
  24. [_location requestWhenInUseAuthorization];//使用应用程序期间允许访问位置数据
  25. }
  26. }
  27. return self;
  28. }
  29. - (void)locationStart {
  30. [_location startUpdatingLocation];
  31. [_location stopUpdatingHeading];
  32. }
  33. #pragma mark -------------获取经纬度----------------
  34. - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
  35. CLLocation *currentLocation = [locations lastObject];
  36. double latitude = currentLocation.coordinate.latitude;
  37. double longitude = currentLocation.coordinate.longitude;
  38. //NSLog(@"成功获得位置:latitude:%f,longitude:%f",latitude,longitude);
  39. //根据经纬度反向地理编译出地址信息
  40. [self getAddressInfo:currentLocation];
  41. //系统会一直更新数据,直到选择停止更新,因为我们只需要获得一次经纬度即可,所以获取之后就停止更新
  42. [manager stopUpdatingLocation];
  43. }
  44. - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
  45. // NSLog(@"成功获得状态");
  46. }
  47. - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
  48. {
  49. //NSLog(@"找不到位置: %@", [error description]);
  50. [self getLocationWithIp];
  51. return;
  52. }
  53. - (void)getAddressInfo:(CLLocation *)location{
  54. // 37.422729, -106.000207
  55. if (_geocoder == nil) {
  56. _geocoder = [[CLGeocoder alloc] init];
  57. }
  58. [self reverseGeocode:location];
  59. }
  60. // 国内反编码
  61. - (void) reverseGeocode:(CLLocation *)location{
  62. [_geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
  63. if (placemarks.count > 0) {
  64. CLPlacemark *placeMark = [placemarks firstObject];
  65. // NSLog(@"placeMark:%@\n name:%@\n thoroughfare:%@\n subThoroughfare:%@\n locality:%@\n subLocality:%@\n administrativeArea:%@\n subAdministrativeArea:%@\n postalCode:%@\n ISOcountryCode:%@\n country:%@\n inlandWater:%@\n ocean:%@\n areasOfInterest:%@",placeMark.addressDictionary,placeMark.name,placeMark.thoroughfare,placeMark.subThoroughfare,placeMark.locality,placeMark.subLocality,placeMark.administrativeArea,placeMark.subAdministrativeArea,placeMark.postalCode,placeMark.ISOcountryCode,placeMark.country,placeMark.inlandWater,placeMark.ocean,placeMark.areasOfInterest);
  66. //获取城市名
  67. NSString *city = placeMark.locality;
  68. if (!city) { //四大直辖市的城市信息可能无法通过locality获得,可通过获取省份的方法来获得
  69. city = placeMark.administrativeArea;
  70. }
  71. if (city) {
  72. self.cityName = city;
  73. _cityId = [g_constant getCityID:city];
  74. }
  75. if (_cityId) {
  76. // [[NSUserDefaults standardUserDefaults] setObject:_cityId forKey:kCityId];
  77. // [[NSUserDefaults standardUserDefaults] synchronize];
  78. }
  79. //获取国家代号(当前所在国家代号,区分国内国外重要依据)
  80. self.countryCode = placeMark.ISOcountryCode;
  81. // self.countryCode = @"MY";
  82. if(self.countryCode) {
  83. [[NSUserDefaults standardUserDefaults] setObject:self.countryCode forKey:kISOcountryCode];
  84. [[NSUserDefaults standardUserDefaults] synchronize];
  85. }
  86. //从 placeMark.addressDictionary 获取详细地址信息
  87. NSDictionary *addressDict = placeMark.addressDictionary;
  88. // NSLog(@"addressDict:%@",addressDict);
  89. //详细地址
  90. NSString *addressStr = [addressDict objectForKey:@"Name"];
  91. //去掉国家名
  92. addressStr = [addressStr stringByReplacingOccurrencesOfString:placeMark.country withString:@""];
  93. //如果有州或省名,去掉之
  94. if ([addressDict objectForKey:@"State"] != nil) {
  95. addressStr = [addressStr stringByReplacingOccurrencesOfString:[addressDict objectForKey:@"State"] withString:@""];
  96. }
  97. if (_address) {
  98. // [_address release];
  99. _address = nil;
  100. }
  101. _address = [[NSString alloc] initWithFormat:@"%@%@",self.cityName,addressStr];
  102. if ([self.delegate respondsToSelector:@selector(location:CountryCode:CityName:CityId:Address:Latitude:Longitude:)]) {
  103. [self.delegate location:self CountryCode:self.countryCode CityName:self.cityName CityId:self.cityId Address:self.address Latitude:location.coordinate.latitude Longitude:location.coordinate.longitude];
  104. }
  105. // NSLog(@"登录地址:%@ countryCode:%@ city:%@ cityId:%d",_address,self.countryCode,_cityName,_cityId);
  106. // if (isLogin || _isGetSetting) {
  107. // [self getSetting:self];
  108. // }
  109. // [g_App.mainVc changeUserCityId];
  110. }else {
  111. [self reverseGeocodeWithGoogleapi:location];
  112. }
  113. }];
  114. }
  115. // 国外使用谷歌api反编码
  116. - (void)reverseGeocodeWithGoogleapi:(CLLocation *)location {
  117. // 国内反编码失败 启用谷歌反编码
  118. NSString *urlString = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=true",location.coordinate.latitude, location.coordinate.longitude];
  119. AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];
  120. [manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
  121. manager.requestSerializer.timeoutInterval = 5.f;
  122. [manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
  123. [manager GET:urlString parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
  124. } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
  125. NSDictionary *responseDic = responseObject;
  126. if ([responseDic[@"status"] isEqualToString:@"OK"]) {
  127. NSArray *returenArray = responseDic[@"results"];
  128. NSDictionary *addressDic = returenArray[0];
  129. // NSDictionary *locationDic = addressDic[@"geometry"][@"location"];
  130. // self.inputLocX = [locationDic[@"lng"] doubleValue];
  131. // self.inputLocY = [locationDic[@"lat"] doubleValue];
  132. NSArray *arr = addressDic[@"address_components"];
  133. // 获取国家代号
  134. for (NSDictionary *dict in arr) {
  135. NSArray *types = dict[@"types"];
  136. NSString *type = [types firstObject];
  137. if ([type isEqualToString:@"country"]) {
  138. self.countryCode = dict[@"short_name"];
  139. break;
  140. }
  141. }
  142. if (self.countryCode) {
  143. [[NSUserDefaults standardUserDefaults] setObject:self.countryCode forKey:kISOcountryCode];
  144. [[NSUserDefaults standardUserDefaults] synchronize];
  145. }
  146. // 获取到城市
  147. for (NSDictionary *dict in arr) {
  148. NSArray *types = dict[@"types"];
  149. NSString *type = [types firstObject];
  150. if ([type isEqualToString:@"locality"]) {
  151. self.cityName = dict[@"long_name"];
  152. // self.cityId = [g_constant getTypeCityId:self.cityName];
  153. break;
  154. }
  155. }
  156. // 如果城市id获取不到,就用省份查id(areas表里 有的外国省对应表里的城市)
  157. if (!self.cityId) {
  158. for (NSDictionary *dict in arr) {
  159. NSArray *types = dict[@"types"];
  160. NSString *type = [types firstObject];
  161. if ([type isEqualToString:@"administrative_area_level_1"]) {
  162. self.cityName = dict[@"long_name"];
  163. // self.cityId = [g_constant getTypeCityId:self.cityName];
  164. break;
  165. }
  166. }
  167. }
  168. if (_cityId) {
  169. [[NSUserDefaults standardUserDefaults] setObject:_cityId forKey:kCityId];
  170. [[NSUserDefaults standardUserDefaults] synchronize];
  171. }
  172. _address = addressDic[@"formatted_address"];
  173. if ([self.delegate respondsToSelector:@selector(location:CountryCode:CityName:CityId:Address:Latitude:Longitude:)]) {
  174. [self.delegate location:self CountryCode:self.countryCode CityName:self.cityName CityId:self.cityId Address:self.address Latitude:location.coordinate.latitude Longitude:location.coordinate.longitude];
  175. }
  176. //
  177. // if (isLogin || _isGetSetting) {
  178. // [self getSetting:self];
  179. // }
  180. // NSLog(@"response = %@",responseObject);
  181. }else {
  182. [self getLocationWithIp];
  183. }
  184. // NSLog(@"response = %@",responseObject);
  185. } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
  186. [self getLocationWithIp];
  187. // self.addrBtn.hidden = YES;
  188. NSLog(@"error = %@",error);
  189. }];
  190. }
  191. - (void)getLocationWithIp {
  192. NSString *urlString = @"https://ipinfo.io/geo";
  193. AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];
  194. manager.requestSerializer.timeoutInterval = 5.0;
  195. [manager GET:urlString parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
  196. } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
  197. NSDictionary *responseDic = responseObject;
  198. // 国家代号
  199. self.countryCode = responseDic[@"country"];
  200. if (self.countryCode) {
  201. [[NSUserDefaults standardUserDefaults] setObject:self.countryCode forKey:kISOcountryCode];
  202. [[NSUserDefaults standardUserDefaults] synchronize];
  203. }
  204. // 城市
  205. // self.cityName = responseDic[@"city"];
  206. self.cityName = responseDic[@"city"];
  207. // self.cityId = [g_constant getCityId:self.cityName Language:@"en"];
  208. // 如果城市id获取不到,就用省份查id(areas表里 有的外国省对应表里的城市)
  209. if (!self.cityId) {
  210. self.cityName = responseDic[@"region"];
  211. // self.cityId = [g_constant getCityId:self.cityName Language:@"en"];
  212. }
  213. if (_cityId) {
  214. [[NSUserDefaults standardUserDefaults] setObject:_cityId forKey:kCityId];
  215. [[NSUserDefaults standardUserDefaults] synchronize];
  216. }
  217. _address = [NSString stringWithFormat:@"%@%@",responseDic[@"region"],responseDic[@"city"]];
  218. NSString *loc = responseDic[@"loc"];
  219. NSRange range = [loc rangeOfString:@","];
  220. NSString *lat = [loc substringToIndex:range.location];
  221. NSString *lon = [loc substringFromIndex:range.location + range.length];
  222. if ([self.delegate respondsToSelector:@selector(location:CountryCode:CityName:CityId:Address:Latitude:Longitude:)]) {
  223. [self.delegate location:self CountryCode:self.countryCode CityName:self.cityName CityId:self.cityId Address:self.address Latitude:[lat doubleValue] Longitude:[lon doubleValue]];
  224. }
  225. if ([self.delegate respondsToSelector:@selector(location:getLocationWithIp:)]) {
  226. [self.delegate location:self getLocationWithIp:responseDic];
  227. }
  228. //
  229. // if (isLogin || _isGetSetting) {
  230. // [self getSetting:self];
  231. // }
  232. // NSLog(@"response = %@",responseObject);
  233. } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
  234. if ([self.delegate respondsToSelector:@selector(location:getLocationError:)]) {
  235. [self.delegate location:self getLocationError:error];
  236. }
  237. // self.addrBtn.hidden = YES;
  238. // NSLog(@"error = %@",error);
  239. }];
  240. }
  241. @end