首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> C++ 入門

XMPPFramework iOS 集成全攻略:從源碼編譯到登錄、好友、消息收發實戰

     編輯:C++ 入門

項目地址與獲取

GitHub: https://github.com/robbiehanson/XMPPFramework

git clone https://github.com/robbiehanson/XMPPFramework.git
cd XMPPFramework
git checkout 

依賴庫添加(手動集成)

  1. CocoaLumberjack:複製 Vendor/CocoaLumberjack 到項目,Add Files 選擇該文件夾。
  2. CocoaAsyncSocket:複製 Vendor/CocoaAsyncSocket,Add Files。需在 Target → Build Phases → Link Binary With Libraries 添加 CFNetwork.framework、Security.framework。
  3. KissXML:複製 Vendor/KissXML,Add Files。添加 libxml2.dylib,Build Settings → Other Linker Flags 加 -lxml2,Header Search Paths 加 /usr/include/libxml2。
  4. libidn:複製 Vendor/libidn,添加 libidn.a、idn-int.h、stringprep.h。

XMPPFramework 核心模塊添加

複製源碼目錄下 Authentication、Categories、Core、Utilities 到項目並 Add Files。
添加動態庫 libresolv.dylib (Link Binary With Libraries)。

擴展模塊按需添加

從 Extensions 選擇需要的模塊(如 XMPPMUC 多人聊天、XMPPvCardTempModule 名片等)加入項目。
常見編譯錯誤補充:添加 CoreData.framework、SystemConfiguration.framework、CoreLocation.framework。

ARC 警告處理

XMPPFramework 使用 ARC。若項目非 ARC,選擇 Edit → Refactor → Convert to Objective-C ARC 消除警告,否則會導致內存洩漏崩潰。

統一頭文件 XMPPFramework.h

根據使用模塊刪改,例如:

#import "XMPP.h"
#import "XMPPReconnect.h"
#import "XMPPRoster.h"
#import "XMPPRosterCoreDataStorage.h"
#import "XMPPvCardTempModule.h"
#import "XMPPvCardAvatarModule.h"
#import "XMPPvCardCoreDataStorage.h"
#import "XMPPCapabilities.h"
#import "XMPPCapabilitiesCoreDataStorage.h"
#import "XMPPMUC.h"
#import "XMPPRoomCoreDataStorage.h"

用戶登錄完整流程

1. 連接服務器

- (void)connect {
    if (!self.xmppStream) self.xmppStream = [[XMPPStream alloc] init];
    [self.xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()];
    if (![self.xmppStream isConnected]) {
        NSString *user = [[NSUserDefaults standardUserDefaults] objectForKey:@"username"];
        XMPPJID *jid = [XMPPJID jidWithUser:user domain:@"lizhen" resource:@"Ework"];
        [self.xmppStream setMyJID:jid];
        [self.xmppStream setHostName:@"10.4.125.113"];  // 或域名
        NSError *err = nil;
        if (![self.xmppStream connect:&err])
            NSLog(@"Connect Error: %@", err);
    }
}

2. 身份認證 (Delegate)

- (void)xmppStreamDidConnect:(XMPPStream *)sender {
    NSString *pwd = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
    NSError *err = nil;
    if (![self.xmppStream authenticateWithPassword:pwd error:&err])
        NSLog(@"Auth Error: %@", err);
}

3. 上線發送 Presence

- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender {
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"available"];
    [self.xmppStream sendElement:presence];
}

4. 斷開連接

- (void)disconnect {
    XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"];
    [self.xmppStream sendElement:presence];
    [self.xmppStream disconnect];
}

好友狀態監聽

- (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence {
    NSString *type = [presence type];  // available, away, dnd, unavailable
    NSString *fromUser = [[presence from] user];
    if (![fromUser isEqualToString:[[sender myJID] user]]) {
        if ([type isEqualToString:@"available"]) { /* 上線 */ }
        else if ([type isEqualToString:@"unavailable"]) { /* 下線 */ }
    }
}

消息收發

接收

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message {
    NSString *body = [[message elementForName:@"body"] stringValue];
    // 處理 body...
}

發送

- (void)sendMessage:(NSString *)text toUser:(NSString *)user {
    NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
    [body setStringValue:text];
    NSXMLElement *msg = [NSXMLElement elementWithName:@"message"];
    [msg addAttributeWithName:@"type" stringValue:@"chat"];
    [msg addAttributeWithName:@"to" stringValue:[NSString stringWithFormat:@"%@@example.com", user]];
    [msg addChild:body];
    [self.xmppStream sendElement:msg];
}

好友列表獲取

- (void)queryRoster {
    NSXMLElement *query = [NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:roster"];
    NSXMLElement *iq = [NSXMLElement elementWithName:@"iq"];
    XMPPJID *myJID = self.xmppStream.myJID;
    [iq addAttributeWithName:@"from" stringValue:myJID.description];
    [iq addAttributeWithName:@"to" stringValue:myJID.domain];
    [iq addAttributeWithName:@"id" stringValue:[self generateID]];
    [iq addAttributeWithName:@"type" stringValue:@"get"];
    [iq addChild:query];
    [self.xmppStream sendElement:iq];
}
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq {
    if ([@"result" isEqualToString:iq.type]) {
        NSXMLElement *query = [iq elementForName:@"query"];
        if (query && [@"jabber:iq:roster" isEqualToString:[query xmlns]]) {
            for (NSXMLElement *item in [query elementsForName:@"item"]) {
                NSString *jidStr = [item attributeStringValueForName:@"jid"];
                XMPPJID *jid = [XMPPJID jidWithString:jidStr];
                [self.roster addObject:jid];
            }
        }
    }
    return NO;
}

常見坑點總結

  • Delegate 必須在主隊列 dispatch_get_main_queue(),否則 UI 更新崩潰。
  • JID 資源名(resource)需唯一,多端登錄用不同 resource。
  • Openfire/ejabberd 服務器配置需啟用相應模塊(如 mod_roster、mod_vcard)。
  • CoreData 存儲模塊需正確配置模型文件(.xcdatamodeld)。
  • 網絡斷開重連建議啟用 XMPPReconnect 模塊自動處理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved