翻译自:IntroToFramework · robbiehanson/XMPPFramework Wiki
XMPP历史
这个xmpp框架在2008年开始,不过是一个简单地RFC实现。提供一个最小的代理去接受三种xmpp的基本类型presence、message、iq。因为framwork只提供了最小的功能实现,它需要第三方的开发者提供许多拓展的代码。然而,大多数应用使用xmpp需要一些xmpp 拓展 如rosters,capabilities 或者其他的的拓展http://xmpp.org/xmpp-protocols/xmpp-extensions/
非常清楚地,工程需要实现更多的常用的xmpp功能。Roster 支持被添加和一些其他的XEP。早期版本的XEP,拓展是各自开发的,整合大家开发的拓展简直是一个噩梦,而且大部分的拓展并不是必须的,这个时候开发者们觉得保持简单、可通用的拓展是必须要的。
所以第二个版本的工程做成了模块化,工程被分离成一个模块化的系统,以及一个包含多个拓展的文件夹。开发者可以简单地添加他们需要的功能,也让第三方开发者更加容易提交工程。
第三个版本基于核心线程安全,继续使用模块化的代码,更加容易放置多个模块。同时第三方开发者已经成长为了一个开发者社区,不仅仅能够添加模板,还包括修复bug、提供技术支持、测试、文档、建议以及鼓励等。
介绍
xmpp框架分成两部分
XMPPCore 的类
XMPPStream
XMPPStream是xmpp的核心,这是你需要接触的主要类,所有的拓展类和定制类需要添加它,它由一些有趣的功能设计,让框架灵活、可拓展和更加容易在它之上开发
XMPPParser 是XMPPStream 使用的一个类,你一般不需要和它打交道
XMPPJID 提供多个JID(Jabber Identifier) 实现,支持解析JID,并解析JID的多种格式,它实现了NSCopying代理,因此JID可以被用作NSDictionary的key。它也实现了NSCoding协议。
XMPPElement 是基本的类,用于三种主要的XMPP 元素 XMPPID,XMPPMessage 和XMPPPresence。 XMPPElement 继承自NSXMLElement
XMPPMddule 提供可选的附加拓展功能,如果你做应用,你可能创建你自己的类,注册和接受代理。然而,如果你正在实现基本的XEP或者你想要添加特定拓展,你需要创建顶层的XMPPModule。
XMPPLoging 提供一个非常快速、高效、灵活的登录框架,之后将详细讲到
XMPPInternal 仅仅是一和core和多个拓展有关的个网络素材
素材:IQ、Message、Presence
继承关系
NSXML 有一个NSXMLElement+XMPP拓展,这个拓展提供了多个转换方法让你的代码更加简洁可读
[element attributeIntValueForName:@"age"];
配置可以被分成多个部分
配置连接
设置stream的myJID属性 xmppStream.myJID = [XMPPJID jidWithString:@"[email protected]"];
xmpp stream 会根据XMPP RFC自动最优配置,包括SRV搜索 _xmpp-client._tcp.doman.在以上的例子,使用gmail,谷歌服务器一般返回像这样的字段"talk.googe.com" xmpp stream 将会连接服务器,如果SRV搜索失败,xmpp stream会简单地连接到JID的doman
如果你知道你连接到一个xmpp server,并且这个server没有SRV记录,你能够告诉xmpp stream 跳过SRV搜索,如下
xmppStream.myJID = [XMPPJID jidWithString:@"[email protected]"]; xmppStream.hostName = @"myCompany.com";
xmppStream.myJID = [XMPPJID jidWithString:@"[email protected]"]; xmppStream.hostName = @"192.168.2.27";
MulticastDelegate介绍
xmpp框架需要支持一个不限制个数的拓展,包括官方的拓展、以及你希望添加到框架中的拓展。所以普通的代理模式不会起作用。XMPP模块和拓展需要被分开到不同的类中,然而每一个类都需要接受代理的回调,而基本的NSNotifaciton不能满足要求,应为一些代理需要返回一个值。
因此MulticastDelegate 允许你使用基本的代理,同时也允许多个类接受相同的代理通知。这样设计妙在: 你不需要把所有的xmpp 句柄代码放在单个类中,你能够根据功能把分开放。
添加和移除XMPPStream delegate [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()]; ... [xmppStream removeDelegate:self];
XMPPReconnect 意外断开会自动重连
XMPPRoster 提供基本的roster名册
XMPPRoom 提供多用户聊天支持
XMPPPubSub 公开subscribe
如下:
xmppReconnect = [ [XMPPReconnect alloc] init]; // Optional configuration of xmppReconnect could go here. // The defaults are fine for our purposes. [xmppReconnect activate:xmppStream]; // You can also optionally add delegates to the module. [xmppReconnect addDelegate:self delegateQueue:dispatch_get_main_queue()]; // And that's all that is needed. // The module will receive any delegate methods it needs automatically // from the xmpp stream, and will continue to do its thing unless you deactivate it.
NSError *error = nil; if (![xmppStream connect:&error]) { NSLog(@"Oops, I probably forgot something: %@", error); }
- (void)xmppStreamDidConnect:(XMPPStream *)sender { [xmppStream authenticateWithPassword:password error:NULL]; }
不是所有log信息有相同的优先级别,如error 这样的,当其他的仅仅是information。级别帮助开发者保持log信息完整,以及方便的开关log的能力
3. 必须可在终端用户配置
xmpp framework的使用者需要根据log报告全局掌控发生了什么。用于有不同的需求,一些想要log报告写到文件中,其他的可能想要log报告写到数据库,或者放到不同的位置基于log报告是来自应用还是来自xmpp framwork。
我开发了很多客户端,我看见很多连接第三方框架一次又一次地出现相同的问题。第三方库散乱的log语句。需要用户注释掉NSLog 语句,或者通过宏定义转化
所以与其被笨笨的NSLog打败,xmpp framework 使用了一个专业的log 框架CocoaLumberjack
这个log框架事实上有时候做同样的事比NSLog 快。同时它还支持不同搞得配置,允许用户添加自己的log语句,添加其他的格式。
下面你需要知道如何把log 连接到XMPPFramework
框架中大部分文件你能够发现以下的两行
// Log levels: off, error, warn, info, verbose static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN;
你可以更改任何文件的 log 级别,让它打印出更多的信息
这里有个标记能够被设置,当tracing 是YES,打印被调用的方法
请注意tracing 是被和 log levels 分开的,如可以设置log等级为warning,同时允许标记如下
// Log levels: off, error, warn, info, verbose static const int xmppLogLevel = XMPP_LOG_LEVEL_WARN | XMPP_LOG_FLAG_TRACE;
XMPPLogTrace(); // Enabled - Will spit out "<FileName>: <MethodName>" XMPPLogError(@"I will get logged"); XMPPLogWarn(@"I will get logged"); XMPPLogInfo(@"I will NOT get logged"); XMPPLogVerbose(@"I will NOT get logged");
#import "DDLog.h" #import "DDTTYLogger.h" - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { [DDLog addLogger:[DDTTYLogger sharedInstance] withLogLevel:XMPP_LOG_FLAG_SEND_RECV]; // All your other code... }
厚吾(http://blog.csdn.net/mangosnow)
本文遵循“署名-非商业用途-保持一致”创作公用协议