【Tech】XMPP IOS客户端(三)

上一篇实现了一个美(hen)化(chou)的聊天界面,这一篇加上发送语音和图片的功能。

其实发送语音和图片最好的办法是一端上传到服务器,另一端从服务器下载;或者用File Transfer,无奈上述第一种我不会,第二种调不通,有大神路过,望不吝指教(Orz)

我这里就是直接把语音和图片都编码为base64格式,然后放在消息里面发送过去了,其中语音是录音得到,图片则掉用相机拍摄得到。

1.发送语音

设置一个录音按钮,实现点击以下录音,再点击以下停止的功能,并且在停止后,编码为base64发送出去。录音由AVAudioRecorder实现。

按钮的action函数如下:

 1 - (IBAction)RecMethod:(id)sender {
 2     if (!self.isRecording) {
 3         self.isRecording = YES;
 4         [self.StopOrRec setTitle:@"点击停止" forState:UIControlStateNormal];
 5         recorder = [[AVAudioRecorder alloc]initWithURL:recordFile settings:nil error:nil];
 6         [recorder prepareToRecord];
 7         [recorder record];
 8         player = nil;
 9     }else{
10         self.isRecording = NO;
11         [self.StopOrRec setTitle:@"点击录音" forState:UIControlStateNormal];
12         [recorder stop];
13         recorder = nil;
14
15         NSError *playerError;
16
17         player = [[AVAudioPlayer alloc]initWithContentsOfURL:recordFile error:&playerError];
18         if (player == nil) {
19             NSLog(@"Error creating player :%@",[playerError description]);
20         }
21
22         /*
23         NSString *docsDir;
24         NSArray *dirPaths;
25
26
27         dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
28         docsDir = [dirPaths objectAtIndex:0];
29         NSString *databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:@"000005.jpg"]];
30         NSError *error;
31         NSURL *newURL = [NSURL fileURLWithPath:databasePath];
32         [[NSFileManager defaultManager] copyItemAtURL:recordFile toURL:newURL error:&error];
33         */
34
35         NSData *data = [NSData dataWithContentsOfURL:recordFile];
36
37         if (data) {
38             NSString *base64 = [data base64EncodedString];
39             [self sendAudio:base64 withName:@"test.amr"];
40
41             NSMutableString *Msg = [[NSMutableString alloc]initWithString:@"base64"];
42             [Msg appendFormat:@"%@",base64];
43             NSMutableDictionary *dict = [NSMutableDictionary dictionary];
44             [dict setObject:Msg forKey:@"msg"];
45             [dict setObject:@"you" forKey:@"sender"];
46
47             [messages addObject:dict];
48             [self.chatTBView reloadData];
49         }else{
50             UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Recording Data!"
51                                                                 message:@"NO DATA!"
52                                                                delegate:nil
53                                                       cancelButtonTitle:@"Ok"
54                                                       otherButtonTitles:nil];
55             [alertView show];
56         }
57
58         //[player play];
59     }
60 }
61
62
63 -(void)sendAudio:(NSString *)base64String withName:(NSString *)audioName{
64     NSMutableString *soundString = [[NSMutableString alloc]initWithString:@"base64"];
65     [soundString appendString:base64String];
66     XMPPMessage *message = [XMPPMessage messageWithType:@"chat" to:self.ajid];
67     [message addBody:soundString];
68     [[[self appDelegate] xmppStream] sendElement:message];
69 }

这里设置一个BOOL型的isRecording变量,如果为true,说明正在录音;否则录音完毕。

录音的时候首先初始化一个recorder,然后使用这个recorder录音。

停止的时候,首先从NSURL *recordFile;这个变量得到录音文件放到data中,然后编码成base64格式发送出去,并且放到messages数组中。并且,在编码成base64字符串的时候,在字符串的开头加上base64这6个字符,表示这是一个音频文件,这样在接受的时候就知道怎么处理了。

