关闭

OC学习日记17 (三) get和post

标签: OCgetpost异步
81人阅读 评论(0) 收藏 举报
分类:

get和post

前言

get和post是我们实现API接口功能所需要的两种方式,实际上需要哪种根据网站对此的要求,而我们获取到所要的消息前,根据进程继续执行与否,我们又分为同步和异步两种方式。因此,我们实际上一共要学习同步get、同步post、异步get、异步post四种方式。

API接口

例子:

我们首先要为自己的软件找一个合适的API接口,这里我就以新浪接口为例子:
注册成功后,我们随便先注册一个企业级测试应用,然后我们就有了对应的access_token值,这个值是所有新浪微博的API接口都必要的一个值。
(图片之后补上)
然后我们点击文档-API文档,找到我们需要实现的功能对应的API接口,如果我们有不懂的可以找到API测试工具去把我们要的接口选中,它会给出返回的数据的形式和例子
(图片之后补上)
我们以其中公共微博为例,我们可以找到获取公共微博的API接口为statuses/public_timeline:

对于get方式而言:

我们需要接口的最终URL地址为:
接口的json的URL地址+?+我们这个接口需要的参数&参数….
(必要的写上,可选的根据需要写,参数之间用&符号连接)
https://api.weibo.com/2/statuses/public_timeline.json + ? +access_token=|这里写我们获取到的API接口的access_token|+?+|需要的其他可选参数|
这里我们举例子所以只需要用到必要的access_token参数,代码如下:

NSString *urlString = @"https://api.weibo.com/2/statuses/public_timeline.json?access_token=|这里写我们获取到的API接口的access_token|";

同步get

获取正确的服务器URL地址

我们首先要把需要的API接口文件的最终URL用字符串接收,如果此URL含有特殊字符或中文,我们就要对此进行编码(最好进行此步骤),编码后将其转为NSURL类型。

- (IBAction)synchronizationGet:(UIButton *)sender {
    NSLog(@"同步get");
    NSString *urlString = @"https://api.weibo.com/2/statuses/public_timeline.json?access_token=|这里写我们获取到的API接口的access_token|";
    //编码
    urlString =[urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL *url=[NSURL URLWithString:urlString];

服务器连接

然后我们用NSURLConnection类型提供的方法,如果同步就用sendSynchronousRequest方法,异步就用sendAsynchronousRequest方法与服务器进行连接。然后我们根据此方法需要的参数,去建立NSURLRequest、NSURLResponse、NSError三种类型的数据。我们除此之外还可以用NSURLConnectionDataDelegate协议代理的方法去进行服务器连接。

    //创建一个url请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
    NSURLResponse *httpURLResponse;
    NSError *error;
    //NSURLConnection类,和服务器连接
    NSData *data=[NSURLConnection sendSynchronousRequest:request returningResponse:&httpURLResponse error:&error];

JSON数据格式解析

直接解析

//JSON数据格式解析,利用系统提供的API进行JSON数据解析
NSDictionary *dictionary=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSLog(@"dictionary = %@",dictionary);
NSDictionary *dic=[dictionary[@"statuses"] objectAtIndex: 0];
NSString *text=dic[@"text"];
}

用相应类解析

或者,我们可以用一个类去解析我们得到的JSON数据,这样子我们可以拆掉我们不要的外层数据,在大数据中,这样可以减轻我们解析的负担
//JSON数据格式解析,利用系统提供的API进行JSON数据解析
    NSDictionary *dictionary=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
    WeiboMode *mode1=[[WeiboMode alloc ]initWithDictionary:dictionary];
    NSString *text=[mode1.statuses[0] objectForKey:@"text"];
    NSLog(@"%@",text);
    self.textView.text=text;
}

建一个解析json数据的类

由于我们获取到新浪微博返回的数据比较繁杂,而且我们每次得到的数据里面的外层结构都是一样的,我们可以建一个相关的类去解析数据

.h文件里面:

在声明文件中,我们首先如果要解析每一层数据,就要把此层的数据全部作为属性列出来,不然会报错。
#import <Foundation/Foundation.h>

@interface WeiboMode : NSObject
@property (nonatomic,strong)NSArray *statuses;
@property (nonatomic,strong)NSNumber *hasvisible;
@property (nonatomic,strong)NSNumber *previous_cursor;
@property (nonatomic,strong)NSNumber *next_cursor;
@property (nonatomic,strong)NSNumber *total_number;
@property (nonatomic,strong)NSNumber *interval;
-(id)initWithDictionary:(NSDictionary *)dictionary;
@end

.m文件:

#import "WeiboMode.h"
@implementation WeiboMode
-(id)initWithDictionary:(NSDictionary *)dictionary{
    if (self=[super init]) {
        [self setValuesForKeysWithDictionary:dictionary];
    }
    return self;
}
@end

异步get

获取正确的服务器URL地址

