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
怎么样成为程序员,学习和实践,日积月累...