iOS--封装网络请求 ——实例

转载自:http://blog.csdn.net/eduora_meimei/article/details/39933437



很值得收藏

一、简单说明

1.分析项目对网路请求(AFN框架)的依赖

 

项目中,多个控制器都使用了AFN框架发送网络请求,如果AFN2.0存在重大BUg,或者是升级至3.0版本,那么对于整个项目都是及其危险的,所有用到AFN的地方都需要做出相应的修改。

另外,如果现在要求不再使用AFN框架,而是使用一个新的框架,那么有关AFN的依赖所关联的所有代码都需要重新来过。

如果把afn这个第三方框架从项目中删除的话,那么项目就相当于作废了,这就是项目对第三方框架的强依赖的体现。

说明:使用第三方框架有很大的风险,如何去屏蔽风险?一个建议的方法是使用分层(自己写一个网络请求的工具类,面向这个类,所有控制器都使用这个类完成网络请求的发送,而这个工具类内部是使用哪个第三方框架来完成发送网络请求这个功能的,由这个工具类自己决定),以进行屏蔽。

如果以后要调整依赖的框架的话,只需要简单的调整工具类就可以了。

 

二、实现

1.新建一个网络请求工具类,负责整个项目中所有的Http网络请求

提示:同步请求会卡住线程,发送网络请求应该使用异步请求(这意味着类方法不能有返回值)

2.工具类的实现

 YYHttpTool.h文件

复制代码
 1 //
 2 //  YYHttpTool.h
 3 //网络请求工具类,负责整个项目中所有的Http网络请求
 4 
 5 #import <Foundation/Foundation.h>
 6 
 7 @interface YYHttpTool : NSObject
 8 /**
 9  *  发送一个GET请求
10  *
11  *  @param url     请求路径
12  *  @param params  请求参数
13  *  @param success 请求成功后的回调(请将请求成功后想做的事情写到这个block中)
14  *  @param failure 请求失败后的回调(请将请求失败后想做的事情写到这个block中)
15  */
16 + (void)get:(NSString *)url params:(NSDictionary *)params success:(void(^)(id responseObj))success failure:(void(^)(NSError *error))failure;
17 
18 /**
19  *  发送一个POST请求
20  *
21  *  @param url     请求路径
22  *  @param params  请求参数
23  *  @param success 请求成功后的回调(请将请求成功后想做的事情写到这个block中)
24  *  @param failure 请求失败后的回调(请将请求失败后想做的事情写到这个block中)
25  */
26 + (void)post:(NSString *)url params:(NSDictionary *)params success:(void(^)(id responseObj))success failure:(void(^)(NSError *error))failure;
27 @end
复制代码

 YYHttpTool.m文件

复制代码
 1 //
 2 //  YYHttpTool.m
 3 //
 4 
 5 #import "YYHttpTool.h"
 6 #import "AFNetworking.h"
 7 @implementation YYHttpTool
 8 +(void)get:(NSString *)url params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSError *))failure
 9 {
10     //1.获得请求管理者
11     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
12     
13     //3.发送Get请求
14     [mgr GET:url parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary*responseObj) {
15         if (success) {
16             success(responseObj);
17         }
18     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
19         if (failure) {
20             failure(error);
21         }
22     }];
23 }
24 
25 +(void)post:(NSString *)url params:(NSDictionary *)params success:(void (^)(id))success failure:(void (^)(NSError *))failure
26 {
27     //1.获得请求管理者
28     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
29     
30     //2.发送Post请求
31     [mgr POST:url parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary*responseObj) {
32         if (success) {
33             success(responseObj);
34         }
35     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
36         if (failure) {
37             failure(error);
38         }
39     }];
40 
41 }
42 @end
复制代码

3.在项目中用到AFN框架的地方使用工具类进行替换

YYHomeTableViewController.m文件

复制代码
  1 //
  2 //  YYHomeTableViewController.m
  3 //
  4 
  5 #import "YYHomeTableViewController.h"
  6 #import "YYOneViewController.h"
  7 #import "YYTitleButton.h"
  8 #import "YYPopMenu.h"
  9 #import "YYAccountModel.h"
 10 #import "YYAccountTool.h"
 11 //#import "AFNetworking.h"
 12 #import "UIImageView+WebCache.h"
 13 #import "YYUserModel.h"
 14 #import "YYStatusModel.h"
 15 #import "MJExtension.h"
 16 #import "YYloadStatusesFooter.h"
 17 #import "YYHttpTool.h"
 18 
 19 @interface YYHomeTableViewController ()<YYPopMenuDelegate>
 20 @property(nonatomic,assign)BOOL down;
 21 @property(nonatomic,strong)NSMutableArray *statuses;
 22 @property(nonatomic,strong)YYloadStatusesFooter *footer;
 23 @property(nonatomic,strong) YYTitleButton *titleButton;
 24 @end
 25 
 26 @implementation YYHomeTableViewController
 27 
 28 #pragma mark- 懒加载
 29 -(NSMutableArray *)statuses
 30 {
 31     if (_statuses==nil) {
 32         _statuses=[NSMutableArray array];
 33     }
 34     return _statuses;
 35 }
 36 - (void)viewDidLoad
 37 {
 38     [super viewDidLoad];
 39     
 40     //设置导航栏内容
 41     [self setupNavBar];
 42     
 43     //集成刷新控件
 44     [self setupRefresh];
 45     
 46     //设置用户的昵称为标题
 47     //先显示首页标题,延迟两秒之后变换成用户昵称
 48     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
 49         [self setupUserInfo];
 50     });
 51 }
 52 
 53 /**
 54  *设置用户的昵称为标题
 55  */
 56 -(void)setupUserInfo
 57 {
 58 //    //1.获得请求管理者
 59 //    AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
 60 //    
 61 //    //2.封装请求参数
 62 //    NSMutableDictionary *params=[NSMutableDictionary dictionary];
 63 //    params[@"access_token"] =[YYAccountTool accountModel].access_token;
 64 //    params[@"uid"]=[YYAccountTool accountModel].uid;
 65 // 
 66 //    //3.发送Get请求
 67 //    [mgr GET:@"https://api.weibo.com/2/users/show.json" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary*userDict) {
 68 //        
 69 //        //字典转模型
 70 //        YYUserModel *user=[YYUserModel objectWithKeyValues:userDict];
 71 //        
 72 //        //设置标题
 73 //        [self.titleButton setTitle:user.name forState:UIControlStateNormal];
 74 //       // 存储账号信息(需要先拿到账号)
 75 //        YYAccountModel *account=[YYAccountTool accountModel];
 76 //        account.name=user.name;
 77 //        //存储
 78 //        [YYAccountTool save:account];
 79 //        
 80 //    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
 81 //
 82 //    }];
 83 
 84     //1.封装请求参数
 85     NSMutableDictionary *params=[NSMutableDictionary dictionary];
 86     params[@"access_token"] =[YYAccountTool accountModel].access_token;
 87     params[@"uid"]=[YYAccountTool accountModel].uid;
 88     
 89     //2.发送网络请求
 90     [YYHttpTool get:@"https://api.weibo.com/2/users/show.json" params:params success:^(id responseObj) {
 91         //字典转模型
 92         YYUserModel *user=[YYUserModel objectWithKeyValues:responseObj];
 93         //设置标题
 94         [self.titleButton setTitle:user.name forState:UIControlStateNormal];
 95        // 存储账号信息(需要先拿到账号)
 96         YYAccountModel *account=[YYAccountTool accountModel];
 97         account.name=user.name;
 98         //存储
 99         [YYAccountTool save:account];
100     } failure:^(NSError *error) {
101         YYLog(@"请求失败");
102     }];
103 }
104 
105 //集成刷新控件
106 -(void)setupRefresh
107 {
108     // 1.添加下拉刷新控件
109     UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
110     [self.tableView addSubview:refreshControl];
111     
112     //2.监听状态
113     [refreshControl addTarget:self action:(@selector(refreshControlStateChange:)) forControlEvents:UIControlEventValueChanged];
114     
115     //3.让刷新控件自动进入到刷新状态
116     [refreshControl beginRefreshing];
117     
118     //4.手动调用方法,加载数据
119     //模拟网络延迟,延迟2.0秒
120     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
121         [self refreshControlStateChange:refreshControl];
122     });
123     
124     //5.上拉刷新数据
125     YYloadStatusesFooter *footer=[YYloadStatusesFooter loadFooter];
126     self.tableView.tableFooterView=footer;
127     self.footer=footer;
128 }
129 
130 /**
131  *  当下拉刷新控件进入刷新状态(转圈圈)的时候会自动调用
132  */
133 -(void)refreshControlStateChange:(UIRefreshControl *)refreshControl
134 {
135     //1.封装请求参数
136     NSMutableDictionary *params=[NSMutableDictionary dictionary];
137     params[@"access_token"] =[YYAccountTool accountModel].access_token;
138     //取出当前微博模型中的第一条数据,获取第一条数据的id
139     YYStatusModel *firstStatus=[self.statuses firstObject];
140     if (firstStatus) {
141         params[@"since_id"]=firstStatus.idstr;
142     }
143     
144     //2.发送网络请求
145     [YYHttpTool get:@"https://api.weibo.com/2/statuses/home_timeline.json" params:params success:^(id responseObj) {
146         
147         // 微博字典 -- 数组
148         NSArray *statusDictArray = responseObj[@"statuses"];
149         //微博字典数组---》微博模型数组
150         NSArray *newStatuses =[YYStatusModel objectArrayWithKeyValuesArray:statusDictArray];
151         
152         //把新数据添加到旧数据的前面
153         NSRange range=NSMakeRange(0, newStatuses.count);
154         NSIndexSet *indexSet=[NSIndexSet indexSetWithIndexesInRange:range];
155         [self.statuses insertObjects:newStatuses atIndexes:indexSet];
156         YYLog(@"刷新了--%d条新数据",newStatuses.count);
157         
158         //重新刷新表格
159         [self.tableView reloadData];
160         //让刷新控件停止刷新(回复默认的状态)
161         [refreshControl endRefreshing];
162         [self showNewStatusesCount:newStatuses.count];
163         
164     } failure:^(NSError *error) {
165         
166         YYLog(@"请求失败");
167         //让刷新控件停止刷新(回复默认的状态)
168         [refreshControl endRefreshing];
169     }];
170 }
171 
172 /**
173  *  加载更多的微博数据
174  */
175 - (void)loadMoreStatuses
176 {
177     // 1.封装请求参数
178     NSMutableDictionary *params = [NSMutableDictionary dictionary];
179     params[@"access_token"] = [YYAccountTool accountModel].access_token;
180     YYStatusModel *lastStatus =  [self.statuses lastObject];
181     if (lastStatus) {
182         params[@"max_id"] = @([lastStatus.idstr longLongValue] - 1);
183     }
184     
185     //2.发送网络请求
186     [YYHttpTool get:@"https://api.weibo.com/2/statuses/home_timeline.json" params:params success:^(id responseObj) {
187         // 微博字典数组
188         NSArray *statusDictArray = responseObj[@"statuses"];
189         // 微博字典数组 ---> 微博模型数组
190         NSArray *newStatuses = [YYStatusModel objectArrayWithKeyValuesArray:statusDictArray];
191     
192         // 将新数据插入到旧数据的最后面
193         [self.statuses addObjectsFromArray:newStatuses];
194         
195         // 重新刷新表格
196         [self.tableView reloadData];
197         
198         // 让刷新控件停止刷新(恢复默认的状态)
199         [self.footer endRefreshing];
200 
201     } failure:^(NSError *error) {
202         YYLog(@"请求失败--%@", error);
203         // 让刷新控件停止刷新(恢复默认的状态)
204         [self.footer endRefreshing];
205     }];
206 }
207 
208 /**
209  *  提示用户最新的微博数量
210  *
211  *  @param count 最新的微博数量
212  */
213 -(void)showNewStatusesCount:(int)count
214 {
215     //1.创建一个label
216     UILabel *label=[[UILabel alloc]init];
217     
218     //2.设置label的文字
219     if (count) {
220         label.text=[NSString stringWithFormat:@"共有%d条新的微博数据",count];
221     }else
222     {
223         label.text=@"没有最新的微博数据";
224     }
225     
226     //3.设置label的背景和对其等属性
227     label.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageWithName:@"timeline_new_status_background"]];
228     label.textAlignment=UITextAlignmentCenter;
229     label.textColor=[UIColor whiteColor];
230     
231     //4.设置label的frame
232     label.x=0;
233     label.width=self.view.width;
234     label.height=35;
235 //    label.y=64-label.height;
236    label.y=self.navigationController.navigationBar.height+20-label.height;
237     
238     //5.把lable添加到导航控制器的View上
239 //    [self.navigationController.view addSubview:label];
240     //把label添加到导航控制器上,显示在导航栏的下面
241     [self.navigationController.view insertSubview:label belowSubview:self.navigationController.navigationBar];
242     
243     //6.设置动画效果
244     CGFloat duration=0.75;
245     //设置提示条的透明度
246     label.alpha=0.0;
247    [UIView animateWithDuration:duration animations:^{
248        //往下移动一个label的高度
249        label.transform=CGAffineTransformMakeTranslation(0, label.height);
250        label.alpha=1.0;
251    } completion:^(BOOL finished) {//向下移动完毕
252        
253        //延迟delay秒的时间后,在执行动画
254        CGFloat delay=0.5;
255        
256        [UIView animateKeyframesWithDuration:duration delay:delay options:UIViewAnimationOptionCurveEaseOut animations:^{
257            
258            //恢复到原来的位置
259            label.transform=CGAffineTransformIdentity;
260            label.alpha=0.0;
261            
262        } completion:^(BOOL finished) {
263            
264            //删除控件
265            [label removeFromSuperview];
266        }];
267    }];
268 }
269 
270 /**
271  UIViewAnimationOptionCurveEaseInOut            = 0 << 16, // 开始:由慢到快,结束:由快到慢
272  UIViewAnimationOptionCurveEaseIn               = 1 << 16, // 由慢到块
273  UIViewAnimationOptionCurveEaseOut              = 2 << 16, // 由快到慢
274  UIViewAnimationOptionCurveLinear               = 3 << 16, // 线性,匀速
275  */
276 
277 /**设置导航栏内容*/
278 -(void)setupNavBar
279 {
280     self.navigationItem.leftBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_friendsearch" highImageName:@"navigationbar_friendsearch_highlighted" target:self action:@selector(friendsearch)];
281     self.navigationItem.rightBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_pop" highImageName:@"navigationbar_pop_highlighted" target:self action:@selector(pop)];
282     
283     //设置导航栏按钮
284     YYTitleButton *titleButton=[[YYTitleButton alloc]init];
285     
286     //设置尺寸
287 //    titleButton.width=100;
288         titleButton.height=35;
289 
290     //设置文字
291     YYAccountModel *account= [YYAccountTool accountModel];
292     NSString *name=account.name;
293     NSLog(@"%@",name);
294 //    name=@"yangye";
295     //判断:如果name有值(上一次登录的用户名),那么就使用上次的,如果没有那么就设置为首页
296     if (name) {
297         [titleButton setTitle:name forState:UIControlStateNormal];
298     }else{
299         [titleButton setTitle:@"首页" forState:UIControlStateNormal];
300     }
301     //设置图标
302     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
303     //设置背景
304     [titleButton setBackgroundImage:[UIImage resizedImage:@"navigationbar_filter_background_highlighted"] forState:UIControlStateHighlighted];
305     
306     //设置尺寸
307 //    titleButton.width=100;
308 //    titleButton.height=35;
309     //监听按钮的点击事件
310     [titleButton addTarget:self action:@selector(titleButtonClick:) forControlEvents:UIControlEventTouchUpInside];
311     self.navigationItem.titleView=titleButton;
312     self.titleButton=titleButton;
313 }
314 -(void)titleButtonClick:(UIButton *)titleButton
315 {
316 
317         [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_up"] forState:UIControlStateNormal];
318         
319         UITableView *tableView=[[UITableView alloc]init];
320         [tableView setBackgroundColor:[UIColor yellowColor]];
321         YYPopMenu *menu=[YYPopMenu popMenuWithContentView:tableView];
322         [menu showInRect:CGRectMake(60, 55, 200, 200)];
323         menu.dimBackground=YES;
324 
325     menu.arrowPosition=YYPopMenuArrowPositionRight;
326         menu.delegate=self;
327 }
328 
329 
330 #pragma mark-YYPopMenuDelegate
331 //弹出菜单
332 -(void)popMenuDidDismissed:(YYPopMenu *)popMenu
333 {
334     YYTitleButton *titleButton=(YYTitleButton *)self.navigationItem.titleView;
335     [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];
336 }
337 -(void)pop
338 {
339     YYLog(@"---POP---");
340 }
341 -(void)friendsearch
342 {
343     //跳转到one这个子控制器界面
344     YYOneViewController *one=[[YYOneViewController alloc]init];
345     one.title=@"One";
346     //拿到当前控制器
347     [self.navigationController pushViewController:one animated:YES];
348     
349 }
350 
351 #pragma mark - Table view data source
352 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
353 {
354 #warning 监听tableView每次显示数据的过程
355     //在tableView显示之前,判断有没有数据,如有有数据那么就显示底部视图
356     self.footer.hidden=self.statuses.count==0;
357     return self.statuses.count;
358 }
359 
360 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
361 {
362     static NSString *ID = @"cell";
363     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
364     if (!cell) {
365         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
366     }
367     
368       //取出这行对应的微博字典数据,转换为数据模型
369     YYStatusModel *status=self.statuses[indexPath.row];
370     cell.textLabel.text=status.text;
371     cell.detailTextLabel.text=status.user.name;
372     NSString *imageUrlStr=status.user.profile_image_url;
373     [cell.imageView setImageWithURL:[NSURL URLWithString:imageUrlStr] placeholderImage:[UIImage imageWithName:@"avatar_default_small"]];
374     
375     return cell;
376 }
377 
378 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
379 {
380     //点击cell的时候,跳到下一个界面
381     UIViewController *newVc = [[UIViewController alloc] init];
382     newVc.view.backgroundColor = [UIColor redColor];
383     newVc.title = @"新控制器";
384     [self.navigationController pushViewController:newVc animated:YES];
385 }
386 
387 #pragma mark-代理方法
388 - (void)scrollViewDidScroll:(UIScrollView *)scrollView
389 {
390     if (self.statuses.count <= 0 || self.footer.isRefreshing) return;
391     
392     // 1.差距
393     CGFloat delta = scrollView.contentSize.height - scrollView.contentOffset.y;
394     // 刚好能完整看到footer的高度
395     CGFloat sawFooterH = self.view.height - self.tabBarController.tabBar.height;
396     
397     // 2.如果能看见整个footer
398     if (delta <= (sawFooterH - 0)) {
399         // 进入上拉刷新状态
400         [self.footer beginRefreshing];
401         
402         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
403             // 加载更多的微博数据
404             [self loadMoreStatuses];
405         });
406     }
407 }
408 @end
复制代码