- (IBAction)AynchronizationGet:(UIButton *)sender {
    NSString *urlString = @"https://api.weibo.com/2/statuses/public_timeline.json?access_token=|这里写我们获取到的API接口的access_token|";
    //编码
    urlString =[urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL *url=[NSURL URLWithString:urlString];
    //创建一个url请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];

服务器连接

服务器连接有两种方法,我们可以用协议代理的方法或直接请求的方法

用代理的方法服务器连接

(如果将异步的get和post两个方法写到同一个代理中,我们将此定义为全局变量,后面会提到)

NSURLConnection &connectionGet= [NSURLConnection connectionWithRequest:request delegate:self];

实现NSURLConnectionDataDelegate协议代理的必要的一些方法(接受完数据后,在connectionDidFinishLoading方法中解析JSON数据)

(为了接受数据,定义一个全局变量_mDataGet)

@interface ViewController ()<NSURLConnectionDataDelegate>
{
    NSMutableData *_mDataGet;
}
@end
服务器开始响应,准备向客户发送数据
-(void)connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse *)response{
    NSLog(@"服务器开始响应,准备向客户发送数据");
        _mDataGet=[NSMutableData data];

从服务器接收到数据,并且此方法会执行多次
-(void)connection:(NSURLConnection *)connection
   didReceiveData:(NSData *)data{
    NSLog(@"从服务器接收到数据,并且此方法会执行多次");
        [_mDataGet appendData:data];
}
服务器接收数据完成
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{ 
        NSLog(@"服务器接收数据完成");  
        NSDictionary *dictionary=[NSJSONSerialization JSONObjectWithData:_mDataGet options:NSJSONReadingAllowFragments error:nil];
        WeiboMode *model=[[WeiboMode alloc]initWithDictionary:dictionary];
        NSString *text=[model.statuses[0] objectForKey:@"text"];
        //更新UI需要回到主线程
        //    self.textView.text=text;
        //    [self.textView performSelectorOnMainThread:@selector(setText:) withObject:text waitUntilDone:NO];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.textView.text =text;
        });
}
更新UI需要回到主线程的方式:
不推荐:self.textView.text=text;
1.采用performSelectorOnMainThread方法
[self.textView performSelectorOnMainThread:@selector(setText:) withObject:text waitUntilDone:NO];
2. 开启一个异步操作 dispatch_async
    dispatch_async(dispatch_get_main_queue(), ^{
            self.textView.text =text;
        });

sendAsynchronousRequest方法(在completionHandler代码块中解析JSON数据)

此方法与sendSynchronousReques方法有所不同,其中有一个参数是代码块。(这里有个小技巧是:我们可以在这个参数上按回车,Xcode会自动帮我们书写正确的代码块格式)

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        NSDictionary *dictionary=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
        WeiboMode *model=[[WeiboMode alloc]initWithDictionary:dictionary];
        NSString *text=[model.statuses[0] objectForKey:@"text"];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.textView.text=text;
        });
    }];
}

同步Post

- (IBAction)SynchronizationPost:(UIButton *)sender {
    NSString *urlString=@"https://api.weibo.com/2/statuses/update.json";
    //字符串编码
    urlString =[urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL *url=[NSURL URLWithString:urlString];
    NSMutableURLRequest *mRequest=[NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
    NSString *bodyString = @"status=|这里写我们要输入的文本数据接口|&access_token=|这里写我们获取到的API接口的access_token|";
    NSData *data=[bodyString dataUsingEncoding:NSUTF8StringEncoding];
    //post 设置它的方法体
    [mRequest setHTTPMethod:@"POST"];
    [mRequest setHTTPBody:data];
    NSData *resultData=[NSURLConnection sendSynchronousRequest:mRequest returningResponse:nil error:nil];
    NSDictionary *dictionary=[NSJSONSerialization JSONObjectWithData:resultData options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"dictionary= %@",dictionary);

}

异步Post

- (IBAction)AynchronizationPost:(UIButton *)sender {
    NSString *urlString=@"https://api.weibo.com/2/statuses/update.json";
    //字符串编码
    urlString =[urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL *url=[NSURL URLWithString:urlString];
    NSMutableURLRequest *mRequest=[NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
    NSString *bodyString = @"status=|这里写我们要输入的文本数据接口|&access_token=|这里写我们获取到的API接口的access_token|";
    NSData *data=[bodyString dataUsingEncoding:NSUTF8StringEncoding];
    [mRequest setHTTPMethod:@"POST"];
    [mRequest setHTTPBody:data];
    _connectionPost=[NSURLConnection connectionWithRequest:mRequest delegate:self];

将get和post的同时写到NSURLConnectionDataDelegate协议代理的方法中

#pragma mark  -------NSURLConnectionDataDelegate-------
//服务器开始响应,准备向客户发送数据
-(void)connection:(NSURLConnection *)connection
didReceiveResponse:(NSURLResponse *)response{
    NSLog(@"服务器开始响应,准备向客户发送数据");
    if (connection ==_connectionGet) {
        _mDataGet=[NSMutableData data];
    }
    if (connection == _connectionPost) {
        _mDataPost=[NSMutableData data];
    }
}
-(void)connection:(NSURLConnection *)connection
   didReceiveData:(NSData *)data{
    NSLog(@"从服务器接收到数据,并且此方法会执行多次");
    if (connection ==_connectionGet) {

        [_mDataGet appendData:data];
    }
    if (connection ==_connectionPost) {
        [_mDataPost appendData:data];
    }
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection{ NSLog(@"服务器接收数据完成");
    if (connection == _connectionGet) {
        NSDictionary *dictionary=[NSJSONSerialization JSONObjectWithData:_mDataGet options:NSJSONReadingAllowFragments error:nil];
        WeiboMode *model=[[WeiboMode alloc]initWithDictionary:dictionary];
        NSString *text=[model.statuses[0] objectForKey:@"text"];
        //更新UI需要回到主线程
        //    self.textView.text=text;
        //    [self.textView performSelectorOnMainThread:@selector(setText:) withObject:text waitUntilDone:NO];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.textView.text =text;
        });
    }
    if (connection == _connectionPost) {
        NSDictionary *dictionary=[NSJSONSerialization JSONObjectWithData:_mDataPost options:NSJSONReadingAllowFragments error:nil];
        NSLog(@"dictionary = %@",dictionary);
    }
}
@end
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2418次
    • 积分:236
    • 等级:
    • 排名:千里之外
    • 原创:22篇
    • 转载:1篇
    • 译文:0篇
    • 评论:2条
    文章分类
    文章存档