iOS天气预报oc仿写

前言

这次仿写的天气预报是本次暑假学习中的最后一个项目,相比于前面几个项目,天气预报涉及到的网络请求以及字典数组的多级存储都是之前很少接触的知识,所以一开始比较折磨,但在学习了基本的api网络请求,以及通知传值(逆向传值)之后写的速度还是挺快的;总之通过这段时间的学习,在oc语言的使用上,感觉自己进步还是挺快的,以下是这段时间学到知识的部分总结

网络请求

当我们需要动态查找数据时,我们必须从网上去查找数据,筛选后并下载下来,这里的筛选也是模糊搜索的实现,这一部分会在代码中解释;
首先,网络请求分为五步:
1.创建请求地址
2.创建请求类
3.创建会话
4.根据会话创建任务
5.启动任务
以下是代码:

 NSString* str01 = [NSString stringWithFormat:@"https://devapi.qweather.com/v7/weather/now?location=%@&key=630ed4a9c54c464180e35e011cb97695",self.strid] ;//地址字符串的创建,这里的location是参数,通过该api的特性,来实现模糊查找,具体可以去看看api的构成
    [str01 stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]] ;//对字符串进行处理,不处理的话有可能访问不了
    NSURL* url01 = [NSURL URLWithString:str01] ;//创建URL
    NSURLRequest* request01 = [NSURLRequest requestWithURL:url01] ;//创建请求类
    NSURLSession* session01 = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]] ;//创建会话
    NSURLSessionTask* dataTask01 = [session01 dataTaskWithRequest:request01]  ;//创建会话任务
    self.datatask01 = dataTask01 ;
    [dataTask01 resume] ;//启动任务

API简单理解的话,就是一个存储大量数据的网址,网络请求的目的就是从该网址中下载数据到本地;
注意一下,API中的数据是以json格式编码的,要先进行翻译才看的懂,翻译以后是这样的:
在这里插入图片描述
我们得到的数据流转化后是一个多层的字典,字典里还有字典和数组;这里也是平时很少遇到的;具体关系看你翻译出的代码;
网络请求下载数据还要通过三个协议函数,如下:

//服务器响应方法
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
    NSLog(@"didreceivereponse") ;
    if (dataTask == self.datatask01) {
        if (self.data01 == nil) {
            self.data01 = [[NSMutableData alloc] init] ;
        } else {
            self.data01.length = 0 ;
        }
    }
    if (dataTask == self.datatask02) {
        if (self.data02 == nil) {
            self.data02 = [[NSMutableData alloc] init] ;
        } else {
            self.data02.length = 0 ;
        }
    }
    if (dataTask == self.datatask03) {
        if (self.data03 == nil) {
            self.data03 = [[NSMutableData alloc] init] ;
        } else {
            self.data03.length = 0 ;
        }
    }
    completionHandler(NSURLSessionResponseAllow) ;//接受数据流
}
//接收数据流方法
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    NSLog(@"didreceivedata") ;
    if (dataTask == self.datatask01) {
        [self.data01 appendData:data] ;
    }
    if (dataTask == self.datatask02) {
        [self.data02 appendData:data] ;
    }
    if (dataTask == self.datatask03) {
        [self.data03 appendData:data] ;
    }
}
//网络接受成功或出现错误时调用的方法
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"didcompletewithreeor") ;
    if (task == self.datatask01) {
        if (error == nil) {
            NSMutableDictionary* dict = [NSJSONSerialization JSONObjectWithData:self.data01 options:kNilOptions error:nil] ;
            self.dict01 = dict[@"now"] ;
        } else {
            NSLog(@"%@",error) ;
        }
        NSLog(@"%d",1) ;
        
    }
    if (task == self.datatask02) {
        if (error == nil) {
            NSMutableDictionary* dict = [NSJSONSerialization JSONObjectWithData:self.data02 options:kNilOptions error:nil] ;
            self.array02 = dict[@"daily"] ;
            NSLog(@"%@",self.array02[0][@"textDay"]) ;
        } else {
            NSLog(@"%@",error) ;
        }
        
       
        NSLog(@"%d",2) ;
    }
    if (task == self.datatask03) {
        if (error == nil) {
            NSMutableDictionary* dict = [NSJSONSerialization JSONObjectWithData:self.data03 options:kNilOptions error:nil] ;
            self.array03 = dict[@"hourly"] ;
        } else {
            NSLog(@"%@",error) ;
        }
       

        NSLog(@"%d",3) ;
    }
    number++ ;
    if (number %3 == 0) {
    //返回主线程调用
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{//该代码块在返回主线程时调用,
        
         }] ;
         }

注意一下,我上面是一个会话执行三个sessiontask,但他们不是同时进行的,即执行一个任务就会返回主线程再执行下一个任务,也就是说会执行三次主线程方法;且sessiontask的处理顺序是随机的;
然后就是网络请求协议函数的调用是在执行玩viewload后调用的,所以我推荐在返回主线程方法中使用我请求到的数据,免的到时候在外面使用不到数据;

通知传值

假如我们有三个界面,我们从1-2,从2-3;那我们从3-1呢,我们会想到用协议传值,但这里我们更推荐使用通知传值(逆向传值);
虽然我感觉协议传值也可以(我没试过不确定);
通知传值比协议传值还简单一些;
主要四步:
1.通过通知中心发起通知:

NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:self.arraycity,@"cityname",self.arraytemp,@"citytemp",self.arraytime, @"citytime",self.arraytext, @"citytext",self.arraymain,@"data",self.array05,@"xinqi",self.array06,@"day", nil] ;
            [[NSNotificationCenter defaultCenter] postNotificationName:@"toshouye" object:nil userInfo:dict] ;

//注意userinfo是字典类型的,他也是我们要传的值
2.通过通知中心发起观察者接受通知

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pressyubao :) name:@"toshouye" object:nil] ;

3.实现通知中的方法

- (void)pressyubao : (NSNotification*)sender {
    self.array01 = sender.userInfo[@"citytime"] ;
    self.array02 = sender.userInfo[@"cityname"] ;
    self.array03 = sender.userInfo[@"citytemp"] ;
    self.array04 = sender.userInfo[@"citytext"] ;
    self.arraymain = sender.userInfo[@"data"] ;
    self.array05 = sender.userInfo[@"xinqi"] ;
    self.array06 = sender.userInfo[@"day"] ;
    NSLog(@"%@",self.arraymain[0][@"now"][@"text"]) ;
    NSLog(@"%@",self.array06[0][0]) ;
    NSLog(@"%@",self.array04[0]) ;
    NSLog(@"passed") ;
    
}

4.取消通知

- (void)dealloc {
    //移除所有通知
//    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    //移除某个通知
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"TransDataNoti" object:nil];
}

效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值