1.引入文件服務器
1.1步驟dom
1.2步驟工具
1.3步驟佈局
1.1用storyboard佈局atom
登陸界面兩個textField,兩個button,輸入用戶名和密碼,點擊登陸,連接服務器成功,並認證成功,點擊註冊,跳到註冊界面,輸入用戶名,密碼,點擊註冊,連接服務器成功,認證成功,並模態退回登陸界面(當註冊過的用戶名和密碼,再次註冊時會打印出錯誤)spa
2.建立loginViewController3d
//延展方法代理
@interface LoginViewController ()orm
//用戶名的輸入框對象
@property (weak, nonatomic) IBOutlet UITextField *userNameTextFied;
//密碼的輸入框
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
@end
#pragma mark - 登陸
- (IBAction)loginAction:(id)sender {
//[XMPPManager sharedManaged] 直接建立一個管理對象,而後直接調用暴露外面的登陸方法
[[XMPPManager sharedManaged] loginWithUserName:self.userNameTextFied.text password:self.passwordTextField.text];
}
3.建立registerViewController
//延展方法
@interface RegistViewController ()<XMPPStreamDelegate>
//註冊的用戶名
@property (weak, nonatomic) IBOutlet UITextField *userNameTextField;
//註冊的密碼
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;
@end
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//遵循協議(實現模態)
[[XMPPManager sharedManaged].xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
}
#pragma mark - 註冊響應的方法
- (IBAction)registAction:(id)sender {
[[XMPPManager sharedManaged] registWithUserName:self.userNameTextField.text password:self.passwordTextField.text];
}
#pragma mark - XMPPStreamDelegate實現協議方法
//實現協議是爲了實現需求:註冊成功以後dismiss到登陸界面
- (void)xmppStreamDidRegister:(XMPPStream *)sender {
NSLog(@"註冊成功");
//返回主界面,模態
[self dismissViewControllerAnimated:YES completion:^{
NSLog(@"模態返回啦");
}];
}
// 註冊失敗
- (void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error {
NSLog(@"註冊失敗1111 %@",error);
}
4.封裝通道文件
4.1 XMPPManager.h
//聲明一個通道的屬性
@property (nonatomic,strong) XMPPStream *xmppStream;
//建立單例
+(XMPPManager *)sharedManaged;
//登陸的方法
- (void) loginWithUserName:(NSString *)userName password:(NSString *)password;
//註冊的方法
- (void)registWithUserName:(NSString *)userName password:(NSString *)password;
4.2 XMPPManager.m
//聲明一個全局單例變量
static XMPPManager *manager = nil;
//建立一個枚舉類型,用來存放連接服務器類型界面
typedef NS_ENUM(NSUInteger,ConnectToServerPurpose) {
ConnectToServerPurposeLogin , //登陸界面
ConnectToServerPurposeRegist, //註冊界面
};
@interface XMPPManager ()<XMPPStreamDelegate>
//*******聲明一個屬性,記錄當前的狀態是登陸仍是註冊***********
//注意:枚舉類型屬性,裏面沒有語義設置,對象也沒有*
@property (nonatomic) ConnectToServerPurpose connectToServer;
//用戶名
@property (nonatomic,strong) NSString *userName;
//密碼
@property (nonatomic,strong) NSString *password;
//註冊的用戶名
@property (nonatomic,strong) NSString *registUserName;
//註冊的用戶密碼
@property (nonatomic,strong) NSString *registPassword;
@end
@implementation XMPPManager
//初始化單例方法
+ (XMPPManager *)sharedManaged {
//建立靜態變量,判斷是否已經有manager對象生成,沒有生成則初始化
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
manager = [[XMPPManager alloc]init];
});
return manager;
}
#pragma mark - 建立通道
//註冊仍是登陸都須要建立通道,用一個就行
- (instancetype)init {
self = [super init];
if (self) {
//初始化通道對象
self.xmppStream = [[XMPPStream alloc] init];
//設置opfire服務器地址
self.xmppStream.hostName = kHostName;
//設置服務器端口號
self.xmppStream.hostPort = kHostPort;
//添加代理
[self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
}
return self;
}
//登陸的方法
- (void) loginWithUserName:(NSString *)userName password:(NSString *)password {
self.userName = userName;
self.password = password;
//**********記錄登陸狀態********************************
self.connectToServer = ConnectToServerPurposeLogin;
//連接服務器
[self linkServer];
}
#pragma mark - 註冊的方法*******************************
- (void)registWithUserName:(NSString *)userName password:(NSString *)password {
self.registUserName = userName;
self.registPassword = password;
//**********記錄註冊狀態*********************************
self.connectToServer = ConnectToServerPurposeRegist;
//連接服務器
[self linkServer];
}
#pragma mark - 連接服務器
- (void) linkServer {
//************區分具體是登陸仍是註冊********************
NSString *string = [[NSString alloc]init];
switch (self.connectToServer) {
case ConnectToServerPurposeLogin:
string = [NSString stringWithFormat:@"%@",self.userName];
break;
case ConnectToServerPurposeRegist:
string = [NSString stringWithFormat:@"%@",self.registUserName];
break;
default:
break;
}
//要連接服務器,要有用戶身份認證
//身份證
//參數1:用戶名 參數2:域名 參數3:資源
XMPPJID *jid = [XMPPJID jidWithUser:string domain:kDomin resource:kResource];
//經過通道進行身份驗證
self.xmppStream.myJID = jid;
//若是當前聊天工具處於連接狀態,或者已經連接狀態,此時須要去斷開連接[此邏輯不惟一]
if ([self.xmppStream isConnected] || [self.xmppStream isConnecting]) {
[self disconnectToServer];
}
//設置連接超時
NSError *error = nil;
if ([self.xmppStream connectWithTimeout:30 error:&error]) {
if (error) {
NSLog(@"服務器連接超時");
}
}
}
#pragma mark - 斷開連接
- (void)disconnectToServer{
//當前用戶下線了
XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
//告訴通道下線了
[self.xmppStream sendElement:presence];
//此通道失去連接
[self.xmppStream disconnect];
}
#pragma mark - XMPPStreamDelegate協議方法
#pragma mark - 連接超時
- (void)xmppStreamConnectDidTimeout:(XMPPStream *)sender {
NSLog(@"連接超時");
}
#pragma mark - 連接成功
- (void)xmppStreamDidConnect:(XMPPStream *)sender {
NSLog(@"連接成功");
//登陸密碼驗證
// 沒用了, [self.xmppStream authenticateWithPassword:self.password error:nil];
//***************區分登陸和註冊密碼驗證**********
switch (self.connectToServer) {
case ConnectToServerPurposeLogin:
//********************登陸密碼認證*********************
[self.xmppStream authenticateWithPassword:self.password error:nil];
break;
case ConnectToServerPurposeRegist:
//********************註冊密碼認證*********************
[self.xmppStream registerWithPassword:self.registPassword error:nil];
break;
default:
break;
}
}
#pragma mark - 斷開連接
- (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error {
//1.手動斷開
//2.被動斷開
if (error) {
NSLog(@"斷開連接,error = %@",error);
}
}
#pragma mark - 認證失敗
- (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error {
NSLog(@"認證失敗");
}
#pragma mark - 認證成功
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
//上線
XMPPPresence *presence = [XMPPPresence presenceWithType:@"available"];
//告訴通道,上線了
[self.xmppStream sendElement:presence];
NSLog(@"登陸成功");
}
5.引用第三方文件XMPPFramework(一進入程序就引入)