xmPP的简单了解及使用(4)

五.添加&删除好友

  • XMPP框架中提供的添加好友的机制是一种订阅(Subscription)机制,类似于微博中的关注,即A可以添加B为好友,但是B不一定要添加A为好友
  • 如果要实现双向添加和删除,可以将xmppRosterautoAcceptKnownPresenceSubscriptionRequests属性设置为YES The default value is YES.

  • 添加好友之前对它进行判断如果是自己和已经存在的好友不予添加
  

    -(void)addUser{

    NSString *user = self.textField.text;
    

    //1.不能添加自己为好友
    if ([userisEqualToString:[WCAccountshareAccount].loginUser]) {
        [self showMsg:@"不能添加自己为好友"];
        return;
    }
    
    //2.已经存在好友无需添加
    XMPPJID *userJid = [XMPPJIDjidWithUser:userdomain:[WCAccountshareAccount].domainresource:nil];
    
    BOOL userExists = [[WCXMPPToolsharedWCXMPPTool].rosterStorageuserExistsWithJID:userJidxmppStream:[WCXMPPToolsharedWCXMPPTool].xmppStream];
    if (userExists) {
        [self showMsg:@"好友已经存在"];
        return;
    }
    
    //3.添加好友 (订阅)
    [[WCXMPPToolsharedWCXMPPTool].rostersubscribePresenceToUser:userJid];
}

备注:添加好友在现有openfire存在的问题 添加不存在的好友通讯录也显示了好友

     解决办法1.服务器可以拦截好友添加的请求,如当前数据库没有好友,不要返回信息

    解决办法2. 过滤数据库的Subscription字段查询请求 

       none 对方没有同意添加好友

       to 发给对方的请求

       from 别人发来的请求

       both 双方互为好友

#pragma mark 删除好友
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    
    
    XMPPUserCoreDataStorageObject *user =_resultsContr.fetchedObjects[indexPath.row];
    if (editingStyle ==UITableViewCellEditingStyleDelete) {
        //删除好友
        [[WCXMPPToolsharedWCXMPPTool].rosterremoveUser:user.jid];
    }
    
    //刷新表格?
}

#pragma mark -结果控制器的代理
#pragma mark -数据库内容改变
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller{
    
    //刷新表格
    [self.tableViewreloadData];

}


六.聊天数据

#pragma mark 发送聊天数据
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
    
    NSString *txt = textField.text;
    
    //怎么发聊天数据 chat格式参考收到的数据格式可知
    XMPPMessage *msg = [XMPPMessagemessageWithType:@"chat"to:self.friendJid];
    [msg addBody:txt];
    [[WCXMPPToolsharedWCXMPPTool].xmppStreamsendElement:msg];
    
    // 清空输入框的文本
    textField.text = nil;
    
    return YES;
}

接受到消息的xml数据格式



 /

/加载数据库的聊天数据
-(void)setChatdata{
    
    // 1.上下文
    NSManagedObjectContext *msgContext = [WCXMPPToolsharedWCXMPPTool].msgArchivingStorage.mainThreadManagedObjectContext;
    
    // 2.查询请求
    NSFetchRequest *request = [NSFetchRequestfetchRequestWithEntityName:@"XMPPMessageArchiving_Message_CoreDataObject"];
    
    // 过滤(当前登录用户并且好友的聊天消息)
    NSString *loginUserJid = [WCXMPPToolsharedWCXMPPTool].xmppStream.myJID.bare;
    WCLog(@"%@",loginUserJid);
    NSPredicate *pre = [NSPredicatepredicateWithFormat:@"streamBareJidStr = %@ AND bareJidStr = %@",loginUserJid,self.friendJid.bare];
    request.predicate = pre;
    
    // 设置时间排序
    NSSortDescriptor *timeSort = [NSSortDescriptorsortDescriptorWithKey:@"timestamp"ascending:YES];
    request.sortDescriptors = @[timeSort];
    
    // 3.执行请求
    _resultContr = [[NSFetchedResultsControlleralloc]initWithFetchRequest:requestmanagedObjectContext:msgContextsectionNameKeyPath:nilcacheName:nil];
    _resultContr.delegate =self;
    NSError *err = nil;
    [_resultContr performFetch:&err];
}


六.表情的输入

  • iOS中,表情文字是通过Unicode字符实现的
  • Unicode(中文:万国码、国际码、统一码、单一码)是计算机科学领域里的一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑可以用更为简单的方式来呈现和处理文字
  • Unicode伴随着通用字符集的标准而发展,同时也以书本的形式对外发表。Unicode至今仍在不断增修,每个新版本都加入更多新的字符,目前最新的版本为第六版,已收入了超过十万个字符
  • Unicode涵盖的数据除了视觉上的字形、编码方法、标准的字符编码外,还包含了字符特性,如大小写字母
  • Unicode备受认可,并广泛地应用于电脑软件的国际化与本地化过程。有很多新科技,如可扩展置标语言、Java编程语言以及现代的操作系统,都采用Unicode编码
  • 表情符号的参照地址:
  • http://www.easyapns.com/iphone-emoji-alerts

