XMPPFrameWork、MBProgressHUD等框架实现了目前来看丑丑的即时聊天APP,名字就叫吱吱,因为我养的一只仓鼠。现在就是界面丑到爆,是用storyboard结合代码做的,有兴趣的可以联系我或者在github上fork。
初步的界面gif如下:
因为自己画工太好,logo盗用了某日漫的,去吧!比卡丘!谁来拯救我的少女心~
首先,一个聊天app由服务器和客户端组成
一、服务器端配置
服务器我们就用著名的openfire,数据库就用mysqlwork bench管理,具体的安装设置步骤百度都能搜到,我下的openfire启动不了,找了个方法:
sudo su 接着输入密码;
cd /usr/local/openfire
export JAVA_HOME=/usr/libexec/java_home
echo $JAVA_HOME /Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home
cd /usr/local/openfire
./openfire.sh
第一次设置openfire时,记得加上编码方式,有用的(解决中文乱码):jdbc:mysql://127.0.0.1:3306/openfire1?useUnicode=true&characterEncoding=utf8
二、客户端开发配置
iOS端开发我们要引用哪些第三方框架,怎么导入这些框架,我用的cocoapods导入,需要导入哪些呢,首先是最总要的XMPPFramework,然后一些效果UIBubbleTableView(聊天气泡框)、MBProgressHUD(菊花效果提示框)。不知道怎么导入可以看看AFNetworking的readme文档,照着写就ok了。
三、我要实现哪些功能
登陆要的,注册要的,注销要的,聊天要的,这是我想要的五大功能,如果你想要好友、头像之类的,可以进一步深入。
ServerController类。
1、单例模式。
为什么要用单例?我一有请求就创建一个服务器类,一个用户发起100个请求,那不得创建一百个实例,自登陆到注销我们用一个实例就好了。
+ (instancetype)shareSever{
static ServerController *sc=nil;
static dispatch_once_t once;
dispatch_once(&once,^{
sc = [[ServerController alloc]init];
});
return sc;
}
2、重写init方法(关键),我是照着别人的写的:
-(instancetype)init{
self = [super init];
if (self) {
self.xmppStream = [[XMPPStream alloc]init];
// 设置stream的代理
[self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
// 系统写好的xmpp存储对象
XMPPRosterCoreDataStorage *rosterCoreDataStorage = [XMPPRosterCoreDataStorage sharedInstance];
self.xmppRoster = [[XMPPRoster alloc]initWithRosterStorage:rosterCoreDataStorage dispatchQueue:dispatch_get_main_queue()];
//激活roster
[self.xmppRoster activate:self.xmppStream];
// 初始化聊天记录管理对象
XMPPMessageArchivingCoreDataStorage * archiving = [XMPPMessageArchivingCoreDataStorage sharedInstance];
self.messageArchiving = [[XMPPMessageArchiving alloc] initWithMessageArchivingStorage:archiving dispatchQueue:dispatch_get_main_queue()];
// 激活管理对象
[self.messageArchiving activate:self.xmppStream];
// 给管理对象添加代理
[self.messageArchiving addDelegate:self delegateQueue:dispatch_get_main_queue()];
self.messageContext = archiving.mainThreadManagedObjectContext;
}
return self;
}
3、connect方法,准确的说应该是登陆、注册方法
-(void) connect:(NSString *)user :(NSString *)password :(NSInteger)purpose{
self.password=password;
self.purpose=purpose; //目的参数,是登陆还是注册。
if([self.xmppStream isConnected]){
[self.xmppStream disconnect];
}
XMPPJID *jid = [XMPPJID jidWithUser:user domain:@"127.0.0.1" resource:@"openfire1"];
[self.xmppStream setMyJID:jid];
[self.xmppStream setHostName:@"127.0.0.1"];
NSError *error = nil;
[self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error];
if (error) {
NSLog(@"error = %@",error);
}
}
4、xmpp的各种代理函数:
- (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender{
NSLog(@"连接服务器失败的方法,请检查网络是否正常");
}
- (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket{
NSLog(@"连接成功");
}
- (void)xmppStreamDidConnect:(XMPPStream *)sender{
NSLog(@"再发送密码授权");
NSError *err = nil;
switch (self.purpose) {
case 1:
[_xmppStream authenticateWithPassword:self.password error:&err];
break;
case 2:
[_xmppStream registerWithPassword:self.password error:&err];
default:
break;
}
if (err) {
NSLog(@"%@",err);
}
}
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
XMPPPresence *presence = [XMPPPresence presenceWithType:@"available"];
[_xmppStream sendElement:presence];
NSLog(@"登陆成功%@",presence);
}
-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{
NSLog(@"授权失败 %@",error);
[_xmppStream disconnect];
}
- (void) xmppStreamDidRegister:(XMPPStream *)sender{
NSLog(@"注册成功");
}
- (void) xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error{
NSLog(@"注册失败");
}
- (void) registerAction:(NSString *)user :(NSString *)password{
}
- (void) XMPPAddFriendSubscribe:(NSString *)name{
XMPPJID *jid = [XMPPJID jidWithString:[NSString stringWithFormat:@"%@@%s",name,"127.0.0.1"]];
//[presence addAttributeWithName:@"subscription" stringValue:@"好友"];
[self.xmppRoster subscribePresenceToUser:jid];
}