XMPP聊天程序iPhone版开发(二):创建XMPPStream连接
2013-10-11 16:42
260 查看
上篇对XMPP进行了介绍,以及如果运行第一个XMPP应用程序,现在这篇就来介绍如何使用XMPPFramework第二方库和服务器进行连接。
#pragma mark Private //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 初始化 XMPPStream - (void)setupStream { xmppStream = [[XMPPStream alloc] init]; #if !TARGET_IPHONE_SIMULATOR{ // 设置后台也进行连接 xmppStream.enableBackgroundingOnSocket = YES; } #endif // 创建XMPPStream重联 xmppReconnect = [[XMPPReconnect alloc] init]; // 创建XMPP花名册.XMPPRosterCoreDataStorage为xmppRoster的代理,里面实现了coreData的保存。 xmppRosterStorage = [[XMPPRosterCoreDataStorage alloc] init]; xmppRoster = [[XMPPRoster alloc] initWithRosterStorage:xmppRosterStorage]; xmppRoster.autoFetchRoster = YES; xmppRoster.autoAcceptKnownPresenceSubscriptionRequests = YES; // Setup vCard support // 创建支持vCard xmppvCardStorage = [XMPPvCardCoreDataStorage sharedInstance]; xmppvCardTempModule = [[XMPPvCardTempModule alloc] initWithvCardStorage:xmppvCardStorage]; xmppvCardAvatarModule = [[XMPPvCardAvatarModule alloc] initWithvCardTempModule:xmppvCardTempModule]; // Setup capabilities // xmppCapabilitiesStorage = [XMPPCapabilitiesCoreDataStorage sharedInstance]; xmppCapabilities = [[XMPPCapabilities alloc] initWithCapabilitiesStorage:xmppCapabilitiesStorage]; xmppCapabilities.autoFetchHashedCapabilities = YES; xmppCapabilities.autoFetchNonHashedCapabilities = NO; // Activate xmpp modules [xmppReconnect activate:xmppStream]; [xmppRoster activate:xmppStream]; [xmppvCardTempModule activate:xmppStream]; [xmppvCardAvatarModule activate:xmppStream]; [xmppCapabilities activate:xmppStream]; [xmppStream addDelegate:self delegateQueue:dispatch_get_main_queue()]; [xmppRoster addDelegate:self delegateQueue:dispatch_get_main_queue()]; } // 取消注册 - (void)teardownStream { [xmppStream removeDelegate:self]; [xmppRoster removeDelegate:self]; [xmppReconnect deactivate]; [xmppRoster deactivate]; [xmppvCardTempModule deactivate]; [xmppvCardAvatarModule deactivate]; [xmppCapabilities deactivate]; [xmppStream disconnect]; xmppStream = nil; xmppReconnect = nil; xmppRoster = nil; xmppRosterStorage = nil; xmppvCardStorage = nil; xmppvCardTempModule = nil; xmppvCardAvatarModule = nil; xmppCapabilities = nil; xmppCapabilitiesStorage = nil; } // 向服务器发送上线操作. - (void)goOnline { XMPPPresence *presence = [XMPPPresence presence]; // type默认为available [[self xmppStream] sendElement:presence]; } // 向服务器发送下线操作 - (void)goOffline { XMPPPresence *presence = [XMPPPresence presenceWithType:@"unavailable"]; [[self xmppStream] sendElement:presence]; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark Connect/disconnect //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 连接服务器 - (BOOL)connect { if (![xmppStream isDisconnected]) { // 如果已经连接 return YES; } NSString *myJID = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyJID]; NSString *myPassword = [[NSUserDefaults standardUserDefaults] stringForKey:kXMPPmyPassword]; if (myJID == nil || myPassword == nil) { return NO; } [xmppStream setMyJID:[XMPPJID jidWithString:myJID]];// 设置账号 // 设置服务器域名,如果不设置默认为账号后面的域名// // [xmppStream setHostName:@""]; // 设置端口号,如果不设置默认为5222 // [xmppStreamsetHostPort:5222]; password = myPassword; NSError *error = nil; if (![xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error]){ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error connecting" message:@"See console for error details." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alertView show]; DDLogError(@"Error connecting: %@", error); return NO; } return YES; } // 取消连接 - (void)disconnect { [self goOffline]; [xmppStream disconnect]; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark XMPPStream Delegate //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 正在连接中…. - (void)xmppStream:(XMPPStream *)sender socketDidConnect:(GCDAsyncSocket *)socket { DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD); } - (void)xmppStream:(XMPPStream *)sender willSecureWithSettings:(NSMutableDictionary *)settings { if (allowSelfSignedCertificates){ [settings setObject:[NSNumber numberWithBool:YES] forKey:(NSString *)kCFStreamSSLAllowsAnyRoot]; } if (allowSSLHostNameMismatch) { [settings setObject:[NSNull null] forKey:(NSString *)kCFStreamSSLPeerName]; }else{ // Google does things incorrectly (does not conform to RFC). // Because so many people ask questions about this (assume xmpp framework is broken), // I've explicitly added code that shows how other xmpp clients "do the right thing" // when connecting to a google server (gmail, or google apps for domains). NSString *expectedCertName = nil; NSString *serverDomain = xmppStream.hostName; NSString *virtualDomain = [xmppStream.myJID domain]; if ([serverDomain isEqualToString:@"talk.google.com"]){ if ([virtualDomain isEqualToString:@"gmail.com"]){ expectedCertName = virtualDomain; }else{ expectedCertName = serverDomain; } }else if (serverDomain == nil){ expectedCertName = virtualDomain; }else{ expectedCertName = serverDomain; } if (expectedCertName){ [settings setObject:expectedCertName forKey:(NSString *)kCFStreamSSLPeerName]; } } } - (void)xmppStreamDidSecure:(XMPPStream *)sender { } // 成功连接服务器 - (void)xmppStreamDidConnect:(XMPPStream *)sender { NSError *error = nil; // 对用户进行认证 if (![[self xmppStream] authenticateWithPassword:password error:&error]){ DDLogError(@"Error authenticating: %@", error); } } // 认证成功 - (void)xmppStreamDidAuthenticate:(XMPPStream *)sender { [self goOnline]; } // 认证失败 - (void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(NSXMLElement *)error { } - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq { return NO; } // 收到消息 - (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message { // A simple example of inbound message handling. if ([message isChatMessageWithBody]){ XMPPUserCoreDataStorageObject *user = [xmppRosterStorage userForJID:[message from] xmppStream:xmppStream managedObjectContext:[self managedObjectContext_roster]]; NSString *body = [[message elementForName:@"body"] stringValue]; NSString *displayName = [user displayName]; if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive){ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:displayName message:body delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alertView show]; }else{ // We are not active, so use a local notification instead UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.alertAction = @"Ok"; localNotification.alertBody = [NSString stringWithFormat:@"From: %@\n\n%@",displayName,body]; [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification]; } } } // 收到好友上线下线,正在输入等一些消息 - (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)presence { DDLogVerbose(@"%@: %@ - %@", THIS_FILE, THIS_METHOD, [presence fromStr]); } // 收到错误消息 - (void)xmppStream:(XMPPStream *)sender didReceiveError:(id)error { DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD); } // 连接出错 - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error { DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD); if (!isXmppConnected) { DDLogError(@"Unable to connect to server. Check xmppStream.hostName"); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #pragma mark XMPPRosterDelegate //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // 收到花名册 - (void)xmppRoster:(XMPPRoster *)sender didReceiveBuddyRequest:(XMPPPresence *)presence { DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD); XMPPUserCoreDataStorageObject *user = [xmppRosterStorage userForJID:[presence from] xmppStream:xmppStream managedObjectContext:[self managedObjectContext_roster]]; NSString *displayName = [user displayName]; NSString *jidStrBare = [presence fromStr]; NSString *body = nil; if (![displayName isEqualToString:jidStrBare]){ body = [NSString stringWithFormat:@"Buddy request from %@ <%@>", displayName, jidStrBare]; }else{ body = [NSString stringWithFormat:@"Buddy request from %@", displayName]; } if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive){ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:displayName message:body delegate:nil cancelButtonTitle:@"Not implemented" otherButtonTitles:nil]; [alertView show]; } else { // We are not active, so use a local notification instead UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.alertAction = @"Not implemented"; localNotification.alertBody = body; [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification]; } }
相关文章推荐
- XMPP聊天程序iPhone版开发(一):初识XMPPFramework
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端二)
- iPhone开发入门3 - 创建一个UITable View程序
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端一)
- [iPhone高级]基于XMPP的iOS聊天客户端程序(XMPP服务器架构)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端一)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端三)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端一)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端三)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端二)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端三)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端三)
- iPhone开发入门4 - 创建一个UITable View程序,不使用Interface Builder
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(XMPP服务器架构)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端一)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端三)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端三)
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端一)