最后我们还要实现一个效果就是点击某行的时候播放这一行对应的录音文件,再次实现tableview的代理方法didSelectRowAtIndexPath:

 1 -(IBAction)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
 2     NSMutableDictionary *dict = [messages objectAtIndex:indexPath.row];
 3     NSString *message = [dict objectForKey:@"msg"];
 4     if ([message hasPrefix:@"base64"]) {
 5         NSData *audioData = [[message substringFromIndex:6] base64DecodedData];
 6         NSError *playerError;
 7
 8         if (audioData) {
 9             player = [[AVAudioPlayer alloc]initWithData:audioData error:&playerError];
10             [player play];
11         }else{
12             UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Rereading Data!"
13                                                                 message:@"NO DATA!"
14                                                                delegate:nil
15                                                       cancelButtonTitle:@"Ok"
16                                                       otherButtonTitles:nil];
17             [alertView show];
18         }
19     }
20 }

2.发送图像

首先,设计一个拍照按钮,用户点击这个按钮会调用照相机,拍照后将照片发送出去。

照相机按钮的action函数如下:

1 - (IBAction)TakePicture:(id)sender {
2     UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
3     UIImagePickerController *picker = [[UIImagePickerController alloc]init];
4     picker.delegate = self;
5     picker.allowsEditing = YES;
6     picker.sourceType = sourceType;
7     [self presentViewController:picker animated:YES completion:nil];
8 }

首先定义sourceType为照相机,然后用presentViewController召唤照相机。

拍照后的动作在代理函数didFinishPickingMediaWithInfo中实现,这里主要就是把拍好的照片发送出去,并且加入到messages数组中,如下:

 1 #pragma mark -
 2 #pragma mark Camera View Delegate Methods
 3 -(void)sendImage:(NSString *)base64String{
 4     NSMutableString *soundString = [[NSMutableString alloc]initWithString:@"image"];
 5     [soundString appendString:base64String];
 6     XMPPMessage *message = [XMPPMessage messageWithType:@"chat" to:self.ajid];
 7     [message addBody:soundString];
 8     [[[self appDelegate] xmppStream] sendElement:message];
 9 }
10
11 -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
12     UIImage *image;
13     image = [info objectForKey:UIImagePickerControllerEditedImage];
14     [picker dismissViewControllerAnimated:YES completion:nil];
15
16     NSData *data = UIImagePNGRepresentation(image);
17     if (data) {
18         NSString *base64 = [data base64EncodedString];
19         [self sendImage:base64];
20
21         NSMutableString *Msg = [[NSMutableString alloc]initWithString:@"image"];
22         [Msg appendFormat:@"%@",base64];
23         NSMutableDictionary *dict = [NSMutableDictionary dictionary];
24         [dict setObject:Msg forKey:@"msg"];
25         [dict setObject:@"you" forKey:@"sender"];
26
27         [messages addObject:dict];
28         [self.chatTBView reloadData];
29
30     }else{
31         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"ERROR!"
32                                                         message:@"Can not get image data."
33                                                        delegate:nil
34                                               cancelButtonTitle:@"OK"
35                                               otherButtonTitles:nil];
36         [alert show];
37     }
38 }
39
40 -(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
41     [picker dismissViewControllerAnimated:YES completion:nil];
42 }

这里的imagePickerControllerDidCancel函数表示用户在拍照后选择退出时的动作。

最终的效果如下:

这几天的成果大概都在这里了,系统还有很多bug:

1.播放语音不能点图片,要点那一行,即上图中灰色的部分。

2.传语音和图片的时候很慢

3.键盘不会自动缩回

4.以下省略3000字。

最后上代码:github

博主新手ios小白一枚,望各路大神指教。

时间: 2024-08-05 14:34:23

【Tech】XMPP IOS客户端(三)的相关文章

XMPP iOS客户端实现三:登录、注册

