xmpp-iOS-擷取好友名單、聊天資訊列表、聊天
typedef enum {//發送訊息類型的枚舉
text,
image,
audio
} MsgType;
#import XMPPData.h#import XMPPFramework.h@interface XMPPData()@property(strong,nonatomic) XMPPStream *xmppStream;@property(assign,nonatomic) BOOL isRegister;@property(strong,nonatomic) NSString*user,*pwd,*hostName,*domain;@property(assign,nonatomic) UInt16 port;@property(strong,nonatomic) XMPPRosterCoreDataStorage * rosterStorage;//花名冊儲存@property(strong,nonatomic) XMPPRoster * rosterModule;//花名冊模組@property(strong,nonatomic) XMPPMessageArchivingCoreDataStorage *msgStorage;//訊息儲存@property(strong,nonatomic) XMPPMessageArchiving * msgModule;//訊息模組@property(strong,nonatomic) NSFetchedResultsController *fetFriend;//查詢好友的Fetch@property(strong,nonatomic) NSFetchedResultsController *fetMsgRecord;//查詢訊息的Fetch@end@implementation XMPPData//開始串連聊天伺服器-(BOOL) connectWithUserName:(NSString*) username andPwd:(NSString*) pwd andHostName:(NSString*) hostname andDomain:(NSString*) domain andHostPort:(UInt16) port andIsRegister:(BOOL) isRegister{ self.hostName = hostname; self.port = port; self.domain = domain; self.user = username; self.pwd = pwd; self.isRegister = isRegister; self.xmppStream = [[XMPPStream alloc] init]; //設定代理 [self.xmppStream addDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)]; //設定聊天伺服器位址 self.xmppStream .hostName = hostname; //設定聊天伺服器連接埠 預設是5222 self.xmppStream.hostPort = port; //設定Jid 就是使用者名稱 XMPPJID *jid = [XMPPJID jidWithUser:username domain:domain resource:@test]; self.xmppStream.myJID = jid; NSError * error = nil; //驗證串連 [self.xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]; if (error) { NSLog(@串連失敗:%@,error); return NO; } else { //註冊所有的模組 [self activeModules]; return YES; }}//啟用相關的模組-(void) activeModules{ //1.花名冊儲存物件 self.rosterStorage = [XMPPRosterCoreDataStorage sharedInstance]; //2.花名冊模組 self.rosterModule = [[XMPPRoster alloc] initWithRosterStorage:self.rosterStorage]; //3.啟用此模組 [self.rosterModule activate:self.xmppStream]; //4.添加roster代理 [self.rosterModule addDelegate:self delegateQueue:dispatch_get_main_queue()]; //1.訊息儲存物件 self.msgStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance]; self.msgModule = [[XMPPMessageArchiving alloc] initWithMessageArchivingStorage:self.msgStorage]; [self.msgModule activate:self.xmppStream]; [self.msgModule addDelegate:self delegateQueue:dispatch_get_main_queue()]; }//下線-(void) logout{ //1.使用者下線 NSLog(@登出使用者); XMPPPresence *presene=[XMPPPresence presenceWithType:@unavailable]; //設定下線狀態 [_xmppStream sendElement:presene]; //2.中斷連線 [_xmppStream disconnect];}//添加好友-(BOOL) addFriend:(NSString*) friendName{ XMPPJID * friendJid = [XMPPJID jidWithString:[NSString stringWithFormat:@%@@%@,friendName,self.domain]]; [self.rosterModule subscribePresenceToUser:friendJid]; return YES;}//移除朋友-(BOOL) deleteFriend:(NSString*) friendName{ XMPPJID * friendJid = [XMPPJID jidWithString:[NSString stringWithFormat:@%@@%@,friendName,self.domain]]; [self.rosterModule removeUser:friendJid]; return YES; }//擷取好友名單-(NSArray*) getFriends{ NSManagedObjectContext *context = self.rosterStorage.mainThreadManagedObjectContext; NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@XMPPUserCoreDataStorageObject]; //篩選本使用者的好友 NSString *userinfo = [NSString stringWithFormat:@%@@%@,self.user,self.domain]; NSLog(@userinfo = %@,userinfo); NSPredicate *predicate = [NSPredicate predicateWithFormat:@ streamBareJidStr = %@ ,userinfo]; request.predicate = predicate; //排序 NSSortDescriptor * sort = [NSSortDescriptor sortDescriptorWithKey:@displayName ascending:YES]; request.sortDescriptors = @[sort]; self.fetFriend = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil]; self.fetFriend.delegate = self; NSError *error; [self.fetFriend performFetch:&error]; //返回的數組是XMPPUserCoreDataStorageObject *obj類型的 //名稱為 obj.displayName NSLog(@%lu,(unsigned long)self.fetFriend.fetchedObjects.count); return self.fetFriend.fetchedObjects;}//資料庫有變化-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath{ NSManagedObject *obj = anObject; if([obj isKindOfClass:[XMPPMessageArchiving_Message_CoreDataObject class]]) { NSLog(@聊天的資訊的資料庫發生變化); }
else NSLog(@資料庫有變化);}//與某個好友聊天-(BOOL) talkToFriend:(NSString*)friendsName andMsg:(NSString*) msg andMsgType:(MsgType) msgT{ XMPPJID *toFriend = [XMPPJID jidWithUser:friendsName domain:self.domain resource:@A];//resource 隨意,目前不影響 XMPPMessage * message = [[XMPPMessage alloc] initWithType:@chat to:toFriend];//chat類型是正常的聊天類型 [message addBody:msg]; [message addAttributeWithName:@msgType intValue:msgT]; [self.xmppStream sendElement:message]; return YES;}//獲得與某個好友的聊天記錄-(NSArray*) getRecords:(NSString*) friendsName{ //所有帳號 和所有人的聊天記錄都在同一個資料庫內 所以 要寫查詢條件 NSManagedObjectContext *context = self.msgStorage.mainThreadManagedObjectContext; NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@XMPPMessageArchiving_Message_CoreDataObject]; NSString *userinfo = [NSString stringWithFormat:@%@@%@,self.user,self.domain]; NSString *friendinfo = [NSString stringWithFormat:@%@@%@,friendsName,self.domain]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@ streamBareJidStr = %@ and bareJidStr = %@,userinfo,friendinfo]; request.predicate = predicate; NSSortDescriptor * sort = [NSSortDescriptor sortDescriptorWithKey:@timestamp ascending:YES]; request.sortDescriptors = @[sort]; self.fetMsgRecord = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil]; self.fetMsgRecord.delegate = self; NSError *error; [self.fetMsgRecord performFetch:&error];// 返回的實值型別 XMPPMessageArchiving_Message_CoreDataObject return self.fetMsgRecord.fetchedObjects;}//串連成功的代理函數-(void)xmppStreamDidConnect:(XMPPStream *)sender{ NSLog(@串連成功); if (self.isRegister) { NSError* error = nil; [sender registerWithPassword:self.pwd error:&error]; if (error) { NSLog(@註冊失敗1,%@,error); } } else { NSError *error = nil; [sender authenticateWithPassword:self.pwd error:&error]; if (error) { NSLog(@驗證失敗1,%@,error); } }}//串連失敗代理函數-(void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error{ NSLog(@串連失敗,%@,error);}//驗證成功代理函數-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{ NSLog(@驗證成功); //4.登陸成功後 線上 [self.xmppStream sendElement:[XMPPPresence presence]];//使用者線上}//驗證失敗代理函數-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{ NSLog(@驗證失敗,%@,error);}//註冊成功代理函數-(void)xmppStreamDidRegister:(XMPPStream *)sender{ NSLog(@註冊成功);}//註冊失敗代理函數-(void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error{ NSLog(@註冊失敗,%@,error);}//收到好友請求 代理函數-(void)xmppRoster:(XMPPRoster *)sender didReceivePresenceSubscriptionRequest:(XMPPPresence *)presence{ NSString * presenceType = [presence type]; NSLog(@presenceType = %@,presenceType); XMPPJID * fromJid = presence.from; if ([presenceType isEqualToString:@subscribe]) {//是訂閱請求 直接通過 [self.rosterModule acceptPresenceSubscriptionRequestFrom:fromJid andAddToRoster:YES]; }}-(void)xmppRoster:(XMPPRoster *)sender didReceiveRosterItem:(DDXMLElement *)item{ NSString *subscription = [item attributeStringValueForName:@subscription]; NSLog(@%@,subscription); if ([subscription isEqualToString:@both]) { NSLog(@雙方成為好友!); }}