麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

xmpp整理筆記:用戶網絡連接及好友的管理

2019-11-14 19:30:14
字體:
來源:轉載
供稿:網友

xmpp中的用戶連接模塊包括用戶的上線與下線信息展現,用戶登錄,用戶的注冊; 好友模塊包括好友的添加,好友的刪除,好友列表的展示。

在xmpp中 負責數據傳輸的類是xmppStream,開發的過程中,針對不同的傳輸內容,會調用不同的代理方法,在使用XMPPFramework開發時,只需要在不同的代理方法中,填寫相同的代碼即可。

往期回顧:

xmpp整理筆記:xmppFramework框架的導入和介紹  http://www.companysz.com/dsxniubility/p/4307057.html 

xmpp整理筆記:環境的快速配置(附安裝包)  http://www.companysz.com/dsxniubility/p/4304570.html

如果你不是在董鉑然博客園看到本文,請點擊查看原文

一。大概的連接過程如下

1.運行后需要和服務器建立一個長連接,系統會反饋鏈接是否成功

2.成功時需要告訴服務器的用戶的密碼,服務器判斷是否給予授權

3.成功授權后,告訴服務器上線了。

4.將要離開時告訴服務器,我需要斷開鏈接了。

5.服務器反饋你可以斷開了,然后你再告訴服務器你下線了

 

二。首先,需要知道  XMPPStreamDelegate 和  XMPPRosterDelegate 的一些代理方法

如果你不是在董鉑然博客園看到本文 請點擊查看原文

xmpp流代理方法:

連接成功時調用

  - (void)xmppStreamDidConnect:(XMPPStream *)sender

斷開連接時調用

  - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error

授權成功時調用

  - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender

授權失敗時調用

  -(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDxmlElement *)error

注冊成功時調用

  - (void)xmppStreamDidRegister:(XMPPStream *)sender

