iOS開發之使用XMPPFramework實現即時通訊(二)

iOS開發之使用XMPPFramework實現即時通訊(二)

  上篇的博客iOS開發之使用XMPPFramework實現即時通訊(一)只是本篇的引子,本篇博客就給以前的微信加上即時通信的功能,主要是對XMPPFramework的使用。本篇博客中用到了Spark作測試,固然也少不了Openfire服務器,在這就不詳述Openfire的安裝過程了(網上的教程仍是蠻多的),Openfire的安裝僅須要一個數據庫的支持,本篇是用的MySql數據庫。固然這不是本篇的重點。html

  廢話少說,切入今天的正題。今天要給以前的微信加入登錄,獲取好友列表,聊天(發送文字,表情,圖片,聲音等功能),最近聯繫人等。在博客的開頭仍是先來幾張圖來介紹一下功能,而後再給出核心代碼的實現。數據庫

  1、功能模塊截圖服務器

    1.登錄和獲取好友列表微信

      登錄的過程就是鏈接用XMPPFramework鏈接Openfire的過程,若是用戶登錄過,就從UserDefault裏獲取用戶的JID和密碼自動鏈接,若是用戶沒有登錄過則登錄。獲取好友列表也是經過XMPPFramework中的Roster來獲取的,運行截圖以下:app

    2.好友點擊去就是聊天頁面,聊天時若是是發送的圖片或者聲音,先存儲到服務器上存儲,服務器會返回存儲路徑而後再把URL發送給接收方,接收方再下載dom

      (1)若是是發送的文字,把文字轉成屬性字符串,而後再轉成NSData,最後轉成字符串放在Message的Body中進行發送,下面是用Spark作接收端作得測試,截圖以下:工具

 

 

    (2)發送圖片,把圖片的存儲路徑發送給對方,讓對方從服務器上下載。截圖以下:測試

 

 

    (3)發送聲音和圖片同樣都是發送URL,截圖以下:fetch

 

  2、代碼實現部分spa

    上面的部分是容許的效果截圖,從截圖上是不難看出功能點的。圖就先貼到這吧,下面給出核心代碼的實現。

    1.使用XMPPFramework前的準備,獲取XmppStream和激活要用的組件,在AppDelegate添加代碼。之後要用xmppStream時,要經過AppDelegate獲取。下面的代碼是在AppDelegate.m中進行的相關組件的初始化,代碼以下

      (1)實例化XMPPStream

    //建立xmppstream
    self.xmppStream = [[XMPPStream alloc]init];

 

      (2)建立重連組件,並在xmppStream中激活

1   //建立重寫鏈接組件2     xmppReconnect= [[XMPPReconnect alloc] init];3     //使組件生效4     [xmppReconnect activate:self.xmppStream];

 

      (3)建立message部分的內容,接受的消息咱們保存在本地數據庫中,咱們要顯示的時候是從數據庫中獲取的。在初始化消息組件的時候,要指定保存策略,通常能夠選的是CoreData仍是內存。指定完保存策略後實例化Message是要關聯保存策略,以後也是須要在XMPPStream中進行激活的,最後要獲取CoreData的上下文。代碼以下:

複製代碼

1     //建立消息保存策略(規則,規定)2     messageStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];3     //用消息保存策略建立消息保存組件4     xmppMessageArchiving = [[XMPPMessageArchiving alloc]initWithMessageArchivingStorage:messageStorage];5     //使組件生效6     [xmppMessageArchiving activate:self.xmppStream];7     //提取消息保存組件的coreData上下文8     self.xmppManagedObjectContext = messageStorage.mainThreadManagedObjectContext;

複製代碼

 

      (4),初始化獲取好友列表的相關組件並指定保存策略,和上面的代碼步驟極爲類似。這也能看出來在XMPPFramework中進行組件的初始化步驟是差很少的。下面咱們設定自動獲取花名冊,代碼以下:

複製代碼

1     xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init];2     xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage];3     //自動獲取用戶列表4     xmppRoster.autoFetchRoster = YES;5     xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES;6     7     [xmppRoster activate:self.xmppStream];8     self.xmppRosterManagedObjectContext = xmppRosterStorage.mainThreadManagedObjectContext;

複製代碼

 

    2.登錄模塊的實現

      登錄時就是用戶輸入JID和Password,而後鏈接服務器和驗證密碼,若是認證成功則跳轉到好友列表才Controller,同時把JID和Password存儲到UserDefaults中便於下次自動鏈接。下面的代碼就是登錄部分的代碼(LoginViewController.m):

      (1).經過應用代理獲取XMPPStream,並註冊回調,代碼以下:

複製代碼

 1 -(void) initXmpp 2 { 3     //獲取應用的xmppSteam(經過Application中的單例獲取) 4     UIApplication *application = [UIApplication sharedApplication]; 5     id delegate = [application delegate]; 6     self.xmppStream = [delegate xmppStream]; 7      8     //註冊回調 9     [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];10 }

複製代碼

 

      (2).建立JID鏈接服務器

複製代碼

 1 //鏈接服務器 2 -(void) xmppConnect 3 { 4     if (![self.userNameTextFiled.text isEqualToString:@""] && self.userNameTextFiled.text != nil) 5     { 6         //1.建立JID 7         XMPPJID *jid = [XMPPJID jidWithUser:self.userNameTextFiled.text domain:MY_DOMAIN resource:@"iPhone"]; 8          9         //2.把JID添加到xmppSteam中10         [self.xmppStream setMyJID:jid];11         12         //鏈接服務器13         NSError *error = nil;14         [self.xmppStream connectWithTimeout:10 error:&error];15         if (error)16         {17             NSLog(@"鏈接出錯:%@",[error localizedDescription]);18         }19 20     }21     else22     {23         UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"用戶名不能爲空" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil];24         [alter show];25     }26 }

複製代碼

 

      (3).鏈接成後須要認證密碼,代碼以下:

複製代碼

 1 //鏈接後的回調 2 -(void)xmppStreamDidConnect:(XMPPStream *)sender 3 { 4     if (![self.passwordTextFiled.text isEqualToString:@""] && self.passwordTextFiled.text != nil) 5     { 6         //鏈接成功後認證用戶名和密碼 7         NSError *error = nil; 8         [self.xmppStream authenticateWithPassword:self.passwordTextFiled.text error:&error]; 9         if (error)10         {11             NSLog(@"認證錯誤:%@",[error localizedDescription]);12         }13     }14     else15     {16         UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"提示" message:@"密碼不能爲空" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:nil];17         [alter show];18     }19 }

複製代碼

 

      (4)密碼認證成功後的回調

複製代碼

 1 //認證成功後的回調 2 -(void)xmppStreamDidAuthenticate:(XMPPStream *)sender 3 { 4     NSLog(@"登錄成功"); 5      6     //密碼進入userDefault 7     NSUserDefaults *userDefult = [NSUserDefaults standardUserDefaults]; 8     [userDefult setObject:self.userNameTextFiled.text forKey:@"username"]; 9     [userDefult setObject:self.passwordTextFiled.text forKey:@"password"];10     11     //設置在線狀態12     XMPPPresence * pre = [XMPPPresence presence];13     [self.xmppStream sendElement:pre];14     15     UIStoryboard *storybard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];16     UIViewController *viewController = [storybard instantiateViewControllerWithIdentifier:@"mainController"];17     [self presentViewController:viewController animated:YES completion:^{18     }];19 }

複製代碼

 

      (5)密碼認證失敗後的回調

1 //認證失敗的回調2 -(void)xmppStream:sender didNotAuthenticate:(DDXMLElement *)error3 {4     NSLog(@"認證失敗");5 }

 

      (6),二次登錄自動鏈接代碼:

複製代碼

 1    // 若是已登陸就直接填充密碼登錄 2     NSUserDefaults *userDefult = [NSUserDefaults standardUserDefaults]; 3      4     NSString *userName = [userDefult objectForKey:@"username"]; 5     NSString *password = [userDefult objectForKey:@"password"]; 6     NSLog(@"%@,%@",userName,password); 7     if (userName != nil && password != nil && ![userName isEqualToString:@""] && ![password isEqualToString:@""]) 8     { 9         self.userNameTextFiled.text = userName;10         self.passwordTextFiled.text = password;11         [self xmppConnect];12     }

複製代碼

    

    3.獲取好友列表的XMPPFramework的代碼實現

      在獲取用戶列表的代碼中就會用到咱們以前註冊的Roster的內容,由於咱們在實例化Roster的時候指定的保存策略是用CoreData進行保存的,而且是自動獲取好友列表。因此在獲取好友列表的TableViewController中咱們只須要經過CoreData來獲取好友列表便可。下面將給出獲取好友列表的核心代碼:

      (1),獲取Roster對應的上下文,用於獲取存儲在Roster相應實體中的數據

1     //獲取Roster的上下文2     UIApplication *application = [UIApplication sharedApplication];3     id delegate = [application delegate];4     self.xmppRosterManagedObjectContext = [delegate xmppRosterManagedObjectContext];

      

      (2).獲取FetchRequst對象,並指定CoreData實體類,以後添加排序規則,代碼以下:

複製代碼

1     //從CoreData中獲取數據2     //經過實體獲取FetchRequest實體3     NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([XMPPUserCoreDataStorageObject class])];4     //添加排序規則5     NSSortDescriptor * sortD = [NSSortDescriptor sortDescriptorWithKey:@"jidStr" ascending:YES];6     [request setSortDescriptors:@[sortD]];

複製代碼

  

      (3).獲取FetchedResultController並註冊回調,用於自動刷新TableView,代碼以下:

1     //獲取FRC2     self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.xmppRosterManagedObjectContext sectionNameKeyPath:nil cacheName:nil];3     self.fetchedResultsController.delegate = self;

 

      (4)獲取存儲的內容

複製代碼

1     2     //獲取內容3     NSError * error;4     ;5     if (![self.fetchedResultsController performFetch:&error])6     {7         NSLog(@"%s  %@",__FUNCTION__,[error localizedDescription]);8     }

複製代碼

  

  至於如何在TableView上顯示FetchedResultController獲取的數據,請參考以前的博客:IOS開發之表視圖愛上CoreData

  最近聯繫人的代碼和歷史表情的代碼相似,請參考以前的博客:iOS開發之微信聊天工具欄的封裝

  聊頁面的實現請參考以前的博客:iOS開發之微信聊天頁面實現

  

  今天的XMPPFramework就先到這兒吧,內容也挺多的了,其實XMPPFramework中的組件使用方法都差很少,首先第初始化內存,而後進行相關配置,在後就是在XMPPStream中激活,最後就是如何使用了。

  轉載請註明出處:青玉伏案:http://www.cnblogs.com/ludashi/ 

做者:青玉伏案
出處:http://www.cnblogs.com/ludashi/ 本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。 若是文中有什麼錯誤,歡迎指出。以避免更多的人被誤導。 

相關文章
相關標籤/搜索