新浪微博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,一经查实,立即删除!

相关文章

[react] 描述下在react中无状态组件和有状态组件的区别是什么?

[react] 描述下在react中无状态组件和有状态组件的区别是什么? 1,无状态组件主要用来定义模板,接收来自父组件props传递过来的数据,使用{props.xxx}的表达式把props塞到模板里面。无状态组件应该保持模板的纯粹性,以便…

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

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

Linux进程状态解析之R、S、D、T、Z

From: http://bbs.hx95.com/read-htm-tid-208094-fpage-2.html R (TASK_RUNNING),可执行状态。 只有在该状态的进程才可能在CPU上运行。同一时刻可能有多个进程处于可执行状态,这些进程的task_struct结构(进程控制块)被放入对…

[react] react父子组件如何通信?

[react] react父子组件如何通信? props 个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌谣一起通关前端面试题

PAT 1100

1100. Mars Numbers (20) 时间限制400 ms内存限制65536 kB代码长度限制16000 B判题程序Standard作者CHEN, YuePeople on Mars count their numbers with base 13: Zero on Earth is called "tret" on Mars.The numbers 1 to 12 on Earch is called "jan, feb, m…

安装linux的准备

首先,在安装linux系统之前应首先做到规划。因为,一个好的服务器,工作台,甚至是个人PC都必须要做到规划。因为这样可以做到以最少的花费实现更高的服务要求。这个很好理解,比如你做邮件服务器就必须要选择一个大的硬盘预…

printf如何输出64位整数

From: http://blog.csdn.net/zzqhost/article/details/6064886 关于printf函数输出64位数的问题,其实在window下和linux下是不一样的: linux下是 printf("%lld/n",a); printf("%llu/n",a); windows下是 printf("%I64d/n"…

[react] 在react中你是怎么进行状态管理的?

[react] 在react中你是怎么进行状态管理的? 使用React原生的ContextuseContext(可选的加上useReducer)使用redux react-redux redux-thunk使用mobx mobx-react 个人简介 我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易, 但坚持一定…

iOS UI-常用控件

1 #import "ViewController.h"2 3 interface ViewController ()<UITextFieldDelegate>4 5 // 标题标签6 property (strong, nonatomic) UILabel *titleLablel;7 // 分段控制器8 property (strong,nonatomic) UISegmentedControl *segment;9 // 开关标签10 prop…

天龙八部***核心代码

天龙八部***核心代码 信息来源&#xff1a;邪恶八进制信息安全团队&#xff08;www.eviloctal.com&#xff09; 文章作者&#xff1a;认真的雪 我也来凑凑热闹..... 发一个网游***核心代码...无聊的时候写的.. 截取了用户名&#xff0c;密码&#xff0c;等级&#xff0c;仓库密…

Linux常用错误码--errno-base.h

经常会需要用到错误码&#xff0c;但是它具体的值 是什么呢&#xff0c;往往不太清楚&#xff0c;所以在使用的时候非常不舒服&#xff0c;下面把linux平台下常用的错误码列了下。 我是Fedora12系统&#xff0c;找到的定义文件是&#xff1a;/usr/include/asm-generic/errno-b…

[react] react组件的state和props两者有什么区别?

[react] react组件的state和props两者有什么区别&#xff1f; State 是一种数据结构&#xff0c;用于组件挂载时所需数据的默认值。State 可能会随着时间的推移而发生突变&#xff0c;但多数时候是作为用户事件行为的结果。 Props(properties 的简写)则是组件的配置。props 由…

[react] react与angular、vue有什么区别?

[react] react与angular、vue有什么区别&#xff1f; Angular以前有接触过&#xff0c;我的感觉是&#xff0c;这不像React和Vue一样是构架补充库&#xff08;比如需要另外的全家桶来配合使用&#xff09;&#xff0c;它的功能非常完整&#xff0c;更像是一个框架&#xff0c;…

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…

南京Uber优步司机奖励政策(12月28日到1月3日)

滴快车单单2.5倍&#xff0c;注册地址&#xff1a;http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单&#xff1a;http://www.cnblogs.com/mfryf/p/4612609.html 优步奖励低/不挣钱/怎么办?看这里&#xff1a;http://www.cnblogs.com/mfry…

[react] 说说你对声明式编程的理解?

[react] 说说你对声明式编程的理解&#xff1f; 声明式编程 区别于命令式编程,它的特点就是我告诉计算机做什么,但是没有告诉你怎么做. 个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大家一起讨论 主目录 与歌…

有谁用过sendinput摸拟一个鼠标击键?

我想用&#xff0c;但定义了MOUSEINPUT和INPUT结构&#xff0c;编译是时出现这个错误&#xff1a; E:\My document\VCprograms\13\13.cpp(152) : error C2065: MOUSEINPUT : undeclared identifier E:\My document\VCprograms\13\13.cpp(152) : error C2065: INPUT : undeclare…

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;而是记录我在…

[react] react有几种构建组件的方式?可以写出来吗?

[react] react有几种构建组件的方式&#xff1f;可以写出来吗&#xff1f; 1.无状态函数式组件 function HelloComponent(props, /* context */) { return <div>Hello {props.name}</div> } ReactDOM.render(<HelloComponent name"Sebastian" /&g…

随机存取存储器(RAM)

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