iOS XMPP——消息列表与发消息

  • 1、XMPPFrame.h头开启下面代码
// 添加消息模块
#import "XMPPMessageArchiving.h"
#import "XMPPMessageArchivingCoreDataStorage.h"
  • 2、在AppDelegate.h头文件中,加入以下属性
// 消息模块
@property (nonatomic, strong,readonly) XMPPMessageArchiving *msgArching;
// 消息数据存储
@property (nonatomic, strong,readonly)XMPPMessageArchivingCoreDataStorage *msgArchingStorage;

消息列表展示

  • 需求:创建控制器,将消息列表 展示数据 到 tableView上
  • 1、 控制器中导入头文件 #import "JPAppDelegate.h"
  • 2、展示消息列表数据
#import "JPChatViewController.h"
#import "JPAppDelegate.h"
#import "UIImageView+WebCache.h"

@interface JPChatViewController (){
    NSFetchedResultsController *_resultContr;//数据库查询结果控制器
}
@end

@implementation JPChatViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view.

    //数据绑定到tableview
    [self dataBind];
}

- (void)dataBind{
    //1.上下文
    NSManagedObjectContext *context = xmppDelegate.msgArchingStorage.mainThreadManagedObjectContext;

    //2.查询请求(查询哪张表)
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"XMPPMessageArchiving_Message_CoreDataObject"];

    //3.设置排序(时间升序)
    NSSortDescriptor *timeSort = [NSSortDescriptor sortDescriptorWithKey:@"timestamp" ascending:YES];

    request.sortDescriptors = @[timeSort];

    //4.过滤条件(当前登录用户jid , 好友jid)
     XMPPJID *myJid = xmppDelegate.xmppStream.myJID;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"bareJidStr = %@ AND streamBareJidStr = %@",self.friendJid.bare,myJid.bare];

    request.predicate = predicate;
   
    //[context executeFetchRequest:request error:nil];
    _resultContr = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];

    //设置代理
    _resultContr.delegate = self;

    //执行请求
    NSError *error = nil;

    [_resultContr performFetch:&error];

    if (error) {
        JPLogError(@"%@",error);
    }
}

#pragma mark -table的数据源

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return _resultContr.fetchedObjects.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *ID = @"ChatCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    //消息模型
    XMPPMessageArchiving_Message_CoreDataObject *chatMessage = _resultContr.fetchedObjects[indexPath.row];

//    //自己发送的消息
//    if ([chatMessage.outgoing boolValue]) {
//        //设置消息内容
//        cell.textLabel.text =[NSString stringWithFormat:@"me:%@",chatMessage.body];
//    }else{//好友发送的消息
//    
//     cell.textLabel.text =[NSString stringWithFormat:@"other:%@",chatMessage.body];
//    }

    //判断是否有图片
    if ([chatMessage.body rangeOfString:kImageTag].location != NSNotFound) {

        NSString *imgUrl = [chatMessage.body substringFromIndex:kImageTag.length];
        NSLog(@"有图片 %@",imgUrl);

        //显示图片
        [cell.imageView setImageWithURL:[NSURL URLWithString:imgUrl]placeholderImage:[UIImage imageNamed:@"DefaultProfileHead"]];

        //消除文字
        cell.textLabel.text = nil;
    }else{
        NSLog(@"无图片");

        //设置消息内容
        cell.textLabel.text =chatMessage.body;

        //消除图片
        cell.imageView.image = nil;
    }

    return  cell;
}
@end

发消息

  • [xmppDelegate.xmppStream sendElement:message];
//发送消息
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
    NSString *text = textField.text;
    
//    //添加图片标识
//    NSString *imageText = [NSString stringWithFormat:@"img:%@",text];
//    JPLogInfo(@"%@",imageText);
//    
//    //音频标识
//    NSString *soundText = [NSString stringWithFormat:@"sound:%@",text];
//    JPLogInfo(@"%@",imageText);
    
    //封装消息对象
    XMPPMessage *message = [XMPPMessage messageWithType:@"chat" to:self.friendJid];
    [message addBody:text];
    
    //所有跟根据通信的话,用XMPPStream
    //发送消息
    [xmppDelegate.xmppStream sendElement:message];
    
    //消除文字
    textField.text = nil;
    return YES;
}
发送图片:
  • 打开相册 选择图片
UIImagePickerController *imagePicker =[[UIImagePickerController alloc] init];
        imagePicker.delegate = self;
        imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        
        [self presentViewController:imagePicker animated:YES completion:nil];
  • 选择到图片从相册中,往文件服务器上传图片,然后把图片完整链接发给通信好友
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    NSLog(@"%@",info);
    
    UIImage *image = info[UIImagePickerControllerOriginalImage];
    
    //销毁图片选择控制器
    [self dismissViewControllerAnimated:YES completion:nil];
    
    //往文件服务器上传图片
    //http://localhost:8080/imfileserver/Upload/Image/00001
    
    //1.给图片全名
    //username + time =  zhangsan20140821140710
    //username + time =  wangwu20140821140710
    NSString *username = xmppDelegate.xmppStream.myJID.user;
    
    //2.获取时间字符串
//    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//    formatter.dateFormat = @"yyyyMMddHHmmss";
//    NSDate *nowDate = [NSDate date];
//    NSString *time = [formatter stringFromDate:nowDate];
// 上面方式太麻烦了,使用我们自己自定义的分类来简化时间获取
    NSString *time = [NSDate nowDateFormat:JPDateFormatyyyyMMddHHmmss];
    
    NSString *imageName = [NSString stringWithFormat:@"%@%@",username,time];
    JPLogInfo(@"imageName %@",imageName);
    
    /**
     * 基准路径 http://localhost:8080/imfileserver/Upload/Image/
     * 图片上传路径 = 基准路径 + 图片名字
     * eg.http://localhost:8080/imfileserver/Upload/Image/ wangwu20140821141429
     */
    
    //imgUrl 就是上传的路径 也是下载路径
    NSString *imgUrl = [NSString stringWithFormat:@"%@%@",kBaseImageUrl,imageName];
#warning 图片的格式一定jpg(因为我服务器只能上传jpg),一定put方法(我的服务器只能接收put请求)
    //发送图片,自定义HttpTool实现上传
    HttpTool *httpTool = [[HttpTool alloc] init];
    [httpTool uploadData:UIImageJPEGRepresentation(image, 0.7) url:[NSURL URLWithString:imgUrl] progressBlock:nil completion:^(NSError *error) {
        if (error == nil) {
            JPLogInfo(@"上传成功");
            //上传成功,发送消息给好友
            NSString *body = [NSString stringWithFormat:@"img:%@",imgUrl];
            
            XMPPMessage *message = [XMPPMessage messageWithType:@"chat" to:self.friendJid];
            [message addBody:body];
            [xmppDelegate.xmppStream sendElement:message];
        }
    }];
}

相关自定义类

NSDate+JP.h
// .h
#import "NSDate+JP.h"

NSString *const JPDateFormatyyyyMMddHHmmss = @"yyyyMMddHHmmss";//年月日时分秒
NSString *const JPDateFormatMMddHHmmss = @"MMddHHmmss";//月日时分秒
NSString *const JPDateFormatHHmmss = @"HHmmss";//时分秒

@implementation NSDate (JP)

+(NSString *)nowDateFormat:(NSString *)format{
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = format;
    return [formatter stringFromDate:[NSDate date]];
}
@end

// .m
#import 

//extern常用于定义常量 其常量本身的内容在其它位置定义
extern NSString *const JPDateFormatyyyyMMddHHmmss;//年月日时分秒
extern NSString *const JPDateFormatMMddHHmmss;//月日时分秒
extern NSString *const JPDateFormatHHmmss;//时分秒

@interface NSDate (JP)
/**
 *  返回格式化后的字符串 如果201401011212(年月时分秒)
 */
+(NSString *)nowDateFormat:(NSString *)format;

@end
HttpTool
// .h
#import 

typedef void (^HttpToolProgressBlock)(CGFloat progress);
typedef void (^HttpToolCompletionBlock)(NSError *error);

@interface HttpTool : NSObject

/**
 上传数据
 */
-(void)uploadData:(NSData *)data
              url:(NSURL *)url
    progressBlock : (HttpToolProgressBlock)progressBlock
            completion:(HttpToolCompletionBlock) completionBlock;

/**
 下载数据
 */
-(void)downLoadFromURL:(NSURL *)url
        progressBlock : (HttpToolProgressBlock)progressBlock
            completion:(HttpToolCompletionBlock) completionBlock;


