Index: src/XMPPJSONFileStorage.m ================================================================== --- src/XMPPJSONFileStorage.m +++ src/XMPPJSONFileStorage.m @@ -37,11 +37,12 @@ @implementation XMPPJSONFileStorage - init { Class c = isa; [self release]; - @throw [OFNotImplementedException exceptionWithClass: c]; + @throw [OFNotImplementedException exceptionWithClass: c + selector: _cmd]; } - initWithFile: (OFString*)file_ { self = [super init]; @@ -101,12 +102,15 @@ } iter = iter2; } - [iter setObject: object - forKey: [pathComponents lastObject]]; + if (object != nil) + [iter setObject: object + forKey: [pathComponents lastObject]]; + else + [iter removeObjectForKey: [pathComponents lastObject]]; } - (id)XMPP_objectForPath: (OFString*)path { OFArray *pathComponents = [path componentsSeparatedByString: @"."]; Index: src/XMPPRoster.m ================================================================== --- src/XMPPRoster.m +++ src/XMPPRoster.m @@ -131,10 +131,11 @@ if ([connection supportsRosterVersioning]) { OFString *ver = [[rosterElement attributeForName: @"ver"] stringValue]; [dataStorage setStringValue: ver forPath: @"roster.ver"]; + [dataStorage save]; } [delegates broadcastSelector: @selector( roster:didReceiveRosterItem:) withObject: self @@ -226,10 +227,13 @@ { if ([connection supportsRosterVersioning]) { OFMutableDictionary *items = [[[dataStorage dictionaryForPath: @"roster.items"] mutableCopy] autorelease]; + if (items == nil) + items = [OFMutableDictionary dictionary]; + if (![[rosterItem subscription] isEqual: @"remove"]) { OFMutableDictionary *item = [OFMutableDictionary dictionaryWithKeysAndObjects: @"JID", [[rosterItem JID] bareJID], @"subscription", [rosterItem subscription], @@ -340,10 +344,11 @@ if ([connection supportsRosterVersioning]) { OFString *ver = [[rosterElement attributeForName: @"ver"] stringValue]; [dataStorage setStringValue: ver forPath: @"roster.ver"]; + [dataStorage save]; } [delegates broadcastSelector: @selector(rosterWasReceived:) withObject: self]; } Index: tests/test.m ================================================================== --- tests/test.m +++ tests/test.m @@ -30,10 +30,11 @@ #import "XMPPStanza.h" #import "XMPPIQ.h" #import "XMPPMessage.h" #import "XMPPPresence.h" #import "XMPPRoster.h" +#import "XMPPJSONFileStorage.h" @interface AppDelegate: OFObject #ifdef OF_HAVE_OPTIONAL_PROTOCOLS #endif @@ -90,14 +91,19 @@ assert([[elem XMLString] isEqual: [stanza XMLString]]); assert(([[OFString stringWithFormat: @"%@, %@, %@, %@", [[stanza from] fullJID], [[stanza to] fullJID], [stanza type], [stanza ID]] isEqual: @"bob@localhost, alice@localhost, get, 42"])); - conn = [[XMPPConnection alloc] init]; - roster = [[XMPPRoster alloc] initWithConnection: conn]; + conn = [[XMPPConnection alloc] init]; [conn addDelegate: self]; + + XMPPJSONFileStorage *storage = + [[XMPPJSONFileStorage alloc] initWithFile: @"storage.json"]; + [conn setDataStorage: storage]; + + roster = [[XMPPRoster alloc] initWithConnection: conn]; [roster addDelegate: self]; if ([arguments count] != 3) { of_log(@"Invalid count of command line arguments!"); [OFApplication terminateWithStatus: 1];