1.创建一个单例模式来管理xmpp的连接和操作 1 +(XMPPManager *)share 2 { 3 static XMPPManager *_share=nil; 4 static dispatch_once_t onceToken; 5 dispatch_once(&onceToken, ^{ 6 _share=[[XMPPManager alloc] init]; 7 }); 8 return _share; 9 } 10 -(id)init 11 { 12 if (self=[su

XMPP iOS客户端实现二:xcode项目配置

1.下载XMPPFramework,下载地址:https://github.com/robbiehanson/XMPPFramework 2.创建项目并将XMPP库引入: 3.添加需要的库文件: 4.配置KissXML: OTHER_LDFLAGS  添加  -lxml2 HEADER_SEARCH_PATHS 添加  /usr/include/libxml2

XMPP iOS客户端 添加好友 (3)

这里记录下我实现添加好友的过程,网上虽然也有相应的例子,但说的不是很全面,其中有一篇没有给出 XMPPRoster类的初始化.我找这个类的初始化设置找了好久.不多说啦.下面开始贴代码啦. 初始化XMPPRoster   对象声明 @interface XMPPModel()<XMPPStreamDelegate,XMPPRosterDelegate> @property (nonatomic , strong) XMPPStream *xmppStream; @property (nonato

XMPP iOS客户端开发(二) 通信

发送消息: - (void) sendMessage:(NSString *) message toUser:(NSString *) user { NSXMLElement *body = [NSXMLElement elementWithName:@"body"]; body.stringValue = message; NSXMLElement *msg = [NSXMLElement elementWithName:@"message"]; [msg add

ios客户端发现_华为爱奇艺手机活动开发总结

这个项目自发布需求.活动原型图交付.修订需求.测试.修改.再测试通过上线可谓旷日持久.回过头来看整个项目工期主要卡在活动原型图交付这儿.而为了避免项目上线最后开发赶工期,在这次获取需求的情况下,先对除了需要图以外的模块进行了开发,并调通接口,从而在得到图之后快速完成需求.而深挖这个项目,可追到爱奇艺与华为合作交付没有顺畅达成,才促使一系列后期延期.     再拿原型图交付.修改需求.测试.修改.再测试上线这几个流程来说,每个环节对需求认识不同,就会做出一定的需求误判,而流程图及原型图又不能兼顾到

汉信码在iOS客户端中的应用和遇到的坑

先简单介绍一下的 汉信码,基本上和 QRCode 即二维码 大差不差,可但是,二维码 一般扫描出来是 非中文的字符串(一般为链接),这就是汉信码区别于二维码的地方,汉信码是涵盖中文的,而且是国家自主研发非骗经费项目,虽然没有推广起来但是还是很好用的.其官网为:http://cscode.gs1cn.org/ 简约而不简单的网站,大家可以看一下,在此提供一个样例: 其优点:汉字编码能力超强.极强抗污损.抗畸变识读能力.识读速度快.信息密度高.纠错能力强.图形美观等官方这么说的. 然后,针对不同的平

仿新浪微博IOS客户端(v5.2.8)——设置导航栏外观

转载请标明出处:http://blog.csdn.net/android_ls/article/details/45849447 声明:仿新浪微博项目,所用所有图片资源都来源于官方新浪微博IOS客户端,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片. 一. 在Xcode6下添加.pch文件 对于使用惯了之前版本Xcode的朋友来说,在系统提醒之下升级到Xcode 6之后,发现新建项目后Xcode不再帮我们创建.pch文件了.可是我们已经习惯了,把一些在很多地方都用的宏

开源中国iOS客户端学习

开源中国iOS客户端学习 续写前言 <开源中国iOS客户端学习>续写前系列博客    http://blog.csdn.net/column/details/xfzl-kykhd.html 开源中国iOS客户端学习——序 说到这款开源软件就得提到她的娘家了--开源中国社区: 开源中国社区简介:开源中国 www.oschina.net 成立于2008年8月,是目前中国最大的开源技术社区.传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现.使用.并交流开源技术的平台.目前开源中国社区已收

ios客户端暑期“动画屋“活动项目总结

    入职实习的这个公司,第一天就分配了任务,从零开始写一个网页,之前虽然了解一些前端知识,但从头开写还是遇到了很多问题,互联网公司讲求效率,有deadline还是比较有紧迫感的,与在实验室放羊状态有了鲜明的对比.mentor.产品经理.组里的boss.实习生同事都给我提供了非常多的帮助.此篇总结为独立完成的第一个项目的项目总结.下图是已上线活动界面效果. 项目介绍 (一).爱奇艺IOS客户端发现-活动页面中"动画屋"活动开始页面的开发     活动开始页面的开发主要需求是: