ios sinaweibo 客户端(三)
这个页面要讲述的是用户的粉丝列表,下面是效果图:
可以看到这个视图明显也是一个tableview,在每一个cell中包含的有三个部分的内容:粉丝头像image,粉丝昵称label,我和粉丝之间的相互关注情况button。
在这个页面我们主要处理的内容有:① 粉丝列表数据的获取 ②tableview视图界面的组织(重点是:添加关注和取消关注)
(1)首先是获取粉丝列表数据,这部分内容没有什么好说的,就是些JSON数据,然后解析。调用的API:https://api.weibo.com/2/friendships/followers.json。其中有一个点是需要注意的。我们注意到其中API请求的参数:
count | false | int | 单页返回的记录条数,默认为50,最大不超过200。 |
cursor | false | int | 返回结果的游标,下一页用返回值里的next_cursor,上一页用previous_cursor,默认为0。 |
可以知道一次数据请求是以页的方式返回的,每一页返回count条数的粉丝记录,这个和前面微博内容的返回的差不多的,都是以页为单位返回,但是这里有一个比较特殊的是,在这个API的数据请求中没有page这个参数,而是用到了cursor这个参数,这个参数开始是0,以后每一次请求后获取的数据中就有next_cursor这个返回值,用它来为cursor赋值,就可以继续获取接下去的数据了,如果粉丝数据已经全部获取到了,那么这个值返回就又是0了。那么我们在继续加载的时候就可以添加一个判断,判断next_cursor是否为0,如果不为0,说明粉丝列表还没有加载完毕,可以继续请求加载;如果为0,则说明所有的粉丝数据都已经加载了,这时就不要继续再加载了。
下面通过代码看看吧!
- - (void) loadFollersDataWithCursor:(int) cursor {
- dispatch_async(dispatch_get_global_queue(0, 0), ^{
- dispatch_sync(dispatch_get_global_queue(0, 0), ^{
- hud = [[MBProgressHUD alloc] init];
- hud.dimBackground = YES;
- hud.labelText = @"正在加载数据...";
- [hud show:YES];
- [self.view addSubview:hud];
- //同步GET请求粉丝数据
- NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:[InfoForSina returnFollowersUrlStringWithCursor:cursor]]];
- NSError *error;
- NSData *followersData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
- //使用JSONKit解析数据
- NSString *follwersString = [[NSString alloc] initWithData:followersData encoding:NSUTF8StringEncoding];
- NSDictionary *followersDictionary = [follwersString objectFromJSONString];
- NSArray *followersArray = [followersDictionary objectForKey:@"users"];
- followersCount = [[followersDictionary objectForKey:@"total_number"] integerValue]; //粉丝总数
- nextCursor = [[followersDictionary objectForKey:@"next_cursor"] integerValue]; //粉丝列表
- for (NSDictionary *dictionary in followersArray) {
- User *followersUser = [[User alloc] init];
- [followersUser initUserWithDictionary:dictionary];
- [self.followersMutableArray addObject:followersUser];
- }
- });
- dispatch_sync(dispatch_get_main_queue(), ^{
- [self.tableView reloadData];
- [hud removeFromSuperview];
- });
- });
- }
- //处理tableview滑动到底了
- - (void) scrollViewDidScroll:(UIScrollView *)scrollView {
- CGPoint contentOffsetPoint = self.tableView.contentOffset;
- CGRect frame = self.tableView.frame;
- if (contentOffsetPoint.y == self.tableView.contentSize.height - frame.size.height)
- {
- if (nextCursor!=0) {
- [self loadFollersDataWithCursor:nextCursor];
- }
- //全部加载完毕
- else {
- MBProgressHUD *endHud = [[MBProgressHUD alloc] init];
- endHud.mode = MBProgressHUDModeText;
- endHud.labelText = @"提示";
- endHud.detailsLabelText = @"粉丝数据已全部加载!";
- [self.tableView addSubview:endHud];
- [endHud show:YES];
- [endHud hide:YES afterDelay:0.5];
- }
- }
- }
注意到其中的nextCursor这个参数,就是用来继续加载的关键参数,在开始的时候
nextCursor = 0;
[self loadFollersDataWithCursor:nextCursor];
以后每一次加载数据的时候就用获取到的新值为它重新赋值。
(2)tableview视图界面的组织
这里粉丝头像和粉丝的昵称的显示就不多说了,很简单的。代码如下:
- - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- static NSString *CellIdentifier = @"FansCell";
- FansCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
- if (cell == nil) {
- cell = [[FansCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
- }
- //这里的User类就是表示一个粉丝
- User *aUser = [[User alloc] init];
- aUser = [_followersMutableArray objectAtIndex:[indexPath row]];
- cell.nameLabel.adjustsFontSizeToFitWidth = YES;
- cell.nameLabel.text = aUser.nameString;
- //设置按键文字
- cell.fansButtonLabel.titleLabel.adjustsFontSizeToFitWidth = YES;
- if (aUser.following) {
- //表示我已经关注了该粉丝
- [cell.fansButtonLabel setTitle:@"互相关注" forState:UIControlStateNormal];
- }
- else {
- [cell.fansButtonLabel setTitle:@"+关注" forState:UIControlStateNormal];
- }
- //设置头像
- __block NSData *imageData;
- dispatch_async(dispatch_get_global_queue(0, 0), ^{
- dispatch_sync(dispatch_get_global_queue(0, 0), ^{
- imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:aUser.profileImageURL]];
- });
- dispatch_sync(dispatch_get_main_queue(), ^{
- UIImage *image = [[UIImage alloc] initWithData:imageData];
- [cell.imageView setImage:image];
- });
- });
- //头像设置圆角
- CALayer *l = [cell.imageView layer]; //获取ImageView的层
- [l setMasksToBounds:YES];
- [l setCornerRadius:6.0];
- //设置粉丝的id号,这里只是为取消关注或者添加关注的请求参数用
- cell.fansUIDString = aUser.IDString;
- return cell;
- }
说明:
1、里面的头像我设置成圆角,这时需要#import "QuartzCore/QuartzCore.h",其他都可以看懂的吧。
2、其中获取头像的方法是:
- -(UIImage *) getImageFromURL:(NSString *)fileURL {
- UIImage * resultImage = [[UIImage alloc] init];
- NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:fileURL]];
- resultImage = [UIImage imageWithData:data];
- return resultImage;
- }
在这一部分的内容中要值得说明的是我添加的那个按键的处理。首先说一下我这个按键的作用:我们在获取到的粉丝JSON数据中有:follow_me和following这两个项,前者表示的是该粉丝是否关注我,显然我的粉丝肯定是关注我的啦,所以一直返回是true;后者表示的是我是否关注这个粉丝,有关注返回true,否则就返回false。所以我们就可以在这里面做点事情了。
如果我没有关注这个粉丝即following是false的话,button的作用就是可以添加对这个粉丝的关注,button的label就是“+关注”。
如果我关注了这个粉丝即following是true的话,button的作用就是可以取消对这个粉丝的关注,button的label就是“取消关注”;
由于有这部分的处理,所以我定义了一个Fanscell类专门是用于处理cell这部分的内容。
下面着重讲的是关注和取消关注粉丝的处理。
①、请求API及参数
添加关注的API:https://api.weibo.com/2/friendships/create.json
取消关注的API: https://api.weibo.com/2/friendships/destroy.json
二者调用时所需的参数除了access_token之外,还要粉丝的uid或者screen_name(二选一),注意前者是long long (int64)类型,后者是string类型,我选用的是uid这个参数。
②、Fanscell类
其中包括的有:
- - (IBAction)fansButton:(id)sender;
- @property (weak, nonatomic) IBOutlet UIButton *fansButtonLabel;
- @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
- @property (weak, nonatomic) IBOutlet UIImageView *headImageView;
- @property (strong, nonatomic) NSString *fansUIDString;//粉丝的UID
其中的fansButton方法是用来处理关注和取消关注粉丝的。
下面先给出处理的过程代码再解说:
- - (IBAction)fansButton:(id)sender {
- destroyFriendships = NO;
- creatFriendships = NO;
- if ([self.fansButtonLabel.titleLabel.text isEqualToString:@"互相关注"]) {
- destroyFriendships = YES;
- UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"是否取消关注" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
- [alert show];
- }
- else if ([self.fansButtonLabel.titleLabel.text isEqualToString:@"+关注"]) {
- creatFriendships = YES;
- UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"是否关注" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
- [alert show];
- }
- }
- - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
- //取消关注
- if (destroyFriendships && buttonIndex == 1) {
- MBProgressHUD *custuonHUD = [[MBProgressHUD alloc]init];
- custuonHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
- custuonHUD.mode = MBProgressHUDModeCustomView;
- [self addSubview:custuonHUD];
- NSURL *url = [NSURL URLWithString:FRIENDSHIPS_DESTROY];
- ASIFormDataRequest *item = [[ASIFormDataRequest alloc] initWithURL:url];
- [item setPostValue:[InfoForSina returnAccessTokenString] forKey:@"access_token"];
- [item setPostValue:[NSString stringWithFormat:@"%lld",[_fansUIDString longLongValue]] forKey:@"uid"];
- [item setCompletionBlock:^{
- [self.fansButtonLabel setTitle:@"+关注" forState:UIControlStateNormal];
- custuonHUD.labelText = @"取消关注成功!";
- [custuonHUD show:YES];
- [custuonHUD hide:YES afterDelay:2];
- }];
- [item setFailedBlock:^{
- custuonHUD.labelText = @"取消关注失败!";
- [custuonHUD show:YES];
- [custuonHUD hide:YES afterDelay:2];
- }];
- [item startAsynchronous];
- }
- //添加关注
- else if (creatFriendships && buttonIndex == 1) {
- //使用ASI这个类库处理添加关注的数据请求
- /*
- MBProgressHUD *custuonHUD = [[MBProgressHUD alloc]init];
- custuonHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
- custuonHUD.mode = MBProgressHUDModeCustomView;
- [self addSubview:custuonHUD];
- NSURL *url = [NSURL URLWithString:FRIENDSHIPS_CREAT];
- ASIFormDataRequest *item = [[ASIFormDataRequest alloc] initWithURL:url];
- [item setPostValue:[InfoForSina returnAccessTokenString] forKey:@"access_token"];
- [item setPostValue:[NSString stringWithFormat:@"%lld",[_fansUIDString longLongValue]] forKey:@"uid"];
- [item setCompletionBlock:^{
- [self.fansButtonLabel setTitle:@"互相关注" forState:UIControlStateNormal];
- custuonHUD.labelText = @"关注成功!";
- [custuonHUD show:YES];
- [custuonHUD hide:YES afterDelay:1];
- }];
- [item setFailedBlock:^{
- custuonHUD.labelText = @"关注失败!";
- [custuonHUD show:YES];
- [custuonHUD hide:YES afterDelay:1];
- }];
- [item startAsynchronous];
- */
- //不使用ASI这个类库处理添加关注的数据请求
- NSURL *url = [NSURL URLWithString:FRIENDSHIPS_CREAT];
- NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5.0];
- [request setHTTPMethod:@"POST"];
- NSString *postString = [NSString stringWithFormat:@"access_token=%@&uid=%lld",[InfoForSina returnAccessTokenString],[_fansUIDString longLongValue]];
- NSMutableData *postData = [[NSMutableData alloc] init];
- [postData appendData:[postString dataUsingEncoding:NSUTF8StringEncoding]];
- [request setHTTPBody:postData];
- self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
- }
- }
- #pragma mark - NSURLConnection delegate Methods
- -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
- {
- self.responseData = [[NSMutableData alloc] initWithLength:0];
- }
- -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
- {
- [self.responseData appendData:data];
- }
- -(void)connectionDidFinishLoading:(NSURLConnection *)theconnection
- {
- MBProgressHUD *custuonHUD = [[MBProgressHUD alloc]init];
- custuonHUD.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]];
- custuonHUD.mode = MBProgressHUDModeCustomView;
- [self addSubview:custuonHUD];
- NSError *error;
- NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:self.responseData options:kNilOptions error:&error];
- NSString *idString = [dict objectForKey:@"idstr"];
- if(idString) {
- [self.fansButtonLabel setTitle:@"互相关注" forState:UIControlStateNormal];
- custuonHUD.labelText = @"关注成功!";
- [custuonHUD show:YES];
- [custuonHUD hide:YES afterDelay:2.3];
- }
- else {
- custuonHUD.labelText = @"关注失败!";
- [custuonHUD show:YES];
- [custuonHUD hide:YES afterDelay:2.3];
- }
- [self.connection cancel];
- }
- -(void)connection:(NSURLConnection *)theconnection didFailWithError:(NSError *)error
- {
- MBProgressHUD *failedHud = [[MBProgressHUD alloc] init];
- failedHud.mode = MBProgressHUDModeText;
- failedHud.labelText = @"提示";
- failedHud.detailsLabelText = @"发表评论失败!";
- [failedHud show:YES];
- [self addSubview:failedHud];
- [failedHud hide:YES afterDelay:1.3];
- [self.connection cancel];
- }
说明:
1、当按下这个button时会触发一个UIAlertView,提示是否确定关注和取消关注。
2、确定要关注或者取消关注粉丝的处理在UIAlertView的delegate方法中处理。
3、关注和取消关注粉丝的数据请求方式是POST,我们可以用ASIHTTPRequest来异步方式处理,也可以用不用这个类库,用系统自带的方法异步POST处理。代码中有我使用了这这两种方式。其中取消关注我是使用ASIHTTPRequest,而添加关注是使用系统自带的方法(当然注释部分也给出了ASIHTTPRequest的使用代码)。
注意,如果是使用系统自带的方式异步POST处理,我还添加了两个property:
@property (strong, nonatomic) NSURLConnection *connection;
@property (strong, nonatomic) NSMutableData *responseData;
通过代码可以清楚的看到,前一种处理方式十分简洁,后一种处理方式由于要实现delegate方法,所以感觉有点麻烦,二者孰好孰不好,自己感觉咯!
4、在数据请求结束我继续使用MBProgressHUD这个类库添加了一些提示框,表示关注是否成功或者取消关注是否成功。效果如下:
这个页面的处理差不多就是这样了!
转载于:https://www.cnblogs.com/yulang314/p/3549550.html
ios sinaweibo 客户端(三)相关推荐
- ios sinaweibo 客户端(一)
上一篇sina微博Demo已经完成的认证,下面就开始进入微博相关内容的加载及显示.其实主要的工作就是调用微博API 加载相关的json数据,然后进行解析,然后在界面中进行组织好在tableview中进 ...
- 除草机(Grasscutter) ios/Android客户端配置教程
本文章仅为Grasscutter的ios/Android客户端配置教程,不提供任何服务器,如果你按图中的数据连上了,纯属瞎猫碰到死耗子. 对应的客户端配置教程在:从零开始,一镜到底,纯净系统搭建除草机 ...
- 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)
最近看了关于XMPP的框架,以文本聊天为例,需要发送的消息为: <message type="chat" from="kang@server.com" t ...
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)
最近看了关于XMPP的框架,以文本聊天为例,需要发送的消息为: [html] view plaincopy <message type="chat" from="k ...
- iOS 苹果手机客户端微信支付调起失败--无法调起微信的原因
1. iOS 苹果手机客户端微信支付调起失败–无法调起微信的原因 微信的SDK分两种,一种包含支付的SDK,另一中是不包含支付的SDK, 因为项目早期集成的是微信分享的SDK,不带支付的功能,所以更换 ...
- android iOS App客户端如何实现在线支付
*android iOS App客户端如何实现在线支付**Q~~1⑨9⑦O*⑦46 阔别已久,小课堂再次开课,今天将和大家分享在开通各个支付渠道之前,你可能想要了解的一些信息. 对支付领域一无所知,对 ...
- 171CMS开源应用市场建站系统,包括 PC站+WAP站+APP原生客户端三站合一
适用范围: 171cms应用市场建站系统 APP下载站开源码 运行环境: php5.2.4及以上+Mysql5.1及以上(请严格按照配置环境要求运行) 程序介绍: 171CMS是国内首款针对AP ...
- iOS内购三:Receipt
iOS内购三:Receipt 可参考: Validating Receipts Locally 需验证receipt,可以在本地验证,也可以在服务端验证 本地验证,涉及到security和加密,比较复 ...
- 杯具,知名游戏的源码丢了;iOS 11 第三个开发者测试版发布
(点击上方公众号,可快速关注) 参考:开源中国.腾讯.solidot.cnBeta.IT之家等 0.杯具!<冰风谷 II>的源代码丢了! 开发了加强版 <博德之门>和<异 ...
最新文章
- 求一棵二叉树根到所有叶子节点的路径
- NOIP2016普及组第四题——魔法阵
- selenium容易忽视的知识点
- 再来一顿贺岁宴 | 从K-Means到Capsule
- web_安全_文件上传漏洞
- Cypress 的条件测试
- C++中的namespace ----转载
- 斗罗大陆真3D手游实力上线,带你感受魂兽猎杀的超燃时刻
- 【Elasticsearch】 Elasticsearch 多字段查询 best_fields、most_fields、cross_fields,傻傻分不清楚?
- android在搭建框架时要注意,Android开发搭建应用框架步骤和注意的问题
- 基于Java保险员工管理系统的设计与实现
- 解决ThinkServer TS250中网卡在centos6.5中没有安装驱动
- 【python】python基础与unittest基础
- 网易免费的企业邮箱smtp的地址
- Java程序员从笨鸟到菜鸟之(五十七)细谈Hibernate(八)Hibernate集合Map关系映射
- 自建ngrok服务支持https访问
- CCR自动炒币机器人到底有多神奇,让无数炒币人疯狂追捧
- 如何升级Python的pip?
- C++最佳实践 | 5. 可移植性及多线程
- 隐患重重遭诟病 细数固态硬盘“七宗罪”