Decouple XMPPRoster and XMPPConnection
This commit is contained in:
parent
7fb28f25c8
commit
0815f46784
5 changed files with 178 additions and 140 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2011, 2012, Jonathan Schleifer <js@webkeks.org>
|
* Copyright (c) 2010, 2011, 2012, Jonathan Schleifer <js@webkeks.org>
|
||||||
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
|
* Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de>
|
||||||
*
|
*
|
||||||
* https://webkeks.org/hg/objxmpp/
|
* https://webkeks.org/hg/objxmpp/
|
||||||
*
|
*
|
||||||
|
@ -29,8 +29,6 @@
|
||||||
@class XMPPMessage;
|
@class XMPPMessage;
|
||||||
@class XMPPPresence;
|
@class XMPPPresence;
|
||||||
@class XMPPAuthenticator;
|
@class XMPPAuthenticator;
|
||||||
@class XMPPRoster;
|
|
||||||
@class XMPPRosterItem;
|
|
||||||
@class SSLSocket;
|
@class SSLSocket;
|
||||||
@class XMPPMulticastDelegate;
|
@class XMPPMulticastDelegate;
|
||||||
|
|
||||||
|
@ -48,15 +46,12 @@
|
||||||
- (void)connectionWasAuthenticated: (XMPPConnection*)connection;
|
- (void)connectionWasAuthenticated: (XMPPConnection*)connection;
|
||||||
- (void)connection: (XMPPConnection*)connection
|
- (void)connection: (XMPPConnection*)connection
|
||||||
wasBoundToJID: (XMPPJID*)JID;
|
wasBoundToJID: (XMPPJID*)JID;
|
||||||
- (void)connectionDidReceiveRoster: (XMPPConnection*)connection;
|
|
||||||
- (BOOL)connection: (XMPPConnection*)connection
|
- (BOOL)connection: (XMPPConnection*)connection
|
||||||
didReceiveIQ: (XMPPIQ*)iq;
|
didReceiveIQ: (XMPPIQ*)iq;
|
||||||
- (void)connection: (XMPPConnection*)connection
|
- (void)connection: (XMPPConnection*)connection
|
||||||
didReceivePresence: (XMPPPresence*)presence;
|
didReceivePresence: (XMPPPresence*)presence;
|
||||||
- (void)connection: (XMPPConnection*)connection
|
- (void)connection: (XMPPConnection*)connection
|
||||||
didReceiveMessage: (XMPPMessage*)message;
|
didReceiveMessage: (XMPPMessage*)message;
|
||||||
- (void)connection: (XMPPConnection*)connection
|
|
||||||
didReceiveRosterItem: (XMPPRosterItem*)rosterItem;
|
|
||||||
- (void)connectionWasClosed: (XMPPConnection*)connection;
|
- (void)connectionWasClosed: (XMPPConnection*)connection;
|
||||||
- (void)connectionWillUpgradeToTLS: (XMPPConnection*)connection;
|
- (void)connectionWillUpgradeToTLS: (XMPPConnection*)connection;
|
||||||
- (void)connectionDidUpgradeToTLS: (XMPPConnection*)connection;
|
- (void)connectionDidUpgradeToTLS: (XMPPConnection*)connection;
|
||||||
|
@ -85,7 +80,6 @@
|
||||||
BOOL needsSession;
|
BOOL needsSession;
|
||||||
BOOL encryptionRequired, encrypted;
|
BOOL encryptionRequired, encrypted;
|
||||||
unsigned int lastID;
|
unsigned int lastID;
|
||||||
XMPPRoster *roster;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OF_HAVE_PROPERTIES
|
#ifdef OF_HAVE_PROPERTIES
|
||||||
|
@ -93,7 +87,6 @@
|
||||||
@property (copy) OFString *privateKeyFile, *certificateFile;
|
@property (copy) OFString *privateKeyFile, *certificateFile;
|
||||||
@property (copy, readonly) XMPPJID *JID;
|
@property (copy, readonly) XMPPJID *JID;
|
||||||
@property (assign) uint16_t port;
|
@property (assign) uint16_t port;
|
||||||
@property (readonly, retain) XMPPRoster *roster;
|
|
||||||
@property (readonly, retain, getter=socket) OFTCPSocket *sock;
|
@property (readonly, retain, getter=socket) OFTCPSocket *sock;
|
||||||
@property (assign) BOOL encryptionRequired;
|
@property (assign) BOOL encryptionRequired;
|
||||||
@property (readonly) BOOL encrypted;
|
@property (readonly) BOOL encrypted;
|
||||||
|
@ -222,7 +215,6 @@
|
||||||
- (XMPPJID*)JID;
|
- (XMPPJID*)JID;
|
||||||
- (void)setPort: (uint16_t)port;
|
- (void)setPort: (uint16_t)port;
|
||||||
- (uint16_t)port;
|
- (uint16_t)port;
|
||||||
- (XMPPRoster*)roster;
|
|
||||||
|
|
||||||
- (void)XMPP_startStream;
|
- (void)XMPP_startStream;
|
||||||
- (void)XMPP_handleStream: (OFXMLElement*)element;
|
- (void)XMPP_handleStream: (OFXMLElement*)element;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2011, 2012, Jonathan Schleifer <js@webkeks.org>
|
* Copyright (c) 2010, 2011, 2012, Jonathan Schleifer <js@webkeks.org>
|
||||||
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
|
* Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de>
|
||||||
*
|
*
|
||||||
* https://webkeks.org/hg/objxmpp/
|
* https://webkeks.org/hg/objxmpp/
|
||||||
*
|
*
|
||||||
|
@ -47,8 +47,6 @@
|
||||||
#import "XMPPIQ.h"
|
#import "XMPPIQ.h"
|
||||||
#import "XMPPMessage.h"
|
#import "XMPPMessage.h"
|
||||||
#import "XMPPPresence.h"
|
#import "XMPPPresence.h"
|
||||||
#import "XMPPRoster.h"
|
|
||||||
#import "XMPPRosterItem.h"
|
|
||||||
#import "XMPPMulticastDelegate.h"
|
#import "XMPPMulticastDelegate.h"
|
||||||
#import "XMPPExceptions.h"
|
#import "XMPPExceptions.h"
|
||||||
#import "namespaces.h"
|
#import "namespaces.h"
|
||||||
|
@ -94,7 +92,6 @@
|
||||||
[delegates release];
|
[delegates release];
|
||||||
[callbacks release];
|
[callbacks release];
|
||||||
[authModule release];
|
[authModule release];
|
||||||
[roster release];
|
|
||||||
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
@ -533,16 +530,12 @@
|
||||||
oldParser = parser;
|
oldParser = parser;
|
||||||
oldElementBuilder = elementBuilder;
|
oldElementBuilder = elementBuilder;
|
||||||
|
|
||||||
[roster release];
|
|
||||||
|
|
||||||
parser = [[OFXMLParser alloc] init];
|
parser = [[OFXMLParser alloc] init];
|
||||||
[parser setDelegate: self];
|
[parser setDelegate: self];
|
||||||
|
|
||||||
elementBuilder = [[OFXMLElementBuilder alloc] init];
|
elementBuilder = [[OFXMLElementBuilder alloc] init];
|
||||||
[elementBuilder setDelegate: self];
|
[elementBuilder setDelegate: self];
|
||||||
|
|
||||||
roster = [[XMPPRoster alloc] initWithConnection: self];
|
|
||||||
|
|
||||||
[sock writeFormat: @"<?xml version='1.0'?>\n"
|
[sock writeFormat: @"<?xml version='1.0'?>\n"
|
||||||
@"<stream:stream to='%@' "
|
@"<stream:stream to='%@' "
|
||||||
@"xmlns='" XMPP_NS_CLIENT @"' "
|
@"xmlns='" XMPP_NS_CLIENT @"' "
|
||||||
|
@ -782,11 +775,6 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([iq elementForName: @"query"
|
|
||||||
namespace: XMPP_NS_ROSTER])
|
|
||||||
if ([roster handleIQ: iq])
|
|
||||||
return;
|
|
||||||
|
|
||||||
handled = [delegates broadcastSelector: @selector(
|
handled = [delegates broadcastSelector: @selector(
|
||||||
connection:didReceiveIQ:)
|
connection:didReceiveIQ:)
|
||||||
forConnection: self
|
forConnection: self
|
||||||
|
@ -1059,11 +1047,6 @@
|
||||||
{
|
{
|
||||||
return delegates;
|
return delegates;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (XMPPRoster*)roster
|
|
||||||
{
|
|
||||||
return [[roster retain] autorelease];
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation OFObject (XMPPConnectionDelegate)
|
@implementation OFObject (XMPPConnectionDelegate)
|
||||||
|
@ -1086,10 +1069,6 @@
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)connectionDidReceiveRoster: (XMPPConnection*)connection
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)connection: (XMPPConnection*)connection
|
- (BOOL)connection: (XMPPConnection*)connection
|
||||||
didReceiveIQ: (XMPPIQ*)iq
|
didReceiveIQ: (XMPPIQ*)iq
|
||||||
{
|
{
|
||||||
|
@ -1106,11 +1085,6 @@
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)connection: (XMPPConnection*)connection
|
|
||||||
didReceiveRosterItem: (XMPPRosterItem*)rosterItem
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)connectionWasClosed: (XMPPConnection*)connection
|
- (void)connectionWasClosed: (XMPPConnection*)connection
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org>
|
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org>
|
||||||
|
* Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
|
||||||
*
|
*
|
||||||
* https://webkeks.org/hg/objxmpp/
|
* https://webkeks.org/hg/objxmpp/
|
||||||
*
|
*
|
||||||
|
@ -22,25 +23,53 @@
|
||||||
|
|
||||||
#import <ObjFW/ObjFW.h>
|
#import <ObjFW/ObjFW.h>
|
||||||
|
|
||||||
@class XMPPConnection;
|
#import "XMPPConnection.h"
|
||||||
|
|
||||||
@class XMPPRosterItem;
|
@class XMPPRosterItem;
|
||||||
@class XMPPIQ;
|
@class XMPPIQ;
|
||||||
|
@class XMPPRoster;
|
||||||
|
|
||||||
|
@protocol XMPPRosterDelegate
|
||||||
|
#ifndef XMPP_ROSTER_M
|
||||||
|
<OFObject>
|
||||||
|
#endif
|
||||||
|
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
|
||||||
|
@optional
|
||||||
|
#endif
|
||||||
|
- (void)rosterWasReceived: (XMPPRoster*)roster;
|
||||||
|
- (void)roster: (XMPPRoster*)roster
|
||||||
|
didReceiveRosterItem: (XMPPRosterItem*)rosterItem;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
@interface XMPPRoster: OFObject
|
@interface XMPPRoster: OFObject
|
||||||
|
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
|
||||||
|
<XMPPConnectionDelegate>
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
XMPPConnection *connection;
|
XMPPConnection *connection;
|
||||||
OFMutableDictionary *rosterItems;
|
OFMutableDictionary *rosterItems;
|
||||||
OFString *rosterID;
|
id <XMPPRosterDelegate, OFObject> delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OF_HAVE_PROPERTIES
|
||||||
|
@property (assign) id <XMPPRosterDelegate> delegate;
|
||||||
|
#endif
|
||||||
|
|
||||||
- initWithConnection: (XMPPConnection*)conn;
|
- initWithConnection: (XMPPConnection*)conn;
|
||||||
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem;
|
|
||||||
- (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem;
|
|
||||||
- (void)XMPP_deleteRosterItem: (XMPPRosterItem*)rosterItem;
|
|
||||||
- (OFDictionary*)rosterItems;
|
- (OFDictionary*)rosterItems;
|
||||||
- (BOOL)handleIQ: (XMPPIQ*)iq;
|
|
||||||
- (void)requestRoster;
|
- (void)requestRoster;
|
||||||
- (void)addRosterItem: (XMPPRosterItem*)rosterItem;
|
- (void)addRosterItem: (XMPPRosterItem*)rosterItem;
|
||||||
- (void)updateRosterItem: (XMPPRosterItem*)rosterItem;
|
- (void)updateRosterItem: (XMPPRosterItem*)rosterItem;
|
||||||
- (void)deleteRosterItem: (XMPPRosterItem*)rosterItem;
|
- (void)deleteRosterItem: (XMPPRosterItem*)rosterItem;
|
||||||
|
- (void)setDelegate: (id <XMPPRosterDelegate>)delegate;
|
||||||
|
- (id <XMPPRosterDelegate>)delegate;
|
||||||
|
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem;
|
||||||
|
- (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem;
|
||||||
|
- (void)XMPP_deleteRosterItem: (XMPPRosterItem*)rosterItem;
|
||||||
|
- (void)XMPP_handleInitialRoster: (XMPPIQ*)iq;
|
||||||
|
- (XMPPRosterItem*)XMPP_rosterItemWithXMLElement: (OFXMLElement*)element;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface OFObject (XMPPRosterDelegate) <XMPPRosterDelegate>
|
||||||
@end
|
@end
|
||||||
|
|
211
src/XMPPRoster.m
211
src/XMPPRoster.m
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org>
|
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org>
|
||||||
|
* Copyright (c) 2012, Florian Zeitz <florob@babelmonkeys.de>
|
||||||
*
|
*
|
||||||
* https://webkeks.org/hg/objxmpp/
|
* https://webkeks.org/hg/objxmpp/
|
||||||
*
|
*
|
||||||
|
@ -24,6 +25,8 @@
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define XMPP_ROSTER_M
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#import "XMPPRoster.h"
|
#import "XMPPRoster.h"
|
||||||
|
@ -35,12 +38,14 @@
|
||||||
#import "namespaces.h"
|
#import "namespaces.h"
|
||||||
|
|
||||||
@implementation XMPPRoster
|
@implementation XMPPRoster
|
||||||
- initWithConnection: (XMPPConnection*)conn
|
- initWithConnection: (XMPPConnection*)connection_
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
|
||||||
@try {
|
@try {
|
||||||
rosterItems = [[OFMutableDictionary alloc] init];
|
rosterItems = [[OFMutableDictionary alloc] init];
|
||||||
|
connection = connection_;
|
||||||
|
[connection addDelegate: self];
|
||||||
} @catch (id e) {
|
} @catch (id e) {
|
||||||
[self release];
|
[self release];
|
||||||
@throw e;
|
@throw e;
|
||||||
|
@ -52,26 +57,10 @@
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
[rosterItems release];
|
[rosterItems release];
|
||||||
[rosterID release];
|
|
||||||
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem
|
|
||||||
{
|
|
||||||
return [self XMPP_updateRosterItem: rosterItem];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem
|
|
||||||
{
|
|
||||||
[rosterItems setObject: rosterItem
|
|
||||||
forKey: [[rosterItem JID] bareJID]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)XMPP_deleteRosterItem: (XMPPRosterItem*)rosterItem
|
|
||||||
{
|
|
||||||
[rosterItems removeObjectForKey: [[rosterItem JID] bareJID]];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (OFDictionary*)rosterItems
|
- (OFDictionary*)rosterItems
|
||||||
{
|
{
|
||||||
|
@ -82,25 +71,21 @@
|
||||||
{
|
{
|
||||||
XMPPIQ *iq;
|
XMPPIQ *iq;
|
||||||
|
|
||||||
if (rosterID != nil)
|
|
||||||
assert(0);
|
|
||||||
|
|
||||||
rosterID = [[connection generateStanzaID] retain];
|
|
||||||
iq = [XMPPIQ IQWithType: @"get"
|
iq = [XMPPIQ IQWithType: @"get"
|
||||||
ID: rosterID];
|
ID: [connection generateStanzaID]];
|
||||||
[iq addChild: [OFXMLElement elementWithName: @"query"
|
[iq addChild: [OFXMLElement elementWithName: @"query"
|
||||||
namespace: XMPP_NS_ROSTER]];
|
namespace: XMPP_NS_ROSTER]];
|
||||||
[connection sendStanza: iq];
|
[connection sendIQ: iq
|
||||||
|
withCallbackObject: self
|
||||||
|
selector: @selector(XMPP_handleInitialRoster:)];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)handleIQ: (XMPPIQ*)iq
|
- (BOOL)connection: (XMPPConnection*)connection_
|
||||||
|
didReceiveIQ: (XMPPIQ*)iq
|
||||||
{
|
{
|
||||||
OFXMLElement *rosterElement;
|
OFXMLElement *rosterElement;
|
||||||
OFXMLElement *element;
|
OFXMLElement *element;
|
||||||
XMPPRosterItem *rosterItem = nil;
|
XMPPRosterItem *rosterItem;
|
||||||
OFString *subscription;
|
|
||||||
OFEnumerator *enumerator;
|
|
||||||
BOOL isPush = ![[iq ID] isEqual: rosterID];
|
|
||||||
|
|
||||||
rosterElement = [iq elementForName: @"query"
|
rosterElement = [iq elementForName: @"query"
|
||||||
namespace: XMPP_NS_ROSTER];
|
namespace: XMPP_NS_ROSTER];
|
||||||
|
@ -108,76 +93,27 @@
|
||||||
if (rosterElement == nil)
|
if (rosterElement == nil)
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
if (isPush) {
|
|
||||||
if (![[iq type] isEqual: @"set"])
|
if (![[iq type] isEqual: @"set"])
|
||||||
return NO;
|
return NO;
|
||||||
} else {
|
|
||||||
if (![[iq type] isEqual: @"result"])
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
enumerator = [[rosterElement children] objectEnumerator];
|
element = [rosterElement elementForName: @"item"
|
||||||
while ((element = [enumerator nextObject]) != nil) {
|
namespace: XMPP_NS_ROSTER];
|
||||||
OFMutableArray *groups = [OFMutableArray array];
|
|
||||||
OFEnumerator *groupEnumerator;
|
|
||||||
OFXMLElement *groupElement;
|
|
||||||
|
|
||||||
if (![[element name] isEqual: @"item"] ||
|
if (element != nil) {
|
||||||
![[element namespace] isEqual: XMPP_NS_ROSTER])
|
rosterItem = [self XMPP_rosterItemWithXMLElement: element];
|
||||||
continue;
|
|
||||||
|
|
||||||
rosterItem = [XMPPRosterItem rosterItem];
|
if ([[rosterItem subscription] isEqual: @"remove"])
|
||||||
[rosterItem setJID: [XMPPJID JIDWithString:
|
|
||||||
[[element attributeForName: @"jid"] stringValue]]];
|
|
||||||
[rosterItem setName:
|
|
||||||
[[element attributeForName: @"name"] stringValue]];
|
|
||||||
|
|
||||||
subscription = [[element attributeForName:
|
|
||||||
@"subscription"] stringValue];
|
|
||||||
|
|
||||||
if (![subscription isEqual: @"none"] &&
|
|
||||||
![subscription isEqual: @"to"] &&
|
|
||||||
![subscription isEqual: @"from"] &&
|
|
||||||
![subscription isEqual: @"both"] &&
|
|
||||||
(![subscription isEqual: @"remove"] || !isPush))
|
|
||||||
subscription = @"none";
|
|
||||||
|
|
||||||
[rosterItem setSubscription: subscription];
|
|
||||||
|
|
||||||
groupEnumerator = [[element
|
|
||||||
elementsForName: @"group"
|
|
||||||
namespace: XMPP_NS_ROSTER] objectEnumerator];
|
|
||||||
while ((groupElement = [groupEnumerator nextObject]) != nil)
|
|
||||||
[groups addObject: [groupElement stringValue]];
|
|
||||||
|
|
||||||
if ([groups count] > 0)
|
|
||||||
[rosterItem setGroups: groups];
|
|
||||||
|
|
||||||
if ([subscription isEqual: @"remove"])
|
|
||||||
[self XMPP_deleteRosterItem: rosterItem];
|
[self XMPP_deleteRosterItem: rosterItem];
|
||||||
else
|
else
|
||||||
[self XMPP_addRosterItem: rosterItem];
|
[self XMPP_addRosterItem: rosterItem];
|
||||||
|
|
||||||
if (isPush) {
|
if ([delegate respondsToSelector:
|
||||||
SEL sel = @selector(connection:didReceiveRosterItem:);
|
@selector(roster:didReceiveRosterItem:)])
|
||||||
|
[delegate roster: self
|
||||||
[[connection XMPP_delegates]
|
didReceiveRosterItem: rosterItem];
|
||||||
broadcastSelector: sel
|
|
||||||
forConnection: connection
|
|
||||||
withObject: rosterItem];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPush) {
|
[connection_ sendStanza: [iq resultIQ]];
|
||||||
[connection sendStanza: [iq resultIQ]];
|
|
||||||
} else {
|
|
||||||
[[connection XMPP_delegates]
|
|
||||||
broadcastSelector: @selector(connectionDidReceiveRoster:)
|
|
||||||
forConnection: connection];
|
|
||||||
|
|
||||||
[rosterID release];
|
|
||||||
rosterID = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
@ -235,4 +171,105 @@
|
||||||
|
|
||||||
[connection sendStanza: iq];
|
[connection sendStanza: iq];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setDelegate: (id <XMPPRosterDelegate>)delegate_
|
||||||
|
{
|
||||||
|
delegate = (id <XMPPRosterDelegate, OFObject>)delegate_;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id <XMPPRosterDelegate>)delegate
|
||||||
|
{
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem
|
||||||
|
{
|
||||||
|
return [self XMPP_updateRosterItem: rosterItem];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)XMPP_updateRosterItem: (XMPPRosterItem*)rosterItem
|
||||||
|
{
|
||||||
|
[rosterItems setObject: rosterItem
|
||||||
|
forKey: [[rosterItem JID] bareJID]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)XMPP_deleteRosterItem: (XMPPRosterItem*)rosterItem
|
||||||
|
{
|
||||||
|
[rosterItems removeObjectForKey: [[rosterItem JID] bareJID]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (XMPPRosterItem*)XMPP_rosterItemWithXMLElement: (OFXMLElement*)element
|
||||||
|
{
|
||||||
|
OFString *subscription;
|
||||||
|
OFEnumerator *groupEnumerator;
|
||||||
|
OFXMLElement *groupElement;
|
||||||
|
OFMutableArray *groups = [OFMutableArray array];
|
||||||
|
XMPPRosterItem *rosterItem = [XMPPRosterItem rosterItem];
|
||||||
|
[rosterItem setJID: [XMPPJID JIDWithString:
|
||||||
|
[[element attributeForName: @"jid"] stringValue]]];
|
||||||
|
[rosterItem setName:
|
||||||
|
[[element attributeForName: @"name"] stringValue]];
|
||||||
|
|
||||||
|
subscription = [[element attributeForName:
|
||||||
|
@"subscription"] stringValue];
|
||||||
|
|
||||||
|
if (![subscription isEqual: @"none"] &&
|
||||||
|
![subscription isEqual: @"to"] &&
|
||||||
|
![subscription isEqual: @"from"] &&
|
||||||
|
![subscription isEqual: @"both"] &&
|
||||||
|
![subscription isEqual: @"remove"])
|
||||||
|
subscription = @"none";
|
||||||
|
|
||||||
|
[rosterItem setSubscription: subscription];
|
||||||
|
|
||||||
|
groupEnumerator = [[element
|
||||||
|
elementsForName: @"group"
|
||||||
|
namespace: XMPP_NS_ROSTER] objectEnumerator];
|
||||||
|
while ((groupElement = [groupEnumerator nextObject]) != nil)
|
||||||
|
[groups addObject: [groupElement stringValue]];
|
||||||
|
|
||||||
|
if ([groups count] > 0)
|
||||||
|
[rosterItem setGroups: groups];
|
||||||
|
|
||||||
|
return rosterItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)XMPP_handleInitialRoster: (XMPPIQ*)iq
|
||||||
|
{
|
||||||
|
OFXMLElement *rosterElement;
|
||||||
|
OFEnumerator *enumerator;
|
||||||
|
OFXMLElement *element;
|
||||||
|
XMPPRosterItem *rosterItem = nil;
|
||||||
|
|
||||||
|
rosterElement = [iq elementForName: @"query"
|
||||||
|
namespace: XMPP_NS_ROSTER];
|
||||||
|
|
||||||
|
enumerator = [[rosterElement children] objectEnumerator];
|
||||||
|
while ((element = [enumerator nextObject]) != nil) {
|
||||||
|
if (![[element name] isEqual: @"item"] ||
|
||||||
|
![[element namespace] isEqual: XMPP_NS_ROSTER])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rosterItem = [self XMPP_rosterItemWithXMLElement: element];
|
||||||
|
|
||||||
|
if ([[rosterItem subscription] isEqual: @"remove"])
|
||||||
|
[self XMPP_deleteRosterItem: rosterItem];
|
||||||
|
else
|
||||||
|
[self XMPP_addRosterItem: rosterItem];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([delegate respondsToSelector: @selector(rosterWasReceived:)])
|
||||||
|
[delegate rosterWasReceived: self];
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation OFObject (XMPPRosterDelegate)
|
||||||
|
- (void)rosterWasReceived: (XMPPRoster*)roster
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)roster: (XMPPRoster*)roster
|
||||||
|
didReceiveRosterItem: (XMPPRosterItem*)rosterItem
|
||||||
|
{
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
24
tests/test.m
24
tests/test.m
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2011, Jonathan Schleifer <js@webkeks.org>
|
* Copyright (c) 2010, 2011, Jonathan Schleifer <js@webkeks.org>
|
||||||
* Copyright (c) 2011, Florian Zeitz <florob@babelmonkeys.de>
|
* Copyright (c) 2011, 2012, Florian Zeitz <florob@babelmonkeys.de>
|
||||||
*
|
*
|
||||||
* https://webkeks.org/hg/objxmpp/
|
* https://webkeks.org/hg/objxmpp/
|
||||||
*
|
*
|
||||||
|
@ -36,8 +36,12 @@
|
||||||
|
|
||||||
@interface AppDelegate: OFObject
|
@interface AppDelegate: OFObject
|
||||||
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
|
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
|
||||||
<OFApplicationDelegate, XMPPConnectionDelegate>
|
<OFApplicationDelegate, XMPPConnectionDelegate, XMPPRosterDelegate>
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
XMPPConnection * conn;
|
||||||
|
XMPPRoster *roster;
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
OF_APPLICATION_DELEGATE(AppDelegate)
|
OF_APPLICATION_DELEGATE(AppDelegate)
|
||||||
|
@ -45,7 +49,6 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
- (void)applicationDidFinishLaunching
|
- (void)applicationDidFinishLaunching
|
||||||
{
|
{
|
||||||
XMPPConnection *conn;
|
|
||||||
OFArray *arguments = [OFApplication arguments];
|
OFArray *arguments = [OFApplication arguments];
|
||||||
|
|
||||||
XMPPPresence *pres = [XMPPPresence presence];
|
XMPPPresence *pres = [XMPPPresence presence];
|
||||||
|
@ -91,7 +94,10 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
||||||
[stanza ID]] isEqual: @"bob@localhost, alice@localhost, get, 42"]));
|
[stanza ID]] isEqual: @"bob@localhost, alice@localhost, get, 42"]));
|
||||||
|
|
||||||
conn = [[XMPPConnection alloc] init];
|
conn = [[XMPPConnection alloc] init];
|
||||||
|
roster = [[XMPPRoster alloc] initWithConnection: conn];
|
||||||
|
|
||||||
[conn addDelegate: self];
|
[conn addDelegate: self];
|
||||||
|
[roster setDelegate: self];
|
||||||
|
|
||||||
if ([arguments count] != 3) {
|
if ([arguments count] != 3) {
|
||||||
of_log(@"Invalid count of command line arguments!");
|
of_log(@"Invalid count of command line arguments!");
|
||||||
|
@ -133,14 +139,14 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
||||||
{
|
{
|
||||||
of_log(@"Bound to JID: %@", [jid fullJID]);
|
of_log(@"Bound to JID: %@", [jid fullJID]);
|
||||||
|
|
||||||
[[conn roster] requestRoster];
|
[roster requestRoster];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)connectionDidReceiveRoster: (XMPPConnection*)conn
|
- (void)rosterWasReceived: (XMPPRoster*)roster_
|
||||||
{
|
{
|
||||||
XMPPPresence *pres;
|
XMPPPresence *pres;
|
||||||
|
|
||||||
of_log(@"Got roster: %@", [[conn roster] rosterItems]);
|
of_log(@"Got roster: %@", [roster_ rosterItems]);
|
||||||
|
|
||||||
pres = [XMPPPresence presence];
|
pres = [XMPPPresence presence];
|
||||||
[pres addPriority: 10];
|
[pres addPriority: 10];
|
||||||
|
@ -160,10 +166,10 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)connectionDidUpgradeToTLS: (XMPPConnection*)conn
|
- (void)connectionDidUpgradeToTLS: (XMPPConnection*)conn_
|
||||||
{
|
{
|
||||||
@try {
|
@try {
|
||||||
[conn checkCertificate];
|
[conn_ checkCertificate];
|
||||||
} @catch (SSLInvalidCertificateException *e) {
|
} @catch (SSLInvalidCertificateException *e) {
|
||||||
OFString *answer;
|
OFString *answer;
|
||||||
[of_stdout writeString: @"Couldn't verify certificate: "];
|
[of_stdout writeString: @"Couldn't verify certificate: "];
|
||||||
|
@ -175,7 +181,7 @@ OF_APPLICATION_DELEGATE(AppDelegate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)connection: (XMPPConnection*)conn
|
- (void)roster: (XMPPRoster*)roster_
|
||||||
didReceiveRosterItem: (XMPPRosterItem*)rosterItem
|
didReceiveRosterItem: (XMPPRosterItem*)rosterItem
|
||||||
{
|
{
|
||||||
of_log(@"Got roster push: %@", rosterItem);
|
of_log(@"Got roster push: %@", rosterItem);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue