首页 > 代码库 > iOS开发项目篇—34获取用户信息

iOS开发项目篇—34获取用户信息

iOS开发项目篇—34获取用户信息

一、简单说明

需求:获取当前用户的昵称 ,需要获取当前登录用户的个人信息。
查看接口
要求传递的参数
这里要获取的时用户的昵称(所以使用用户id作为参数传入)
 
二、实现代码
 1 - (void)viewDidLoad 2 { 3     [super viewDidLoad]; 4      5     //设置导航栏内容 6     [self setupNavBar]; 7      8     //集成刷新控件 9     [self setupRefresh];10     11     //设置用户的昵称为标题12     [self setupUserInfo];13 }14 15 /**16  *设置用户的昵称为标题17  */18 -(void)setupUserInfo19 {20     //1.获得请求管理者21     AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];22     23     //2.封装请求参数24     NSMutableDictionary *params=[NSMutableDictionary dictionary];25     params[@"access_token"] =[YYAccountTool accountModel].access_token;26     params[@"uid"]=[YYAccountTool accountModel].uid;27  28     //3.发送Get请求29     [mgr GET:@"https://api.weibo.com/2/users/show.json" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary*userDict) {30         31         //字典转模型32         YYUserModel *user=[YYUserModel objectWithKeyValues:userDict];33         //设置标题34         [self.titleButton setTitle:user.name forState:UIControlStateNormal];35         36     } failure:^(AFHTTPRequestOperation *operation, NSError *error) {37 38     }];39 }

显示效果:

 新的问题:用户的昵称过长,导致在标题显示的时候出现问题。

 

三、完善

解决思路:可以根据用户的昵称(字体的长度)来设置标题按钮的实际宽度。而不是使用一个固定的值。

实现效果:

注意点:注意需要调整设置按钮宽度和高度值的代码在代码段中的位置,如果在[titleButton setTitle:@"首页" forState:UIControlStateNormal];之后再进行设置,那么self.height的值为0。

YYTitleButton.m文件

 1 // 2 //  YYTitleButton.m 3 // 4  5 #import "YYTitleButton.h" 6  7 @implementation YYTitleButton 8  9 - (id)initWithFrame:(CGRect)frame10 {11     self = [super initWithFrame:frame];12     if (self) {13         //设置图片居中14         self.imageView.contentMode=UIViewContentModeCenter;15         //当高亮的时候,不调整图片16         self.adjustsImageWhenHighlighted=NO;17         //设置文字对齐方式为右对齐18         self.titleLabel.textAlignment=NSTextAlignmentRight;19         //设置文字颜色为黑色20         [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];21         //设置文字的字体为统一的20号字体22         self.titleLabel.font=YYNavigationTitleFont;23     }24     return self;25 }26 27 //设置内部图标的frame28 -(CGRect)imageRectForContentRect:(CGRect)contentRect29 {30     CGFloat imageY=0;31     CGFloat imageW=self.height;32     CGFloat imageH=imageW;33     CGFloat imageX=self.width-imageW;34     return CGRectMake(imageX, imageY, imageW, imageH);35 36 }37 //设置内部文字的frame38 -(CGRect)titleRectForContentRect:(CGRect)contentRect39 {40     CGFloat titleY=0;41     CGFloat titleX=0;42     CGFloat titleH=self.height;43     //图片为正方形44     CGFloat titleW=self.width-self.height;45     return CGRectMake(titleX, titleY, titleW, titleH);46 }47 48 //设置title的宽度49 -(void)setTitle:(NSString *)title forState:(UIControlState)state50 {51     [super setTitle:title forState:state];52     53     //计算文字的尺寸54     CGSize titleSize=[title sizeWithFont:self.titleLabel.font];55     56     //计算按钮的宽度57     //整个标题按钮的宽度=用户昵称文字的宽度+图片的宽度+10个间距58     self.width=titleSize.width+self.height+10;59 }60 @end

先显示首页标题,延迟两秒之后变换成用户昵称

1     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{2 3         [self setupUserInfo];4 5     });

把获取的用户昵称保存起来,下次登录的时候直接使用即可。

在账号(YYAccountModel)模型中添加一个name属性,用来保存获取的用户昵称,注意需要归档等也需要修改。

YYAccountModel.h文件

 1 // 2 //  YYAccountModel.h 3 // 4  5 #import <Foundation/Foundation.h> 6  7 @interface YYAccountModel : NSObject <NSCoding> 8 /**access_token    string    用于调用access_token,接口获取授权后的access token。*/ 9 @property(nonatomic,copy)NSString *access_token;10 11 /**expires_in    string    access_token的生命周期,单位是秒数。*/12 @property(nonatomic,copy)NSString *expires_in;13  14 /**uid    string    当前授权用户的UID。*/15 @property(nonatomic,copy)NSString *uid;16 17 /**18  *expires_time    nsdate    access_token的过期时间。19  */20 @property(nonatomic,copy)NSDate *expires_time;21 22 /**    string    用户昵称*/23 @property(nonatomic,copy)NSString *name;24 25 +(instancetype)accountModelWithDcit:(NSDictionary *)dict;26 @end

YYAccountModel.m文件

 1 // 2 //  YYAccountModel.m 3 // 4  5 #import "YYAccountModel.h" 6  7 @implementation YYAccountModel 8 +(instancetype)accountModelWithDcit:(NSDictionary *)dict 9 {10     //注意,json中返回的数据和model中的成员属性不对应,因此不能直接使用KVC11     YYAccountModel *model=[[self alloc]init];12     model.access_token=dict[@"access_token"];13     model.expires_in=dict[@"expires_in"];14     model.uid=dict[@"uid"];15     16     //确定账号的过期时间= 账号创建的时间 + 有效期17     NSDate *now=[NSDate date];18     model.expires_time=[now dateByAddingTimeInterval:model.expires_in.doubleValue];19     return model;20 }21 22 /**23  *从文件中解析出一个对象的时候调用24  *在这个方法中写清楚:怎么解析文件中的数据25  */26 -(id)initWithCoder:(NSCoder *)aDecoder27 {28     if (self=[super init]) {29         self.access_token=[aDecoder decodeObjectForKey:@"access_token"];30         self.expires_in=[aDecoder decodeObjectForKey:@"expires_in"];31         self.uid=[aDecoder decodeObjectForKey:@"uid"];32         self.expires_time=[aDecoder decodeObjectForKey:@"expires_time"];33         self.name=[aDecoder decodeObjectForKey:@"name"];34     }35     return self;36 }37 38 /**39  *将对象写入到文件中的时候调用40  *在这个方法中写清楚:要存储哪些对象的哪些属性,以及怎样存储属性41  */42 -(void)encodeWithCoder:(NSCoder *)aCoder43 {44     [aCoder encodeObject:self.access_token forKey:@"access_token"];45     [aCoder encodeObject:self.expires_in forKey:@"expires_in"];46     [aCoder encodeObject:self.uid forKey:@"uid"];47     [aCoder encodeObject:self.expires_time forKey:@"expires_time"];48     [aCoder encodeObject:self forKey:@"name"];49 }50 @end

在首页设置标题的时候进行判断,如果用户的昵称已经存在,那么就使用已经保存到模型中的用户昵称,如果不存在则可以先设置为“首页”,之后读取昵称之后,再进行设置。

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

错误提示:name