天天看点

iOS - 网络求值URLSession协议传值

这周写天气预报用到了网络求值,我用的是URLSession协议传值

总的来说就5步

  • 创建请求地址
  • 创建请求类
  • 创建会话
  • 根据会话创建任务
  • 启动任务
  • 以及它所带的一些方法

    下面是URLSession协议传值模版

#define LIST_URL @"https://geoapi.heweather.net/v2/city/lookup?location=beijing&key=b92646e0f4194731b50870798cfad1d0"

- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //1.创建请求地址
    NSURL *url = [NSURL URLWithString:LIST_URL];
    //2.创建请求类
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //3.创建会话
    /*
     @property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
     @property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;

     + (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier
     */
    
    //delegateQueue 表示协议方法在哪个线程中执行
    
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    //4. 根据会话创建任务
    NSURLSessionDataTask * dataTask = [session dataTaskWithRequest:request];
    //5. 启动任务
    [dataTask resume];
}

//接收到服务器的响应
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler
{
    NSLog(@"didReceiveResponse");
    
    if(self.data == nil) {
        self.data = [[NSMutableData alloc] init];
    }else {
        self.data.length = 0;
    }
    
    /*
     NSURLSessionResponseCancel = 0,              默认请求之后步接受服务器的数据                      Cancel the load, this is the same as -[task cancel]
     NSURLSessionResponseAllow = 1,               允许接收服务器的数据                         Allow the load to continue
     NSURLSessionResponseBecomeDownload = 2,      转成下载任务                         Turn this request into a download
     NSURLSessionResponseBecomeStream            转成流*/
    completionHandler  (NSURLSessionResponseAllow);
}

//接收到数据,该方法会被调用多次
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
    
    NSLog(@"didReceiveData");
    [self.data appendData:data];
}

//数据请求完成或请求出现错误
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullable NSError *)error
{
    NSLog(@"didCompleteWithError");
    
    if(error == nil) {
        //解析数据
        id objc = [NSJSONSerialization JSONObjectWithData:self.data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"--%@", objc);
    }
}
           

在实际的运用当中,先放一段我的代码中的节选

- (void)pass:(NSString *)str {
    
    NSLog(@"%@", str);
    
    NSString *string = [NSString stringWithFormat:@"https://yiketianqi.com/api?version=v9&appid=82228326&appsecret=gk6TsRcE&city=%@",str];
    
    //处理字符,有些中文,,,
    string = [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
    //1. 创建请求地址
    NSURL *url = [NSURL URLWithString:string];
    //2. 创建请求类
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //3. 创建会话
    //NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    NSURLSession *session = [NSURLSession sharedSession];
    //4. 根据会话创建任务
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
        
        //str = [NSMutableString stringWithFormat:@"%@",dic[@"location"][0][@"now"][@"temp"]];
        //NSString *str = [NSString stringWithFormat:@"%@",dic[@"location"][0][@"now"][@"temp"]];
        NSString *str1 = [NSString stringWithFormat:@"%@",dic[@"data"][0][@"date"]];
        [self.timeArray addObject:str1];
        //[self->_tmpDictionary setObject:str forKey:self->_nameArray];
        NSLog(@"%@",str1);
        //NSLog(@"%@",dic);
        
        //str = [NSMutableString stringWithFormat:@"%@",dic[@"location"][0][@"now"][@"obsTime"]];
        NSString *str2 = [NSString stringWithFormat:@"%@",dic[@"data"][0][@"tem"]];
        [self.tmpArray addObject:str2];
        NSLog(@"%@",str2);
       
        [self.nameArray addObject:str];
        
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [self.tableView reloadData];
        }];
    }];
    //5. 启动任务
    [dataTask resume];
}
           
  1. 首先我这个例子是传入了一个字符串,然后接下来之后的动作
  2. 通常会建一个字符串,用于接收请求的网站,而不是宏定义那个网站,因为搜索的城市或者其他属性会发生变化
  3. 在第四步根据会话创建任务中,你所请求的内容会根据翻译过来的json字符串发生相应的变化

    先看一下我请求到的数据翻译成json的样子

{
    "cityid":"101090801",
    "city":"衡水",
    "cityEn":"hengshui",
    "country":"中国",
    "countryEn":"China",
    "update_time":"2020-08-09 21:12:26",
    "data":[
        {
            "day":"09日(星期日)",
1           "date":"2020-08-09",
            "week":"星期日",
            "wea":"多云",
            "wea_img":"yun",
            "wea_day":"多云",
            "wea_day_img":"yun",
            "wea_night":"多云",
            "wea_night_img":"yun",
2           "tem":"29",
            "tem1":"33",
            "tem2":"25",
            "humidity":"74%",
            "visibility":"24.09km",
            "pressure":"994",
            "win":[
                "东南风",
                "南风"
            ],
            "win_speed":"<3级",
            "win_meter":"小于12km/h",
            "sunrise":"05:27",
            "sunset":"19:18",
            "air":"39",
            "air_level":"优",
            "air_tips":"空气很好,可以外出活动,呼吸新鲜空气,拥抱大自然!",
            "alarm":{
                "alarm_type":"",
                "alarm_level":"",
                "alarm_content":""
            },
4           "hours":[
                {
                    "hours":"21时",
                    "wea":"多云",
                    "wea_img":"yun",
                    "tem":"27",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"22时",
                    "wea":"多云",
                    "wea_img":"yun",
                    "tem":"26",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"23时",
                    "wea":"晴",
                    "wea_img":"qing",
                    "tem":"26",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"00时",
                    "wea":"晴",
                    "wea_img":"qing",
                    "tem":"26",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"01时",
                    "wea":"多云",
                    "wea_img":"yun",
                    "tem":"25",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"02时",
                    "wea":"多云",
                    "wea_img":"yun",
                    "tem":"25",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"03时",
                    "wea":"多云",
                    "wea_img":"yun",
                    "tem":"25",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"04时",
                    "wea":"多云",
                    "wea_img":"yun",
                    "tem":"24",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"05时",
                    "wea":"多云",
                    "wea_img":"yun",
                    "tem":"24",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"06时",
                    "wea":"多云",
                    "wea_img":"yun",
                    "tem":"25",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"07时",
                    "wea":"多云",
                    "wea_img":"yun",
                    "tem":"26",
                    "win":"南风",
                    "win_speed":"<3级"
                }
            ],
        },
        {
            "day":"10日(星期一)",
            "date":"2020-08-10",
3           "week":"星期一",
            "wea":"雷阵雨转阴",
            "wea_img":"lei",
            "wea_day":"雷阵雨",
            "wea_day_img":"lei",
            "wea_night":"阴",
            "wea_night_img":"yin",
            "tem":"33",
            "tem1":"33",
            "tem2":"24",
            "humidity":"",
            "visibility":"",
            "pressure":"",
            "win":[
                "南风",
                "北风"
            ],
            "win_speed":"<3级",
            "win_meter":"",
            "sunrise":"05:27",
            "sunset":"19:17",
            "air":"",
            "air_level":"",
            "air_tips":"",
            "alarm":{
                "alarm_type":"",
                "alarm_level":"",
                "alarm_content":""
            },
            "hours":[
                {
                    "hours":"08时",
                    "wea":"多云",
                    "wea_img":"yun",
                    "tem":"27",
                    "win":"南风",
                    "win_speed":"<3级"
                },
                {
                    "hours":"09时",
                    "wea":"雷阵雨",
                    "wea_img":"lei",
                    "tem":"28",
                    "win":"南风",
                    "win_speed":"<3级"
                },
           

因为只是举例,所以只选取了一部分

例如我的代码里

4.

NSString *str1 = [NSString stringWithFormat:@"%@",dic[@"data"][0][@"date"]];

NSString *str2 = [NSString stringWithFormat:@"%@",dic[@"data"][0][@"tem"]];

str1所对应的就是我在上面标注的1的位置的data对应的字符串,是个日期

str2所对应的就是我在上面标注的1的位置的tem对应的字符串,是个维度

5. 我举一些其他的例子

big.cell2time3 = [NSString stringWithFormat:@"%@", dic[@"data"][2][@"week"]];

这个对应的就是data的第二个组数据{}中对应的week,即上面标注3的位置。

for(int i = 0; i < 11; i++) {
            //NSString *strhour = [NSString stringWithFormat:@"%@", dic[@"data"][@"hours"][i][@"hours"]];
            NSString *strhour = [[NSString alloc] initWithFormat:@"%@",[[[dic objectForKey:@"data"][0] objectForKey:@"hours"][i] objectForKey:@"hours"]];
            [self.hourtimeArray addObject:strhour];
}
           

这个循环,对应的是date里hours里的11个小hours,晴仔细看我上面标注的4位置及4以下的10个hours包括的{}括号,即21时,22时,23时…

这里的objectForKey指进入一个[]包括的内容。

NSString *str = [NSString stringWithFormat:@"%@", dic[@"location"][i][@"name"]];
相等于   
NSString *str = [NSString stringWithFormat:@"%@", array[i][@"name"]];
           

另外这两行代码和上面的json代码无关,我只是想表达,这两行的最终呈现是一样的,只是写法有所不同,便于理解。

在我看来,根据json读取数据来写代码,其实类似于数组取值,大括号时字典,中括号时数组。以上的几个例子也解释了一下,可以对照着好好看看。