【问题标题】:XMPPFramework - XEP-0048: Bookmark StorageXMPPFramework - XEP-0048:书签存储
【发布时间】:2013-12-26 23:40:45
【问题描述】:

在我的应用程序中,我实现了创建 XMPPRoom 和邀请用户。现在,我正在寻找一种方法来存储这些组(我创建的或我被邀请加入的组),以便我可以在需要时轻松地在我的应用程序中检索它。我遇到了书签 XEP-0048 但是,我找不到任何在线使用此功能的示例。以前有人用过这个吗?你能分享一些例子吗?

http://www.xmpp.org/extensions/attic/xep-0048-1.0.html

艾哈迈德

【问题讨论】:

    标签: ios xmpp xmppframework


    【解决方案1】:

    根据XEP-0048: Bookmarks,要将书签上传到服务器,您必须像这样发送iq 请求:

    <iq from='juliet@capulet.lit/balcony' type='set' id='pip1'>
      <pubsub xmlns='http://jabber.org/protocol/pubsub'>
        <publish node='storage:bookmarks'>
          <item id='current'>
            <storage xmlns='storage:bookmarks'>
              <conference name='The Play&apos;s the Thing' 
                          autojoin='true'
                          jid='theplay@conference.shakespeare.lit'>
                <nick>JC</nick>
              </conference>
            </storage>
          </item>
        </publish>
        <publish-options>
          <x xmlns='jabber:x:data' type='submit'>
            <field var='FORM_TYPE' type='hidden'>
              <value>http://jabber.org/protocol/pubsub#publish-options</value>
            </field>
            <field var='pubsub#persist_items'>
              <value>true</value>
            </field>
            <field var='pubsub#access_model'>
              <value>whitelist</value>
            </field>
          </x>
        </publish-options>
      </pubsub>
    </iq>
    

    在Objective-C中使用NSXMLElement类,上面的XML可以这样写:

        NSXMLElement *pubsub = [[NSXMLElement alloc] initWithName:@"pubsub" xmlns:@"http://jabber.org/protocol/pubsub"];
        NSXMLElement *publish = [[NSXMLElement alloc] initWithName:@"publish"];
        [publish addAttributeWithName:@"node" stringValue:@"storage:bookmarks"];
        NSXMLElement *item = [[NSXMLElement alloc] initWithName:@"item"];
        [item addAttributeWithName:@"id" stringValue:@"current"];
        NSXMLElement *storage = [[NSXMLElement alloc] initWithName:@"storage" xmlns:@"storage:bookmarks"];
        NSXMLElement *conference = [[NSXMLElement alloc] initWithName:@"conference"];
        [conference addAttributeWithName:@"name" stringValue:@"The Play&apos;s the Thing"];
        [conference addAttributeWithName:@"autojoin" stringValue:@"true"];
        [conference addAttributeWithName:@"jid" stringValue:@"theplay@conference.shakespeare.lit"];
        NSXMLElement *nick = [[NSXMLElement alloc] initWithName:@"nick" stringValue:@"JC"];
        [conference addChild:nick];
        [storage addChild:conference];
        [item addChild:storage];
        [publish addChild:item];
    
        NSXMLElement *publish_options = [[NSXMLElement alloc] initWithName:@"publish-options"];
        NSXMLElement *x = [[NSXMLElement alloc] initWithName:@"x" xmlns:@"jabber:x:data"];
        [x addAttributeWithName:@"type" stringValue:@"submit"];
        NSXMLElement *field1 = [[NSXMLElement alloc] initWithName:@"field"];
        [field1 addAttributeWithName:@"var" stringValue:@"FORM_TYPE"];
        [field1 addAttributeWithName:@"type" stringValue:@"hidden"];
        NSXMLElement *value1 = [[NSXMLElement alloc] initWithName:@"value" stringValue:@"http://jabber.org/protocol/pubsub#publish-options"];
        [field1 addChild:value1];
        [x addChild:field1];
        NSXMLElement *field2 = [[NSXMLElement alloc] initWithName:@"field"];
        [field2 addAttributeWithName:@"var" stringValue:@"pubsub#persist_items"];
        NSXMLElement *value2 = [[NSXMLElement alloc] initWithName:@"value" stringValue:@"whitelist"];
        [field2 addChild:value2];
        [x addChild:field2];
        [publish_options addChild:x];
    
        [pubsub addChild:publish];
        [pubsub addChild:publish_options];
    
        XMPPIQ *iq = [[XMPPIQ alloc] initWithType:@"set" child:pubsub];
        [iq addAttributeWithName:@"from" stringValue:@"juliet@capulet.lit/balcony"];
        [iq addAttributeWithName:@"id" stringValue:@"pip1"];
    

    当然也可以只用一个 NSXMLElement 来写,比如

    NSXMLElement *iq = [NSXMLElement alloc] initWithName:@"iq" stringValue:[NSString stringWithFormat:@"all xml code from first paragraph with %@ to add your dynamic data...", data1, data2, ...];
    [iq addAttributeWithName:@"from" stringValue:@"juliet@capulet.lit/balcony"];
    [iq addAttributeWithName:@"id" stringValue:@"pip1"];
    

    创建 iq 后,是时候将其发送到服务器了,就像

    [xmppStream sendElement:iq];
    

    这就是将书签发送到服务器的方式。您在 XMPPStream 委托 - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq 中监听服务器响应,服务器响应应该是这样的:

    <iq to='juliet@capulet.lit/balcony' type='result' id='pip1'/>
    

    或在 Objective-C 代码中:

    - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
    {
        if([iq isResultIQ])
        {
            if([[iq attributeStringValueForName:@"id"] isEqualToString:@"pip1"])
            {
                NSLog(@"Bookmarks with id %@ succesfully uploaded", [iq attributeStringValueForName:@"id"]);
            }
        }
    }
    

    现在,根据上面的示例,为 clinet 从服务器 (XEP-0048: Bookmarks 3.3 Retrieving Data) 请求书签的 xml 创建 Objective-c 代码:

    <iq from='juliet@capulet.lit/randomID' type='get' id='retrieve1'>
      <pubsub xmlns='http://jabber.org/protocol/pubsub'>
        <items node='storage:bookmarks'/>
      </pubsub>
    </iq>
    

    objective-c 代码:

    NSXMLElement *pubsub = [[NSXMLElement alloc] initWithName:@"pubsub" xmlns:@"http://jabber.org/protocol/pubsub"];
    NSXMLElement *items = [[NSXMLElement alloc] initWithName:@"items"];
    [items addAttributeWithName:@"node" stringValue:@"storage:bookmarks"];
    [pubsub addChild:items];
    
    XMPPIQ *iq = [[XMPPIQ alloc] initWithType:@"get" child:pubsub];
    [iq addAttributeWithName:@"from" stringValue:@"juliet@capulet.lit/balcony"];
    [iq addAttributeWithName:@"id" stringValue:@"retrive1"];
    

    像以前一样发送到服务器:

    [xmppStream sendElement:iq];
    

    并像以前一样监听服务器响应:

    <iq type='result'
        to='juliet@capulet.lit/randomID'
        id='retrieve1'>
      <pubsub xmlns='http://jabber.org/protocol/pubsub'>
        <items node='storage:bookmarks'>
          <item id='current'>
            <storage xmlns='storage:bookmarks'>
              <conference name='The Play&apos;s the Thing' 
                          autojoin='true'
                          jid='theplay@conference.shakespeare.lit'>
                <nick>JC</nick>
              </conference>
            </storage>
          </item>
        </items>
      </pubsub>
    </iq>
    

    或objective-c代码:

    - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
    {
    
        if([iq isResultIQ])
        {
            if([[iq attributeStringValueForName:@"id"] isEqualToString:@"retrive1"])
            {
                NSXMLElement *pubsub = [iq elementForName:@"pubsub"];
                NSArray *items = [pubsub elementsForName:@"items"];
    
                NSLog(@"Bookmarks for id %@ are: %@", [iq attributeStringValueForName:@"id"], items);
            }
        }
    }
    

    【讨论】:

    • 嗨 Sihad,添加书签时是否必须发送所有已添加书签的会议,因为如果我单独执行,它会覆盖?如果是,我如何在 [xmppStream sendElement:iq] 中发送多个元素,还是必须使用 for 循环?
    • xmpp.org/extensions/xep-0223.html#composition 中,您将看到每个数据都存储为单独的项目。您会注意到每个项目都有一个 id 表示此书签是唯一的(如果未添加,它将由服务器添加)。请尝试一下。添加多个项目节点,看看会发生什么?此外,查看这些 xmpp 扩展 XEP-0060、XEP-0223 以了解有关存储书签的更多信息。 XEP-0060、XEP-0223有xmpp框架函数
    • 要向服务器发送多个元素,只需创建多个 iq,如 iq1、iq2、iq3,... 并像 [xmppStream sendElement:iq1]、[xmppStream sendElement:iq2]、[xmppStream sendElement :iq3], ...
    • @DevCali 您是否设法在不覆盖的情况下更新书签列表?
    【解决方案2】:

    每当您创建群组或接受聊天室邀请时,将群组与必要的信息一起存储到本地数据库。退出组时将其从 db 中删除。

    【讨论】:

      【解决方案3】:

      从 jabber 服务器获取用户组。

        XMPPIQ *iq = [[XMPPIQ alloc]init];
          [iq addAttributeWithName:@"type" stringValue:@"get"];
          NSString *from = [NSString stringWithFormat:@"%@/ResouseName",[[AppDelegate instance] xmppStream].myJID.bare];
          [iq addAttributeWithName:@"from" stringValue:from];
          NSXMLElement *query =[NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:private"];
          NSXMLElement *storage =   [NSXMLElement elementWithName:@"storage" xmlns:@"storage:bookmarks"];
          [query addChild:storage];
          [iq addChild:query];
          [xmppStream sendElement:iq];
      

      【讨论】:

        【解决方案4】:

        你很容易做到这一点。 请试试这个。 您可以使用此方法添加到服务器中的书签。

        -(void)bookMark :(NSString *)roomName{ 
        
          XMPPIQ *iq = [[XMPPIQ alloc]init];
         [iq addAttributeWithName:@"type" stringValue:@"set"];
        NSString *from = [NSString stringWithFormat:@"%@/ResouseName",[[AppDelegate instance] xmppStream].myJID.bare];
        [iq addAttributeWithName:@"from" stringValue: from];    
         NSXMLElement *query =[NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:private"];
         NSXMLElement *storage =   [NSXMLElement elementWithName:@"storage" xmlns:@"storage:bookmarks"];
        NSXMLElement *conference_s = [NSXMLElement elementWithName:@"conference"];
        [conference_s addAttributeWithName:@"autojoin" stringValue:@"true"];
        [conference_s addAttributeWithName:@"jid" stringValue:roomName];    
        [storage addChild:conference_s];
        [query addChild:storage];
        [iq addChild:query];    
        NSLog(@"print eml log %@:",iq);
        [xmppStream sendElement:iq];
        }
        

        【讨论】:

          【解决方案5】:

          你终于可以得到你的组列表了。

          - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {
          
          NSXMLElement *pubsub = [iq elementForName:@"query"];
          
          NSXMLElement *storage = [pubsub elementForName:@"storage"];
          
           NSArray *conferenceName = [storage elementsForName:@"conference"];
          for (NSXMLElement *conference in conferenceName) {
              NSString *jid = [[conference attributeForName:@"jid"]stringValue];
               NSLog(@"print conference jid=====%@",jid);
          
          }
           NSLog(@"Bookmarks for id are: %@", conferenceName);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-05-05
            • 1970-01-01
            • 2012-09-02
            • 2012-01-24
            • 1970-01-01
            • 2012-04-29
            • 1970-01-01
            相关资源
            最近更新 更多