1
1
#import " XMPPRoster.h"
2
2
#import " XMPP.h"
3
+ #import " XMPPIDTracker.h"
3
4
#import " XMPPLogging.h"
4
5
#import " XMPPFramework.h"
5
6
#import " DDList.h"
@@ -88,7 +89,9 @@ - (BOOL)activate:(XMPPStream *)aXmppStream
88
89
89
90
if ([super activate: aXmppStream])
90
91
{
91
- XMPPLogVerbose (@" %@ : Activated" , THIS_FILE);
92
+ XMPPLogVerbose (@" %@ : Activated" , THIS_FILE);
93
+
94
+ xmppIDTracker = [[XMPPIDTracker alloc ] initWithDispatchQueue: moduleQueue];
92
95
93
96
#ifdef _XMPP_VCARD_AVATAR_MODULE_H
94
97
{
@@ -113,7 +116,7 @@ - (BOOL)activate:(XMPPStream *)aXmppStream
113
116
}];
114
117
}
115
118
#endif
116
-
119
+
117
120
return YES ;
118
121
}
119
122
@@ -123,6 +126,18 @@ - (BOOL)activate:(XMPPStream *)aXmppStream
123
126
- (void )deactivate
124
127
{
125
128
XMPPLogTrace ();
129
+
130
+ dispatch_block_t block = ^{ @autoreleasepool {
131
+
132
+ [xmppIDTracker removeAllIDs ];
133
+ xmppIDTracker = nil ;
134
+
135
+ }};
136
+
137
+ if (dispatch_get_specific (moduleQueueTag))
138
+ block ();
139
+ else
140
+ dispatch_sync (moduleQueue, block);
126
141
127
142
#ifdef _XMPP_VCARD_AVATAR_MODULE_H
128
143
{
@@ -371,6 +386,28 @@ - (void)_setPopulatingRoster:(BOOL)flag
371
386
else
372
387
flags &= ~kPopulatingRoster ;
373
388
}
389
+
390
+ - (void )_addRosterItems : (NSArray *)rosterItems
391
+ {
392
+ NSAssert (dispatch_get_specific(moduleQueueTag) , @"Invoked on incorrect queue");
393
+
394
+ BOOL hasRoster = [self _hasRoster ];
395
+
396
+ for (NSXMLElement *item in rosterItems)
397
+ {
398
+ // During roster population, we need to filter out items for users who aren't actually in our roster.
399
+ // That is, those users who have requested to be our buddy, but we haven't approved yet.
400
+ // This is described in more detail in the method isRosterItem above.
401
+
402
+ [multicastDelegate xmppRoster: self didReceiveRosterItem: item];
403
+
404
+ if (hasRoster || [self isRosterItem: item])
405
+ {
406
+ [xmppRosterStorage handleRosterItem: item xmppStream: xmppStream];
407
+ }
408
+ }
409
+ }
410
+
374
411
/* *
375
412
* Some server's include in our roster the JID's of user's NOT in our roster.
376
413
* This happens when another user adds us to their roster, and requests permission to receive our presence.
@@ -652,9 +689,13 @@ - (void)fetchRoster
652
689
653
690
NSXMLElement *query = [NSXMLElement elementWithName: @" query" xmlns: @" jabber:iq:roster" ];
654
691
655
- NSXMLElement *iq = [NSXMLElement elementWithName: @" iq" ];
656
- [iq addAttributeWithName: @" type" stringValue: @" get" ];
692
+ XMPPIQ *iq = [XMPPIQ iqWithType: @" get" elementID: [xmppStream generateUUID ]];
657
693
[iq addChild: query];
694
+
695
+ [xmppIDTracker addElement: iq
696
+ target: self
697
+ selector: @selector (handleFetchRosterQueryIQ:withInfo: )
698
+ timeout: 60 ];
658
699
659
700
[xmppStream sendElement: iq];
660
701
@@ -668,38 +709,14 @@ - (void)fetchRoster
668
709
}
669
710
670
711
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
671
- #pragma mark XMPPStream Delegate
712
+ #pragma mark XMPPIDTracker
672
713
// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
673
714
674
- - (void )xmppStreamDidAuthenticate : (XMPPStream *)sender
675
- {
676
- // This method is invoked on the moduleQueue.
677
-
678
- XMPPLogTrace ();
679
-
680
- if ([self autoFetchRoster ])
681
- {
682
- [self fetchRoster ];
683
- }
684
- }
685
-
686
- - (BOOL )xmppStream : (XMPPStream *)sender didReceiveIQ : (XMPPIQ *)iq
687
- {
688
- // This method is invoked on the moduleQueue.
689
-
690
- XMPPLogTrace ();
691
-
692
- // Note: Some jabber servers send an iq element with an xmlns.
693
- // Because of the bug in Apple's NSXML (documented in our elementForName method),
694
- // it is important we specify the xmlns for the query.
695
-
696
- NSXMLElement *query = [iq elementForName: @" query" xmlns: @" jabber:iq:roster" ];
697
- if (query)
698
- {
699
- if ([iq isSetIQ ])
700
- {
701
- [multicastDelegate xmppRoster: self didReceiveRosterPush: iq];
702
- }
715
+ - (void )handleFetchRosterQueryIQ : (XMPPIQ *)iq withInfo : (XMPPBasicTrackingInfo *)basicTrackingInfo {
716
+
717
+ dispatch_block_t block = ^{ @autoreleasepool {
718
+
719
+ NSXMLElement *query = [iq elementForName: @" query" xmlns: @" jabber:iq:roster" ];
703
720
704
721
BOOL hasRoster = [self _hasRoster ];
705
722
@@ -712,19 +729,7 @@ - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
712
729
}
713
730
714
731
NSArray *items = [query elementsForName: @" item" ];
715
- for (NSXMLElement *item in items)
716
- {
717
- // During roster population, we need to filter out items for users who aren't actually in our roster.
718
- // That is, those users who have requested to be our buddy, but we haven't approved yet.
719
- // This is described in more detail in the method isRosterItem above.
720
-
721
- [multicastDelegate xmppRoster: self didReceiveRosterItem: item];
722
-
723
- if (hasRoster || [self isRosterItem: item])
724
- {
725
- [xmppRosterStorage handleRosterItem: item xmppStream: xmppStream];
726
- }
727
- }
732
+ [self _addRosterItems: items];
728
733
729
734
if (!hasRoster)
730
735
{
@@ -741,8 +746,60 @@ - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
741
746
{
742
747
[self xmppStream: xmppStream didReceivePresence: presence];
743
748
}
749
+
744
750
[earlyPresenceElements removeAllObjects ];
745
751
}
752
+
753
+ }};
754
+
755
+ if (dispatch_get_specific (moduleQueueTag))
756
+ block ();
757
+ else
758
+ dispatch_async (moduleQueue, block);
759
+
760
+ }
761
+
762
+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
763
+ #pragma mark XMPPStream Delegate
764
+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
765
+
766
+ - (void )xmppStreamDidAuthenticate : (XMPPStream *)sender
767
+ {
768
+ // This method is invoked on the moduleQueue.
769
+
770
+ XMPPLogTrace ();
771
+
772
+ if ([self autoFetchRoster ])
773
+ {
774
+ [self fetchRoster ];
775
+ }
776
+ }
777
+
778
+ - (BOOL )xmppStream : (XMPPStream *)sender didReceiveIQ : (XMPPIQ *)iq
779
+ {
780
+ // This method is invoked on the moduleQueue.
781
+
782
+ XMPPLogTrace ();
783
+
784
+ // Note: Some jabber servers send an iq element with an xmlns.
785
+ // Because of the bug in Apple's NSXML (documented in our elementForName method),
786
+ // it is important we specify the xmlns for the query.
787
+
788
+ NSXMLElement *query = [iq elementForName: @" query" xmlns: @" jabber:iq:roster" ];
789
+
790
+ if (query)
791
+ {
792
+ if ([iq isSetIQ ])
793
+ {
794
+ [multicastDelegate xmppRoster: self didReceiveRosterPush: iq];
795
+
796
+ NSArray *items = [query elementsForName: @" item" ];
797
+ [self _addRosterItems: items];
798
+ }
799
+ else if ([iq isResultIQ ])
800
+ {
801
+ [xmppIDTracker invokeForID: [iq elementID ] withObject: iq];
802
+ }
746
803
747
804
return YES ;
748
805
}
0 commit comments