首页 > 代码库 > iOS定位和获取当前天气

iOS定位和获取当前天气

  这里是定义了一个类,用来当app 启动的时候,在后台获取当前和位置,并根据位置获取当前天气信息,当点击底部的 tabbar 显示我的控制器的时候,在页面上显示当前位置和当前的天气状况,天气接口用的 “心知天气” 这个免费的接口,因为是免费的所以天气信息很少,只能获取到当前温度、当前天气状况(晴还是雨)和指定的一组天气图片从他们网站下载下来直接拖进项目里面,根据天气状态显示指定的图片。(项目全面接入的MVVM 和 RAC)

 CHMLocationManager.h

 1 #import "BaseViewModel.h"
 2 #import "Config.h"
 3 
 4 @class CHMSeniverseResultModel;
 5 
 6 @interface CHMLocationManager : BaseViewModel
 7 
 8 @property (nonatomic, assign) double latitude;
 9 @property (nonatomic, assign) double longitude;
10 @property (nonatomic, assign) BOOL currentLocationAbility;
11 @property (nonatomic, strong) RACSubject *refreshSubject;
12 @property (nonatomic, strong) RACCommand *weatherDataCommand;
13 @property (nonatomic, copy) NSString *currentCity;
14 @property (nonatomic, strong) CHMSeniverseResultModel *seniverseResultModel;
15 
16 + (instancetype)sharedInstance;
17 - (void)startLocation;
18 
19 @end

 CHMLocationManager.m

  1 #import "CHMLocationManager.h"
  2 #import <CoreLocation/CoreLocation.h>
  3 #import "MBProgressHUD+Custom.h"
  4 #import "MLNetworkingManager.h"
  5 #import "NSString+Custom.h"
  6 #import "CHMSeniverseResultModel.h"
  7 
  8 #define kSeniverseAPI @"bfdvxqnyj8k2sooo"
  9 
 10 @interface CHMLocationManager () <CLLocationManagerDelegate>
 11 
 12 @property (nonatomic, strong) CLLocationManager *locationManager;
 13 @property (nonatomic, strong) CLGeocoder *geocoder;
 14 
 15 @end
 16 
 17 @implementation CHMLocationManager
 18 
 19 + (instancetype)sharedInstance {
 20     static CHMLocationManager *locationManager = nil;
 21     static dispatch_once_t onceToken;
 22     dispatch_once(&onceToken, ^{
 23         locationManager = [[CHMLocationManager alloc] init];
 24     });
 25     return locationManager;
 26 }
 27 
 28 - (void)xm_initialize {
 29     self.locationManager = [[CLLocationManager alloc] init];
 30     self.geocoder = [[CLGeocoder alloc] init];
 31     self.locationManager.delegate = self;
 32     self.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
 33     self.refreshSubject = [RACSubject subject];
 34 }
 35 
 36 - (void)startLocation {
 37     if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
 38         if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.f) {
 39             [self.locationManager requestWhenInUseAuthorization];
 40         }
 41     }
 42     
 43     [self.locationManager startUpdatingLocation];
 44     
 45     if ([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
 46         self.currentCity = NSLocalizedString(@"打开定位", nil);
 47         self.currentLocationAbility = NO;
 48     } else {
 49         self.currentLocationAbility = YES;
 50     }
 51 }
 52 
 53 #pragma mark - CLLocationManagerDelegate
 54 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
 55     CLLocation *location = [locations lastObject];
 56     CLLocationCoordinate2D coordinate = location.coordinate;
 57     
 58     self.latitude = coordinate.latitude;
 59     self.longitude = coordinate.longitude;
 60     DebugLog(@"当前位置信息 %lf %lf", self.latitude, self.longitude);
 61     
 62     [manager stopUpdatingLocation];
 63     
 64     [self reverseCurrentGeocodeLocation:location];
 65 }
 66 
 67 - (void)reverseCurrentGeocodeLocation:(CLLocation *)location {
 68     @weakify(self);
 69     [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
 70         @strongify(self);
 71         if (placemarks.count > 0) {
 72             CLPlacemark *place = [placemarks firstObject];
 73             if (place != nil) {
 74                 if (place.locality && place.locality.length > 0) {
 75                     self.currentCity = place.locality;
 76                 } else {
 77                     //四大直辖市的城市信息无法通过locality获得,只能通过获取省份的方法来获得(如果city为空,则可知为直辖市)
 78                     self.currentCity = place.administrativeArea;
 79                 }
 80 
 81                 [self.weatherDataCommand execute:@{@"location": [NSString stringWithFormat:@"%.2f:%.2f", self.latitude, self.longitude], @"language": [NSString currentLanguageForSeniverse]}];
 82             } else {
 83                 DebugLog(@"CLPlacemark place 是 nil");
 84                 self.currentCity = NSLocalizedString(@"位置未知", nil);
 85             }
 86         } else if (error == nil && placemarks.count == 0) {
 87             DebugLog(@"没有定位结果返回");
 88             self.currentCity = NSLocalizedString(@"没有定位信息", nil);
 89         } else {
 90             DebugLog(@"反地理编码失败 %@", error);
 91         }
 92         [self.refreshSubject sendNext:self.currentCity];
 93     }];
 94 }
 95 
 96 - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
 97     [manager stopUpdatingLocation];
 98     
 99     switch (error.code) {
100         case kCLErrorDenied:
101         {
102             DebugLog(@"用户拒绝了对位置或测距的访问权限");
103             self.currentCity = NSLocalizedString(@"打开定位", nil);
104         }
105             break;
106         default:
107         {
108             [MBProgressHUD showBriefPoint:NSLocalizedString(@"定位失败", nil)];
109             self.currentCity = NSLocalizedString(@"定位失败", nil);
110         }
111             break;
112     }
113 }
114 
115 #pragma mark - Setter Getter
116 - (CHMSeniverseResultModel *)seniverseResultModel {
117     if (!_seniverseResultModel) {
118         _seniverseResultModel = [[CHMSeniverseResultModel alloc] init];
119     }
120     return _seniverseResultModel;
121 }
122 
123 - (RACCommand *)weatherDataCommand {
124     if (!_weatherDataCommand) {
125         _weatherDataCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(NSDictionary *dic) {
126             
127             DebugLog(@"请求当前的天气情况 %@", dic);
128             
129             return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
130                 
131                 MLURLSessionTask *task = [MLNetworkingManager requestWeatherWithAPI:kSeniverseAPI location:[dic objectForKey:@"location"] language:[dic objectForKey:@"language"] unit:@"c" success:^(CHMSeniverseResultModel *response) {
132                     [CHMLocationManager sharedInstance].seniverseResultModel = response;
133                     [subscriber sendNext:response];
134                     [subscriber sendCompleted];
135                 } fail:^(NSError *error) {
136                     [subscriber sendError:error];
137                 }];
138                 
139                 return [RACDisposable disposableWithBlock:^{
140                     [task cancel];
141                 }];
142             }];
143         }];
144     }
145     return _weatherDataCommand;
146 }
147 
148 @end
 1 + (MLURLSessionTask *)requestWeatherWithAPI:(NSString *)API location:(NSString *)location language:(NSString *)language unit:(NSString *)unit success:(MLResponseSuccess)success fail:(MLResponseFail)fail {
 2     NSString *tempURLStr = [NSString stringWithFormat:@"https://api.seniverse.com/v3/weather/now.json?key=%@&location=%@&language=%@&unit=%@", API, location, language, unit];
 3     
 4     NSURLSessionTask *task = [MLNetworking getWithUrl:tempURLStr refreshCache:YES showMBProHUD:NO success:^(id response) {
 5         CHMSeniverseResultModel *seniverseResultModel = [CHMSeniverseResultModel mj_objectWithKeyValues:((NSArray *)[response objectForKey:@"results"]).firstObject];
 6         seniverseResultModel.seniverseNowModel = [CHMSeniverseNowModel mj_objectWithKeyValues:[((NSArray *)[response objectForKey:@"results"]).firstObject objectForKey:@"now"]];
 7         seniverseResultModel.seniverseLocationModel = [CHMSeniverseLocationModel mj_objectWithKeyValues:[((NSArray *)[response objectForKey:@"results"]).firstObject objectForKey:@"location"]];
 8         
 9         if (success) {
10             success(seniverseResultModel);
11         }
12         DebugLog(@"requestWeatherWithAPI %@", response);
13     } fail:^(NSError *error) {
14         if (fail) {
15             fail(error);
16         }
17         [MLNetworkingManager showRequestFailInfo:kFailErrorUserInfoDataStr];
18         DebugLog(@"requstWeatherWithAPI %@", error);
19     }];
20     
21     return task;
22 }

END

 

iOS定位和获取当前天气