iOS 10获取定位,根据位置获取天气
有时候我们在实现类似于日记本,天气预报等效果的时候,总是免不了获取用户手机当前的地理位置,根据位置进行网络请求获取天气预报,然后呈现给用户。iOS 10里面对用户隐私进行了更深入的保护,下面我们来看看iOS系统下的定位与天气。
配置相关设置,导入AFNetWorking第三方库
先在info.plist里面加入Privacy - Location Always Usage Description以及Privacy - Location When In Use Usage Description字段以获取用户手机定位权限。用cocoaPods或者手动导入AFNetWoking框架。
配置三方网络请求类
写一个NetRequest类,继承自NSObject
NetRequest.h
#import <Foundation/Foundation.h>
@interface NetRequest : NSObject
//get
+ (void)GET:(NSString *)url parameters:(NSDictionary *)parameters sucess:(void (^)(id responseObject))sucess failure:(void(^)(NSError *error))failure;
//post
+ (void)POST:(NSString *)url parameters:(NSDictionary *)parameters sucess:(void (^)(id responseObject))sucess failure:(void(^)(NSError *error))failure;
@end
NetRequest.m
#import "NetRequest.h"
#import "AFNetworking.h"
@implementation NetRequest
+ (void)GET:(NSString *)url parameters:(NSDictionary *)parameters sucess:(void (^)(id))sucess failure:(void (^)(NSError *))failure{
//实例化网络请求管理类
AFHTTPSessionManager *manger = [AFHTTPSessionManager manager];
//配置请求超时时间
manger.requestSerializer.timeoutInterval = 8;
//配置MIME类型
manger.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html", nil];
[manger GET:url parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
sucess(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(error);
}];
}
+ (void)POST:(NSString *)url parameters:(NSDictionary *)parameters sucess:(void (^)(id))sucess failure:(void (^)(NSError *))failure{
//实例化网络请求管理类
AFHTTPSessionManager *manger = [AFHTTPSessionManager manager];
//配置请求超时时间
manger.requestSerializer.timeoutInterval = 8;
//配置MIME类型
manger.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html", nil];
[manger POST:url parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//执行成功
sucess(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//执行失败
failure(error);
}];
}
@end
主页面实现
主页面代码
#define URL @"http://op.ju.cn/onebox/weather/query?"
#define KEY @"27713e981ae6ac23a93bdd066967"
#import "NetRequest.h"
#import <CoreLocation/CoreLocation.h> //添加定位服务头文件(不可缺少)
@interface NewRecordViewController ()<CLLocationManagerDelegate>
//定位地址
@property (nonatomic, strong) CLLocationManager *locationManager;//定位服务管理类
@property (nonatomic, assign) NSInteger locationNumber;
@property (nonatomic, strong) NSDictionary *dic;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
_locationManager = [[CLLocationManager alloc] init];//创建CLLocationManager对象
_locationManager.delegate = self;//设置代理,这样函数didUpdateLocations才会被回调
[_locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];//精确到10米范围
[_locationManager requestAlwaysAuthorization];
[_locationManager startUpdatingLocation]; //启动定位服务
self.locationNumber = 0;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// 设备的当前位置
CLLocation *currLocation = [locations lastObject];
[_locationManager stopUpdatingLocation];
CLGeocoder *geocoder = [[CLGeocoder alloc]init];
[geocoder reverseGeocodeLocation:currLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
for (CLPlacemark *place in placemarks) {
NSDictionary *location = [place addressDictionary];
NSString *city = [location objectForKey:@"City"];
NSString *subLocality = [location objectForKey:@"SubLocality"];
NSString *street = [location objectForKey:@"Street"];
if (city == nil) {
city = @"";
}if (subLocality == nil) {
subLocality = @"";
}if (street == nil) {
street = @"";
}
self.locationLabel.text = [NSString stringWithFormat:@"%@%@%@",city,subLocality,street];
if (self.locationNumber == 0) {
//进行天气网络请求
self.locationNumber += 1;
[self dicWithUrl:subLocality subLocality:city];
}
}
}];
}
- (void)dicWithUrl:(NSString *)city subLocality:(NSString *)subLocality{
NSString *url = [NSString stringWithFormat:@"%@cityname=%@&key=%@",URL,city,KEY];
NSString *utf8String = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
[NetRequest GET:utf8String parameters:nil sucess:^(id responseObject) {
if ([responseObject[@"error_code"] integerValue] == 0) {
self.dic = responseObject[@"result"][@"data"][@"weather"][0];
self.temperatureLabel.text = [NSString stringWithFormat:@"%@ %@-%@℃",self.dic[@"info"][@"day"][1],self.dic[@"info"][@"night"][2],self.dic[@"info"][@"day"][2]];
self.weatherImg.image = IMGNAME(self.dic[@"info"][@"day"][1]);
self.weatherImgString = self.dic[@"info"][@"day"][1];
} else {
if (city.length > 2) {
[self dicWithUrl:[city substringToIndex:city.length - 1] subLocality:subLocality];
} else {
[self dicWithUrl:[subLocality substringToIndex:subLocality.length - 1] subLocality:[subLocality substringToIndex:subLocality.length - 1]];
}
}
} failure:^(NSError *error) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"天气获取失败" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *a = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
[alert addAction:a];
[self presentViewController:alert animated:true completion:nil];
}];
}
获取天气API是在网络上拿的免费API,各位看官大人就自行处理吧。在获取天气的时候又一些小细节需要处理,我们有时候在得到一个城市的时候,传入API获取数据是获取不了的,需要我们对得到的地址进行操作。我的方法就是一个字一个字的删除,直到API传回数据之后才结束。各位有什么其它更好的方法可以跟我交流。