上周老师让我用两周时间来模仿新浪微博的客户端来做一个伪客户端。做工不好,请提出你的宝贵意见。做出来的效果先展示一下。

-----------------我是分割线君------------------

展示篇:

黑微薄  (。。。)

这个主页做得不好的地方在于没有显示图片缩略图和转发的微薄没有显示出来。因为我用的是普通的subtitle的cell,没有自定义cell,所以使用起来不方便。左上方是刷新按钮,右上方是新微博。下面是一个UITabbar。

这是新微博的编辑框。

这是微博的详细内容,可以点进去看评论,也是用Table来实现。学评论和转发功能跟新微博差不多。收藏的按钮会根据你的收藏情况改变。对了。点缩略图会有大图查看(大图是用UIWebVIew直接载入。我承认我偷懒了。= =|)

这个是消息的页面,上面有一条segmented control可供选择。(话说我要不要帮我的名字加个马?)

好友列表显示的是你互相关注的好友。第一行是用户的资料。(各位被卖的童鞋,如果你在这里见到你的名字,我深感抱歉。)

在做的时候突然发现收藏是没有接口的。所以收藏点了没反映,但是其他三个按钮点进去就跟前面的页面差不多。这里就不多做演示了。

----------------我是分割线君----------------

实现篇:

下面给出实现代码。这个小程序是用storyboard和arc来实现的。先来看看storyboard的框架结构。

以及我的文件列表

----------------我是分割线君----------------

(1)Oauth2.0获取Token

在LoginViewController里面,其实它的主要任务是用OAuth2.0拿到你授权帐号的token,时效为24小时。详细的提取流程在官网 http://open.weibo.com/wiki/Oauth2  可以看到。下面是我提取的方法。

- (void) getAuthorization_URL;
{self.AuthorizationString = [[NSString alloc] initWithString:KAuthorizationURL];self.AuthorizationString = [self.AuthorizationString stringByReplacingOccurrencesOfString:@"YOUR_CLIENT_ID" withString:KAppKey];self.Authorization_URL = [[NSURL alloc] initWithString:self.AuthorizationString];[self.LoginView loadRequest:[NSURLRequest requestWithURL:self.Authorization_URL]];
}- (void) getToken
{self.Token_URL = [self.LoginView.request URL];NSString *Token_URL_Str = [[NSString alloc] initWithString:[self.Token_URL absoluteString]];Token_URL_Str = [Token_URL_Str substringFromIndex:22];NSArray *ar = [Token_URL_Str componentsSeparatedByString:@"&"];self.Token = [[ar objectAtIndex:0] substringFromIndex:13];      self.Expires_In = [[NSNumber alloc] initWithInt:[[[ar objectAtIndex:2] substringFromIndex:11] integerValue]];self.uid = [[NSNumber alloc] initWithInt:[[[ar objectAtIndex:3] substringFromIndex:4] integerValue]];}

首先用你的Appkey来代替官网给出的URL中的数据。然后在WebVIew中加载就能得到以下界面。

一旦授权之后它就会返回一个前缀为你设定好的回调网址的URL,而URL后附带有你需要储存起来的token、uid、有效期限。这些数据我是用了存放在plist的方式储存起来了。

存起来之后在下一个运行程序的时候你就能重新读取数据,然后再判断是否过期,如果过期了就重新授权,没过期就可以直接segue到主界面。

----------------我是分割线君----------------

(2)plist存放数据

其实在登录之后的控制器中,很多自己写的方法都是大同小异的。在主界面HomeViewController中,首先要做的是在plist中读取token,因为在这个程序中,无论你要get数据,还是要post数据,token是必须的!

- (void) loadData
{NSString *filePath = [self dataFilePath];NSDictionary *data = [[NSDictionary alloc] initWithContentsOfFile:filePath];self.Token = [data objectForKey:@"token"];self.Expires_In = [data objectForKey:@"expires_in"];self.Uid = [data objectForKey:@"Uid"];
}- (NSString *) dataFilePath
{NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentsDictionary = [paths objectAtIndex:0];return [documentsDictionary stringByAppendingPathComponent:@"Data.plist"];
}

----------------我是分割线君----------------

(3)json格式数据的获取

然后首页显示的是登录用户所关注的人的最新微博,用Table来展现。所以接下来要做的就是接受Json格式的数据。

我自己定义了一个weibo类。

Weibo.h

#import <Foundation/Foundation.h>@interface Weibo : NSObject
@property (strong, nonatomic) NSString *myName;
@property (strong, nonatomic) NSString *myText;
@property (strong, nonatomic) NSString *myImgURL;
@property (strong, nonatomic) NSString *myTextImgURL;
@property (strong, nonatomic) NSString *myTextImgDetail;
@property (strong, nonatomic) NSString *myTid;
@property (strong, nonatomic) NSString *myUsid;
@property (strong, nonatomic) UIImage *myImg;- (id) initWithName:(NSString *)nameandText:(NSString *)textandImgURL:(NSString *)imageURLandTextImgURL:(NSString *)TextImgURLandImgDetail:(NSString *)ImgDetailandmyTid:(NSString *)TidandUsid:(NSString *)Usid;@end

weibo.m

#import "Weibo.h"@implementation Weibo
@synthesize myName = _myName;
@synthesize myText = _myText;
@synthesize myImgURL = _myImgURL;
@synthesize myTextImgURL = _myTextImgURL;
@synthesize myTextImgDetail = _myTextImgDetail;
@synthesize myUsid = _myUsid;
@synthesize myTid = _myTid;
@synthesize myImg = _myImg;- (id) initWithName:(NSString *)nameandText:(NSString *)textandImgURL:(NSString *)imageURLandTextImgURL:(NSString *)TextImgURLandImgDetail:(NSString *)ImgDetailandmyTid:(NSString *)TidandUsid:(NSString *)Usid{if(self = [super init]){self.myImg = nil;self.myName = name;self.myImgURL = imageURL;self.myText = text;  self.myTextImgURL = TextImgURL;self.myTextImgDetail = ImgDetail;self.myUsid = Usid;self.myTid = Tid;}return self;
}@end

下面就是提取json数据的方法。

- (void) getHomeItems
{self.HomeItems = [[NSMutableArray alloc] init];NSError *error = nil;NSString *HomeDataURL_Str = [NSString stringWithFormat:@"%@?access_token=%@",KHomeURL,self.Token];NSURL *HomeDataURL = [[NSURL alloc] initWithString:HomeDataURL_Str];NSData *HomeData= [[NSData alloc] initWithContentsOfURL:HomeDataURL];NSArray *ar = [NSJSONSerialization JSONObjectWithData:HomeData options:kNilOptions error:&error];ar = [ar valueForKey:@"statuses"];for(NSDictionary *dc in ar){NSDictionary *user = [dc valueForKey:@"user"];Weibo *wb = [[Weibo alloc] initWithName:[user valueForKey:@"screen_name"]andText:[dc valueForKey:@"text"]andImgURL:[user valueForKey:@"profile_image_url"]andTextImgURL:[dc valueForKey:@"thumbnail_pic"]     andImgDetail:[dc valueForKey:@"original_pic"]andmyTid:[dc valueForKey:@"id"]andUsid:[user valueForKey:@"id"]];[self.HomeItems addObject:wb];/*   NSLog(@"%@",[dc valueForKey:@"text"]);NSLog(@"%@",[user valueForKey:@"screen_name"]);NSLog(@"%@",[user valueForKey:@"profile_image_url"]);       */ }
}

在控制器内定义一个NSMutableArray属性的HomeItems来存放每组的数据,把得到的数据就可在方法

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

中展示出来。

----------------我是分割线君----------------

(4)gcd获取图片

为了避免在载入头像的时候出现界面处于假死状态,我在载入头像的时候使用了gcd多线程的方法。

- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{  NSString *imgStr = [[self.HomeItems objectAtIndex:indexPath.row] myImgURL];NSIndexPath *path = indexPath;cell.imageView.image = [UIImage imageNamed:@"head.jpg"];if([[self.HomeItems objectAtIndex:indexPath.row] myImg])cell.imageView.image = [[self.HomeItems objectAtIndex:indexPath.row] myImg];else{   if(imgStr){dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{NSURL *imgURL = [[NSURL alloc] initWithString:imgStr];NSData *imgData = [NSData dataWithContentsOfURL:imgURL];[[self.HomeItems objectAtIndex:indexPath.row] setMyImg:[[UIImage alloc] initWithData:imgData]];for(NSIndexPath * ip in [self.tableView indexPathsForVisibleRows])if(path.row == ip.row)cell.imageView.image = [[self.HomeItems objectAtIndex:indexPath.row] myImg]; }); }}
} 

第一个if是判断图片是否已经存在,如果已经存在的话就直接加载,否则就判断图片的URL是否存在,存在才进行下载。然后就是用了gcd开一条线程进行图片的下载,下载完再用一个循环来判断一下刚刚下载的图片跟你当前看到的cell有没有一致的。如果有就加载图片。事实上我只用了一个异步的方法,有人说要用一个异步里面加两个同步。我对gcd的了解也不深,我不知道这样跟只用一个异步有什么区别,求高手指点。

突然发现这样

            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{NSURL *imgURL = [[NSURL alloc] initWithString:imgStr];NSData *imgData = [NSData dataWithContentsOfURL:imgURL];[[self.HomeItems objectAtIndex:indexPath.row] setMyImg:[[UIImage alloc] initWithData:imgData]];dispatch_async(dispatch_get_main_queue(), ^{for(NSIndexPath * ip in [self.tableView indexPathsForVisibleRows])if(path.row == ip.row)cell.imageView.image = [[self.HomeItems objectAtIndex:indexPath.row] myImg]; 

异步中的异步,load图的效率也会高很多,再求高手指点。

这里有一篇师兄翻译的关于block和gcd的文章,有兴趣的童鞋可以看看。

block && Grand Central Dispatch

----------------我是分割线君----------------

(5)post数据

在新微博编辑界面控制器有一个done的按钮,按钮有个IBAction的方法

- (IBAction)done:(id)sender
{NSString *text = [[NSString alloc] initWithString:self.myText.text];NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);if([text lengthOfBytesUsingEncoding:enc]>280) {   UIAlertView *Av = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"您所输入的字数超过140字。" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];[Av show];}else{NSString *write_Str = [[NSString alloc] initWithFormat:@"&access_token=%@&status=%@",self.token,text];const char *CStr = [write_Str UTF8String];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:KWriteNew]];NSData *data = [NSData dataWithBytes:CStr length:strlen(CStr)];[request setHTTPMethod:@"POST"];[request setHTTPBody:data];NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil ]; NSError *error = nil;NSArray *ar = [NSJSONSerialization JSONObjectWithData:returnData options:kNilOptions error:&error];if([ar valueForKey:@"text"]){UIAlertView *Av = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"发送成功。" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];[Av show];[self dismissModalViewControllerAnimated:YES];}else{UIAlertView *Av = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"发送失败,请稍后再试。" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];[Av show];}}
}

首先要判断一下用户编写的微博字数有没有超过280个字节,我们可以用

    NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);[text lengthOfBytesUsingEncoding:enc]; 

就能知道text的字节长度。

如果超出了规定字数

        UIAlertView *Av = [[UIAlertView alloc] initWithTitle:@"Warning" message:@"您所输入的字数超过140字。" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];[Av show];

我们定义了一个AV,就是我们平时见到的一个弹出提示窗口,就会弹出来警告用户。

下面时post的方法,把你要post的数据先用UTF8转码转为CString,然后用NSData装起来。(KWriteNew是我的宏定义)再用POST的方法发上去。最后返回一下数据来判断发送是否成功。

然后后面的其实也都差不多,就没什么好说了。

后期修改了一下,添加了转发的查看功能,增加了自动加载更多微博功能,并优化了界面,发现自己model层做得超级烂,我把程序贴上来,有兴趣的童鞋可以下载,可以看看效果,并且思考下model怎样做得更好。只要把App Key和App Secret改为自己的就可以登录了。

点击下载

