iOS项目实战-新浪微博客户端


iOS项目实战-新浪微博客户端

本章内容概述

  • 项目准备工作
  • 搭建项目基础框架
  • 项目功能概述
  • 项目界面结构
  • 获得最新微博信息
  • 发布微博
  • 微博详细
  • 获得微博评论
  • 获得微博转发
  • 发表评论
  • 转发微博
  • 收藏微博

31.1 项目准备工作

在这一章里,我们通过一个新浪微博客户端项目,来对前面所学的基础知识进行综合,使得对基础理解更深入、使用更灵活。

开发新浪微博客户端,需要使用新浪的微博Open API接口,Open API即开放API,也称开放平台。 所谓的开放API(OpenAPI)是服务型网站常见的一种应用,网站的服务商将自己的网站服务封装成一系列API(Application Programming Interface,应用编程接口)开放出去,供第三方开发者使用,这种行为就叫做开放网站的API,所开放的API就被称作OpenAPI(开放API)。

现在Open API 服务非常多,例如,新浪微博、Google地图、豆瓣网、腾讯、淘宝等,这些Open API服务一是可以给开发这带来服务,二是可以给服务平台本身带来流量,可以说是双赢。

使用新浪微博开发平台的步骤如下:

  1. 需要注册一个微博账号。

可以在如下的地址注册新浪微博账号:http://weibo.com/signup/signup.php?c=&type=&inviteCode=&code=&spe=&lang=zh。如下图所示。

31.1 注册微博账号

  1. 注册成功后,在如下地址进行登陆: http://open.weibo.com/。如下图所示。

31.2 登陆微博

  1. 登陆成功后,选择页面的顶部连接的"应用开发"下面的"移动开发",如下图所示。

31.3 创建应用

  1. 点击右边的"创建应用"按钮,来创建应用。如下图所示。

31.4 填写应用信息

  1. 在管理中心中可以找到我们创建的应用,如下图所示。

31.5 创建好的应用

  1. 点击应用链接进入,应用的详细内容,如下图所示。

31.6 应用详细内容

  1. 在应用详细页面中,有控制台、应用信息、数据统计、接口管理、转让应用和删除应用等链接,在这些链接中我们常用到的有:应用信息和接口管理。在"应用信息"中可以获得授权的apikey和加密信息。

31.7  应用信息

  1. 在接口管理中我们可以查询到详细的api调用方法。

31.8  接口管理

通过上述步骤,我们就申请了一个应用,这需要审核,审核通过后我们就可以使用该接口开发自己的微博客户端了。

31.2 搭建项目基础框架

在上一节我们已经申请了一个应用程序,本节我们来看如何搭建项目的基础框架。要开发新浪微博客户端,官方提供了开发文档和SDK,我们可以下载开发文档学习开发步骤,并且需要将SDK集成到我们的项目当中。

下载开发文档的网站是:http://open.weibo.com/wiki。在这里选择iOS SDK进行文档和SDK的下载。如下图所示。

31.9  下载文档和SDK

在下载的SDK中包括了,包含SDK说明文档,源代码,示例代码。如下图所示。

31.10  SDK中的内容

将SDK集成到自己的项目当中需要,如下步骤:

  1. 创建新浪微博开放平台应用

1) 获取 app_key,app_secret

第三方开发者须到新浪微博开放平台 http://open.weibo.com/ 注册并创建第三方应用。进而获取应用专属 app_key 及 app_secret。App Key 及 App Secret 查看方式:第三方应用主页->应用信息->基本信息,应用基本信息一栏。

31.11  获得app\_key和app\_secret

2) 配置授权回调页

授权回调页是为 Oauth2.0 认证机制中的登录认证地址,用户登录完成后最后会跳转此地址。需在应用中配置此跳转地址才能使用 SDK 完成用户登录。授权回调页查看及设置地址:第三方应用主页->应用信息->高级信息->Oauth2.0 授权设置。

31.12  配置授权回调页

注:在使用 SDK 时,配置授权回调页是必不可少的;若没有配置,则登陆完成后 无法检测到授权地址,就无法获取授权的 token 等信息。此地址并非必须得配置成 能访问的地址,保证格式正确即可。

  1. 下载新浪微博 sdk

在新浪微博开放平台文档一页有 SDK 下载一项,找到 IOS SDK 下载链接

https://github.com/mobileresearch/weibo/ios/sdk/sso-oauth ,打开后可打包下载。

31.13  下载页

上图"ZIP"按钮,下载的 zip 包是一个编译运行的 SDK Demo。SDK 的源码是在此 demo 工程中 src 目录下,包含 JSONKit 和 SinaWeibo 两个包。

  1. 创建新应用,添加 SDK 源码及配置使用环境

1) 第三方应用在本地环境用 Xcode 新建一个工程;

2) 将 src 中的源码引入至你的工程中,如下图的 SinaWeibo,JSONKit:

31.14  配置SDK

3) 在你的工程设置项,targets 一栏下,选中自己的 target,在 Info->URL Types 中添加 URL Schemes,此值是 sso 登录时回调时所用。本例采用默认格式:"sinaweibosso."+" 自己应用的 app key",如下图:

31.15  配置URL Schemes

  1. 使用 sdk

1) 定义你的 app_key, app_secret 及授权回调页,此处定义是为了后面调用 SDK 接口做准备,如下图:

#define kAppKey             @"28796305491"

#define kAppSecret          @"76b5cd21a6e755840ce92e33f09c44d51"

#define kAppRedirectURI     @"http://www.any-phone.com"

2) 构造 SinaWeibo 对象

self.sinaweibo = [[SinaWeibo alloc] initWithAppKey:kAppKey appSecret:kAppSecret appRedirectURI:kAppRedirectURI andDelegate:self.viewController];

kAppKey,kAppSecret,kAppRedirectURI 即第一步定义的值。参数_viewController 作为 SinaWeibo 对象的代理,需要实现 SinaWeiboDelegate 接口:

3) 重写 AppDelegate 的 handleOpenURL 和 openURL 方法:

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url

{

    return [self.sinaweibo handleOpenURL:url];

}

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

{

    return [self.sinaweibo handleOpenURL:url];

}

4) 登录

直接调用 logIn 接口:[sinaweibo logIn]。

5) 接收登录信息需重写 sinaweiboDidLogIn 方法(在此例中_viewController 对象实现的 SinaWeiboDelegate 接口,故应该在此类中加入以下代码):

-(void)sinaweiboDidLogIn:(SinaWeibo *)sinaweibo{

    NSLog(@"here.......");

    NSLog(@"%msg=%@",sinaweibo);

    [self storeAuthData];

}

- (void)request:(SinaWeiboRequest *)request didFinishLoadingWithResult:(id)result{

    NSLog(@"result=%@",result);

}
  1. 运行项目,登陆界面如下所示。

31.16  登陆界面

31.3 项目功能概述

新浪微博本身的功能非常多也非常复杂,在我们的项目里主要实现了如下功能:

  1. 最新微博浏览

  2. 发布微博

  3. 微博详细

  4. 获得微博评论

  5. 获得微博转发

  6. 转发微博

  7. 收藏微博

最新微博浏览

根据如下URL,https://api.weibo.com/2/statuses/home/timeline.json。可以获得获取当前登录用户及其所关注用户的最新微博信息。请求参数如下图所示。

31.17  最新微博请求参数

31.18  最新微博运行结果

发布微博

我们也可以将我们的新鲜事分享到微博平台,根据如下URL,https://api.weibo.com/2/statuses/update.json。来发一条新微博。请求参数如下所示。

31.19  发一条新微博请求参数

程序运行结果如下所示。

31.20  发一条新微博运行结果

微博详细

根据微博ID可以获得微博详细,包括发送微博的用户信息、评论数、转发数等。根据如下URL,https://api.weibo.com/2/statuses/show.json,可以获得微博详细内容。请求参数如下:

31.21  微博详细请求参数

程序运行结果如下所示。

31.22  微博详细运行结果

获得微博评论

在微博的详细下面可以显示该条微博的评论,使用如下URL, https://api.weibo.com/2/comments/show.json ,可以获得微博类型。请求参数如下所示。

31.23  微博详细运行结果

程序运行结果如下所示。

31.24  微博评论

获得微博转发

微博详细下面列出了评论和转发内容,可以使用如下URL, https://api.weibo.com/2/statuses/repost.json ,实现微博转发。请求参数如下所示。

31.25  微博转发

程序运行结果如下所示。

31.26  微博转发

发表评论

可以针对一条微博发表评论,发表评论的URL为,https://api.weibo.com/2/comments/create.json 。请求参数如下所示。

31.27  发表评论请求参数

程序运行结果如下所示。

31.28  发表评论运行结果

转发微博

也可以转发一条微博,转发微博的URL为,https://api.weibo.com/2/statuses/repost.json。请求参数如下所示。

31.29  转发微博请求参数

程序运行结果如下所示。

31.30  转发微博运行结果

收藏微博

可以对喜爱的微博进行收藏,收藏微博的URL为,https://api.weibo.com/2/favorites/create.json。请求参数如下所示。

31.31  收藏微博请求参数

程序运行结果如下所示。

31.32  收藏微博运行结果

31.4 项目界面结构

本项目的基础UI结构采用UITabbarController+UITableView的结构,UITabbarController将内容分为首页、消息、好友、广场和更多等分区。在各个分区中一般使用UITableView来展现内容。如下图所示。

31.33  主界面结构

主界面的实现步骤如下所示。

  1. 创建一个项目。

  2. 创建一个RootViewController,程序运行到该界面登陆界面。如果登陆成功,跳转到主界面。

  3. 分别创建HomeViewController、PlaceViewController、MessageViewController、FriendViewController和MoreViewController分别表示首页、消息、好友、广场和更多。在各个控制器的初始化方法中设置Tab的标题和图片。

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        // Custom initialization

        self.tabBarItem.title = @"首页";

        UIImage *originalImage = [UIImage imageNamed:@"home.png"];

        self.tabBarItem.image = [ImageUtil scaleImage:originalImage andScale:2.0];

    }

    return self;

}

我们这里使用的图片稍大了一下,定义了一个工具类来实现图片的缩写,代码如下。

#import "ImageUtil.h"

@implementation ImageUtil

+(UIImage*)scaleImage:(UIImage*)img andScale:(float)scale{

    // 缩小2倍

    UIImage *scaledImage =

    [UIImage imageWithCGImage:[img CGImage]

                        scale:(img.scale * scale)

                  orientation:(img.imageOrientation)];

    return scaledImage;

}

@end
  1. 在RootViewController的头文件中,声明UITabbarController和其他控制器实例。
#import <UIKit/UIKit.h>

#import "SinaWeibo.h"

#import "HomeViewController.h"

#import "PlaceViewController.h"

#import "MessageViewController.h"

#import "FriendViewController.h"

#import "MoreViewController.h"

@interface RootViewController : UIViewController<SinaWeiboDelegate, SinaWeiboRequestDelegate>

// 登陆方法

- (IBAction)login:(id)sender;

// 跳转

- (void)forward;

// UITabBarController 实例

@property (strong,nonatomic) UITabBarController *myTabController;

// 首页控制器

@property (strong,nonatomic) HomeViewController *homeViewController;

// 广场控制器

@property (strong,nonatomic) PlaceViewController *placeViewController;

// 消息控制器

@property (strong,nonatomic) MessageViewController *messageViewController;

// 好友控制器

@property (strong,nonatomic) FriendViewController *friendViewController;

// 更多控制器

@property (strong,nonatomic) MoreViewController *moreViewController;

@end
  1. 在实现类的viewDidLoad方法中实例化这些控制器。
- (void)viewDidLoad

