Skip to content

Commit bcaae05

Browse files
committed
XMPPRoster autoClearAllUsersAndResources API
Fixes robbiehanson#238 Fixes an Issue where deleting a resource wouldn't update a User's primary resource
1 parent 68386d6 commit bcaae05

File tree

5 files changed

+70
-23
lines changed

5 files changed

+70
-23
lines changed

Extensions/Roster/CoreDataStorage/XMPPRosterCoreDataStorage.m

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ - (void)commonInit
4848
[super commonInit];
4949

5050
// This method is invoked by all public init methods of the superclass
51+
autoRemovePreviousDatabaseFile = YES;
5152
autoRecreateDatabaseFile = YES;
5253

5354
rosterPopulationSet = [[NSMutableSet alloc] init];
@@ -119,8 +120,10 @@ - (void)_clearAllResourcesForXMPPStream:(XMPPStream *)stream
119120

120121
for (XMPPResourceCoreDataStorageObject *resource in allResources)
121122
{
123+
XMPPUserCoreDataStorageObject *user = resource.user;
122124
[moc deleteObject:resource];
123-
125+
[user recalculatePrimaryResource];
126+
124127
if (++unsavedCount >= saveThreshold)
125128
{
126129
[self save];
@@ -133,24 +136,6 @@ - (void)_clearAllResourcesForXMPPStream:(XMPPStream *)stream
133136
#pragma mark Overrides
134137
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
135138

136-
- (void)willCreatePersistentStoreWithPath:(NSString *)filePath options:(NSDictionary *)theStoreOptions
137-
{
138-
// This method is overriden from the XMPPCoreDataStore superclass.
139-
// From the documentation:
140-
//
141-
// Override me, if needed, to provide customized behavior.
142-
//
143-
// For example, if you are using the database for pure non-persistent data you may want to delete the database
144-
// file if it already exists on disk.
145-
//
146-
// The default implementation does nothing.
147-
148-
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
149-
{
150-
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
151-
}
152-
}
153-
154139
- (void)didCreateManagedObjectContext
155140
{
156141
// This method is overriden from the XMPPCoreDataStore superclass.

Extensions/Roster/CoreDataStorage/XMPPUserCoreDataStorageObject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151

5252
- (void)updateWithItem:(NSXMLElement *)item;
5353
- (void)updateWithPresence:(XMPPPresence *)presence streamBareJidStr:(NSString *)streamBareJidStr;
54+
- (void)recalculatePrimaryResource;
5455

5556
- (NSComparisonResult)compareByName:(XMPPUserCoreDataStorageObject *)another;
5657
- (NSComparisonResult)compareByName:(XMPPUserCoreDataStorageObject *)another options:(NSStringCompareOptions)mask;

Extensions/Roster/CoreDataStorage/XMPPUserCoreDataStorageObject.m

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,17 @@ - (BOOL)isPendingApproval
383383

384384
- (NSArray *)allResources
385385
{
386-
return [[self resources] allObjects];
386+
NSMutableArray *allResources = [NSMutableArray array];
387+
388+
for (XMPPResourceCoreDataStorageObject *resource in [[self resources] allObjects]) {
389+
390+
if(![resource isDeleted])
391+
{
392+
[allResources addObject:resource];
393+
}
394+
}
395+
396+
return allResources;
387397
}
388398

389399
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Extensions/Roster/XMPPRoster.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@
7777
**/
7878
@property (assign) BOOL autoFetchRoster;
7979

80+
/**
81+
* Whether or not to automatically clear all Users and Resources when the stream disconnects.
82+
* If you are using XMPPRosterCoreDataStorage you may want to set autoRemovePreviousDatabaseFile to NO.
83+
*
84+
* All Users and Resources will be cleared when the roster is next populated regardless of this property.
85+
*
86+
* The default value is YES.
87+
**/
88+
@property (assign) BOOL autoClearAllUsersAndResources;
89+
8090
/**
8191
* In traditional IM applications, the "buddy" system is rather straightforward.
8292
* User A sends a request to become "friends" with user B.

Extensions/Roster/XMPPRoster.m

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
kAutoFetchRoster = 1 << 0, // If set, we automatically fetch roster after authentication
2222
kAutoAcceptKnownPresenceSubscriptionRequests = 1 << 1, // See big description in header file... :D
2323
kRosterlessOperation = 1 << 2,
24+
kAutoClearAllUsersAndResources = 1 << 3,
2425
};
2526
enum XMPPRosterFlags
2627
{
@@ -71,7 +72,7 @@ - (id)initWithRosterStorage:(id <XMPPRosterStorage>)storage dispatchQueue:(dispa
7172
XMPPLogError(@"%@: %@ - Unable to configure storage!", THIS_FILE, THIS_METHOD);
7273
}
7374

74-
config = kAutoFetchRoster | kAutoAcceptKnownPresenceSubscriptionRequests;
75+
config = kAutoFetchRoster | kAutoAcceptKnownPresenceSubscriptionRequests | kAutoClearAllUsersAndResources;
7576
flags = 0;
7677

7778
earlyPresenceElements = [[NSMutableArray alloc] initWithCapacity:2];
@@ -112,7 +113,7 @@ - (BOOL)activate:(XMPPStream *)aXmppStream
112113
}];
113114
}
114115
#endif
115-
116+
116117
return YES;
117118
}
118119

@@ -188,6 +189,38 @@ - (void)setAutoFetchRoster:(BOOL)flag
188189
dispatch_async(moduleQueue, block);
189190
}
190191

192+
- (BOOL)autoClearAllUsersAndResources
193+
{
194+
__block BOOL result = NO;
195+
196+
dispatch_block_t block = ^{
197+
result = (config & kAutoClearAllUsersAndResources) ? YES : NO;
198+
};
199+
200+
if (dispatch_get_specific(moduleQueueTag))
201+
block();
202+
else
203+
dispatch_sync(moduleQueue, block);
204+
205+
return result;
206+
}
207+
208+
- (void)setAutoClearAllUsersAndResources:(BOOL)flag
209+
{
210+
dispatch_block_t block = ^{
211+
212+
if (flag)
213+
config |= kAutoClearAllUsersAndResources;
214+
else
215+
config &= ~kAutoClearAllUsersAndResources;
216+
};
217+
218+
if (dispatch_get_specific(moduleQueueTag))
219+
block();
220+
else
221+
dispatch_async(moduleQueue, block);
222+
}
223+
191224
- (BOOL)autoAcceptKnownPresenceSubscriptionRequests
192225
{
193226
__block BOOL result = NO;
@@ -672,6 +705,7 @@ - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
672705

673706
if (!hasRoster)
674707
{
708+
[xmppRosterStorage clearAllUsersAndResourcesForXMPPStream:xmppStream];
675709
[self _setPopulatingRoster:YES];
676710
[multicastDelegate xmppRosterDidBeginPopulating:self];
677711
[xmppRosterStorage beginRosterPopulationForXMPPStream:xmppStream];
@@ -823,7 +857,14 @@ - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
823857

824858
XMPPLogTrace();
825859

826-
[xmppRosterStorage clearAllUsersAndResourcesForXMPPStream:xmppStream];
860+
if([self autoClearAllUsersAndResources])
861+
{
862+
[xmppRosterStorage clearAllUsersAndResourcesForXMPPStream:xmppStream];
863+
}
864+
else
865+
{
866+
[xmppRosterStorage clearAllResourcesForXMPPStream:xmppStream];
867+
}
827868

828869
[self _setRequestedRoster:NO];
829870
[self _setHasRoster:NO];

0 commit comments

Comments
 (0)