這里接著 第一部分 繼續(xù)
這里是對(duì)ReactiveCocoa 框架學(xué)習(xí)的一個(gè)實(shí)踐蚕礼,不是技術(shù)性的文章严卖,可行性還有待商榷席舍。
首先思考一下使用XMPP登陸的流程大致為:
一般來(lái)說(shuō)會(huì)將使用XMPP的方法都寫(xiě)在一個(gè)工具類(lèi)設(shè)置為單例
根據(jù)上面的流程嘗試寫(xiě)一個(gè)使用ReactiveCocoa的登錄過(guò)程
這里要擴(kuò)充一個(gè)方法[self rac_signalForSelector:SEL] 用來(lái)監(jiān)聽(tīng)代理方法是否執(zhí)行了
首先寫(xiě)一個(gè)登錄方法 使用block返回登錄結(jié)果
實(shí)現(xiàn)登錄方法:
<code>
- (void)login:(XMPPLoginBlock)resultBlock {
//開(kāi)始連接服務(wù)器
[self connectHost]; //在這里傳入?yún)?shù)第一次握手
}
</code>
如果成功建立連接會(huì)調(diào)用代理方法 使用 rac_signalForSelector:SEL 方法監(jiān)聽(tīng)
<code>
- (void)login:(XMPPLoginBlock)resultBlock {
//開(kāi)始連接服務(wù)器
[self connectHost]; //在這里傳入?yún)?shù)第一次握手
//連接成功
[[[self rac_signalForSelector:@selector(xmppStreamDidConnect:)] doNext:^(id x) {
//發(fā)送密碼進(jìn)行第二次握手
[self sendPwdToHost];
}] subscribeNext:^(id x) {
//返回結(jié)果給Block
resultBlock(XMPPToolConnectSuccess);
}];
}
</code>
接下來(lái)是授權(quán)成功
<code>
- (void)login:(XMPPLoginBlock)resultBlock {
//開(kāi)始連接服務(wù)器
[self connectHost]; //在這里傳入?yún)?shù)第一次握手
//連接成功
[[[self rac_signalForSelector:@selector(xmppStreamDidConnect:)] doNext:^(id x) {
//發(fā)送密碼進(jìn)行第二次握手
[self sendPwdToHost];
}] subscribeNext:^(id x) {
//返回結(jié)果給Block
resultBlock(XMPPToolConnectSuccess);
}];
</code>
登錄成功
<code>
[[[self rac_signalForSelector:@selector(xmppStreamDidAuthenticate:)] doNext:^(id x) {
//發(fā)送現(xiàn)在消息第三次握手
[self sendOnlineToHost];
}] subscribeNext:^(id x) {
resultBlock(XMPPToolLoginSuccess);
}];
}
</code>
好了簡(jiǎn)單的一個(gè)過(guò)程就寫(xiě)好了 這里resultBlock內(nèi)是自定義的枚舉
接著完善一下第一部分中的代碼 添加對(duì)按鈕點(diǎn)擊監(jiān)聽(tīng)
<code>
[[self.login rac_signalForControlEvents:UIControlEventTouchUpInside]
subscribeNext:^(id x) {
}
</code>
因?yàn)檫@里要跳轉(zhuǎn)控制器 所以 加 deliverOn:[RACScheduler mainThreadScheduler] 保證在主線(xiàn)程安全跳轉(zhuǎn) 執(zhí)行在單例中的方法:
<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>
如果需要做其他如連接失敗,密碼錯(cuò)誤等 和上面一樣 擴(kuò)充枚舉就可以了
看下整個(gè)登陸的代碼過(guò)程的代碼別集中在了一起
<code>
//登陸
- (void)login:(XMPPLoginBlock)resultBlock {
//開(kāi)始連接服務(wù)器
[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);
}];
//授權(quán)失敗
[[[self rac_signalForSelector:@selector(xmppStream:didNotAuthenticate:)]
doNext:^(id x) {
[_xmppStream disconnect];
}]
subscribeNext:^(id x) {
resultBlock(XMPPToolLoginFailed);
}];
}
</code>
注意到這次沒(méi)有使用__weak 來(lái)處理block 因?yàn)檫@里使用的是單例不需要被銷(xiāo)毀哮笆,實(shí)際開(kāi)發(fā)還有視情況而定 畢竟單例會(huì)一直占用內(nèi)存来颤。
由于剛開(kāi)始初學(xué)ReactiveCocoa 一些高級(jí)用法還有接觸 以后慢慢改進(jìn) 下一篇 開(kāi)始嘗試獲取好友列表 這里是 第三部分 獲取好友列表
完整Dome