iOS上的XMPPFramework -xmppRoomDidDestroy:没有被调用
Posted
技术标签:
【中文标题】iOS上的XMPPFramework -xmppRoomDidDestroy:没有被调用【英文标题】:XMPPFramework on iOS -xmppRoomDidDestroy: not getting called 【发布时间】:2013-09-16 19:40:54 【问题描述】:我正在使用适用于 ios/OSX 的 XMPP 框架开发 iPhone 应用程序,并且我正在使用 XEP-0045 扩展(多用户聊天)。我已经成功创建和配置了房间,我可以邀请其他用户并与他们聊天。当我去破坏我创建的房间时,问题就出现了。我已经遵循了在框架内执行的代码路径,并且我已经弄清楚了为什么框架没有触发该方法,但是我不确定鉴于我看到的行为它会如何触发该方法.
该行为如下:
1) 我通过调用 [room destroyRoom] 请求销毁房间
2) 然后我看到 XMPPRoom 类设置了它的 XMPPIDResponse 跟踪器来监视服务器将发回的“结果”iq 节,说它已成功删除房间。
3)(这就是问题所在)我从房间收到一个出席信息节,说它现在不可用(因为我也是房间的住户)然后框架清除响应跟踪器并调用 -xmppRoomDidLeave :.
4) 服务器然后发回“结果” iq 节,说房间已成功删除,但没有人再听了。这会导致错过对 xmppRoomDidDestroy 的调用。
此行为与我在 XEP-0045 定义中阅读的内容一致,鉴于此,我不确定如何调用 -xmppRoomDidDestroy: 委托。我在这里做错了吗?
【问题讨论】:
嗨,扎卡里,我遇到了完全相同的问题。你找到解决办法了吗? -xmppRoomDidDestroy 在销毁时组中有更多成员时调用,但在我的环境中,问题是我应该只销毁我是其中最后一个成员的房间... 嘿莱特曼。我知道这已经晚了,但希望它会有所帮助。不幸的是,我无法找到解决方案。我最终不得不使用自己的 XMPPIDResponseTracker 来监视它并自己调用代理。 【参考方案1】:我遇到了同样的问题,这是我的解决方案:
在 XMPPRoom 方法中
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
替换
[responseTracker removeAllIDs];
与:
if ([x elementForName:@"destroy"])
NSArray *allKeys = [responseTracker allIDs];
for (NSString *key in allKeys)
SEL aSel = [responseTracker selectorForElementID:key];
if (aSel != @selector(handleDestroyRoomResponse:withInfo:))
[responseTracker removeID:key];
else
[responseTracker removeAllIDs];
在 XMPPIDTracker.h 中添加新公共方法的声明
- (NSArray *)allIDs;
- (SEL)selectorForElementID:(NSString *)elementID;
也在XMPPBasicTrackingInfo接口中添加
@property (nonatomic, readonly) SEL selector;
在 XMPPIDTracker.m 中添加两个公共方法
- (NSArray *)allIDs
return [dict allKeys];
- (SEL)selectorForElementID:(NSString *)elementID
id <XMPPTrackingInfo> info = [dict objectForKey:elementID];
if ([info isKindOfClass:[XMPPBasicTrackingInfo class]])
return [(XMPPBasicTrackingInfo *)info selector];
return nil;
在@implementation XMPPBasicTrackingInfo 的末尾添加
@synthesize selector;
基本上,这段代码会删除所有响应跟踪器,除了 handleDestroyRoomResponse:withInfo: 因为我们需要这个处理程序来响应 IQ destroy 节。
我希望这会有所帮助。
【讨论】:
您好,我已按照您提供的步骤进行操作,但无法正常工作。请指导我。【参考方案2】:与最新的XMPPFramework 3.6.6
相同的问题。
解决办法如下:
仍然使用destroyRoom
函数,xmppStream:didReceivePresence:
和xmppRoomDidLeave:
将被调用,通过在两个委托中添加NSLog
进行测试,然后我使用 Spark(Windows 版本)破坏房间,Xcode 控制台打印以下内容文字:
<presence xmlns="jabber:client" type="unavailable" from="wei@conference.10.50.200.94/admin" to="admin@10.50.200.94/iOS">
<x xmlns="http://jabber.org/protocol/muc#user">
<item affiliation="none" role="none"></item>
<destroy>
<reason>destroy room</reason>
</destroy>
</x>
</presence>
我使用<destroy>
元素来确定destroyRoom
操作。
- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence
/*
<presence xmlns="jabber:client" type="unavailable" from="wei@conference.10.50.200.94/admin" to="admin@10.50.200.94/iOS"><x xmlns="http://jabber.org/protocol/muc#user"><item affiliation="none" role="none"></item><destroy><reason>destroy room</reason></destroy></x></presence>
*/
// NSLog(@"%s %@", __FUNCTION__, presence);
if ([presence.fromStr containsString:@"conference"])
NSXMLElement *x = [presence elementForName:@"x"];
if (x)
NSXMLElement *destroy = [x elementForName:@"destroy"];
if (destroy)
XMPPJID *roomJID = presence.from.bareJID;
// TODO: do something with the roomJID
但是XMPPFramework
发送一个空的<destory/>
元素,我猜openfire 服务器只是忽略<destroy/>
和响应<presence>..</presence>
而没有<destroy>
。
修改XMPPFramework
中的destroyRoom
函数或实现以下委托添加销毁原因。
- (XMPPIQ *)xmppStream:(XMPPStream *)sender willSendIQ:(XMPPIQ *)iq
/*
<iq type="set" to="weixin@conference.10.50.200.94" id="BCF55C6A-9C5E-4740-BE6A-63E17B5C58F6"><query xmlns="http://jabber.org/protocol/muc#owner"><destroy></destroy></query></iq>
*/
if ([iq isSetIQ])
NSXMLElement *query = [iq elementForName:@"query" xmlns:XMPPMUCOwnerNamespace];
if (query)
NSXMLElement *destroy = [query elementForName:@"destroy"];
if (destroy)
NSXMLElement *reason = [destroy elementForName:@"reason"];
if (!reason)
reason = [NSXMLElement elementWithName:@"reason" stringValue:@"destroy reason"];
[destroy addChild:reason];
return iq;
【讨论】:
以上是关于iOS上的XMPPFramework -xmppRoomDidDestroy:没有被调用的主要内容,如果未能解决你的问题,请参考以下文章
如何在目标c中通过ios中的XMPPFramework连接XMPP服务器