这里接着 第一部分 继续
这里是对ReactiveCocoa 框架学习的一个实践,不是技术性的文章,可行性还有待商榷。
首先思考一下使用XMPP登陆的流程大致为:
一般来说会将使用XMPP的方法都写在一个工具类设置为单例
根据上面的流程尝试写一个使用ReactiveCocoa的登录过程
这里要扩充一个方法[self rac_signalForSelector:SEL] 用来监听代理方法是否执行了
首先写一个登录方法 使用block返回登录结果
实现登录方法:
<code>
- (void)login:(XMPPLoginBlock)resultBlock {
//开始连接服务器
[self connectHost]; //在这里传入参数第一次握手
}
</code>
如果成功建立连接会调用代理方法 使用 rac_signalForSelector:SEL 方法监听
<code>
- (void)login:(XMPPLoginBlock)resultBlock {
//开始连接服务器
[self connectHost]; //在这里传入参数第一次握手
//连接成功
[[[self rac_signalForSelector:@selector(xmppStreamDidConnect:)] doNext:^(id x) {
//发送密码进行第二次握手
[self sendPwdToHost];
}] subscribeNext:^(id x) {
//返回结果给Block
resultBlock(XMPPToolConnectSuccess);
}];
}
</code>
接下来是授权成功
<code>
- (void)login:(XMPPLoginBlock)resultBlock {
//开始连接服务器
[self connectHost]; //在这里传入参数第一次握手
//连接成功
[[[self rac_signalForSelector:@selector(xmppStreamDidConnect:)] doNext:^(id x) {
//发送密码进行第二次握手
[self sendPwdToHost];
}] subscribeNext:^(id x) {
//返回结果给Block
resultBlock(XMPPToolConnectSuccess);
}];
</code>
登录成功
<code>
[[[self rac_signalForSelector:@selector(xmppStreamDidAuthenticate:)] doNext:^(id x) {
//发送现在消息第三次握手
[self sendOnlineToHost];
}] subscribeNext:^(id x) {
resultBlock(XMPPToolLoginSuccess);
}];
}
</code>
好了简单的一个过程就写好了 这里resultBlock内是自定义的枚举
接着完善一下第一部分中的代码 添加对按钮点击监听
<code>
[[self.login rac_signalForControlEvents:UIControlEventTouchUpInside]
subscribeNext:^(id x) {
}
</code>
因为这里要跳转控制器 所以 加 deliverOn:[RACScheduler mainThreadScheduler] 保证在主线程安全跳转 执行在单例中的方法:
<code>
[[[self.login rac_signalForControlEvents:UIControlEventTouchUpInside] deliverOn:[RACScheduler mainThreadScheduler]]
subscribeNext:^(id x) {
[[XMPPTool sharedXMPPTool] login:^(XMPPToolLoginResult result) {
if (result == XMPPToolLoginSuccess) {
dispatch_async(dispatch_get_main_queue(), ^{
TestController *testVC = [[TestController alloc] init];
UINavigationController *navVC=[[UINavigationController alloc] initWithRootViewController:testVC];
[UIApplication sharedApplication].keyWindow.rootViewController = navVC;
});
}
}];
}];
</code>
如果需要做其他如连接失败,密码错误等 和上面一样 扩充枚举就可以了
看下整个登陆的代码过程的代码别集中在了一起
<code>
//登陆
- (void)login:(XMPPLoginBlock)resultBlock {
//开始连接服务器
[self connectHost];
//连接成功
[[[self rac_signalForSelector:@selector(xmppStreamDidConnect:)]
doNext:^(id x) {
[self sendPwdToHost];
}]
subscribeNext:^(id x) {
resultBlock(XMPPToolConnectSuccess);
}];
//登录成功
[[[self rac_signalForSelector:@selector(xmppStreamDidAuthenticate:)]
doNext:^(id x) {
[self sendOnlineToHost];
}]
subscribeNext:^(id x) {
resultBlock(XMPPToolLoginSuccess);
}];
//连接失败
[[self rac_signalForSelector:@selector(xmppStreamDidDisconnect:withError:)]
subscribeNext:^(id x) {
resultBlock(XMPPToolConnectFailed);
}];
//授权失败
[[[self rac_signalForSelector:@selector(xmppStream:didNotAuthenticate:)]
doNext:^(id x) {
[_xmppStream disconnect];
}]
subscribeNext:^(id x) {
resultBlock(XMPPToolLoginFailed);
}];
}
</code>
注意到这次没有使用__weak 来处理block 因为这里使用的是单例不需要被销毁,实际开发还有视情况而定 毕竟单例会一直占用内存。
由于刚开始初学ReactiveCocoa 一些高级用法还有接触 以后慢慢改进 下一篇 开始尝试获取好友列表 这里是 第三部分 获取好友列表
完整Dome