概念: XMPP就是基于点对点的即时通讯协议
需要配置java环境等一些列环境, 具体的配置请参考:
1. 导入 libxml2 和 libresolv框架 和 XMPP第三方类库
2. 路径 输入: /usr/include/libxml2
3. . 如果有错就在错误的类 导入UIKit框架
4. 先在写登录注册
创建一个单例类 XMPPManager
XMMPPManager.h
//
// XMPPManager.h
// XMPP_1
//
// Created by nyl on 15/10/20.
// Copyright (c) 2015年 nieyinlong. All rights reserved.
//
#import <Foundation/Foundation.h>
// 导入第三方类
#import "XMPPConfig.h"
// 导入第三方全局.h文件
#import "XMPPFramework.h"
@interface XMPPManager : NSObject<XMPPStreamDelegate>
/**
* 流, 客户端与服务器的通道
所有的操作都是基于通道的
*/
@property (nonatomic, strong) XMPPStream *xmppStrem; // XMPPStream 是通道
// 这里用单例 因为都使用同一个通道
+ (XMPPManager *)shareManager;
// 登录
- (void)loginWithUserNameString:(NSString *)userName password:(NSString *)password;
// 注册开始
- (void)registWhithUserName:(NSString *)userName password:(NSString *)password;
XMMPPManager.m
<span style="font-size:12px;">//
// XMPPManager.m
// XMPP_1
//
// Created by lanou3g on 15/10/20.
// Copyright (c) 2015年 nieyinlong. All rights reserved.
//
#import "XMPPManager.h"
// typedef 枚举
typedef NS_ENUM(NSUInteger, ConnectToServerPurpose){
ConnectToServerPurposeLogin,
ConnectToServerPurposeRegister
};
@interface XMPPManager ()
// 枚举变量
@property (nonatomic) ConnectToServerPurpose connectToServ;
// 记录 登录密码
@property (nonatomic, strong) NSString *loginPassword;
// 记录注册密码
@property (nonatomic, strong) NSString *registerPassword;
@end
@implementation XMPPManager
// 实现单例方法
//+ (XMPPManager *)shareManager
//{
// static XMPPManager *manager = nil;
// if (manager == nil) {
// manager = [[XMPPManager alloc] init];
// }
// return manager;
//}
+ (XMPPManager *)shareManager
{
static XMPPManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once (&onceToken, ^{
manager = [[[self class] alloc] init];
});
return manager;
}
/**
初始化的同时 设置域名 和 端口
*/
- (instancetype)init
{
if (self = [super init]) {
// 初始化通道
self.xmppStrem = [[XMPPStream alloc] init];
// 设置域名
self.xmppStrem.hostName = kHostName;
// 端口号
self.xmppStrem.hostPort = kHostPort;
// 添加代理
[self.xmppStrem addDelegate:self delegateQueue:dispatch_get_main_queue()];
}
return self;
}
// 用 用户名密码登录
- (void)loginWithUserNameString:(NSString *)userName password:(NSString *)password
{
// 登录是 建立在连接的基础上的
// 记录登录密码
self.loginPassword = password;
// 枚举变量赋值
self.connectToServ = ConnectToServerPurposeLogin;
// 调用连接服务器的方法
[self connectToServiceWithUserName:userName];
}
// 连接服务器 (是谁在连接, 记录身份)
- (void)connectToServiceWithUserName:(NSString *)userName
{
// 设置连接请求的身份
// jidWithUser:userName domain:kDomin resource:kResource
// 1. 这个方法获取身份信息
XMPPJID *myJid = [XMPPJID jidWithUser:userName domain:kDomin resource:kResource];
// domain 是只读属性, 不能用.语法
// 2. 把获取的主机信息给通道的一个身份属性
self.xmppStrem.myJID = myJid;
// 3. 获取身份信息以后 调用连接服务器方法
[self connectToService];
}
#pragma mark--- 连接服务器方法
- (void)connectToService
{
// 进来先判断
// 如果已经连接 或者 正在连接 就断开连接
if ([self.xmppStrem isConnected] || [self.xmppStrem isConnecting]) {
// 断开通道的连接, 执行新的连接
[self disConnect];
}
NSError *error = nil;
// 通道去执行连接的方法
[self.xmppStrem connectWithTimeout:30 error:&error];
if (error) {
NSLog(@"连接失败");
}
}
#pragma mark---断开连接
- (void)disConnect
{
// 保证用户下线
//1. 生成下线状态 , unavaiable
XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavaiable"];
// 将元素插入xml文件
[self.xmppStrem sendElement:presence];
//断开与服务器连接的方法
[self.xmppStrem disconnect];
}
#pragma mark--- XMLPPStreamDelegate 代理方法
// 连接超时
- (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender
{
NSLog(@"连接超时 ⌚️ %s, %d", __FUNCTION__, __LINE__);
}
#warning 在连接成功的方法里面 登录 注册
- (void)xmppStreamDidConnect:(XMPPStream *)sender
{
NSLog(@"连接成功 ✅ %s, %d", __FUNCTION__, __LINE__);
switch (self.connectToServ) {
case ConnectToServerPurposeLogin:
// 连接成功 在这里登录认定
[self.xmppStrem authenticateWithPassword:self.loginPassword error:nil];
break;
case ConnectToServerPurposeRegister:
// 连接成功, 注册
[self.xmppStrem registerWithPassword:self.registerPassword error:nil];
break;
default:
break;
}
}
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
NSLog(@"断开连接成功 %s, %d", __FUNCTION__, __LINE__);
}
// 未认定
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error
{
NSLog(@"未登录 %s, %d", __FUNCTION__, __LINE__);
}
// Authenticate 认定
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
{
NSLog(@"已经登录 %s, %d", __FUNCTION__, __LINE__);
// Authenticate --- 认证
// 在通道设置上线状态
XMPPPresence *present = [XMPPPresence presenceWithType:@"available"];
// 将元素插入xml文件
[self.xmppStrem sendElement:present];
}
/**
/**
/**
/**
/**
/**
/**
// 注册开始
// 注册开始
- (void)registWhithUserName:(NSString *)userName password:(NSString *)password
{
self.registerPassword = password;
self.connectToServ = ConnectToServerPurposeRegister;
// 还需要调用上面的连接到服务器的方法, 记录本机信息和用户信息
[self connectToServiceWithUserName:userName];
}
- (void)xmppStreamDidRegister:(XMPPStream *)sender
{
NSLog(@"注册成功 ✅ %s, %d", __FUNCTION__, __LINE__);
}
- (void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error
{
NSLog(@"注册失败 %s, %d", __FUNCTION__, __LINE__);
}
/**
* 代理与通知的区别
代理: 一对一
通知: 一对多
*/
@end</span>
// 登录控制器.m
//
// LoginViewController.m
// XMPP_1
//
// Copyright (c) 2015年 nieyinlong. All rights reserved.
//
#import "LoginViewController.h"
#import "XMPPManager.h"
@interface LoginViewController ()<XMPPStreamDelegate>
@end
@implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.passwordTF.secureTextEntry = YES;
}
#pragma mark--- 登录按钮
- (IBAction)LoginMySelfBtn:(UIButton *)sender {
// 调用单例方法
[[XMPPManager shareManager] loginWithUserNameString:self.userNameTF.text password:self.passwordTF.text];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
//
// RegeistViewController.m
// XMPP_1
//
// Copyright (c) 2015年 nieyinlong. All rights reserved.
//
#import "RegeistViewController.h"
#import "XMPPManager.h"
@interface RegeistViewController ()<XMPPStreamDelegate>
@end
@implementation RegeistViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
#pragma mark--- 注册按钮
- (IBAction)regeistButton:(UIButton *)sender {
[[XMPPManager shareManager] registWhithUserName:self.userName.text password:self.password.text];
}
//- (void)xmppStreamDidRegister:(XMPPStream *)sender
//{
// NSLog(@"注册成功 ✅ %s, %d", __FUNCTION__, __LINE__);
//}
//
//- (void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error
//{
// NSLog(@"注册失败 %s, %d", __FUNCTION__, __LINE__);
//}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end