新浪微博iOS版SDK“宝玉XP”框架学习笔记

本文为论坛会员3h2om分享,对新浪微博iOS版SDK-“宝玉XP”框架进行研究所写的学习笔记,非常详细和精彩。

本人刚入学iOS开发,在学习的过程中,对新浪微博iOS版SDK-“宝玉XP”框架进行了学习(下载地址:https://github.com/JimLiu/WeiboSDK),在没有获得相应的说明文档前提下,要理解其中的内幕对于初涉OPEN API的新人来说不算是件易事,为了满足一窥究竟的一惯心理,我在对其源代码进行一番抽丝剥茧式的跟踪后,基本上搞懂了框架内各类之间的调用关系,初略地理解了各类的大概用途,也对OAuth 认证机会有了进一步的认识。充分理解该框架后将对于开发基于HTTP协议的类似项目有一定的参考作用。现将我的这种“理解”简要地进行整理,愿能对学习并想了解该SDK的人有所帮助。
一、组成和关系
该框架除了由大量的诸如数据连接、数据模型等基础类支撑外,其主要的功能由 RootViewControllerComposeViewController、OAuthcontroller、OAuthEngine URLConnection、WeiboClient 6个类完成,RootViewController是整个框架的视图控制器,它作为应用程序委托中的UINavigationController类型的输出口,控制该系统的主视图以呈现给用户。ComposeViewController类是作为RootViewController类的组成部分存在的,用以控制写微博时所呈现出的发送视图。OAuthcontrller用以控制完成OAuth认证机制所需要的视图。类OAuthEngine、URLConnection、WeiboClient为服务类,为各视图控制类提供服务,类OAuthEngine为完成OAuth方式认证提供了支持,通过该方法完成授权和认证过程,URLConncetion和WeiboClient建立网络连接,实现新浪提供的OPEN API功能,设置并完成HTTP请求以发送和接受数据。


二、各类简单说明
1、RootViewController类
该类是整个系统的视图控制类,是系统与外面交互的入口,也是系统的运行的驱动点,它关联了OAuthEngine等服务类,在该类通过调用其他各服务类提供的功能,完成从用户的登录授权认证到把微博客。在viewDidLoad方法中,完成了对用于保存微博列表的NSMutableArray类的status的初如化。接着在viewDidAppear方法中,用服务方提供的三个URL和应用程序在新浪方获取的Key和Secret完成其成员OAuthEngine类型的_engine的初始化工作,为OAuth认证提供了准备。在此之类,就调用自身loadTimeline方法,来完成包括OAuth认证、请求数据等一系列动作,从此,系统运行的万里长征正式踏上征程。
2、ComposeViewController类

该类所控制的视图是RootViewController类所控制的视图的组成一部分,当用户点击主视图上面导航栏中的发送按钮,该类所控制的视图将呈现出来,主要用于发送微博。Draft类描述发送微博时的附件信息,newTweet方法的主要作用是初始化draft,为发送新的微博上传相关附件提供对应的对象,send方法用于调用的OPENG API完成发送这一动作,insert方法在发送微博时插入附件时被调用。
3、OAuthController类该类主要用于调用OAuthEngine类的服务来完成OAuth认证机制中的认证工作的三步认证,它由RootViewController类中的loodTimeline方法调用。该类中的_webView成员是用来显示用户授权界面的UIVebView控件,因此就实现了UIWebViewDelegate委托,用委托中相应的方法协调完成认证过程。该控件的URLRequest属性被设置为三步认证中的第二个URL,用于获取用户授权的Request Token。
4、OAuthEngine类该类是OAuth认证实现的核心类,为其他类提供认证服务。调用requestRequestToken将获取到经过授权的获取用户授权的Request Token,调用requestAccessToken将用授权的Request Token换取Access Token。
5、URLConnection和WeiboClient类WeiboClient是URLConnection的子类,WeiboClient实现了OPEN API方法,设置并完成HTTP请求以发送和接受数据,并用指定的action来处理通过的HTTP请求得到数据。

二、进入用户授权界面的步骤


系统运行后,经过RootViewController类的viewDidApper事件方法,调用其lodadTimeline方法完成OAuth认证机制的第一步(获取未授权的Request Token),之后进入到OAuthController类的loadView方法,该方法中通过语句:“*request = _engine.authorizeURLRequest; [_webView loadRequest: request];”完成认证机制中第二步,接着进入到webViewDidFinshg
事件方法,进入到授权界面。具体细节比较复杂,见下面的(进入授权界面的时序图),由于没有专门的UML工具,加之涉及到的对象较多,时序图没有列出所有的对象和细节。在进入RootViewController的viewDidAppear事件方法中,判断该类中的_engine是否已经存在,如果没有就对其初始化,接着调用“[self performSelector:@selector(loadTimeline) withObject:nil afterDelay:0.0]; ”进入到loadTimeline方法中。loadTimeline方法首先用本类中的实例成员_engine作为参数,着手构建OAuthController对象,下一步就判断刚刚构建的动作是否真的构建了对象,如果对象存在,就立即转入到刚刚构建OAuthController类对象所对应的视图,即进入到授权界面,以供用户进行授权。如果不存在OAuthController对象,就说明已经完成了认证,不用进入到授权界面,直接调用loadData加载与授权用户相关的微博信息后,进入到RootViewController对应视图即可。其中创建OAuthController对象是关键,在其中进行了判断,如果已经授权了或者cache中还保存着相应的cooke的话,就退出,否则就用_engine为参数,调用OAuthController的初始化方法,初始化后又判断_engine.OAuthSetup 的值,如果为NO则表示还没有进行过认证(若为YES则表示已经完成了认证步中的第一步),于是就调用¬¬¬¬_engine requestRequestToken来完成认证的第一步操作。OAuthEngine类中requestRequestToken方法的调用过程:该方法是一中间方法,起到过渡作用,它只是调用 requestURL: token:onSuccess: onFai:方法,后一个方法用指定的URL和两个方法SEL作为参数,其中两个SEL分别用于当该HTTP请求成功或失败返回时对应的处理方法。它分别指定为setRequestToken和outhTicketFailed方法。
OAuthEngine类中的requestURL:token:onSuccess:onFail方法又用给定的URL和token构建了OAMutableURLRequest对象,然后构建OADataFetcher对象,并把它来提取基于OAMutableURLRequest网络连接的数据(调用onSucess:和onFail方法)。如果成功,就调用上面传过来的OAuthEngine类中setRequestToken方法处理认证第一步的返回数据。setRequestToken只是用得到的数据填充用OAuthEngine类中的_requestToken。
至此,已经完成了构建OAuthController对象,并工作完成了OAuth认证中的第一步了。接着,程序一路回退,回退至loadTimeline
方法中:
UIViewController *controller = [OAuthController controllerToEnterCredentialsWithEngine: _engine delegate:self]//通过以上的过程,该句已经执行完毕
if(controller)//第一次进入时总需要认证,总会构建controller,所以为为真值
[self presentModalViewContrllor: controller animated:YES];//
else
[self loadData];由于presentModalViewContrllor是异步方法,调用后,loadTimeline就当即结束了。经过几番系统 的“原子操作后”,进入到OAuthController类中的loadView 事件方法中,在该事件方法中,将完成OAuth认证机制中的第二步过程。该方法对即将出现的授权界面中的一些UI进行了初始化设置后,调用:
NSURLRequest *request = _engine.authorizeURLRequest;
[_webView loadRequest:request];

在OAuthEngine类的authorizeURLRequest方法中,首先判断_requestToke.key是否为空(由于我在第一步的认证过程上,已经设置好了),若不为空,则用authorizeURL和_requestToken等为参数,构建OAMutableURLRequest对象,并基于此设置好相关的HTTP请求,并返回供_webView加载,loadView结束后再进入_webViewDidFinishLoad事件方法。
至此,授权界面已经出现,以供用户对其授权,界面如下:

此过程的详细调用情况见下图:

接上:进入授权界面的时序图

三、用户授权后并进入到微博主界面的调用关系
当用户在授权界面上填写好帐号和密码后,点击“授权”后,触发OAuthController类的webViewStartLoadWithRequest事件和webViewDidFinishLoad方法,在webViewDidFinishLoad中调用gotPin方法得到Access Token完成OAuth认证机制的最后一步。之后RootViewController类中的viewDidAppear事件方法被触发,在该方法中,调用loadData方法,完成数据的加载工作,然后就显示了微博的主列表界面。

具体细节比较复杂,见下面的(进入授权界面的时序图),由于没有专门的UML工具,加之涉及到的对象较多,时序图没有列出所有的对象和细节。该时序图仅描述用户授权过程(即OAuth认证的最后步),没有描述认证后其中加载数据的详细过程,详细过程见方法调用图。

几个重要方法:
RootViewController类中loadTimeline方法:该方法是本框架中的一个主要中转方法,此方法调用OAuthController类的controllerToEnterCredentialsWithEng
ine完成认证中的前两步操作,调用loadData方法完成认证的第三步和加载数据过程。
OAuthEngine类中的requestRequestToken方法用来完成认证第步的请求,setRequestToken方法用来处理接收数据,并设置好_requestToken;requestAccessToken方法用来完成认证第三步,setAccessToken方法用来处理上步接收的数据,并设置_accessToken
从而完成整个认证操作。OAuthController类中的locateAuthPinInW
ebView方法用来从返回的HTTP请求中获取PIN码,即获取用授权的Request Token,完成认证的第二步,用此来作为第三步的参数。
RootViewController类中的timelineDidReceiveForComment方法用来处理接收从HTTP请求返回中的数据,在此方法中实现微博的数据的反序列化工作。
四、几点发现
1、OAuthController类中的webViewDiFinishLoad事件方法中通过调用: _delegate OAuthController:self authenticatiedWit
ntroller:authenticatedWithUserName:_engine.username 方法间接地又调用了一次loadTimeline和loadData 方法生成WeiboCleint
对象并进行认证和加载数据操作,但由于WeiboClient对象是自动销毁后,程序立即进入到了RootViewController类的viewDidApper事件方法,在这个方法中又调用loadTimeline,以至于上面的操作是多余的,等于在进行了两次认证(第二步和第三步)和加载数据操作。
2.关于OAuthController类中的webView:shouldStartLoadWit
hRequest事件方法(视图类的相关事件方法也一样)连续被调用多次问题。这是一个很有趣的问题,至今我没有发现什么原因。比如说要转到(presentModalViewController:)一个视图(该视图实现了UIWebViewDelegate委托),该视图控制器中实现了viewDidLoad和loadView事件方法,如果在这些方法中没有调用其父类的对应方法,则被转到的视图控制器中的这两个方法会连接地被调用,我一次试验是连续地被调用了11次?但如果加上 super viewDidLoad 的话只正常地被调用1次。至于是什么原因,我至今未懂。 

原帖地址:http://www.cocoachina.com/bbs/read.php?tid-73476.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/404460.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Lync Server 2010所需媒体网络流量带宽详解和计算

如果在组织内部部署Lync Server 2010,那么最大的优势就是解决了组织内部的即时通讯需求,为什么这么说?因为纵观现在微软所推行的商业智能应用平台,可以非常直观的了解到实际上整个微软商业平台就是由Lync Server、Exchange Server…

Linux互斥锁的使用代码实现

From: http://blog.csdn.net/leo115/article/details/8037869 [cpp] view plaincopy#include <stdio.h> #include <pthread.h> #include <sched.h> #include <unistd.h> //对临界区的保护问题 void *fun1(void *arg); void *fun2(void *ar…

USB Camera摄像头(UVC 与 gspca)

From: http://www.cnblogs.com/leaven/archive/2010/08/19/1802934.html http://weijb0606.blog.163.com/blog/static/131286274201063145356429/ 我的摄像头终于出现图像了&#xff01; 李迟按&#xff1a;本文章不是教程&#xff0c;不是心得总结&#xff0c;而是记录我在…

随机存取存储器(RAM)

RAM&#xff08;random access memory&#xff09;随机存储器。存储单元的内容可按需随意取出或存入&#xff0c;且存取的速度与存储单元的位置无关的存储器。这种存储器在断电时将丢失其存储内容&#xff0c;故主要用于存储短时间使用的程序。 按照存储信息的不同&#xff0c;…

创建弹出窗口的图片展示

本帖最后由 oisweb 于 2009-11-24 14:11 编辑图片有点大了 显示不是很好 自己看着办吧 1 创建工程 设置页面属性 <mx:Application xmlns:mx"http://www.adobe.com/2006/mxml" layout"vertical" horizontalAlign"center" verticalAlign&…

移植gdb到DM368 IPNC中 linux arm gdb

From: http://blog.csdn.net/ghostyu/article/details/8081897 移植gdb到嵌入式的ipnc中&#xff0c;大多数人习惯使用printf调试&#xff0c;但是遇到像”segment fault“这的错误也是后就很难定位&#xff0c;这时候gdb的作用就体现出来了 在pc使用gdb调试应用程序前&…

Silverlight实用窍门系列:56.Silverlight中的Binding使用(一)【附带实例源码】

本文将详细讲述Silverlight中Binding&#xff0c;包括Binding的属性和用法&#xff0c;Binding的数据流向。 Binding:一个完整的Binding过程是让源对象中的某个属性值通过一定流向规则进行转换和验证之后绑定到目标对象的某个属性上面。这个源对象由ElementName指定&#xff0c…

jqGrid + JSON + WebService 完整示例

真没找到这样的例子&#xff0c;于是自已写了个&#xff0c;分享出来。 第一步&#xff0c;首先在WebService上&#xff0c;添加[System.Web.Script.Services.ScriptService]属性标签&#xff0c;让WebServer支持JSON. namespace jqGrid_JSON_WebService_Sample.Services{/// &…

交叉编译和交叉调试环境搭建及使用

From: http://blog.chinaunix.net/uid-25119314-id-226230.html 1. 交叉编译器 1.1 交叉编译器介绍 在一种计算机环境中运行的编译程序&#xff0c;能编译出在另外一种环境下运行的代码&#xff0c;我们就称这种编译器支持交叉编译。这个编译过程就叫交叉编译。简单地说&…

Hello Views之Spinner(yaozq翻译,仅供参考)

Spinner是一种类似于下拉列表的widget。 在这个教程中&#xff0c;你将创建一个简单的用于展示星球列表的spinner组件。当选择列表中的一项时&#xff0c;将会弹出一个表示所选项的toast信息。下面是具体步骤&#xff1a; 1&#xff0c;新建一个名为HelloSpinner的项目。 2&…

Bitmap 之 getPixels() 的 stride

学习Graphics中遇到位图(Bitmap)中getPixels()方法&#xff0c;对该方法的用法大体理解&#xff0c;但对其中的stride参数却不明白具体的用法以及用意&#xff0c;现记述过程如下&#xff1a; getPixels()方法的用处为获取位图(Bitmap)中的像素值(颜色值)&#xff0c;存入类型为…

i++ 和 ++i 效率的分析以及自定义类型的自增/自减运算符重载实例

From: http://blog.csdn.net/leo115/article/details/8101541 我们通常在写for循环 的时候&#xff0c;要实现变量 i 的自增 1 &#xff1b;往往会在i 和i中随便挑一种写&#xff0c;对于i和i的理解&#xff0c;我们往往停留在返回的值的不同&#xff0c;其实i与i在实现效率上…

BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )

树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. 时间复杂度O(N*log^3(N))------------------------------------------------------…

struts2遍历select

2019独角兽企业重金招聘Python工程师标准>>> <s:bean name"org.apache.struts2.util.Counter" id"counter"> <s:param name"first" value"1" /> <s:param name"last" value"pageCount"…

Oracle 彻底 kill session

为什么80%的码农都做不了架构师&#xff1f;>>> --*************************** -- Oracle 彻底 kill session --*************************** kill session 是DBA经常碰到的事情之一。如果kill 掉了不该kill 的session&#xff0c;则具有破坏性&#xff0c;因此尽…

WebService学习总结——调用第三方提供的webService服务

互联网上面有很多的免费webService服务&#xff0c;我们可以调用这些免费的WebService服务&#xff0c;将一些其他网站的内容信息集成到我们的Web应用中显示&#xff0c;下面就以获取天气预报数据。气象中心的管理系统将收集的天气信息并将数据暴露出来(通过WebService Server)…

【017】◀▶ C#学习(九) - ADO.NET

《C#入门经典&#xff08;中文第四版&#xff09;》在程序中访问数据库学习笔记 --------------------------------------------------------------------------------------------------------- ●● 目录&#xff1a; A0 ………… System.Data.SqlClient 命名空间 A1 ……………

【转】主流PHP框架间的比较(Zend Framework,CakePHP,CodeIgnit...

2019独角兽企业重金招聘Python工程师标准>>> 【转】主流PHP框架间的比较&#xff08;Zend Framework&#xff0c;CakePHP&#xff0c;CodeIgniter&#xff0c;Symfony&#xff0c;ThinkPHP&#xff0c;FleaPHP&#xff09; 2011年08月14日 星期日 12:51 转载自 leol…

如何利用业务时间提升自我

转载于:https://www.cnblogs.com/helloIT/articles/5140273.html

ping得通外网,上得了QQ,游戏,却打不开网页。

操作系统&#xff1a;win7_64bit 下午帮我小艾优化电脑&#xff0c;不知道把什么插件给卸载了。 她回来以上就上不了网&#xff0c;我首先ping网关&#xff0c;DNS&#xff0c;外网&#xff0c;都通。 登QQ正常。 我的思路&#xff1a; 先把Socket套字结相关的卸载掉就是&#…