伪ios新浪微博客户端(自家用)相关推荐

  1. iOS新浪微博客户端开发(4)——自定义微博Cell的实现

    首先看一下效果图(不带转发微博和带转发微博):   一.微博Cell布局分析 微博Cell的详细布局如下图所示,其主要控件有:头像.昵称.微博时间.来源.微博正文.如果有被转发微博,还包括被转发微博的 ...

  2. ios小项目——新浪微博客户端总结

    2019独角兽企业重金招聘Python工程师标准>>> 们还是登录不了,你们要用还是得自己申请appkey并且把回调网址设为baidu.或者是再下面留言,留下你的微博uid我把你加入 ...

  3. android新浪微博客户端毕业设计课题背景

        原本天真地以为毕业设计课题选个做项目的就不用弄这些形形式式的文档了,结果导师告诉我:不要抱有侥幸心理!     然后就按部就班地花了近两小时写课题背景,奈何各种原因又要更换选题,为了资源的再利 ...

  4. 山寨新浪微博客户端与新浪微博API调用的总结

    这次是我第一次写的项目总结,虽然这只是一个小项目,但确实是获益良多.虽然说是独立完成,但其实在做的过程中,也有和大家交流了很多意见.尽管如此,我对这个尚不能算写好的项目,还是有非常多的不满意.不过碍于 ...

  5. 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)

    最近看了关于XMPP的框架,以文本聊天为例,需要发送的消息为: <message type="chat" from="kang@server.com" t ...

  6. android开发我的新浪微博客户端-用户授权页面UI篇(3.1)

    看上面的图,其实这个页面的UI实现不复杂,首先是背景部分的实现这个参考 android开发我的新浪微博客户端-载入页面UI篇(1.1),重点来讲讲这个半透明的弹出对话框窗口是如何实现的,首先新建名为A ...

  7. LightBus新浪微博客户端开源下载

    LightBus是一款基于Silverlight技术的新浪微博客户端,该客户端使用Silverlight的Out-of-Browser模式,通过新浪OPEN API,采用oAuth认证方式访问新浪微博 ...

  8. android分享到新浪微博客户端吗,Android调用手机新浪微博客户端分享

    通过Action_Send以及Intent.createChoose()调用系统分享功能时,是可以显示当前手机上已安装的能分享的客户端列表,当然,开发者也可以指定单独某一个平台来分享,代码如下: pu ...

  9. [iPhone高级] 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)

    最近看了关于XMPP的框架,以文本聊天为例,需要发送的消息为: [html] view plaincopy <message type="chat" from="k ...

最新文章

  1. 整理下.net分布式系统架构的思路
  2. 清华大学大数据研究中心“RONG”奖学金申请通知
  3. Vivado中如何避免信号被优化掉?
  4. kafka 不同分区文件存储_Kafka文件存储机制思考及答案:为什么要分区呢?分区存了哪些内容?...
  5. OpenCASCADE绘制测试线束:数据交换命令之XDE 形状命令
  6. linux下源码软件包的安装
  7. Java(ArrayList和LinkedList)、(HashTable与HashMap)、(HashMap、Hashtable、LinkedHashMap和TreeMap比较)
  8. console vue 打包之后怎么去掉_Vue Cli 3 打包配置--自动忽略 console.log 语句
  9. 腾讯地图api-前端定位组件
  10. Mac版Illustrator CS6破解版
  11. php随机发牌游戏,JavaScript_javascript实例--教你实现扑克牌洗牌功能,我们一般都会按照顺序把随机 - phpStudy...
  12. ATH9K Driver Learning Part VII: Transmission Tasklet and Interrupts
  13. 计量经济学之格兰杰因果关系检验(Granger causality test)
  14. 《分布式虚拟现实系统(DVR)》(Yanlz+Unity+SteamVR+分布式+DVR+人工智能+边缘计算+人机交互+云游戏+框架编程+立钻哥哥+)
  15. cakephp视图用php文件,CakePHP的视图
  16. 【算法模板】轻松学会KMP算法
  17. GetLasError参数详解
  18. pydicom----用法一
  19. element走马灯自动_[转]vue Element UI走马灯组件重写
  20. 数据可视化:icon统一风格

热门文章

  1. Delphi中的DBGrid如何实现使用鼠标滚轮上下滚动
  2. 好用的一款文档转换链接(在线免费)
  3. 警惕职场的竞业协议坑
  4. BUAA数据结构第四次作业2023
  5. 差距在哪儿?苹果M1瞄准了英特尔和微软
  6. 怎么在VMware虚拟机里体验HomeAssistant(多图模式)
  7. LeetCode 2437. 有效时间的数目
  8. 如何理解【叉乘得到误差】
  9. 数据治理解决方案数据标准明细表
  10. Code 39码详细介绍