[iPhone進階] 基於XMPP的IOS聊天用戶端程式(IOS端二)

來源:互聯網
上載者:User

接上一章的,這一章我們著重介紹XMPP

為了方便程式調用,我們把XMPP的一些主要方法寫在AppDelegate中


在AppDelegate.m下這幾個方法為:

-(void)setupStream{        //初始化XMPPStream    xmppStream = [[XMPPStream alloc] init];    [xmppStream addDelegate:self delegateQueue:dispatch_get_current_queue()];    }-(void)goOnline{        //發送線上狀態    XMPPPresence *presence = [XMPPPresence presence];    [[self xmppStream] sendElement:presence];    }-(void)goOffline{        //發送下線狀態    XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];    [[self xmppStream] sendElement:presence];    }-(BOOL)connect{        [self setupStream];        //從本地取得使用者名稱,密碼和伺服器位址    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];        NSString *userId = [defaults stringForKey:USERID];    NSString *pass = [defaults stringForKey:PASS];    NSString *server = [defaults stringForKey:SERVER];        if (![xmppStream isDisconnected]) {        return YES;    }        if (userId == nil || pass == nil) {        return NO;    }        //設定使用者    [xmppStream setMyJID:[XMPPJID jidWithString:userId]];    //設定伺服器    [xmppStream setHostName:server];    //密碼    password = pass;        //串連伺服器    NSError *error = nil;    if (![xmppStream connect:&error]) {        NSLog(@"cant connect %@", server);        return NO;    }        return YES;}-(void)disconnect{        [self goOffline];    [xmppStream disconnect];    }

這幾個是基礎方法,接下來就是XMPPStreamDelegate中的方法,也是接受好友狀態,接受訊息的重要方法

//串連伺服器- (void)xmppStreamDidConnect:(XMPPStream *)sender{        isOpen = YES;    NSError *error = nil;    //驗證密碼    [[self xmppStream] authenticateWithPassword:password error:&error];    }//驗證通過- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender{        [self goOnline];}//收到訊息- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message{    //    NSLog(@"message = %@", message);        NSString *msg = [[message elementForName:@"body"] stringValue];    NSString *from = [[message attributeForName:@"from"] stringValue];        NSMutableDictionary *dict = [NSMutableDictionary dictionary];    [dict setObject:msg forKey:@"msg"];    [dict setObject:from forKey:@"sender"];        //訊息委託(這個後面講)    [messageDelegate newMessageReceived:dict];    }//收到好友狀態- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence{    //    NSLog(@"presence = %@", presence);        //取得好友狀態    NSString *presenceType = [presence type]; //online/offline    //目前使用者    NSString *userId = [[sender myJID] user];    //線上使用者    NSString *presenceFromUser = [[presence from] user];        if (![presenceFromUser isEqualToString:userId]) {                //線上狀態        if ([presenceType isEqualToString:@"available"]) {                        //使用者列表委託(後面講)            [chatDelegate newBuddyOnline:[NSString stringWithFormat:@"%@@%@", presenceFromUser, @"nqc1338a"]];                    }else if ([presenceType isEqualToString:@"unavailable"]) {            //使用者列表委託(後面講)            [chatDelegate buddyWentOffline:[NSString stringWithFormat:@"%@@%@", presenceFromUser, @"nqc1338a"]];        }            }}

這裡面有兩個委託方法,一個是使用者列表委託,還有一個就是訊息委託,使用者列表委託主要就是取得線上使用者,更新使用者TableView,訊息委託就是取得好友發送的訊息,並更新訊息TableView,當然這兩個TableView是在不同的Controller中的



定義完兩個委託,我們就要在不同的Controller中實現這兩個委託了

在好友Controller中實現<KKChatDelegate>並寫入如下方法

//取得當前程式的委託-(KKAppDelegate *)appDelegate{        return (KKAppDelegate *)[[UIApplication sharedApplication] delegate];    }//取得當前的XMPPStream-(XMPPStream *)xmppStream{        return [[self appDelegate] xmppStream];}//線上好友-(void)newBuddyOnline:(NSString *)buddyName{        if (![onlineUsers containsObject:buddyName]) {        [onlineUsers addObject:buddyName];        [self.tView reloadData];    }    }//好友下線-(void)buddyWentOffline:(NSString *)buddyName{        [onlineUsers removeObject:buddyName];    [self.tView reloadData];    }

在viewDidLoad中加入

//設定線上使用者委託    KKAppDelegate *del = [self appDelegate];    del.chatDelegate = self;

這兩行代碼,讓好友名單的委託實現方法在本程式中

在viewWillAppear中加入

    [super viewWillAppear:animated];        NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:@"userId"];        if (login) {                if ([[self appDelegate] connect]) {            NSLog(@"show buddy list");                    }            }else {                //設定使用者        [self Account:self];            }

判斷本地儲存的資料中是否有userId,沒有的話就跳轉到登入頁面

這裡最重要的就是connect了,這一句話就是登入了,成功的話,頁面就會顯示好友名單了。

#pragma mark UITableViewDelegate-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{        //start a Chat    chatUserName = (NSString *)[onlineUsers objectAtIndex:indexPath.row];        [self performSegueWithIdentifier:@"chat" sender:self];    }-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{        if ([segue.identifier isEqualToString:@"chat"]) {        KKChatController *chatController = segue.destinationViewController;        chatController.chatWithUser = chatUserName;    }}


當顯示出好友名單,我們選擇一個好友進行聊天

將當前好友名稱發送給聊天頁面

下面是聊天Controller了

在KKChatController.h中加入

NSMutableArray *messages;

這是我們要顯示的訊息,每一條訊息為一條字典

接下來就是每一條訊息的顯示了

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{        static NSString *identifier = @"msgCell";        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];        if (cell == nil) {        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];    }        NSMutableDictionary *dict = [messages objectAtIndex:indexPath.row];        cell.textLabel.text = [dict objectForKey:@"msg"];    cell.detailTextLabel.text = [dict objectForKey:@"sender"];    cell.accessoryType = UITableViewCellAccessoryNone;        return cell;    }

