亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

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

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

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

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

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

往期回顧:

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

xmpp整理筆記:環境的快速配置(附安裝包)  http://www.49028c.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];

 

 

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

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产午夜精品全部视频播放| 最近的2019中文字幕免费一页| 欧美日韩午夜激情| 国产精品视频自在线| 亚洲欧美日韩综合| 97热精品视频官网| 国产精品极品美女在线观看免费| 欧美国产日韩一区二区三区| 久热精品视频在线免费观看| 久久精视频免费在线久久完整在线看| 亚洲精品wwwww| 亚洲国产高潮在线观看| 精品国产美女在线| 日韩精品亚洲精品| 国产拍精品一二三| 欧美壮男野外gaytube| 日韩亚洲综合在线| 一本色道久久综合狠狠躁篇怎么玩| 亚洲欧美日韩图片| 欧美三级欧美成人高清www| 久久久久久午夜| 日韩精品在线观看一区二区| 亚洲美女喷白浆| 国产日韩av在线播放| 精品欧美激情精品一区| 亚洲欧洲美洲在线综合| 国产精品揄拍一区二区| 亚洲视频axxx| 欧美激情一区二区三区成人| 成人在线中文字幕| 欧美老女人www| 久久大大胆人体| 欧美日本中文字幕| 国产99视频在线观看| 日韩欧美一区二区在线| 亚洲一区二区三| 九九热99久久久国产盗摄| 亚洲美女精品成人在线视频| 午夜精品视频在线| 久久精品91久久香蕉加勒比| 久久久久久久久久国产| 中文字幕欧美专区| 国产欧美日韩精品专区| 久久精品久久久久久国产 免费| 亚洲国产精彩中文乱码av在线播放| 欧美自拍视频在线| 国产精品扒开腿爽爽爽视频| 久久五月天色综合| 欧美色视频日本高清在线观看| 亚洲va久久久噜噜噜久久天堂| 日韩视频免费中文字幕| 欧美激情精品久久久久久黑人| 欧美激情xxxx性bbbb| 久久99精品久久久久久青青91| 欧美最猛黑人xxxx黑人猛叫黄| 久久精视频免费在线久久完整在线看| 97国产真实伦对白精彩视频8| 国产精品r级在线| 97热精品视频官网| 一区二区三区回区在观看免费视频| 国产成人精品久久久| 中文字幕久久亚洲| 成人免费高清完整版在线观看| 亚洲激情电影中文字幕| 中文字幕在线亚洲| 亚洲最大av网站| 另类少妇人与禽zozz0性伦| 91精品在线影院| 日韩专区在线播放| 国产亚洲激情视频在线| 国产日韩精品在线观看| 日本国产欧美一区二区三区| 欧美极品在线播放| 国产精品视频免费在线| 色综合色综合网色综合| 亚洲国产成人精品一区二区| 日韩精品中文字幕视频在线| 欧美激情一区二区三级高清视频| 亚洲japanese制服美女| 97超碰色婷婷| 精品成人国产在线观看男人呻吟| 国产成人精品午夜| 欧美日韩国产成人| 国产一区二区三区在线| 欧美—级a级欧美特级ar全黄| 国模精品一区二区三区色天香| 色婷婷av一区二区三区久久| 欧美高清性猛交| 在线视频精品一| 亚洲精品乱码久久久久久按摩观| 国产成人综合亚洲| 国产成人精品电影| 久久婷婷国产麻豆91天堂| 日韩经典中文字幕在线观看| www.久久久久久.com| 国产亚洲人成a一在线v站| 日本欧美精品在线| 国产精品1区2区在线观看| 日韩av资源在线播放| 日本午夜在线亚洲.国产| 美女视频黄免费的亚洲男人天堂| 亚洲最大激情中文字幕| 久久乐国产精品| 欧美一级片在线播放| 久久精品国产欧美亚洲人人爽| 国产三级精品网站| 亚洲欧美精品在线| 一区二区三区精品99久久| 欧美大尺度激情区在线播放| 九九热精品视频在线播放| 一区二区在线免费视频| 国产视频丨精品|在线观看| 中文字幕av一区| 亚洲精品第一国产综合精品| 亚洲电影免费观看高清完整版在线观看| 午夜精品一区二区三区av| 91精品综合久久久久久五月天| 欧美色欧美亚洲高清在线视频| 精品亚洲永久免费精品| 在线精品国产成人综合| 成人乱人伦精品视频在线观看| 日韩精品在线观看网站| 日韩中文字幕精品视频| 国产精品久久久久久久久免费| 国产日产久久高清欧美一区| 色综合五月天导航| 欧美资源在线观看| 久久视频免费观看| 国产免费观看久久黄| 热99精品只有里视频精品| 一区二区三区 在线观看视| 国产精品jvid在线观看蜜臀| 在线观看欧美视频| 欧美成人激情图片网| 91久久久精品| 欧美另类暴力丝袜| 国产精品久久久久7777婷婷| 日本免费在线精品| 中文字幕在线精品| 亚洲美女中文字幕| 精品自拍视频在线观看| 日韩国产在线播放| 蜜月aⅴ免费一区二区三区| 777精品视频| 亚洲性视频网址| 91精品久久久久久久久久久| 国产狼人综合免费视频| 亚洲国产小视频| 91黑丝在线观看| 国模视频一区二区三区| 亚洲美女中文字幕| 日韩av在线免费观看一区| 亚洲精品成人网| 在线看日韩av| 美日韩精品视频免费看| 久久91精品国产91久久久| 在线观看欧美日韩| 国产日韩精品在线观看| 日韩精品有码在线观看| 欧美国产日韩二区| 久久精品国产91精品亚洲| 久久久久久高潮国产精品视| 韩国日本不卡在线| 日韩中文字幕免费视频|