{

    [super viewDidLoad];

    SinaWeibo *swb = [self getSinaWeibo];

    [swb logIn];

    // 实例化UITabBarController

    self.myTabController = [[UITabBarController alloc]init];

    // 实例化主页控制器

    self.homeViewController = [[HomeViewController alloc]initWithNibName:@"HomeViewController" bundle:nil];

    // 主页导航控制器

    UINavigationController *homeNav = [[UINavigationController alloc]initWithRootViewController:self.homeViewController];

    // 微博广场控制器

    self.placeViewController = [[PlaceViewController alloc]initWithNibName:@"PlaceViewController" bundle:nil];

    // 广场导航

    UINavigationController *placeNav = [[UINavigationController alloc]initWithRootViewController:self.placeViewController];

    // 好友控制器

    self.friendViewController = [[FriendViewController alloc]initWithNibName:@"FriendViewController" bundle:nil];

    // 广场导航

    UINavigationController *friendNav = [[UINavigationController alloc]initWithRootViewController:self.friendViewController];

    // 消息控制器

    self.messageViewController = [[MessageViewController alloc]initWithNibName:@"MessageViewController" bundle:nil];

    // 消息导航

    UINavigationController *messageNav = [[UINavigationController alloc]initWithRootViewController:self.messageViewController];

    // 更多控制器

    self.moreViewController = [[MoreViewController alloc]initWithNibName:@"MoreViewController" bundle:nil];

    // 更多导航

    UINavigationController *moreNav = [[UINavigationController alloc]initWithRootViewController:self.moreViewController];

    // 为UITabBarController指定控制器集合

    self.myTabController.viewControllers = @[homeNav,messageNav,friendNav,placeNav,moreNav];

}
  1. 定义跳转方法,如果登陆成功,跳转到程序主界面。
// 跳转

-(void)forward{

    [self presentViewController:self.myTabController animated:YES completion:nil];

}

// 登陆成功

-(void)sinaweiboDidLogIn:(SinaWeibo *)sinaweibo{

    NSLog(@"%msg=%@",sinaweibo);

    // 保存用户数据到本地

    [self storeAuthData];

    // 跳转到主页

    [self forward];

}

31.5 获得最新微博信息

用户登陆后,进入系统主界面,在UITabBarController的"首页"Tab中显示最新微博信息。最新微博信息使用自定义表展示。如下图所示。

图 31.34 最新微博

获得最新微博信息的实现步骤如下:

  1. 导入ASIHttpRequest类库,在获得微博信息时,需要加载微博图片。这里我们使用之前讲述过的网络框架ASIHttpRequest。

1.1 下载ASIHttpRequest类库,地址如下: https://github.com/pokeb/asi-http-request/

1.2 导入类库文件。如下图所示。

图 31.35 ASIHttpRequest框架

1.3 由于ASIHttpRequest不支持ARC,需要在"Targets"下的"Build Phases"做如下图所示设置。

图 31.36 ASIHttpRequest设置

  1. 在HomeViewController中实现SinaWeiboRequestDelegate(请求代理协议)、UITableViewDataSource(表视图数据源协议)和UITableViewDelegate(表视图代理协议),并添加需要的属性。这些属性有表视图属性、数据源属性、头像属性、图片属性、用户名称、博客内容、转发数量、评论数量、创建时间、来源、推荐数量等。
#import <UIKit/UIKit.h>

#import "SinaWeibo.h"

#import "HomeTableViewCell.h"

#import "WeiboDetailViewController.h"

@interface HomeViewController : UIViewController<SinaWeiboRequestDelegate,UITableViewDataSource,UITableViewDelegate>

// 表视图属性

@property(nonatomic,strong)UITableView *tv;

// 表视图数据源

@property(nonatomic,strong)NSMutableArray *tvDataSource;

// 头像

@property(nonatomic,strong) IBOutlet UIImageView *profileImageView;

// 图片

@property(nonatomic,strong)IBOutlet UIImageView *picImageView;

// 用户名称、博客内容、转发数量、评论数量、创建时间、来源、推荐数量

@property(nonatomic,strong)IBOutlet UILabel *usernameLabel,*myTextLabel,*repostCountLabel,*commentCountLabel,*createAtLabel,*sourceLabel,*attitudeCountLabel;

// 行高

@property(nonatomic)float cellHeight;

@end
  1. 定义加载微博信息方法,并在viewDidLoad方法中调用。
// 加载微博信息

- (void)loadWeibo {

    // 获得SinaWeibo实例

    SinaWeibo *sinaweibo = [self getSinaWeibo];

    // 发出请求

    [sinaweibo requestWithURL:@"statuses/home\_timeline.json"

                       params:[NSMutableDictionary dictionaryWithObject:sinaweibo.accessToken forKey:@"access\_token"]

                   httpMethod:@"GET"

                     delegate:self];

}
  1. 加载微博信息方法调用后,微博的请求代理方法会被调用,在这样我们可以获得微博信息。
- (void)request:(SinaWeiboRequest *)request didFinishLoadingWithResult:(id)result{

   // 转换为NSDictionary

    NSDictionary *dic = (NSDictionary*)result;

    // 获得key为statuses的内容

    NSArray *statuses = [dic objectForKey:@"statuses"];

    NSLog(@"statused=%@",statuses);

    // 清除数据源

    [self.tvDataSource removeAllObjects];

    // 设置数据源

    [self.tvDataSource addObjectsFromArray:statuses];

    // 重新加载表视图

    [self.tv reloadData];

}
  1. 在viewDidLoad方法中,加载微博信息、实例化表视图、设置表视图代理和导航按钮。
- (void)viewDidLoad

{

    [super viewDidLoad];

    // 加载微博信息

    [self loadWeibo];

    // 表视图的frame

    CGRect tvFrame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);

    // 实例化表视图

    self.tv = [[UITableView alloc]initWithFrame:tvFrame];

    // 设置代理

    self.tv.dataSource = self;

    self.tv.delegate = self;

    // 将表视图添加到当前视图

    [self.view addSubview:self.tv];

    // 实例化表视图数据源

    self.tvDataSource = [NSMutableArray arrayWithCapacity:5];

    // 设置写微博导航按钮

    UIBarButtonItem *writeWeiboBtnItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemCompose target:self action:@selector(writeWeibo)];

    self.navigationItem.leftBarButtonItem = writeWeiboBtnItem;

    // 刷新微博导航按钮

    UIBarButtonItem *refreshBtnItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refresh)];

    self.navigationItem.rightBarButtonItem = refreshBtnItem;

}
  1. 自定义一个表格视图单元,HomeTableViewCell,继承UITableViewCell,实现自定义表视图行内容。
#import <UIKit/UIKit.h>

@interface HomeTableViewCell : UITableViewCell

@end
  1. 在获得表单元方法中,实例化UITableViewCell,并获得用户信息、头像URL,并异步加载头像。
// 标示id

static NSString *cid = @"cid";

// 实例化UITableViewCell

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cid];

if (cell==nil) {

    cell = [[UITableViewCell alloc]initWithFrame:CGRectZero];

}

// 获得当前行内容

NSDictionary *dic = [self.tvDataSource objectAtIndex:indexPath.row];

// 用户信息

NSDictionary *userDic = [dic objectForKey:@"user"];

// 1. 头像

NSString *profile\_image\_url = [userDic objectForKey:@"profile\_image\_url"];

NSURL *photoURL = [NSURL URLWithString:profile\_image\_url];

\_\_weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:photoURL];

// 异步加载头像信息

[request setDownloadCache:[ASIDownloadCache sharedCache]];

[request setCompletionBlock:^{

    NSData *responseData = [request responseData];

    UIImage *tempImage = [UIImage imageWithData:responseData];

    self.profileImageView = [[UIImageView alloc]initWithImage:tempImage];

    //[self.profileImageView.layer setBorderColor: [[UIColor whiteColor] CGColor]];

    [[self.profileImageView layer] setBorderWidth:2.0f];

    self.profileImageView.layer.cornerRadius = 5;

    self.profileImageView.frame = CGRectMake(5, 5, self.profileImageView.frame.size.width,  self.profileImageView.frame.size.height);

   // NSLog(@"w=%f",self.profileImageView.frame.size.width);

    [cell.contentView addSubview:self.profileImageView];

    [cell setNeedsLayout];

}];

[request startAsynchronous];
  1. 获得用户名称属性,并添加到当前表视图行。
// 2. 用户名称

NSString *username = [userDic objectForKey:@"name"];

self.usernameLabel = [[UILabel alloc]initWithFrame:CGRectZero];

CGRect usernameFrame = CGRectMake(60, 5, 100, 21);

self.usernameLabel.frame = usernameFrame;

self.usernameLabel.text = username;

self.usernameLabel.font = [UIFont systemFontOfSize:12];

[cell.contentView addSubview:self.usernameLabel];
  1. 获得转发数和评论数并添加到当前表视图行。
// 3. 转发数

NSString *reposts\_count = [dic objectForKey:@"reposts\_count"];

self.repostCountLabel = [[UILabel alloc]initWithFrame:CGRectZero];

CGRect repostCountFrame = CGRectMake(160, 5, 60, 21);

self.repostCountLabel.frame = repostCountFrame;

self.repostCountLabel.text = [NSString stringWithFormat:@"转发数:%@",reposts\_count];

self.repostCountLabel.font = [UIFont systemFontOfSize:10];

[cell.contentView addSubview:self.repostCountLabel];

// 4. 评论数

NSString *comments\_count = [dic objectForKey:@"comments\_count"];

self.commentCountLabel = [[UILabel alloc]initWithFrame:CGRectZero];

CGRect commentsCountFrame = CGRectMake(220, 5, 60, 21);

self.commentCountLabel.frame = commentsCountFrame;

self.commentCountLabel.text = [NSString stringWithFormat:@"评论数:%@",comments\_count];

self.commentCountLabel.font = [UIFont systemFontOfSize:10];

[cell.contentView addSubview:self.commentCountLabel];
  1. 获得微博信息,需要注意的是,微博信息是根据实际内容动态改变UILabel大小的。
// 5. 微博信息

NSString *text = [dic objectForKey:@"text"];

CGSize constraint = CGSizeMake(CELL\_CONTENT\_WIDTH - (CELL\_CONTENT\_MARGIN * 2), 20000.0f);

CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];

self.myTextLabel = [[UILabel alloc]initWithFrame:CGRectZero];

self.myTextLabel.frame = CGRectMake(60, 26, size.width-20, size.height);

self.myTextLabel.numberOfLines = 0;

self.myTextLabel.lineBreakMode = NSLineBreakByWordWrapping;

self.myTextLabel.font = [UIFont systemFontOfSize:12];

self.myTextLabel.text = text;

[cell.contentView addSubview:self.myTextLabel];
  1. 异步加载图片并根据是否有图标的情况,确定创建时间的位置。
// 6. 图片

NSString *thumbnail\_pic = [dic objectForKey:@"thumbnail\_pic"];

if (thumbnail\_pic!=nil&amp;&amp;[thumbnail\_pic length]>0) {

    NSURL *thumbnail\_picURL = [NSURL URLWithString:thumbnail\_pic];

    request = [ASIHTTPRequest requestWithURL:thumbnail\_picURL];

    \_\_block UIImage *tempImage;

    [request setDownloadCache:[ASIDownloadCache sharedCache]];

    [request setCompletionBlock:^{

        NSData *responseData = [request responseData];

        tempImage = [UIImage imageWithData:responseData];

        self.picImageView = [[UIImageView alloc]initWithImage:tempImage];

        self.picImageView.frame = CGRectMake(60, size.height+30, tempImage.size.width, tempImage.size.height);

        [cell.contentView addSubview:self.picImageView];



        // 7. 创建时间

        NSString *created\_at = [dic objectForKey:@"created\_at"];

        self.createAtLabel = [[UILabel alloc]initWithFrame:CGRectZero];

        self.createAtLabel.frame = CGRectMake(5, size.height+self.picImageView.frame.size.height+50, 200, 21);

        self.createAtLabel.text = [NSString stringWithFormat:@"创建时间:%@",created\_at];

        self.createAtLabel.font = [UIFont systemFontOfSize:10];

        [cell.contentView addSubview:self.createAtLabel];

        self.cellHeight = size.height+self.picImageView.frame.size.height+60;

        [cell setNeedsLayout];

    }];

    [request startAsynchronous];

}else{

    // 7. 创建时间

    NSString *created\_at = [dic objectForKey:@"created\_at"];

    self.createAtLabel = [[UILabel alloc]initWithFrame:CGRectZero];

    self.createAtLabel.frame = CGRectMake(5, size.height+50, 200, 21);

    self.createAtLabel.text = [NSString stringWithFormat:@"创建时间:%@",created\_at];

    self.createAtLabel.font = [UIFont systemFontOfSize:10];

    [cell.contentView addSubview:self.createAtLabel];

    self.cellHeight = size.height+self.picImageView.frame.size.height+60;

    [cell setNeedsLayout];

}

31.6 发布微博

在需要的时候,我们也可以通过发送微博来分享自己的新鲜事。发送微博需要想服务器提交的信息是access_token和微博内容status,另外,用户需要是登陆状态。实现发送微博的步骤如下所示。

  1. 创建一个视图控制器PostWeiboViewController,实现请求代理协议SinaWeiboRequestDelegate,并定义一个UITextView属性来填写微博内容。
#import <UIKit/UIKit.h>

#import "SinaWeiboRequest.h"

@interface PostWeiboViewController : UIViewController<SinaWeiboRequestDelegate>

// 微博内容

@property (strong, nonatomic) IBOutlet UITextView *postTextView;

@end
  1. viewDidLoad方法中设置写微博和取消写微博的导航按钮,并使UITextView获得焦点,显示键盘。
- (void)viewDidLoad

{

    [super viewDidLoad];

    // 设置取消微博导航按钮

    UIBarButtonItem *cancelBtnItem = [[UIBarButtonItem alloc]initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(cancel)];

    self.navigationItem.leftBarButtonItem = cancelBtnItem;

    // 设置写微博导航按钮

    UIBarButtonItem *postBtnItem = [[UIBarButtonItem alloc]initWithTitle:@"发送" style:UIBarButtonItemStylePlain target:self action:@selector(post)];

    self.navigationItem.rightBarButtonItem = postBtnItem;

    // 是UITextView获得焦点

    [self.postTextView becomeFirstResponder];

}
  1. 定义一个post方法发送微博,设置提交给服务器的信息,并设置提交方法为POST。
// 发送微博

- (void)post{

    SinaWeibo *sinaweibo = [self getSinaWeibo];

    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:5];

    [params setObject:sinaweibo.accessToken forKey:@"access\_token"];

    [params setObject:self.postTextView.text forKey:@"status"];

    [sinaweibo requestWithURL:@"statuses/update.json"

                       params:params

                   httpMethod:@"POST"

                     delegate:self];

}
  1. 实现请求代理方法,获得请求返回结果。
// 实现请求代理方法,获得返回结果

- (void)request:(SinaWeiboRequest *)request didFinishLoadingWithResult:(id)result{

    // NSLog(@"result=%@",result);

    NSDictionary *dic = (NSDictionary*)result;

    NSArray *statuses = [dic objectForKey:@"statuses"];

    NSLog(@"statused=%@",statuses);

}
  1. 程序运行结果如下所示。

图 31.37  写微博

31.7 微博详细

选中微博列表中的一个,将跳转到微博详细信息。详细信息会显示发微博的用户信息,包括头像、用户名称,以及微博详细内容和图片。另外,还有针对该微博的评论和转发。如下图所示。

图 31.38  微博详细

微博详细的实现步骤如下:

  1. 定义一个微博详细视图控制器类WeiboDetailViewController,该类实现请求代理协议SinaWeiboRequestDelegate、表视图数据源协议UITableViewDataSource、表视图代理协议UITableViewDelegate和动作列表协议UIActionSheetDelegate。
#import <UIKit/UIKit.h>

#import "SinaWeiboRequest.h"

@interface WeiboDetailViewController : UIViewController<SinaWeiboRequestDelegate,UITableViewDataSource,UITableViewDelegate,UIActionSheetDelegate>
  1. 添加用户名称、博客内容、头像和图片等属性。
// 头像

@property(nonatomic,strong) IBOutlet UIImageView *profileImageView;

// 图片

@property(nonatomic,strong)IBOutlet UIImageView *picImageView;

// 用户名称、博客内容

@property(nonatomic,strong)IBOutlet UILabel *usernameLabel,*myTextLabel;
  1. 在viewDidLoad方法中获得用户信息,包括头像和用户名称,以及微博信息。
// 用户信息

NSDictionary *userDic = [self.weiboContentDic objectForKey:@"user"];

// 1. 头像

NSString *profile\_image\_url = [userDic objectForKey:@"profile\_image\_url"];

NSURL *photoURL = [NSURL URLWithString:profile\_image\_url];

\_\_weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:photoURL];

[request setDownloadCache:[ASIDownloadCache sharedCache]];

[request setCompletionBlock:^{

    NSData *responseData = [request responseData];

    UIImage *tempImage = [UIImage imageWithData:responseData];

    self.profileImageView = [[UIImageView alloc]initWithImage:tempImage];

    //[self.profileImageView.layer setBorderColor: [[UIColor whiteColor] CGColor]];

    [[self.profileImageView layer] setBorderWidth:2.0f];

    self.profileImageView.layer.cornerRadius = 5;

    self.profileImageView.frame = CGRectMake(5, 5, self.profileImageView.frame.size.width,  self.profileImageView.frame.size.height);

    // NSLog(@"w=%f",self.profileImageView.frame.size.width);

    [self.view addSubview:self.profileImageView];

    [self.view setNeedsLayout];

}];

[request startAsynchronous];

// 2. 用户名称

NSString *username = [userDic objectForKey:@"name"];

self.usernameLabel = [[UILabel alloc]initWithFrame:CGRectZero];

CGRect usernameFrame = CGRectMake(60, 5, 100, 21);

self.usernameLabel.frame = usernameFrame;

self.usernameLabel.text = username;

self.usernameLabel.font = [UIFont systemFontOfSize:12];

[self.view addSubview:self.usernameLabel];

// 3. 分割线

CGRect lintViewFrame = CGRectMake(0, 70, 320, 1);

UIView *lineView = [[UIView alloc]initWithFrame:lintViewFrame];

lineView.backgroundColor = [UIColor blackColor];

[self.view addSubview:lineView];

// 4. 微博信息

NSString *text = [self.weiboContentDic objectForKey:@"text"];

CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f);

CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:12] constrainedToSize:constraint lineBreakMode:NSLineBreakByWordWrapping];

self.myTextLabel = [[UILabel alloc]initWithFrame:CGRectZero];

self.myTextLabel.frame = CGRectMake(10, 75, size.width-20, size.height);

self.myTextLabel.numberOfLines = 0;

self.myTextLabel.lineBreakMode = NSLineBreakByWordWrapping;

self.myTextLabel.font = [UIFont systemFontOfSize:12];

self.myTextLabel.text = text;

[self.view addSubview:self.myTextLabel];

以上是微博详细的部分内容,有关微博评论和微博转发类别将在后续小结中讲述。

31.8 获得微博评论和转发

在微博详细中来显示微博评论列表和微博转发列表,本节将讲述微博评论列表的实现。实现步骤如下:

  1. 在上一节的基础上,在微博详细头文件中声明评论和转发表视图和数据源以及其他属性。
// 评论表和转发表的容器视图

@property(nonatomic,strong)UIView *containerView;

// 评论表

@property(nonatomic,strong) UITableView *commentTv;

// 转发表

@property(nonatomic,strong) UITableView *repostTv;

// 当前表

@property(nonatomic,strong) UITableView *currentTv;

// 评论数据源

@property(nonatomic,strong) NSMutableArray *commentDataSource;

// 转发数据源

@property(nonatomic,strong) NSMutableArray *repostDataSource;

// 当前微博内容

@property(nonatomic,strong)NSDictionary *weiboContentDic;

// 当前微博id

@property(nonatomic,strong)NSString *sid;
  1. 在viewDidLoad方法中初始化导航按钮、表视图和表视图数据源,并设置代理。
// 评论表和转发表的容器视图

@property(nonatomic,strong)UIView *containerView;

// 评论表

@property(nonatomic,strong) UITableView *commentTv;

// 转发表

@property(nonatomic,strong) UITableView *repostTv;

// 当前表

@property(nonatomic,strong) UITableView *currentTv;

// 评论数据源

@property(nonatomic,strong) NSMutableArray *commentDataSource;

// 转发数据源

@property(nonatomic,strong) NSMutableArray *repostDataSource;

// 当前微博内容

@property(nonatomic,strong)NSDictionary *weiboContentDic;

// 当前微博id

@property(nonatomic,strong)NSString *sid;
  1. 加载微博图片,并根据图片位置动态设置评论和转发列表的位置,并加载评论和转发数据。
// 5. 图片

NSString *thumbnail\_pic = [self.weiboContentDic objectForKey:@"thumbnail\_pic"];

if (thumbnail\_pic!=nil&amp;&amp;[thumbnail\_pic length]>0) {

    NSURL *thumbnail\_picURL = [NSURL URLWithString:thumbnail\_pic];

    request = [ASIHTTPRequest requestWithURL:thumbnail\_picURL];

    \_\_block UIImage *tempImage;

    [request setDownloadCache:[ASIDownloadCache sharedCache]];

    [request setCompletionBlock:^{

        NSData *responseData = [request responseData];

        tempImage = [UIImage imageWithData:responseData];

        self.picImageView = [[UIImageView alloc]initWithImage:tempImage];

        self.picImageView.frame = CGRectMake(60, size.height+80, tempImage.size.width, tempImage.size.height);

        [self.view addSubview:self.picImageView];

        // 6. 转发和评论 根据文字和图片高度计算分段控件的位置

        CGRect scFrame = CGRectMake(0, size.height+self.picImageView.frame.size.height+80, 320, 44);

        NSArray *items = @[@"转发",@"评论"];

        sc = [[SDSegmentedControl alloc]initWithItems:items];

        sc.backgroundColor = [UIColor clearColor];

        sc.frame = scFrame;

        [self.view addSubview:sc];

        [sc addTarget:self action:@selector(change:) forControlEvents:UIControlEventValueChanged];

        // 容器视图

        CGRect containerFrame = CGRectMake(0, size.height+self.picImageView.frame.size.height+80+44, 320, 300);

        self.containerView = [[UIView alloc]initWithFrame:containerFrame];

       // self.containerView.backgroundColor = [UIColor redColor];

        [self.view addSubview:self.containerView];

        // 评论表

        CGRect commentTvFrame = CGRectMake(0, 0, 320, 300);

        self.commentTv.frame = commentTvFrame;

        //[self.containerView addSubview:self.commentTv];

        // 转发表

        CGRect repostTvFrame = CGRectMake(0, 0, 320, 300);

        self.commentTv.frame = repostTvFrame;

        //[self.containerView addSubview:self.commentTv];

        [self.containerView addSubview:self.repostTv];

    }];

[request startAsynchronous];

}else{

    // 如果没有图片,根据文字高度计算分段控件的位置

    CGRect scFrame = CGRectMake(0, size.height+80, 320, 44);

    NSArray *items = @[@"转发",@"评论"];

    sc = [[SDSegmentedControl alloc]initWithItems:items];

    sc.backgroundColor = [UIColor clearColor];

    sc.frame = scFrame;

    [self.view addSubview:sc];

    [sc addTarget:self action:@selector(change:) forControlEvents:UIControlEventValueChanged];

    // 容器视图

    CGRect containerFrame = CGRectMake(0, size.height+80+44, 320, 300);

    self.containerView = [[UIView alloc]initWithFrame:containerFrame];

    self.containerView.backgroundColor = [UIColor redColor];

    [self.view addSubview:self.containerView];

    // 评论表

    CGRect commentTvFrame = CGRectMake(0, 0, 320, 300);

    self.commentTv.frame = commentTvFrame;

    //[self.containerView addSubview:self.commentTv];

    // 转发表

    CGRect repostTvFrame = CGRectMake(0, 0, 320, 300);

    self.repostTv.frame = repostTvFrame;

    [self.containerView addSubview:self.repostTv];

}

// 6. 加载转发和评论数据

NSString *sid = [self.weiboContentDic objectForKey:@"idstr"];

NSLog(@"sid=%@",sid);

[self loadComment:sid];

[self loadRepost:sid];

// 设置当前微博id

self.sid = sid;

这里我们使用了一个开源的分段组件,下载地址是,https://github.com/rs/SDSegmentedControl](https://github.com/rs/SDSegmentedControl

  1. 根据当前表的实例,设置表的行数。
// 表的行数

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    // 评论表

    if ([tableView isEqual:self.commentTv]) {

        NSLog(@"count=%d",[self.commentDataSource count]);

        return [self.commentDataSource count];

    }

    // 转发表

    if ([tableView isEqual:self.repostTv]) {

        NSLog(@"count=%d",[self.repostDataSource count]);

        return [self.repostDataSource count];

    }

    return 0;

}
  1. 根据当前表实例,设置表的行单元格数据。
// 表行

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    // 评论行

    if ([tableView isEqual:self.commentTv]) {

        static NSString *cid = @"cid";

        UITableViewCell *cCell = [tableView dequeueReusableCellWithIdentifier:cid];

        if (cCell==nil) {

            cCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cid];

        }

        NSDictionary *dic = [self.commentDataSource objectAtIndex:indexPath.row];

        NSDictionary *userDic = [dic objectForKey:@"user"];

        // 用户名称

        NSString *name = [userDic objectForKey:@"name"];

        cCell.textLabel.text = name;

        cCell.textLabel.font = [UIFont systemFontOfSize:10];

        // 用户头像

        NSString *profile\_image\_urlStr = [userDic objectForKey:@"profile\_image\_url"];

        NSURL *profile\_image\_url = [NSURL URLWithString:profile\_image\_urlStr];

        \_\_weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:profile\_image\_url];

        \_\_block UIImage *tempImage;

        [request setDownloadCache:[ASIDownloadCache sharedCache]];

        [request setCompletionBlock:^{

            NSData *responseData = [request responseData];

            tempImage = [UIImage imageWithData:responseData];

            cCell.imageView.image = tempImage;

            [cCell setNeedsLayout];

        }];

        [request startAsynchronous];

        //评论内容

        NSString *text = [dic objectForKey:@"text"];

        cCell.detailTextLabel.text = text;

        cCell.detailTextLabel.font = [UIFont systemFontOfSize:8];

        return cCell;

    }

    // 转发行

    if ([tableView isEqual:self.repostTv]) {

        static NSString *rid = @"rid";

        UITableViewCell *rCell = [tableView dequeueReusableCellWithIdentifier:rid];

        if (rCell==nil) {

            rCell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:rid];

        }

        NSDictionary *dic = [self.repostDataSource objectAtIndex:indexPath.row];

        NSDictionary *userDic = [dic objectForKey:@"user"];

        // 用户名称

        NSString *name = [userDic objectForKey:@"name"];

        rCell.textLabel.text = name;

        rCell.textLabel.font = [UIFont systemFontOfSize:10];

        // 用户头像

        NSString *profile\_image\_urlStr = [userDic objectForKey:@"profile\_image\_url"];

        NSURL *profile\_image\_url = [NSURL URLWithString:profile\_image\_urlStr];

        \_\_weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:profile\_image\_url];

        \_\_block UIImage *tempImage;

        [request setDownloadCache:[ASIDownloadCache sharedCache]];

        [request setCompletionBlock:^{

            NSData *responseData = [request responseData];

            tempImage = [UIImage imageWithData:responseData];

            rCell.imageView.image = tempImage;

            [rCell setNeedsLayout];

        }];

        [request startAsynchronous];

        //评论内容

        NSString *text = [dic objectForKey:@"text"];

        rCell.detailTextLabel.text = text;

        rCell.detailTextLabel.font = [UIFont systemFontOfSize:8];

        return rCell;

    }

    return nil;

}
  1. 实现分段组件事件方法,实现转发和评论之间的相互切换。
// 分段切换事件

-(void)change:(UISegmentedControl*)sender{

    int index = sender.selectedSegmentIndex;

    [self.currentTv removeFromSuperview];

    switch (index) {

        case 0:

            [self.containerView addSubview:self.repostTv];

            self.currentTv = self.repostTv;

            break;

        case 1:

            [self.containerView addSubview:self.commentTv];

            self.currentTv = self.commentTv;

            break;

        default:

            break;

    }

}
  1. 下面是加载评论和转发方法实现。
// 加载评论

- (void)loadComment:(NSString*)sid {

    SinaWeibo *sinaweibo = [self getSinaWeibo];

    NSMutableDictionary *param = [NSMutableDictionary dictionaryWithCapacity:3];

    [param setObject:sinaweibo.accessToken forKey:@"access\_token"];

    [param setObject:sid forKey:@"id"];

    [sinaweibo requestWithURL:@"comments/show.json"

                       params:param

                   httpMethod:@"GET"

                     delegate:self];

}

// 加载转发

- (void)loadRepost:(NSString*)sid {

    SinaWeibo *sinaweibo = [self getSinaWeibo];

    NSMutableDictionary *param = [NSMutableDictionary dictionaryWithCapacity:3];

    [param setObject:sinaweibo.accessToken forKey:@"access\_token"];

    [param setObject:sid forKey:@"id"];

    [sinaweibo requestWithURL:@"statuses/repost\_timeline.json"

                       params:param

                   httpMethod:@"GET"

                     delegate:self];

}
  1. 获得请求结果,根据URL结尾判断是那个请求,包括评论、转发和收藏。
// 获得请求结果

- (void)request:(SinaWeiboRequest *)request didFinishLoadingWithResult:(id)result{

    // 判断是评论还是转发

    if ([request.url hasSuffix:@"comments/show.json"]){

        NSDictionary *dic = (NSDictionary*)result;

        NSArray *commnts = [dic objectForKey:@"comments"];

        NSLog(@"comments=%@",commnts);

        [self.commentDataSource removeAllObjects];

        [self.commentDataSource addObjectsFromArray:commnts];

        [self.commentTv reloadData];

    // 转发

    }else if([request.url hasSuffix:@"statuses/repost\_timeline"]){

        NSDictionary *dic = (NSDictionary*)result;

        NSArray *reposts = [dic objectForKey:@"reposts"];

        NSLog(@"reposts=%@",reposts);

        [self.repostDataSource removeAllObjects];

        [self.repostDataSource addObjectsFromArray:reposts];

        [self.repostTv reloadData];

    // 收藏

    }else if([request.url hasSuffix:@"favorites/create.json"]){

        NSDictionary *dic = (NSDictionary*)result;

        NSDictionary *status = [dic objectForKey:@"status"];

        NSString *favor = [status objectForKey:@"favorited"];

        if ([favor boolValue]) {

            [SGInfoAlert showInfo:@"收藏成功!" bgColor:nil inView:self.view vertical:100];

           //  NSLog(@"收藏成功!");

        }else{

            // NSLog(@"收藏失败!");

            [SGInfoAlert showInfo:@"收藏失败!" bgColor:nil inView:self.view vertical:100];

        }

    }else{

    }

}
  1. 程序运行结果如下所示。

图 31.39  获得微博评论和转发

31.9 发表评论

可以针对某条微博发表评论,评论、转发和收藏通过UIActionSheet提供接口,点击评论跳转到评论界面,输入评论内容,点击导航栏上的发送按钮可以发送评论。如下图所示。

图 31.40  发表评论

发表评论的实现步骤如下:

  1. 实现UIActionSheet,点击微博详细的右侧导航按钮,可以弹出UIActionSheet列表,选择评论按钮跳转到评论界面。
// 显示转发、评论、收藏弹出框

-(void)showActionSheet{

    UIActionSheet *actions = [[UIActionSheet alloc]initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:@"转发" otherButtonTitles:@"评论", @"收藏",nil];

    [actions showInView:self.view];

}
  1. 实现UIActionSheetDelegate的协议方法。
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{

    NSString *title = [actionSheet buttonTitleAtIndex:buttonIndex];

    if ([title isEqualToString:@"转发"]) {

         [self forwardToRepost];

    }

    if ([title isEqualToString:@"评论"]) {

        [self forwardToComment];

    }

    if ([title isEqualToString:@"收藏"]) {

        [self doFavor];

    }

}
  1. 定义一个评论视图控制器CommentViewController,实现SinaWeiboRequestDelegate请求代理协议,并设置评论内容输入框属性和微博id属性。
#import <UIKit/UIKit.h>

#import "SinaWeibo.h"

#import "SinaWeiboRequest.h"

@interface CommentViewController : UIViewController<SinaWeiboRequestDelegate>

// 评论内容输入框

@property (strong, nonatomic) IBOutlet UITextView *commentTextView;

// 当前微博id

@property(strong,nonatomic) NSString *sid;

@end
  1. 在viewDidLoad方法中添加导航按钮,并使输入框获得焦点。
- (void)viewDidLoad

{

    [super viewDidLoad];

    // Do any additional setup after loading the view from its nib.

    UIBarButtonItem *right = [[UIBarButtonItem alloc]initWithTitle:@"评论" style:UIBarButtonItemStyleBordered target:self action:@selector(comment)];

    self.navigationItem.rightBarButtonItem = right;

    [self.commentTextView becomeFirstResponder];

}
  1. 点击评论按钮发出评论,并获得评论响应结果。
// 发出评论

- (void)comment {

    SinaWeibo *sinaweibo = [self getSinaWeibo];

    NSMutableDictionary *param = [NSMutableDictionary dictionaryWithCapacity:3];

    [param setObject:sinaweibo.accessToken forKey:@"access\_token"];

    [param setObject:self.sid forKey:@"id"];

    [param setObject:self.commentTextView.text forKey:@"comment"];

    [sinaweibo requestWithURL:@"comments/create.json"

                       params:param

                   httpMethod:@"POST"

                     delegate:self];

}

// 获得请求结果

- (void)request:(SinaWeiboRequest *)request didFinishLoadingWithResult:(id)result{

    NSDictionary *dic = (NSDictionary*)result;

    // NSArray *commnts = [dic objectForKey:@"comments"];

    NSLog(@"dic=%@",dic);

}

31.10 转发微博

转发微博和评论类似,使用UIActionSheet提供接口,点击转发跳转到转发界面,输入转发信息转发微博。

图 31.41  转发微博

转发微博实现步骤如下:

  1. 定义一个转发微博的视图控制器类RepostViewController,并定义转发内容属性和微博id属性。
#import <UIKit/UIKit.h>

#import "SinaWeibo.h"

#import "SinaWeiboRequest.h"

// 实现请求代理

@interface RepostViewController : UIViewController<SinaWeiboRequestDelegate>

// 转发内容文本视图

@property (strong, nonatomic) IBOutlet UITextView *repostTextView;

// 微博id

@property(strong,nonatomic) NSString *sid;

@end
  1. 在viewDidLoad方法中添加导航按钮并使UITextView获得焦点。
- (void)viewDidLoad

{

    [super viewDidLoad];

    // 转发导航按钮

    UIBarButtonItem *right = [[UIBarButtonItem alloc]initWithTitle:@"转发" style:UIBarButtonItemStyleBordered target:self action:@selector(repost)];

    self.navigationItem.rightBarButtonItem = right;

    // 内容框获得焦点

    [self.repostTextView becomeFirstResponder];

}
  1. 点击转发按钮转发微博,并获得响应结果。
// 转发

- (void)repost {

    SinaWeibo *sinaweibo = [self getSinaWeibo];

    NSMutableDictionary *param = [NSMutableDictionary dictionaryWithCapacity:3];

    [param setObject:sinaweibo.accessToken forKey:@"access\_token"];

    [param setObject:self.sid forKey:@"id"];

    [param setObject:self.repostTextView.text forKey:@"status"];

    [sinaweibo requestWithURL:@"statuses/repost.json"

                       params:param

                   httpMethod:@"POST"

                     delegate:self];

}

// 获得请求结果

- (void)request:(SinaWeiboRequest *)request didFinishLoadingWithResult:(id)result{

    NSDictionary *dic = (NSDictionary*)result;

   // NSArray *commnts = [dic objectForKey:@"comments"];

    NSLog(@"dic=%@",dic);

}

31.11 收藏微博

可以将喜欢的微博收藏,使用UIActionSheet提供操作接口,点击收藏按钮实现收藏。收藏方法代码如下:

// 收藏

-(void)doFavor{

    SinaWeibo *sinaweibo = [self getSinaWeibo];

    NSMutableDictionary *param = [NSMutableDictionary dictionaryWithCapacity:3];

    [param setObject:sinaweibo.accessToken forKey:@"access\_token"];

    [param setObject:self.sid forKey:@"id"];

    [sinaweibo requestWithURL:@"favorites/create.json"

                       params:param

                   httpMethod:@"POST"

                     delegate:self];

}

根据请求返回的结果判断收藏成功还是失败。

// 收藏

    }else if([request.url hasSuffix:@"favorites/create.json"]){

        NSDictionary *dic = (NSDictionary*)result;

        NSDictionary *status = [dic objectForKey:@"status"];

        NSString *favor = [status objectForKey:@"favorited"];

        if ([favor boolValue]) {

            [SGInfoAlert showInfo:@"收藏成功!" bgColor:nil inView:self.view vertical:100];

           //  NSLog(@"收藏成功!");

        }else{

            // NSLog(@"收藏失败!");

            [SGInfoAlert showInfo:@"收藏失败!" bgColor:nil inView:self.view vertical:100];

        }

    }

这里我们使用了一个开源的弹出框组件SGInfoAlert,下载地址是,https://github.com/sagiwei/SGInfoAlert](https://github.com/sagiwei/SGInfoAlert,示例程序运行结果如下所示。

图 31.42  SGInfoAlert运行结果

到这里,微博项目就全部结束了。其实新浪微博的功能还有很多,但是操作流程都是类似的,即发出请求,获得响应结果,并将结果显示在界面上。