授权控制器

 YYOAuthViewController.m文件

复制代码
  1 //
  2 //  YYOAuthViewController.m
  3 //
  4 
  5 #import "YYOAuthViewController.h"
  6 #import "MBProgressHUD+MJ.h"
  7 //#import "AFNetworking.h"
  8 #import "YYTabBarViewController.h"
  9 #import "YYNewfeatureViewController.h"
 10 #import "YYControllerTool.h"
 11 #import "YYAccountModel.h"
 12 #import "YYAccountTool.h"
 13 #import "YYHttpTool.h"
 14 
 15 @interface YYOAuthViewController ()<UIWebViewDelegate>
 16 
 17 @end
 18 
 19 @implementation YYOAuthViewController
 20 
 21 - (void)viewDidLoad
 22 {
 23     [super viewDidLoad];
 24     
 25     //1.创建UIWebView
 26     UIWebView *webView=[[UIWebView alloc]init];
 27     webView.frame=self.view.bounds;
 28     [self.view addSubview:webView];
 29 
 30     
 31     //2.加载登陆界面
 32     NSString *urlStr=[NSString stringWithFormat:@"https://api.weibo.com/oauth2/authorize?client_id=%@&redirect_uri=%@",YYAppKey,YYRedirectURI];
 33     NSURL *url=[NSURL URLWithString:urlStr];
 34     NSURLRequest *request=[[NSURLRequest alloc]initWithURL:url];
 35     [webView loadRequest:request];
 36     
 37     //3.设置代理
 38     webView.delegate=self;
 39 }
 40 
 41 #pragma mark-UIWebViewDelegate
 42 /**
 43  *  UIWebView开始加载资源的时候调用(开始发送请求)
 44  */
 45 -(void)webViewDidStartLoad:(UIWebView *)webView
 46 {
 47     [MBProgressHUD showMessage:@"正在努力加载中···"];
 48 }
 49 
 50 /**
 51  *  UIWebView加载完毕的时候调用(请求结束)
 52  */
 53 -(void)webViewDidFinishLoad:(UIWebView *)webView
 54 {
 55     [MBProgressHUD hideHUD];
 56 }
 57 
 58 /**
 59  *  UIWebView加载失败的时候调用(请求失败)
 60  */
 61 -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
 62 {
 63     [MBProgressHUD hideHUD];
 64 }
 65 
 66 /**
 67  *  UIWebView每当发送一个请求之前,都会先调用这个代理方法(询问代理允不允许加载这个请求)
 68  *  @param request        即将发送的请求
 69  *  @return YES允许加载,NO不允许加载
 70  */
 71 -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
 72 {
 73     //1.获得请求地址
 74     NSString *urlStr=request.URL.absoluteString;
 75 //    NSLog(@"%@",urlStr);
 76     
 77     //2.判断url是否为回调地址
 78     //urlStr在字符串中的范围
 79     //设置从等号位置开始,不用再额外的找位置
 80     NSString *redirectURI=[NSString stringWithFormat:@"%@?code=",YYRedirectURI];
 81     NSRange range=[urlStr rangeOfString:redirectURI];
 82     //判断是否为回调地址
 83     if (range.location!=NSNotFound) {//是回调地址
 84         //截取授权成功后的请求标记
 85         int from=range.location+range.length;
 86         NSString *code=[urlStr substringFromIndex:from];
 87 //        YYLog(@"%@--%@--",urlStr,code);
 88         
 89         //根据code获得一个accessToken
 90         [self accessTokenWithCode:code];
 91         
 92         //禁止加载回调页面,拿到想要的东西就好了。
 93         return NO;
 94     }
 95     return YES;
 96 }
 97 /**
 98  *  根据code获得一个accessToken(发送一个Post请求)
 99  *  @param code 授权成功后的请求标记
100  */
101 -(void)accessTokenWithCode:(NSString *)code
102 {
103     //1.封装请求参数
104     NSMutableDictionary *params=[NSMutableDictionary dictionary];
105     params[@"client_id"] =YYAppKey;
106     params[@"client_secret"] =YYAppSecret;
107     params[@"grant_type"] =@"authorization_code";
108     params[@"code"] =code;
109     params[@"redirect_uri"] =YYRedirectURI;
110     
111     //2.发送网络请求
112     [YYHttpTool post:@"https://api.weibo.com/oauth2/access_token" params:params success:^(id responseObj) {
113         //隐藏遮罩
114         [MBProgressHUD hideHUD];
115         
116         //字典转模型
117         YYAccountModel *accountmodel=[YYAccountModel accountModelWithDcit:responseObj];
118         //存储账号模型
119         [YYAccountTool save:accountmodel];
120         
121         //3.2切换控制器
122         [YYControllerTool chooseRootViewController];
123     
124         YYLog(@"请求成功");
125 
126     } failure:^(NSError *error) {
127         //隐藏遮罩
128         [MBProgressHUD hideHUD];
129         YYLog(@"请求失败");
130     }];
131 }
132 @end
复制代码

发微博控制器中的处理(说明:发送带图片的微博暂时未做处理)

YYComposeViewController.m文件

复制代码
  1 //
  2 //  YYComposeViewController.m
  3 //
  4 
  5 #import "YYComposeViewController.h"
  6 #import "YYTextView.h"
  7 #import "YYComposeToolBar.h"
  8 #import "YYComposePhotosView.h"
  9 #import "YYAccountModel.h"
 10 #import "YYAccountTool.h"
 11 //#import "AFNetworking.h"
 12 #import "MBProgressHUD+MJ.h"
 13 #import "YYHttpTool.h"
 14 
 15 @interface YYComposeViewController ()<YYComposeToolBarDelegate,UITextViewDelegate,UINavigationControllerDelegate, UIImagePickerControllerDelegate>
 16 @property(nonatomic,weak)YYTextView *textView;
 17 @property(nonatomic,weak)YYComposeToolBar *toolBar;
 18 @property(nonatomic,weak)YYComposePhotosView *photoView;
 19 @end
 20 
 21 @implementation YYComposeViewController
 22 
 23 #pragma mark-初始化方法
 24 - (void)viewDidLoad
 25 {
 26     [super viewDidLoad];
 27   
 28     //设置导航栏
 29     [self setupNavBar];
 30     
 31     //添加子控件
 32     [self setupTextView];
 33     
 34     //添加工具条
 35     [self setupToolbar];
 36     
 37     //添加photoView
 38     [self setupPhotoView];
 39     
 40     //写图片代码,把五张图片写入到相册中保存
 41     for (int i=0; i<5; i++) {
 42         NSString *name=[NSString stringWithFormat:@"minion_0%d",i+1];
 43         UIImage *image=[UIImage imageNamed:name];
 44         UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
 45     }
 46     
 47 }
 48 
 49 -(void)setupPhotoView
 50 {
 51     YYComposePhotosView *photoView=[[YYComposePhotosView alloc]init];
 52     photoView.width=self.textView.width;
 53     photoView.height=self.textView.height;
 54     photoView.y=50;
 55 //    photoView.backgroundColor=[UIColor redColor];
 56     [self.textView addSubview:photoView];
 57     self.photoView=photoView;
 58 }
 59 -(void)setupToolbar
 60 {
 61     //1.创建
 62     YYComposeToolBar *toolBar=[[YYComposeToolBar alloc]init];
 63     toolBar.width=self.view.width;
 64     toolBar.height=44;
 65     self.toolBar=toolBar;
 66     //设置代理
 67     toolBar.delegate=self;
 68     
 69     //2.显示
 70 //    self.textView.inputAccessoryView=toolBar;
 71     toolBar.y=self.view.height-toolBar.height;
 72     [self.view addSubview:toolBar];
 73 }
 74 
 75 
 76 /**
 77  *  view显示完毕的时候再弹出键盘,避免显示控制器view的时候会卡住
 78  */
 79 - (void)viewDidAppear:(BOOL)animated
 80 {
 81     [super viewDidAppear:animated];
 82     
 83     // 成为第一响应者(叫出键盘)
 84     [self.textView becomeFirstResponder];
 85 }
 86 
 87 #pragma mark-UITextViewDelegate
 88 /**
 89  *  当用户开始拖拽scrollView时调用
 90  */
 91 -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
 92 {
 93     [self.view endEditing:YES];
 94 }
 95 
 96 //添加子控件
 97 -(void)setupTextView
 98 {
 99     //1.创建输入控件
100     YYTextView *textView=[[YYTextView alloc]init];
101     //设置垂直方向上拥有弹簧效果
102     textView.alwaysBounceVertical=YES;
103     textView.delegate=self;
104     //设置frame
105     textView.frame=self.view.bounds;
106     [self.view addSubview:textView];
107     self.textView=textView;
108     
109     //2.设置占位文字提醒
110     textView.placehoder=@"分享新鲜事···";
111     //3.设置字体(说明:该控件继承自UITextfeild,font是其父类继承下来的属性)
112     textView.font=[UIFont systemFontOfSize:15];
113     //设置占位文字的颜色为棕色
114     textView.placehoderColor=[UIColor lightGrayColor];
115     
116     //4.监听键盘
117     //键盘的frame(位置即将改变),就会发出UIKeyboardWillChangeFrameNotification通知
118     //键盘即将弹出,就会发出UIKeyboardWillShowNotification通知
119     [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(KeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
120     //键盘即将隐藏,就会发出UIKeyboardWillHideNotification通知
121     [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(KeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
122 }
123 
124 -(void)dealloc
125 {
126     [[NSNotificationCenter defaultCenter]removeObserver:self];
127 }
128 
129 #pragma mark-设置代理方法
130 /**
131  *当textView的内容改变的时候,通知导航栏“发送”按钮为可用
132  */
133 -(void)textViewDidChange:(UITextView *)textView
134 {
135     self.navigationItem.rightBarButtonItem.enabled=textView.text.length!=0;
136 }
137 #pragma mark-键盘处理
138 /**
139  *键盘即将弹出
140  */
141 -(void)KeyboardWillShow:(NSNotification *)note
142 {
143     YYLog(@"%@",note.userInfo);
144     //1.键盘弹出需要的时间
145     CGFloat duration=[note.userInfo [UIKeyboardAnimationDurationUserInfoKey] doubleValue];
146     
147     //2.动画
148     [UIView animateWithDuration:duration animations:^{
149         //取出键盘的高度
150         CGRect keyboardF=[note.userInfo [UIKeyboardFrameEndUserInfoKey] CGRectValue];
151         CGFloat keyboardH=keyboardF.size.height;
152         self.toolBar.transform=CGAffineTransformMakeTranslation(0, -keyboardH);
153     }];
154 }
155 
156 /**
157  *键盘即将隐藏
158  */
159 -(void)KeyboardWillHide:(NSNotification *)note
160 {
161     //1.键盘弹出需要的时间
162     CGFloat duration=[note.userInfo [UIKeyboardAnimationDurationUserInfoKey] doubleValue];
163     //2.动画
164     [UIView animateWithDuration:duration animations:^{
165         self.toolBar.transform=CGAffineTransformIdentity;
166     }];
167 }
168 
169 //设置导航栏
170 -(void)setupNavBar
171 {
172     self.title=@"发消息";
173     self.view.backgroundColor=[UIColor whiteColor];
174     self.navigationItem.leftBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"取消" style:UIBarButtonItemStyleBordered target:self action:@selector(cancel)];
175     self.navigationItem.rightBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"发送" style:UIBarButtonItemStyleBordered target:self action:@selector(send)];
176     self.navigationItem.rightBarButtonItem.enabled=NO;
177 }
178 
179 -(void)send
180 {
181     //1.发表微博
182     if (self.photoView.images.count) {
183         [self sendStatusWithImage];
184     }else
185     {
186         [self sendStatusWithoutImage];
187     }
188     //2.退出控制器
189     [self dismissViewControllerAnimated:YES completion:nil];
190 }
191 
192 /**
193  *  发送带图片的微博
194  */
195 -(void)sendStatusWithImage
196 {
197 //    //1.获得请求管理者
198 //    AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
199 //    
200 //    //2.封装请求参数
201 //    NSMutableDictionary *params=[NSMutableDictionary dictionary];
202 //    params[@"access_token"] =[YYAccountTool accountModel].access_token;
203 //    params[@"status"]=self.textView.text;
204 //    
205 //    //3.发送POST请求
206 ////    [mgr POST:@"https://api.weibo.com/2/statuses/update.json" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary*statusDict) {
207 ////
208 ////    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
209 ////
210 ////    }];
211 //    [mgr POST:@"https://upload.api.weibo.com/2/statuses/upload.json" parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
212 //#warning 目前新浪提供的发微博接口只能上传一张图片
213 //        //取出图片
214 //        UIImage *image=[self.photoView.images firstObject];
215 //        //把图片写成NSData
216 //        NSData *data=UIImageJPEGRepresentation(image, 1.0);
217 //        //拼接文件参数
218 //        [formData appendPartWithFileData:data name:@"pic" fileName:@"status.jpg" mimeType:@"image/jpeg"];
219 //        
220 //    } success:^(AFHTTPRequestOperation *operation, id responseObject) {
221 //        [MBProgressHUD showSuccess:@"发表成功"];
222 //    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
223 //        [MBProgressHUD showError:@"发表失败"];
224 //    }];
225 }
226 
227 /**
228  *  发送不带图片的微博
229  */
230 -(void)sendStatusWithoutImage
231 {
232 //    
233 //    //1.获得请求管理者
234 //    AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
235 //    
236 //    //2.封装请求参数
237 //    NSMutableDictionary *params=[NSMutableDictionary dictionary];
238 //    params[@"access_token"] =[YYAccountTool accountModel].access_token;
239 //    params[@"status"]=self.textView.text;
240 //    
241 //    //3.发送POST请求
242 //    [mgr POST:@"https://api.weibo.com/2/statuses/update.json" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary*statusDict) {
243 //        [MBProgressHUD showSuccess:@"发表成功"];
244 //    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
245 //        [MBProgressHUD showError:@"发表失败"];
246 //    }];
247 //    
248 //    //4.关闭发送微博界面
249 ////    [self dismissViewControllerAnimated:YES completion:nil];
250     
251     //1.封装请求参数
252     NSMutableDictionary *params=[NSMutableDictionary dictionary];
253     params[@"access_token"] =[YYAccountTool accountModel].access_token;
254     params[@"status"]=self.textView.text;
255     
256     //2.发送网络请求
257     [YYHttpTool post:@"https://api.weibo.com/2/statuses/update.json" params:params success:^(id responseObj) {
258          [MBProgressHUD showSuccess:@"发表成功"];
259     } failure:^(NSError *error) {
260          [MBProgressHUD showError:@"发表失败"];
261     }];
262 }
263 -(void)cancel
264 {
265     [self dismissViewControllerAnimated:YES completion:nil];
266 //    self.textView.text=@"测试";
267 }
268 
269 
270 #pragma mark-YYComposeToolBarDelegate
271 -(void)composeTool:(YYComposeToolBar *)toolbar didClickedButton:(YYComposeToolbarButtonType)buttonType
272 {
273     switch (buttonType) {
274         case YYComposeToolbarButtonTypeCamera://照相机
275             [self openCamera];
276             break;
277             
278         case YYComposeToolbarButtonTypePicture://相册
279             [self openAlbum];
280             break;
281             
282         case YYComposeToolbarButtonTypeEmotion://表情
283             [self openEmotion];
284             break;
285             
286         case YYComposeToolbarButtonTypeMention://提到
287             YYLog(@"提到");
288             break;
289             
290         case YYComposeToolbarButtonTypeTrend://话题
291             YYLog(@"打开话题");
292             break;
293             
294         default:
295             break;
296     }
297 }
298 
299 /**
300  *  打开照相机
301  */
302 -(void)openCamera
303 {
304     //如果不能用,则直接返回
305     if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) return;
306     
307     UIImagePickerController *ipc=[[UIImagePickerController alloc]init];
308     ipc.sourceType=UIImagePickerControllerSourceTypeCamera;
309     ipc.delegate=self;
310     [self presentViewController:ipc animated:YES completion:nil];
311     
312 }
313 /**
314  *  打开相册
315  */
316 -(void)openAlbum
317 {
318     //如果不能用,则直接返回
319     if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;
320     
321     UIImagePickerController *ipc=[[UIImagePickerController alloc]init];
322     ipc.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
323     ipc.delegate=self;
324     [self presentViewController:ipc animated:YES completion:nil];
325 }
326 /**
327  *  打开表情
328  */
329 -(void)openEmotion
330 {
331 
332 }
333 
334 #pragma mark-UIImagePickerControllerDelegate
335 -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
336 {
337     [picker dismissViewControllerAnimated:YES completion:nil];
338     //1.取出选取的图片
339     UIImage *image=info[UIImagePickerControllerOriginalImage];
340     
341     //2.添加图片到相册中
342     [self.photoView addImage:image];
343 }
344 @end
复制代码

 

三、补充

关于block的知识点的补充:

block的使用

不足:监控网络状态+发送带图片的微博


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值