// 添加消息模塊
#import "XMPPMessageArchiving.h"
#import "XMPPMessageArchivingCoreDataStorage.h"
- 2斩松、在AppDelegate.h頭文件中,加入以下屬性
// 消息模塊
@property (nonatomic, strong,readonly) XMPPMessageArchiving *msgArching;
// 消息數(shù)據(jù)存儲
@property (nonatomic, strong,readonly)XMPPMessageArchivingCoreDataStorage *msgArchingStorage;
消息列表展示
- 需求:創(chuàng)建控制器,將消息列表 展示數(shù)據(jù) 到 tableView上
- 1、 控制器中導(dǎo)入頭文件 #import "JPAppDelegate.h"
- 2怎囚、展示消息列表數(shù)據(jù)
#import "JPChatViewController.h"
#import "JPAppDelegate.h"
#import "UIImageView+WebCache.h"
@interface JPChatViewController ()<NSFetchedResultsControllerDelegate, UIImagePickerControllerDelegate>{
NSFetchedResultsController *_resultContr;//數(shù)據(jù)庫查詢結(jié)果控制器
}
@end
@implementation JPChatViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//數(shù)據(jù)綁定到tableview
[self dataBind];
}
- (void)dataBind{
//1.上下文
NSManagedObjectContext *context = xmppDelegate.msgArchingStorage.mainThreadManagedObjectContext;
//2.查詢請求(查詢哪張表)
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"XMPPMessageArchiving_Message_CoreDataObject"];
//3.設(shè)置排序(時間升序)
NSSortDescriptor *timeSort = [NSSortDescriptor sortDescriptorWithKey:@"timestamp" ascending:YES];
request.sortDescriptors = @[timeSort];
//4.過濾條件(當(dāng)前登錄用戶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];
//設(shè)置代理
_resultContr.delegate = self;
//執(zhí)行請求
NSError *error = nil;
[_resultContr performFetch:&error];
if (error) {
JPLogError(@"%@",error);
}
}
#pragma mark -table的數(shù)據(jù)源
- (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];
// //自己發(fā)送的消息
// if ([chatMessage.outgoing boolValue]) {
// //設(shè)置消息內(nèi)容
// cell.textLabel.text =[NSString stringWithFormat:@"me:%@",chatMessage.body];
// }else{//好友發(fā)送的消息
//
// 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(@"無圖片");
//設(shè)置消息內(nèi)容
cell.textLabel.text =chatMessage.body;
//消除圖片
cell.imageView.image = nil;
}
return cell;
}
@end
發(fā)消息
- [xmppDelegate.xmppStream sendElement:message];
//發(fā)送消息
-(BOOL)textFieldShouldReturn:(UITextField *)textField{
NSString *text = textField.text;
// //添加圖片標(biāo)識
// NSString *imageText = [NSString stringWithFormat:@"img:%@",text];
// JPLogInfo(@"%@",imageText);
//
// //音頻標(biāo)識
// NSString *soundText = [NSString stringWithFormat:@"sound:%@",text];
// JPLogInfo(@"%@",imageText);
//封裝消息對象
XMPPMessage *message = [XMPPMessage messageWithType:@"chat" to:self.friendJid];
[message addBody:text];
//所有跟根據(jù)通信的話,用XMPPStream
//發(fā)送消息
[xmppDelegate.xmppStream sendElement:message];
//消除文字
textField.text = nil;
return YES;
}
發(fā)送圖片:
UIImagePickerController *imagePicker =[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePicker animated:YES completion:nil];
- 選擇到圖片從相冊中,往文件服務(wù)器上傳圖片桥胞,然后把圖片完整鏈接發(fā)給通信好友
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSLog(@"%@",info);
UIImage *image = info[UIImagePickerControllerOriginalImage];
//銷毀圖片選擇控制器
[self dismissViewControllerAnimated:YES completion:nil];
//往文件服務(wù)器上傳圖片
//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);
/**
* 基準(zhǔn)路徑 http://localhost:8080/imfileserver/Upload/Image/
* 圖片上傳路徑 = 基準(zhǔn)路徑 + 圖片名字
* eg.http://localhost:8080/imfileserver/Upload/Image/ wangwu20140821141429
*/
//imgUrl 就是上傳的路徑 也是下載路徑
NSString *imgUrl = [NSString stringWithFormat:@"%@%@",kBaseImageUrl,imageName];
#warning 圖片的格式一定jpg(因為我服務(wù)器只能上傳jpg),一定put方法(我的服務(wù)器只能接收put請求)
//發(fā)送圖片,自定義HttpTool實現(xiàn)上傳
HttpTool *httpTool = [[HttpTool alloc] init];
[httpTool uploadData:UIImageJPEGRepresentation(image, 0.7) url:[NSURL URLWithString:imgUrl] progressBlock:nil completion:^(NSError *error) {
if (error == nil) {
JPLogInfo(@"上傳成功");
//上傳成功,發(fā)送消息給好友
NSString *body = [NSString stringWithFormat:@"img:%@",imgUrl];
XMPPMessage *message = [XMPPMessage messageWithType:@"chat" to:self.friendJid];
[message addBody:body];
[xmppDelegate.xmppStream sendElement:message];
}
}];
}
相關(guān)自定義類
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 <Foundation/Foundation.h>
//extern常用于定義常量 其常量本身的內(nèi)容在其它位置定義
extern NSString *const JPDateFormatyyyyMMddHHmmss;//年月日時分秒
extern NSString *const JPDateFormatMMddHHmmss;//月日時分秒
extern NSString *const JPDateFormatHHmmss;//時分秒
@interface NSDate (JP)
/**
* 返回格式化后的字符串 如果201401011212(年月時分秒)
*/
+(NSString *)nowDateFormat:(NSString *)format;
@end
HttpTool
// .h
#import <Foundation/Foundation.h>
typedef void (^HttpToolProgressBlock)(CGFloat progress);
typedef void (^HttpToolCompletionBlock)(NSError *error);
@interface HttpTool : NSObject
/**
上傳數(shù)據(jù)
*/
-(void)uploadData:(NSData *)data
url:(NSURL *)url
progressBlock : (HttpToolProgressBlock)progressBlock
completion:(HttpToolCompletionBlock) completionBlock;
/**
下載數(shù)據(jù)
*/
-(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()<NSURLSessionDownloadDelegate,NSURLSessionTaskDelegate>{
//下載
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, @"上傳數(shù)據(jù)不能為空");
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 - 上傳進(jìn)度
-(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 大多數(shù)使用單例即可
NSURLResponse *response = nil;
//發(fā)達(dá)同步請求
[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 下載進(jìn)度
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
if (_dowloadProgressBlock) {
//已寫數(shù)據(jù)字節(jié)數(shù)除以總字節(jié)數(shù)就是下載進(jìn)度
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