-(NSString *)fileSavePath:(NSString *)fileName;

@end

// .m
#import "HttpTool.h"

#define kTimeOut 5.0


@interface HttpTool(){

    //下载
    HttpToolProgressBlock _dowloadProgressBlock;
    HttpToolCompletionBlock _downladCompletionBlock;
    NSURL *_downloadURL;
    
    
    //上传
    HttpToolProgressBlock _uploadProgressBlock;
    HttpToolCompletionBlock _uploadCompletionBlock;

}

@end


@implementation HttpTool


#pragma mark - 上传
-(void)uploadData:(NSData *)data url:(NSURL *)url progressBlock:(HttpToolProgressBlock)progressBlock completion:(HttpToolCompletionBlock)completionBlock{
    
    NSAssert(data != nil, @"上传数据不能为空");
    NSAssert(url != nil, @"上传文件路径不能为空");
    
    _uploadProgressBlock = progressBlock;
    _uploadCompletionBlock = completionBlock;
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:kTimeOut];
    request.HTTPMethod = @"PUT";
    
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    
    //NSURLSessionDownloadDelegate
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
    
    
    //定义下载操作
    NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:data];
    
    [uploadTask resume];
}

#pragma mark - 上传代理


#pragma mark - 上传进度
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{

    if (_uploadProgressBlock) {
        CGFloat progress = (CGFloat) totalBytesSent / totalBytesExpectedToSend;
        _uploadProgressBlock(progress);
    }
}


#pragma mark - 上传完成
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    if (_uploadCompletionBlock) {
        _uploadCompletionBlock(error);
        
        _uploadProgressBlock = nil;
        _uploadCompletionBlock = nil;
    }
}


#pragma mark - 下载
-(void)downLoadFromURL:(NSURL *)url
         progressBlock:(HttpToolProgressBlock)progressBlock
            completion:(HttpToolCompletionBlock)completionBlock{
    
  
    
    NSAssert(url != nil, @"下载URL不能传空");
    
    _downloadURL = url;
    _dowloadProgressBlock = progressBlock;
    _downladCompletionBlock = completionBlock;
    
    
    
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:kTimeOut];
    
    
    //session 大多数使用单例即可
    
    NSURLResponse *response = nil;
    
    
    //发达同步请求
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
    
    //NSLog(@"%lld",response.expectedContentLength);
    if (response.expectedContentLength <= 0) {
        if (_downladCompletionBlock) {
            NSError *error =[NSError errorWithDomain:@"文件不存在" code:404 userInfo:nil];
            _downladCompletionBlock(error);
            
            //清除block
            _downladCompletionBlock = nil;
            _dowloadProgressBlock = nil;
        }
        
        return;
    }
    

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    
    
    //NSURLSessionDownloadDelegate
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
    
    
    //定义下载操作
    NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request];
    
    [downloadTask resume];

}


#pragma mark -NSURLSessionDownloadDelegate
#pragma mark 下载完成
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{

    //图片保存在沙盒的Doucument下
    NSString *fileSavePath = [self fileSavePath:[_downloadURL lastPathComponent]];
    
    //文件管理
    NSFileManager *fileManager = [NSFileManager defaultManager];
    [fileManager copyItemAtURL:location toURL:[NSURL fileURLWithPath:fileSavePath] error:nil];
    
    if (_downladCompletionBlock) {
        //通知下载成功,没有没有错误
        _downladCompletionBlock(nil);
        
        //清空block
        _downladCompletionBlock = nil;
        _dowloadProgressBlock = nil;
    }

}

#pragma mark 下载进度
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
    
    
    if (_dowloadProgressBlock) {
        //已写数据字节数除以总字节数就是下载进度
        CGFloat progress = (CGFloat)totalBytesWritten / totalBytesExpectedToWrite;
        
        _dowloadProgressBlock(progress);

    }
}


-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
    
}


#pragma mark -传一个文件名,返回一个在沙盒Document下的文件路径
-(NSString *)fileSavePath:(NSString *)fileName{
    NSString *document = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    //图片保存在沙盒的Doucument下
    return [document stringByAppendingPathComponent:fileName];
}
@end

你可能感兴趣的:(iOS XMPP——消息列表与发消息)