美文网首页
定位当前城市并获取天气信息

定位当前城市并获取天气信息

作者: 蜂蜜柚子茶v | 来源:发表于2016-12-16 10:13 被阅读0次

    一、首先,说一下怎么定位当前城市

    可能定位城市有很多做法,我只写一种我在项目中应用的

    注意:我们需要打开info.plist文件添加定位权限的说明,否则程序在iOS10上会出现崩溃。

    <!-- 位置 --> 
    <key>NSLocationUsageDescription</key> 
    <string>App需要您的同意,才能访问位置</string> 
    <!-- 在使用期间访问位置 --> 
    <key>NSLocationWhenInUseUsageDescription</key> 
    <string>App需要您的同意,才能在使用期间访问位置</string> 
    <!-- 始终访问位置 --> 
    <key>NSLocationAlwaysUsageDescription</key> 
    <string>App需要您的同意,才能始终访问位置</string>
    

    iOS10其他权限设置

    1、我们需要导入框架

    #import <CoreLocation/CoreLocation.h>
    

    2、设置代理并声明一个全局变量,因为这个城市变量在获取天气的时候要用

    @interface MainAppViewController ()<CLLocationManagerDelegate>{
        NSString * currentCity; //当前城市
    }
    

    3、接下来就是重点了,直接上代码,注释很全

    //判断定位服务是否打开
        if(![CLLocationManager locationServicesEnabled])
        {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"定位服务未打开" preferredStyle:UIAlertControllerStyleAlert];
            //创建按钮
            //handler:点击按钮执行的事件
            UIAlertAction *action = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil];
            [alert addAction:action];
            [self presentViewController:alert animated:YES completion:nil];
            return;
        }
        
        self.locationManager = [[CLLocationManager alloc]init];
        //iOS8之后需要请求权限
        //判断当前手机系统是否高于8.0
        if([UIDevice currentDevice].systemVersion.floatValue >= 8.0)
        {
            //请求使用期间访问位置信息权限
            [self.locationManager requestWhenInUseAuthorization];
            //请求一直访问位置信息权限
            //[locationManager requestAlwaysAuthorization];
        }
        //定位精度 kCLLocationAccuracyBest:最精确
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        //多少米之外去更新用户位置
        //locationManager.distanceFilter = 100;
        //设置代理
        self.locationManager.delegate = self;
        //开始定位
        [self.locationManager startUpdatingLocation];
        NSLog(@"开始定位");
    
    

    4、接下来就是代理方法了

    定位失败
    //定位失败则执行此代理方法
    //定位失败弹出提示框,点击"打开定位"按钮,会打开系统的设置,提示打开定位服务
    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
        
        NSLog(@"定位失败");
        UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"允许\"定位\"提示" message:@"请在设置中打开定位" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction * ok = [UIAlertAction actionWithTitle:@"打开定位" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            //打开定位设置
            NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
            [[UIApplication sharedApplication] openURL:settingsURL];
        }];
        UIAlertAction * cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            
        }];
        
        [alertVC addAction:cancel];
        [alertVC addAction:ok];
        [self presentViewController:alertVC animated:YES completion:nil];
        
    }
    
    定位成功

    定位成功,获取到当前所在城市,也可以得到具体坐标,因为我要用城市去获取天气信息,所以我只拿到城市名字就可以了

    //定位成功
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
        NSLog(@"定位成功");
        [self.locationManager stopUpdatingLocation];
        CLLocation *currentLocation = [locations lastObject];
        CLGeocoder * geoCoder = [[CLGeocoder alloc] init];
        
        //反编码
        [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
            if (placemarks.count > 0) {
                CLPlacemark *placeMark = placemarks[0];
                currentCity = placeMark.locality;
                if (!currentCity) {
                    currentCity = @"无法定位当前城市";
                }
                NSLog(@"%@",currentCity); //这就是当前的城市
                NSLog(@"%@",placeMark.name);//具体地址:  xx市xx区xx街道   
            }
            else if (error == nil && placemarks.count == 0) {
                NSLog(@"No location and error return");
            }
            else if (error) {
                NSLog(@"location error: %@ ",error);
            }
            
        }];        
    }
    
    定位服务状态改变
    // 定位服务状态改变
     -(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
         switch (status) {
             case kCLAuthorizationStatusNotDetermined:{
                 if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
                     [self.locationManager requestAlwaysAuthorization];
                 }
                 NSLog(@"用户还未决定授权");
                 break;
             }
             case kCLAuthorizationStatusRestricted:{
                 NSLog(@"访问受限");
                 break;
             }
             case kCLAuthorizationStatusDenied:{
                 // 类方法,判断是否开启定位服务
                 if ([CLLocationManager locationServicesEnabled]) {
                     NSLog(@"定位服务开启,被拒绝");
                 } else {
                     NSLog(@"定位服务关闭,不可用");
                 }
                 break;
             }
             case kCLAuthorizationStatusAuthorizedAlways:{
                 NSLog(@"获得前后台授权");
                 break;
             }
             case kCLAuthorizationStatusAuthorizedWhenInUse:{
                 NSLog(@"获得前台授权");
                 break;
             }
             default:
                 break;
         }
     }
    

    二、有了城市,我们就可以获取天气了

    天气的api也有很多,我这里用的是聚合数据,他里面天气信息数据是免费的,基本天气的数据都有,还有具体api是怎么用的,都有详细介绍(我不是打广告的)。
    请求示例(两种都可以):
    https://op.juhe.cn/onebox/weather/query?cityname=%E6%B8%A9%E5%B7%9E&key=您申请的KEY
    
    http://op.juhe.cn/onebox/weather/query?cityname=%E6%B8%A9%E5%B7%9E&key=您申请的KEY
    
    注意:
    • 支持https,省去了很多麻烦。
    • 支持json/xml。
    • 我们定位得到的城市名字是中文编码,需要转换一下接口中cityname,下面代码里有。
    • 还需要你去聚合数据 申请一个key,免费的。
    • 建议写之前去看一下他给出来的示例 json/xml文件,很多数据你可能用得到。
    NSString *url = [NSString stringWithFormat:@"https://op.juhe.cn/onebox/weather/query?cityname=%@&key=您申请的KEY",currentCity];
                NSString *str = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                NSURL *url1 = [NSURL URLWithString:str];
                NSURLRequest *urlR = [NSURLRequest requestWithURL:url1];
                NSURLSession *session = [NSURLSession sharedSession];
                
                NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:urlR completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
                    NSString *rec = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
                    NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:[rec dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:nil];
                   // NSLog(@"weather dic is %@", dic);
                    NSDictionary *resultDic = [dic objectForKey:@"result"];
                   // NSLog(@"resultArr is %@",resultDic);
                    NSDictionary *dataDic = [resultDic objectForKey:@"data"];
                   // NSLog(@"dataArr is %@",dataDic);
                    NSArray *weatherArr = [dataDic objectForKey:@"weather"];
                   // NSLog(@"weather is %@", weatherDic);
                    //回到主线程刷新页面
                    dispatch_async(dispatch_get_main_queue(), ^{
                        //NSLog(@"weatherDic is %@");
                         NSLog(@"weatherArr[0] is %@",weatherArr[0]);
                        NSLog(@"地点:%@",currentCity);
                        NSString *date = [weatherArr[0] objectForKey:@"date"]; //日期
                        NSLog(@"日期:%@",date);
                        NSDictionary *info = [weatherArr[0] objectForKey:@"info"];
                        NSArray *day = [info objectForKey:@"day"];
                        NSArray *night = [info objectForKey:@"night"];
                        NSLog(@"温度%@-%@",night[2],day[2]);
                        NSLog(@"天气:%@",day[1]);
                        NSLog(@"风向风力:%@\%@",day[3],day[4]);
                        NSString *week = [weatherArr[0] objectForKey:@"week"];
                        NSLog(@"星期: %@",week)                    
                    });
    
    

    这样你就能得到当前城市的天气信息了,当然手动获取其他城市的天气流程是一样的。

    相关文章

      网友评论

          本文标题:定位当前城市并获取天气信息

          本文链接:https://www.haomeiwen.com/subject/fncnmttx.html