XMPP中的文件传输

  • XEP-0096: File Transfer这是传输文件的统一接口,客户端之间用它来协商到底采用那种具体的传输方式,包括以下三种:
  • XEP-0047: In-Band ByteStreams带内字节流,这个协议实际上用于小数据量传输,只是它用的字节流传输,所以也顺便说一下。带内,也就是夹带在XML流中,通过XMPP服务器中转传输。具体用法是把数据用base64编码放在XML流中传给对方。这个办法不好,base64编码效率很低,而且所有数据必须由服务器中转(字符串格式的数据中转
  • XEP-0066: Out of Band Data带外字节流,带内不行就走带外,也就是不经过XMPP服务器。这个用法是在发起传输的客户端临时建立一个http服务(当然也可以是别的服务),把自己的IP和端口(通过XMPP消息)告诉接收方,让对方直接来下载。这个方法有一个问题,发送一方必须是公网IP,否则对方无法访问。 注:目前PandionLinq支持这个XEP
  • XEP-0065: SOCKS5 Bytestreams SOCKS5字节流,使用SOCKS5传输文件,有直连式和代理传输两种方式。发送方把预定的IP和端口(通过XMPP消息)告诉接收方。如果双方都在公网,采用SOCKS直接传输。如果任何一方在内网,经过SOCKS5代理服务器传输,发送方把代理服务器的IP和端口告诉给接收方。这里的SOCKS5代理服务器和通用的代理服务器稍有差别,因为它需要通过发送方提出的一个sessionIDXMPP服务器通知SOCKS5代理服务器把双方的SOCKS通道连通,也就是激活。 注:目前PsiLinq支持这个XEP

Base64

  • Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息
  • 采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到

#pragma mark 用户选择的图片
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    WCLog(@"%@",info);
    
    UIImage *img = info[UIImagePickerControllerOriginalImage];
    
   //发送附件
    [selfsendAttachmentWithData:UIImagePNGRepresentation(img)bodyType:@"image"];
    
    //隐藏图片选择的控制器
    [selfdismissViewControllerAnimated:YEScompletion:nil];
}


#pragma mark 发送图片附件
-(void)sendAttachmentWithData:(NSData *)data bodyType:(NSString *)bodyType{
    //发送图片
    XMPPMessage *msg = [XMPPMessagemessageWithType:@"chat"to:self.friendJid];
    
    //设置类型
    [msg addAttributeWithName:@"bodyType"stringValue:bodyType];//对应标签内部的属性
#pragma mark 没有body就不认
    [msg addBody:bodyType];
//    [msg addBody:@"sound"];
//    [msg addBody:@"doc"];
//    [msg addBody:@"xls"];
    //把附件经过"base64编码"转成字符串
    NSString *base64Str = [database64EncodedStringWithOptions:0];
    
    //定义附件
    XMPPElement *attachment = [XMPPElementelementWithName:@"attachment"stringValue:base64Str];
    
    //添加字节点
    [msg addChild:attachment];
    
    
    
    [[WCXMPPToolsharedWCXMPPTool].xmppStreamsendElement:msg];
}

两种比较好的处理图片方式

#pragma mark接受图片数据1
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    static NSString *ID =@"ChatCell";
    UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:ID
                             ];
    
    //获取聊天信息
    XMPPMessageArchiving_Message_CoreDataObject *msgObj =_resultContr.fetchedObjects[indexPath.row];
    
    // 判断消息的类型到有没有附件
    // 1.获取原始的xml数据
    XMPPMessage *message =  msgObj.message;
    
    // 获取附件的类型
     NSString *bodyType = [message attributeStringValueForName:@"bodyType"];
    
    if ([bodyType isEqualToString:@"image"]) {//图片
        // 2.遍历message的子节点
        NSArray *child = message.children;
        for (XMPPElement *notein child) {
            // 获取节点的名字
            if ([[note name] isEqualToString:@"attachment"]){
                WCLog(@"获取到附件....");
                //获取附件字符串,然后转成NSData,接转成图片
                NSString *imgBase64Str = [notestringValue];
                NSData *imgData = [[NSDataalloc] initWithBase64EncodedString:imgBase64Stroptions:0];
                UIImage *img = [UIImageimageWithData:imgData];
                cell.imageView.image = img;
                
            }
        }

    }else if([bodyTypeisEqualToString:@"sound"]){//音频
    
    }else{//纯文本
        cell.textLabel.text = msgObj.body;
    }
    return cell;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值