注冊失敗時調用

  - (void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error

xmppRoster花名冊代理方法 

接收到好友請求時調用

  - (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence

 

三。用戶的登錄:

用戶需要在連接成功后的代理方法中 將自己的密碼發送給服務器,自己的密碼應該是在點擊登錄的時候就和其他信息一起存入偏好設置了,在現在需要的時候可以輕而易舉的取出來。在發送驗證請求的時候會用到這個方法authenticateWithPassWord: 后面的error在實際開發中建議必須處理,我在這就偷懶了如下所示

/** 連接成功時調用 */- (void)xmppStreamDidConnect:(XMPPStream *)sender{        NSLog(@"連接成功");            NSString *password = [[NSUserDefaults standardUserDefaults] valueForKey:SXLoginPasswordKey];        // 將用戶密碼發送給服務器,進行用戶登錄        [self.xmppStream authenticateWithPassword:password error:NULL];}

 然后等待結果,在授權成功后來到授權成功代理方法在這應該先告訴服務器用戶上線,然后給發出成功通知,自己的AppDelegate在遠處接收,一旦接收到通知馬上更換應用程序的根控制器到進入后的界面,這里要注意這些代理方法都是在異步的,所以這里要用到線程間通訊,在主線程發送通知

    // 通知服務器用戶上線    [self goOnline];    // 在主線程利用通知發送廣播    dispatch_async(dispatch_get_main_queue(), ^{        [[NSNotificationCenter defaultCenter] postNotificationName:SXLoginResultNotification object:@(YES)];    });

如果授權失敗的話,應該斷開與服務器的鏈接,并且把開始存儲的用戶偏好清空(因為這些是錯誤的沒用),然后再到主線程更新UI彈出一個框顯示密碼錯誤,并且發出失敗通知,讓APPDelegate切換根控制器到登錄界面 (董鉑然原創)

// 斷開與服務器的連接    [self disconnect];    // 清理用戶偏好    [self clearUserDefaults];    // 在主線程更新UI    if (self.failed) {        dispatch_async(dispatch_get_main_queue(), ^ {self.failed(@"用戶名或者密碼錯誤!");});    }    // 在主線程利用通知發送廣播    dispatch_async(dispatch_get_main_queue(), ^{        [[NSNotificationCenter defaultCenter] postNotificationName:SXLoginResultNotification object:@(NO)];    });

 

四。用戶的上線和下線:

關于用戶的上線和下線,需要用到一個類XMPPPresence 類。這個類是XMPPElement的子類,主要用來管理某些信息的展現。首先要實例化一個對象,這其中會用到一個presenceWithType 方法,有兩個選擇@"unavailable"代表下線,@"available"代表上線,一般情況上線的時候后面就可以直接省略。實例化之后用xmpp流發出去。如下所示

#pragma mark - ******************** 用戶的上線和下線- (void)goOnline {    XMPPPresence *p = [XMPPPresence presence];        [self.xmppStream sendElement:p];}- (void)goOffline {    XMPPPresence *p = [XMPPPresence presenceWithType:@"unavailable"];        [self.xmppStream sendElement:p];}

對用戶是否在線狀態的判斷

// 取出用戶XMPPUserCoreDataStorageObject *user = [self.fetchedResultsController objectAtIndexPath:indexPath];

 用戶的 user.section 就是用戶的狀態

// section    // 0 在線    // 1 離開   // 2 離線

 

 

五。用戶注冊:

自己在UI里搭建好注冊頁面,里面需要用戶填寫好用戶信息。在點擊注冊按鈕時,把單例類里自己設定的一個布爾值isRegisterUser 設置為YES。 然后重新發送連接請求。最終還是會來到,連接成功時的代理方法,剛才在這里發送用戶密碼登錄的,現在可以加一層判斷,如果isRegisterUser的值為YES 就不是發送用戶密碼登錄了,而是發送用戶密碼注冊,這里將會用到一個方法registerWithPassword:

if (self.isRegisterUser) {        // 將用戶密碼發送給服務器,進行用戶注冊        [self.xmppStream registerWithPassword:password error:NULL];        // 將注冊標記復位        self.isRegisterUser = NO;    }

 然后有兩個代理方法,注冊成功和注冊失敗,分別寫上合適的操作。

 

六。添加好友:

搭建一個加好友的UI只需要一個文本框和一個按鈕。

在文本框的回車按鈕點擊代理方法中,做文本框是否為空得判斷,不為空就添加好友,(添加好友方法可以抽出來寫使得結構更加清晰)

添加好友方法如下:有兩個注意點一個是判斷用戶是否寫了域名,如果只是單單寫了個賬號,也可以自動幫他拼接個域名然后注冊。還有個就是判斷是否已經是自己的好友,如果是就不做任何操作。如果不是好友 那就馬上添加。最后讓導航控制器返回到登陸界面

// 添加好友- (void)addFriendWithName:(NSString *)name {        // 你寫了域名那更好,你沒寫系統就自動幫你補上    NSRange range = [name rangeOfString:@"@"];    // 如果沒找到 NSNotFound,不要寫0    if (range.location == NSNotFound) {        name = [name stringByAppendingFormat:@"@%@", [SXXMPPTools sharedXMPPTools].xmppStream.myJID.domain];    }        // 如果已經是好友就不需要再次添加    XMPPJID *jid = [XMPPJID jidWithString:name];        BOOL contains = [[SXXMPPTools sharedXMPPTools].xmppRosterCoreDataStorage userExistsWithJID:jid xmppStream:[SXXMPPTools sharedXMPPTools].xmppStream];        if (contains) {        [[[UIAlertView alloc] initWithTitle:@"提示" message:@"已經是好友,無需添加" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] show];        return;    }        [[SXXMPPTools sharedXMPPTools].xmppRoster subscribePresenceToUser:jid];        [self.navigationController popViewControllerAnimated:YES];}

 這里會用到一個通過JID加好友的方法subscribePresenceToUser: 但是這個方法是通過Roster 調用的所以要在單例類里導入頭文件 聲明屬性,遵守協議,實現代理方法(董鉑然原創)

在單例類里所有特殊類的操作都要寫在xmppStream的懶加載里

        // 實例化        _xmppReconnect = [[XMPPReconnect alloc]init];        _xmppRosterCoreDataStorage = [XMPPRosterCoreDataStorage sharedInstance];        _xmppRoster = [[XMPPRoster alloc]initWithRosterStorage:_xmppRosterCoreDataStorage dispatchQueue:dispatch_get_global_queue(0, 0)];                // 激活        [_xmppRoster activate:_xmppStream];        // 添加代理        [_xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()];                

 

接受到加好友請求的代理方法

- (void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence

在這個方法中,先要拼接提示的字符串,就是從 presence.from(申請人的id)的人請求加你為好友。然后設置彈窗,確定和拒絕,點擊確定按鈕后

// 接受好友請求        [self.xmppRoster acceptPresenceSubscriptionRequestFrom:presence.from andAddToRoster:YES];

 這個彈窗建議使用iOS8的新功能  UIAlertController。 這樣可以不用寫alertDelegate 也能設置確定按鈕點擊事件 。用 alert addAction: 添加按鈕,把點擊事件寫在block里,最后再取到當前窗口的根控制器彈出presentViewController,相當于以前的show 。iOS8蘋果的思想漸漸是想把所有彈出控制器的各種方法都慢慢統一到present。

補充:這個功能就是QQ上所謂的加好友不需要驗證,是布爾值可以控制開關。

        // 取消接收自動訂閱功能,需要確認才能夠添加好友!        _xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = NO;

 

七。好友列表的展示。

這里需要用到查詢結果調度器

- (NSFetchedResultsController *)fetchedResultsController{    if (_fetchedResultsController != nil) {        return  _fetchedResultsController;    }    // 指定查詢的實體    NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:@"XMPPUserCoreDataStorageObject"];        // 在線狀態排序    NSSortDescriptor *sort1 = [NSSortDescriptor sortDescriptorWithKey:@"sectionNum" ascending:YES];    // 顯示的名稱排序    NSSortDescriptor *sort2 = [NSSortDescriptor sortDescriptorWithKey:@"displayName" ascending:YES];        // 添加排序    request.sortDescriptors = @[sort1,sort2];        // 添加謂詞過濾器    request.predicate = [NSPredicate predicateWithFormat:@"!(subscription CONTAINS 'none')"];        // 添加上下文    NSManagedObjectContext *ctx = [SXXMPPTools sharedXMPPTools].xmppRosterCoreDataStorage.mainThreadManagedObjectContext;        // 實例化結果控制器    _fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:request managedObjectContext:ctx sectionNameKeyPath:nil cacheName:nil];        // 設置他的代理    _fetchedResultsController.delegate = self;        return _fetchedResultsController;}

寫完了結果調度器之后要切記在viewdidload頁面首次加載中加上一句,否則不干活

// 查詢數據    [self.fetchedResultsController performFetch:NULL];

 

結果調度器有一個代理方法,一旦上下文改變觸發,也就是剛加了好友,或刪除好友時會觸發

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller{    NSLog(@"上下文改變");    [self.tableView reloadData];}

 

整個tableview的數據源方法如下

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{    return self.fetchedResultsController.fetchedObjects.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    static NSString *ID = @"ContactCell";    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];        XMPPUserCoreDataStorageObject *user = [self.fetchedResultsController objectAtIndexPath:indexPath];        // 顯示此好友是否相互關注    NSString *str = [user.jidStr stringByAppendingFormat:@" | %@",user.subscription];        cell.textLabel.text = str ;    // 這里有個自定義方法傳入section 通過switch判斷返回漢字。section關系到是否在線    cell.detailTextLabel.text = [self userStatusWithSection:user.section];        return cell;}

 其中subscription是用戶的好友互加情況

  // 如果是none表示對方還沒有確認   // to 我關注對方  // from 對方關注我  // both 互粉

再提一下 user.section 就是用戶的狀態

// section    // 0 在線    // 1 離開   // 2 離線

當有好友上線,上下文改變時,結果調度器會重新排序,然后在線的好友會顯示在上面。

 

八。刪除好友

好友的列表顯示界面可以給tableView添加滑動刪除。(開啟編輯模式)

#pragma mark - ******************** 開啟編輯模式刪除好友- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {        if (editingStyle == UITableViewCellEditingStyleDelete) {        XMPPUserCoreDataStorageObject *user = [self.fetchedResultsController objectAtIndexPath:indexPath];                 XMPPJID *jid = user.jid;        // 接下來是設置彈窗

在彈窗的點擊事件里面刪除好友用到的方法是

[[SXXMPPTools sharedXMPPTools].xmppRoster removeUser:jid];

 

 

如果你不是在董鉑然博客園看到本文,請點擊查看原文

正在整理關于信息發送模塊的各種細節,有興趣的可以關注


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 亚洲一区久久久 | 国产精品jk白丝蜜臀av软件 | 91精品国产91久久久久久丝袜 | 国产1区在线观看 | 双性精h调教灌尿打屁股的文案 | 久久影城 | 国外成人在线视频 | 国产一级毛片国产 | 全黄性性激高免费视频 | 久久久久北条麻妃免费看 | 99re66热这里只有精品8 | 国产成人77亚洲精品www | 一区在线免费视频 | 暴力肉体进入hdxxxx古装 | www日韩大片 | 精品99在线视频 | 黄色大片免费网站 | 亚洲成人福利网站 | 99re热精品视频 | 日本高清黄色片 | 男女生羞羞视频网站在线观看 | 国产亚洲高清视频 | 日本欧美视频 | 欧美成人理论片乱 | 极品国产91在线网站 | 国产成人精品午夜视频' | 精品一区二区三区四区在线 | 美女羞羞视频在线观看 | 欧美日韩免费在线观看视频 | h视频免费观看 | 精品国产欧美一区二区 | 欧美日韩一区二区综合 | 国产九色在线播放九色 | 高清做爰免费无遮网站挡 | 欧产日产国产精品乱噜噜 | 免费一区二区三区 | 国产黄色一级大片 | 中国美女一级黄色大片 | 一级电影在线观看 | 亚洲自拍第二页 | 国产一区免费观看 |