跟上面好友Controller一樣,這裡我們也需要XMPPStream

-(KKAppDelegate *)appDelegate{        return (KKAppDelegate *)[[UIApplication sharedApplication] delegate];}-(XMPPStream *)xmppStream{        return [[self appDelegate] xmppStream];}

在ViewDidLoad中加入

KKAppDelegate *del = [self appDelegate];del.messageDelegate = self;

設定訊息委託由自己來接收和處理

#pragma mark KKMessageDelegate-(void)newMessageReceived:(NSDictionary *)messageCotent{        [messages addObject:messageCotent];        [self.tView reloadData];    }

接下來最重要的就是發送訊息了

- (IBAction)sendButton:(id)sender {        //本地輸入框中的資訊    NSString *message = self.messageTextField.text;        if (message.length > 0) {                //XMPPFramework主要是通過KissXML來產生XML檔案        //產生<body>文檔        NSXMLElement *body = [NSXMLElement elementWithName:@"body"];        [body setStringValue:message];                //產生XML訊息文檔        NSXMLElement *mes = [NSXMLElement elementWithName:@"message"];        //訊息類型        [mes addAttributeWithName:@"type" stringValue:@"chat"];        //發送給誰        [mes addAttributeWithName:@"to" stringValue:chatWithUser];        //由誰發送        [mes addAttributeWithName:@"from" stringValue:[[NSUserDefaults standardUserDefaults] stringForKey:USERID]];        //組合        [mes addChild:body];                //發送訊息        [[self xmppStream] sendElement:mes];                self.messageTextField.text = @"";        [self.messageTextField resignFirstResponder];                NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];                [dictionary setObject:message forKey:@"msg"];        [dictionary setObject:@"you" forKey:@"sender"];        [messages addObject:dictionary];                //重新重新整理tableView        [self.tView reloadData];            }        }

上面都加了注釋,大家應該能明白,接下來還有一個章節,我們會對發送的訊息在介面進行美化,跟蘋果內建的訊息一樣。謝謝大家有耐心看完,我這個人比較不喜歡打字,所以有的地方注釋比較少,希望大家別介意,還有希望大家能夠多多支援, 以後會接著介紹XMPP檔案傳輸之類的內容。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.