这算是自己做的第一个比较完整的ios的小应用程序,接触到了很多自己以前没怎么用到的东西,好像coredata,GCD,post发送请求,自定义UITableViewCell等等。

先介绍下这个小应用吧,这是新浪微博iphone版的客户端,开发环境是Xcode4.3版本以上的,ios5.1,storyboard和arc,都是比较新的东西,在低版本的Xcode是运行不了的,可以查看自己关注的人的微博,写微博,评论微博,转发,收藏等一些很基本的功能,大概就这个样子。

接下来说一下准备工作吧,首先要有一个4.3版本以上的Xcode,其实低版本的Xcode也是可以的,但是因为本人的机子是ios5.1.1的,要在上面运行程序,只能用4.3以上的版本,再就是到新浪微博开放平台申请一个应用,得到一个appkey,这是非常关键的,接下来的oauth认证需要这个appkey来实现,构思好整个应用的框架之后,就可以开始进行开发了。

现在,进入正题吧。

一、应用程序框架构造

我写应用程序的时候,会先构造一个框架,把整一个页面以及要实现的内容初步的规划出来,接着在写程序的过程有什么新的想法在加上去,下图是我整个应用程序的storyboard

二、Oauth认证

要调用新浪API,必须要有一个认证过的access_token,通过这个token才可以拿到你想要的数据,整个应用的运行成功与否,关键就是这一步了,也可以说是这是整个应用的一个难点,在做这个之前,大家最好还是先看一下开放平台上的文档,上面的解释都很清楚,最重要的是要理解这个token和如何拿到它。

在第一个视图上添加一个WebView,web认证的url为https://api.weibo.com/oauth2/authorize?client_id=appkey&response_type=token&display=mobile&redirect_uri=http://baidu.com,url中client_id是必选参数,即你自己申请的应用的appkey,response_type也是必选参数,这里设置为token,还有就是回调网址redirect_uri,我这里设置的是百度,其他的有效网址也是ok的,另外一个需要注意的是将display设为mobile,即按手机屏幕显示网页。

NSURL *applyUrl=[[NSURL alloc]initWithString:apply_url];NSURLRequest *applyRequest=[NSURLRequest requestWithURL:applyUrl];[webView loadRequest:applyRequest];

apply_url为上面所说的认证url,运行之后,会来到登陆界面,如下图:

输入你的微博账号和密码之后,单击授权,会跳到你所给的回调地址中,这时在跳到回调地址的过程中,会返回一些数据,返回次数有4次,这个是自己算出来的,每次得到一个回传的url就计一次数,并输出,结果得到4个输出结果,得到回传url在函数:- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType,返回的4个url中只有一个具有我们需要的access_token,所以这里要进行判断对那个拥有access_token的url进行保存,其实在输出返回url的时候不难看出4个url的不同,有access_token的必有字符”#”,所以可以根据这个来进行判断,然后保存url,并截取自己需要的access_token,具体代码如下:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{self.curUrl=request.URL.absoluteString;for(int i=0;i<[self.curUrl length];i++){char n=[self.curUrl characterAtIndex:i];if(n=='#'){self.wantedUrl=self.curUrl;break;}else {self.wantedUrl=nil;}}self.loadtime++;//NSLog(@"%@,%i",self.wantedUrl,self.loadtime);if(self.wantedUrl){self.access_token=[self.wantedUrl substringWithRange:NSMakeRange(31, 32)];self.expires_in=[self.wantedUrl substringWithRange:NSMakeRange(92, 5)];self.uid=[self.wantedUrl substringWithRange:NSMakeRange(102, 10)];}NSLog(@"%@",self.access_token);return YES;
}

access_token便是认证过的可以使用的token,拿完token之后就要load数据,一般都是跳到自己的微博首页,提醒一下各位,在跳转之前先把token存放在一个静态变量里,这里也顺便说一下吧,存为一个类的静态变量是为了以后的参数传递,静态变量的方法也不失为传递参数的一个好办法。

由于一开始没把开放平台的开发文档看透,自己花了很长的去想要怎么拿到token,最后再看了几遍文档之后,再得出上面说到的获取access_token的url,拿到token数据。

三、Coredata

这应该是第一次接触coredata吧,之前学过用sqlite来存放数据,但是觉得老是要自己建表很麻烦,如今,coredata出现了,它可以说是一个可视化的数据库,可直接在上面建表,增加属性建立联系等,这里之所以用到coredata,是用来存放token和实现账号管理的,这样就不用每次打开应用都要输入自己的账号密码,可以直接使用已授权过的token,直接进到应用的首页,这里还要注意一个问题,授权过的token的寿命是有限的,一般用来测试的token寿命为24小时,所以这里要进行一个判断,判断token是否已经过期,如果过期要重新授权,即重新回到登陆页面

在这里说一下,由于我是在中途加入coredata的,不是Xcode自动生成的,有一个办法就是随便新建一个勾选了coredata的project,将它的appdelegate里所有你之前的应用的appdelegate里没有的东西复制,这里要注意一个问题,在运行程序后,你会发现程序出错无法运行,经过自己的一番研究和对比,原来是文件名称和文件路径在作怪,如果你本身就是用coredata的话,它会帮你创建一个你的app名字的数据库和一些相关的文件索引之类的,所以,解决的办法就是在复制的代码中凡是有看到app名称的都改为你要复制到的那个app名称,问题解决。

接下来就是如何利用coredata了。

首先,在coredata.xcdatamodeld文件中建表,这里,我只需要一个Token实体存放access_token就可以了;接着就是查表赋值取值删除等数据操作。

首先是取coredata里的数据,代码如下:

MyWeiboAppDelegate *appdelegate=[[UIApplication sharedApplication]delegate];NSManagedObjectContext *context=[appdelegate managedObjectContext];NSEntityDescription *entityDescription=[NSEntityDescription entityForName:@"Token" inManagedObjectContext:context];NSFetchRequest *request=[[NSFetchRequest alloc]init];[request setEntity:entityDescription];NSError *error;NSArray *objects=[context executeFetchRequest:request error:&error];

先要拿到一个管理上下文即NSManagedObjectContext,然后用这个context找到Token这个实体,NSFetchRequest相当于一个查询,查询实体结构Token里的数据,再利用context将Token里的数据赋值到一个NSArray中,接下来就按照NSArray的取值方法取得access_token

以后程序每次来到这一步的时候,会先从coredata里查找有没有授权过的token,有的话可以直接使用,跳到首页,没有的话就重新回到登陆界面,输入账号密码授权,这里还有一个token是否过期的判断,我用的方法是,继续使用这个token的url,取得data,判断data是否为空,因为过期了的token,使用其url的话是得不到数据的,所数据为空,这样就好判断了,另外,还要将过期了的token从coredata里面删除掉,具体的代码如下:

for(NSDictionary *object in objects){if([object valueForKey:@"access_token"]){[token_info setToken:[object valueForKey:@"access_token"]];NSError *error;NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:shouye_url,[token_info getToken]]];NSData *data=[NSData dataWithContentsOfURL:url];if(!data){[context deleteObject:[objects objectAtIndex:0]];if (![context save:&error]) {exit(-1);}goto loop;}NSLog(@"%@",[token_info getToken]);[self performSegueWithIdentifier:@"GoHome" sender:self];}loop:break;}

这里用到一个for循环,是为了以后实现多用户账号管理的,现在的程序还没有实现账号管理,等以后实现了账号管理再和大家分享一下,由于只有一个token数据,所以只要一次就可以退出循环了,用一个break实现

在之前说到的拿token时,拿到token便将它存入到coredata里面,具体代码如下:

MyWeiboAppDelegate *appdelegate=[[UIApplication sharedApplication]delegate];NSManagedObjectContext *context=[appdelegate managedObjectContext];NSManagedObject *token=[NSEntityDescription insertNewObjectForEntityForName:@"Token" inManagedObjectContext:context];[token setValue:self.access_token forKey:@"access_token"];NSError *error;if(![context save:&error]){NSLog(@"error!");}

其实存与取的方法是差不多的,得到coredata里Token实体的代码是一样的,接着就是setValue而已,不要忘了,每一次执行数据操作后要保存,这样,才是真正地完成一次数据操作

重点和难点和关键步骤在以上部分已经体现得差不多了,接下来就是load数据这些重复枯燥的事情,不过,这里也要千万注意小心的,因为返回的数据是json数据,建议大家使用一下json数据查看插件,我用的是FireFox的jsonView,个人感觉还不错,其实这些东西都大同小异的,取数据的时候千万看清楚数据的位置,数据的key等,有时一个数据取错,或者因为位置算错了,导致产生一个根本不存在的数据,那么程序就会崩溃,以一段代码为例子吧:

NSError *error2;NSURL *url=[[NSURL alloc]initWithString:[[NSString alloc]initWithFormat:shouye_url,self.access_token]];NSData *data=[[NSData alloc]initWithContentsOfURL:url];NSArray *ar=[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error2];NSArray *statuses=[ar valueForKey:@"statuses"];for(NSDictionary *d in statuses){NSDictionary *user =[d valueForKey:@"user"];WeiboData *wb = [[WeiboData alloc]initWithName:[user valueForKey:@"screen_name"] andText:[d valueForKey:@"text"] andImgUrl:[user valueForKey:@"profile_image_url"]];if([d valueForKey:@"bmiddle_pic"]){wb.picUrl=[d valueForKey:@"bmiddle_pic"];}[wb setWeiboMid:[d valueForKey:@"mid"] andReposts_count:[[d valueForKey:@"reposts_count"]intValue] andComments_count:[[d valueForKey:@"comments_count"]intValue]];[self.allItems addObject:wb];}

用之前得到的token获取json数据,存入数组中,然后找到自己要的那个数据就ok了,建议大家将要取的数据封装在一个类里面,用这个微博数据类来存取数据,我这里取的是微博头像,微博内容,微博名字和微博图片

四、自定义UITableViewCell

自己一开始写代码的时候,很是依赖storyboard本身提供的插件,用鼠标拉一拉,点一点就可以有很好的效果,但后来发现自己想加点东西的时候便很困难了,所以这次自己尝试了自己定义控件,第一个尝试便是UITableViewCell,其实自定义的东西一点也不难,而且好用,自己想加上什么控件就加什么,建议大家大的框图就可以用Xcode自带的东西来弄,viewcontroller里面的东西就自己定义,这样,以后加上美工什么的就不会那么麻烦了,下面就给一段代码:

UITableViewCell *cell=[[UITableViewCell alloc]init];WeiboData *wb = [self.allItems objectAtIndex:indexPath.row];CGSize size=[self calculateHeigh:wb.text];UILabel *r_label=[[UILabel alloc]init];r_label.backgroundColor=[UIColor clearColor];UILabel *c_label=[[UILabel alloc]init];c_label.backgroundColor=[UIColor clearColor];UILabel *r_count=[[UILabel alloc]init];r_count.backgroundColor=[UIColor clearColor];UILabel *c_count=[[UILabel alloc]init];c_count.backgroundColor=[UIColor clearColor];r_label.text=@"转发";r_count.text=[NSString stringWithFormat:@"%i",wb.reposts_count];c_label.text=@"评论";c_count.text=[NSString stringWithFormat:@"%i",wb.comments_count];UILabel *mylabel=[[UILabel alloc]init];mylabel.backgroundColor=[UIColor clearColor];mylabel.frame=CGRectMake(120, 30, 150, 50);mylabel.tag=1;mylabel.text=wb.name;[cell.contentView addSubview:mylabel];//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{UILabel *mytext=[[UILabel alloc]init];mytext.backgroundColor=[UIColor clearColor];mytext.numberOfLines=0;mytext.lineBreakMode=UILineBreakModeWordWrap;mytext.tag=2;mytext.frame=CGRectMake(20, 100, size.width-40, size.height+10);//dispatch_async(dispatch_get_main_queue(), ^{mytext.text=wb.text;[cell.contentView addSubview:mytext];

这里还涉及一个问题,就是文本自适应高度和cell自适应高度,网上查了很多资料,自己总结了自己认为最好的办法,计算文本的size可以用这个函数来实现CGSize size = [string sizeWithFont:font constrainedToSize:CGSizeMake(320.0f, CGFLOAT_MAX) lineBreakMode:UILineBreakModeCharacterWrap],然后就可以跟据size的width和heigh属性去设置文本label的frame了,cell高度设置在函数:- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath里面实现,把所有的控件的高度加起来,再加上一个调整的数值,return这个高度就是cell的自定义高度,这样,cell自适应内容高度就完成了

其实,有人肯定会有一些疑问,为什么这里没用到cell的复用,是这样的,大家是知道,每条微博不一定都有微博图片,所以有些cell是不用加上UIImageView控件显示微博图片的,但是如果采用复用的话,会有一个很严重的后果,就是之前cell里的东西还会存在新的cell里,只是被你添加的控件覆盖掉而已,自己试着改几下,发现问题还是存在,复用这个问题还真让人不省心啊,后来迫不得已直接就不用用了,每次都新建一个空的新的cell,可能是自己学艺未精吧,应该是有解决的办法的,不采用复用也有很大的不好,就是每次都要新建cell,这样浪费内存和时间,这是需要改正的地方

五、GCD

又一个重点难点啊,GCD即Grend Central Dispath,就是多线程的意思,还是建议大家先看资料,理解透彻后再使用它会事半功倍,看一些操作系统的书也是有帮助的,并发,同步,异步,什么的,理解这些概念后看一些相关例子会很清晰一点,我承认自己对GCD的理解还只停留在表层的阶段,还没有真正地懂得怎么使用GCD,下面给一段cell里load图片的代码吧:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{NSURL *url = [NSURL URLWithString:wb.imgUrl];wb.image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];});dispatch_sync(dispatch_get_main_queue(), ^{myimage.image = wb.image;  [cell.contentView addSubview:myimage];

这段大概就是一个异步里面嵌套两个同步,把下载图片和显示图片分别放在两个同步线程里面,这样写就是一次性的把图片都下载完,然后再显示出来,这段代码看起来挺简单的,就是它简单所以也出现了不少问题,最最主要的问题就是网速的问题,如果是一般SIM卡的话图片会load很久,然后很久才显示出来,还会出现头像闪换,到最后才稳定下来,建议大家测试的时候还是用wifi,或者网速更好的,这样就看不出什么问题了,而且很流畅,自己觉得应该要在两个同步里再加多东西,这个问题应该可以解决的,现在终于知道有些app为什么会出现闪退的问题了,我相信有些应该就是因为load数据的时候因为网速问题卡死了。

六、post发送请求

这次是第一次接触post发送请求这个东西,一开始还手忙脚乱的不知道该怎么弄,上网查了些资料,自己又刚好学了计算机网络这门课,这就大概知道post发送请求是什么样的一个概念了,说白了,就是将一个post方式的数据封装起来发送到要其允许的url,就这么简单,已写微博为例吧,你要把你写的东西发送出去,允许后在你的微博里就可以看到你发的微博了,需要封装的数据里包括access_token即token的值和你所发的内容status,注意,这里需要将数据编码NSUTF8StringEncoding,具体代码如下:

NSURL *url;NSMutableURLRequest *urlRequest;NSMutableData *postBody = [NSMutableData data];url = [NSURL URLWithString:update_url];  urlRequest = [[NSMutableURLRequest alloc] initWithURL:url]; [urlRequest setHTTPMethod:@"POST"];NSString *string=[[NSString alloc]initWithFormat:@"&access_token=%@&status=%@",[token_info getToken],self.myLable.text];[postBody appendData:[string dataUsingEncoding: NSUTF8StringEncoding allowLossyConversion:YES]]; [urlRequest setHTTPBody:postBody];NSData *returnData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil]; if(returnData){NSString *result = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];NSLog(@"%@",result);}else{NSLog(@"Error!");  }

看代码才结合开发文档里所说的,以上的代码不难理解,转发,收藏和删除微博取消收藏等道理也是一样的,不同就是在数据块那里需要添加一个微博id,用来指定要转发,收藏或者是要删除的微博等,这里就不多说了

七、整个客户端的几个运行界面

最后再做个总结吧

这次做这个微博客户端确实是让自己学到了很多东西,对自己以后的ios开发很有用处,一些平常没怎么用到的东西,这一次都有了尝试,这其中也又遇到了很多问题,还好身边有很多很厉害的人,不懂的时候可以问一下他们,其实自己觉得上网查资料,加上自己的理解和不断的尝试,总有个解决问题的办法出来

在总结一下这个应用吧,首先,有很多待解决的问题,cell的复用,GCD遇到网速不行的时候该怎么办,还有就是账号管理这一块,希望在以后的项目开发中能逐个逐个的解决,界面方面也做得不是很好,用了太多的视图,下次争取能够一个视图多用,大概就这些了吧

代码来咯,ios:新浪微博iphone客户端

提醒一下大家,在资源下载那我也有说了,请大家到新浪微博开放平台自己申请一个appkey,在程序文件中找到名为Url.h的文件,在找到apply_url,把里面的AppKey替换成你自己的appkey就可以了,不然是运行不了的。

ios:新浪微博iphone客户端相关推荐

  1. 关于新浪微博iPhone客户端设计与实现硕士论文学习心得

    关于新浪微博iPhone客户端设计与实现硕士论文学习心得 1.SNS系统介绍 SNS(Social Networking Services)即社会性网络服务,主要帮助人们建立社会性网络的互联网应用服务 ...

  2. DIY 新浪微博Android客户端 ----用Android手机发送来自iPhone的微博

    今天看到一个哥们发布的DIY新浪微博客户端,自己试了下,确实好用,赫赫,给大家分享下 链接 http://hi.baidu.com/aqtata817/blog/item/776246021f81b6 ...

  3. 伪ios新浪微博客户端(自家用)

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

  4. iPhone客户端开发笔记(八)

    客户端稳定性和提升用户体验. 1,掌握app的运行状态 这是官方文档中关于Application State的详细描述: https://developer.apple.com/library/ios ...

  5. 转载关于通过判断浏览器的userAgent,用正则来判断是否是ios和Android客户端

    声明:本文为转载文章  中间部分穿插文字为本人查阅其他资料所得,其目的只是为了加强记忆和方便阅读,并无它意. 通过判断浏览器的userAgent,用正则来判断是否是ios和Android客户端.代码如 ...

  6. 新浪微博PC客户端(DotNet WinForm版)——功能实现分解介绍

    上一篇:新浪微博PC客户端(DotNet WinForm版)-- 初探 说明一下:只是兴趣,并不是想发布为一个软件,说实在的,如果要作为一个软件发布,要做的工作还有很多. 新浪微博API地址:http ...

  7. html判断手机浏览器,JS判断浏览器iOS(iPhone)、Android手机移动端

    通过判断浏览器的userAgent,用正则来判断手机是否是ios和Android客户端.网上搜索来的,比较简单: var u = navigator.userAgent; var isAndroid ...

  8. IOS新浪微博开发--分享、授权登录

    一.准被工作 1.注册成为开发者,创建应用项目,获取APPkey 2.添加 SDK 文件到工程           将从 GitHub 上下载的 libWeiboSDK 文件夹添加至工程,其中包含 W ...

  9. (11)Xamarin.iOS - 新增iPhone storyboard

    原文 Xamarin.iOS - 新增iPhone storyboard 1. 开启Xamarin Studio 并建立新项目 专案类型为 iOS=>iPhone Storyboard => ...

最新文章

  1. 浏览器URL地址里一堆%或者6E616D6531之类的是啥?编码
  2. 一丶宝塔+青龙面板安装部署教程及命令-依赖库
  3. JavaScript高级笔记
  4. Rust 算法排位记 - 插入排序的图示和代码实现
  5. 试用VisualStudio2005Beta2出现的小BUG
  6. 安卓手机通话录音软件
  7. SQLServer数据库的发布订阅读写分离主从复制对新增表的自动同步深究
  8. 盘点人工智能十大经典应用领域、图解技术原理
  9. 云计算技术与应用 - 知识点
  10. 高德地图加载谷歌地图瓦片
  11. 2022中秋股市复盘随笔
  12. python数据清洗笔记
  13. 使用百度地图api制作地图名片
  14. coreldraw铺花纹_CorelDRAW打造漂亮剪纸花纹教程
  15. 十大IT网站排名 及IT论坛(技术社区)排名
  16. Cocos2d-x的多线程与异步加载实现详解
  17. 计算机房颁奖词,成绩优异颁奖词.doc
  18. js中的boolean原始类型和Boolean引用类型
  19. Seq2SQL :使用强化学习通过自然语言生成SQL
  20. 用C++写好一个基本的文本编辑软件

热门文章

  1. Linux 管理面板云帮手、APPNODE与宝塔哪个好
  2. 那些你可能不知道的微信奇技淫巧
  3. 数据库审计方案简介和功能对比
  4. 重复照片查找软件Duplicate Photos Sweeper Mac
  5. 虚拟机安装和破解密码
  6. 微信小程序webview清除缓存、微信公众号h5清除缓存、页面白屏、空白、不刷新问题
  7. 开源项目之开源的2D游戏引擎 HGE
  8. 【动态规划】钢条切割问题
  9. 使用obi fluid进行洪水模拟,持续更新~
  10. 用计算机绘制函数图像ppt,如何利用描点画函数图像课件制作