您的位置:首页 > 其它

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];
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: