這里接著 第一部分 繼續
這里是對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