NSHTTPCookieStorage notification troubles

  • My application needs to observe changes in the shared cookie storage
    so it can check if a certain one changed. I've added it as an observer
    to the notification with this:

    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(updateIDField)
    name:NSHTTPCookieManagerCookiesChangedNotification
    object:nil];

    When I delete a cookie from within my application, Safari gets the
    message, and with a refresh or two, it takes effect. However, when a
    cookie is added in Safari, it seems unreliable whether or not my
    application gets the notification. Does this have something to do with
    the suspensionBehavior of the observation, maybe?
  • On 2007 Dec, 22, at 21:47, Jacob Bandes-Storch wrote:

    > My application needs to observe changes in the shared cookie storage
    > so it can check if a certain one changed. I've added it as an
    > observer to the notification with this:
    >
    > [[NSNotificationCenter defaultCenter] addObserver:self
    > selector:@selector(updateIDField)
    > name:NSHTTPCookieManagerCookiesChangedNotification
    > object:nil];
    >
    > When I delete a cookie from within my application, Safari gets the
    > message, and with a refresh or two, it takes effect. However, when a
    > cookie is added in Safari, it seems unreliable whether or not my
    > application gets the notification. Does this have something to do
    > with the suspensionBehavior of the observation, maybe?

    I've had a similar problem.  I believe I found that when cookies are
    ^deleted^ in Safari, they are still available for other apps for up to
    five seconds.  I therefore implemented a ten second delay and this has
    seemed to work.

    I don't remember whether or not I played with the suspensionBehavior,
    but you might want to read the top three hits on this in the list
    archives for term NSHTTPCookieStorage:

    http://www.cocoabuilder.com/search/archive/cocoa?words=NSHTTPCookieStorage

    I was going to file this bug a few months ago, but it looks like it
    slipped through a crack.  If you do, please post the text and number
    of your bug report so that others, like me, can file their own bugs
    and reference it.

    I found the complete code from a little project that I used to test
    this.  If I recall correctly, it worked better if the observer was a
    Foundation tool instead of an application.  Run this tool, then log in
    and out of a Google account several times and watch what happens.

    Sorry my memory on this is a bit foggy.  Reply if you have any
    specific questions.

    #import <Foundation/Foundation.h>

    @interface CookieChecker : NSObject {
        BOOL _googleLoggedIn ;
    }

    @end

    @implementation CookieChecker

    - (void)cookieChomp:(NSNotification*)notification {
        NSHTTPCookieStorage* sharedCookieStorage = [NSHTTPCookieStorage
    sharedHTTPCookieStorage] ;
        NSArray* cookies = [sharedCookieStorage cookies] ;
        NSEnumerator* e = [cookies objectEnumerator] ;
        NSHTTPCookie* cookie ;
        BOOL gotGoogle = NO ;
        while ((cookie = [e nextObject])) {
            NSString* domain = [cookie domain] ;
            if ([domain hasSuffix:@"google.com"]) {
                if ([[cookie name] isEqualToString:@"LSID"]) {
                    gotGoogle = YES ;
                    break ;
                }
            }
        }

        if (gotGoogle) {
            NSLog(@"Notification: Google cookie APPEARED") ;
        }
        else {
            NSLog(@"Notification: Google cookie DIS-APPEARED") ;
        }
    }

    - (void)check:(NSTimer*)timer {
        NSHTTPCookieStorage* sharedCookieStorage = [NSHTTPCookieStorage
    sharedHTTPCookieStorage] ;
        NSArray* cookies = [sharedCookieStorage cookies] ;
        NSEnumerator* e = [cookies objectEnumerator] ;
        NSHTTPCookie* cookie ;
        BOOL gotGoogle = NO ;
        while ((cookie = [e nextObject])) {
            NSString* domain = [cookie domain] ;
            if ([domain hasSuffix:@"google.com"]) {
                if ([[cookie name] isEqualToString:@"LSID"]) {
                    gotGoogle = YES ;
                    break ;
                }
            }
        }
        if (gotGoogle != _googleLoggedIn) {
            if (gotGoogle) {
                NSLog(@"Polling: Google cookie APPEARED") ;
            }
            else {
                NSLog(@"Polling: Google cookie DIS-APPEARED") ;
            }
        }
        _googleLoggedIn = gotGoogle ;
    }

    @end

    int main (int argc, const char * argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

        // Same code:
        CookieChecker* checker = [[CookieChecker alloc] init] ;
        [NSTimer scheduledTimerWithTimeInterval:0.20
                                            target:checker
                                          selector:@selector(check:)
                                          userInfo:nil
                                        repeats:YES] ;

        [[NSNotificationCenter defaultCenter] addObserver:checker

    selector:@selector(cookieChomp:)

    name:NSHTTPCookieManagerCookiesChangedNotification
                                                      object:nil] ;

        [[NSRunLoop currentRunLoop] run] ;

        [pool release];

        return 0;
    }
  • Alright, so it works better in a Foundation Tool... is there a
    workaround for making it work correctly in a Cocoa application?

    > On 2007 Dec, 22, at 21:47, Jacob Bandes-Storch wrote:
    >
    >> My application needs to observe changes in the shared cookie storage
    >> so it can check if a certain one changed. I've added it as an
    >> observer to the notification with this:
    >>
    >> [[NSNotificationCenter defaultCenter] addObserver:self
    >> selector:@selector(updateIDField)
    >> name:NSHTTPCookieManagerCookiesChangedNotification
    >> object:nil];
    >>
    >> When I delete a cookie from within my application, Safari gets the
    >> message, and with a refresh or two, it takes effect. However, when a
    >> cookie is added in Safari, it seems unreliable whether or not my
    >> application gets the notification. Does this have something to do
    >> with the suspensionBehavior of the observation, maybe?
    >
    > I've had a similar problem.  I believe I found that when cookies are
    > ^deleted^ in Safari, they are still available for other apps for up to
    > five seconds.  I therefore implemented a ten second delay and this has
    > seemed to work.
    >
    > I don't remember whether or not I played with the suspensionBehavior,
    > but you might want to read the top three hits on this in the list
    > archives for term NSHTTPCookieStorage:
    >
    > http://www.cocoabuilder.com/search/archive/cocoa?words=NSHTTPCookieStorage
    >
    > I was going to file this bug a few months ago, but it looks like it
    > slipped through a crack.  If you do, please post the text and number
    > of your bug report so that others, like me, can file their own bugs
    > and reference it.
    >
    > I found the complete code from a little project that I used to test
    > this.  If I recall correctly, it worked better if the observer was a
    > Foundation tool instead of an application.  Run this tool, then log in
    > and out of a Google account several times and watch what happens.
    >
    > Sorry my memory on this is a bit foggy.  Reply if you have any
    > specific questions.
    >
    >
    > #import <Foundation/Foundation.h>
    >
    > @interface CookieChecker : NSObject {
    > BOOL _googleLoggedIn ;
    > }
    >
    > @end
    >
    > @implementation CookieChecker
    >
    > - (void)cookieChomp:(NSNotification*)notification {
    > NSHTTPCookieStorage* sharedCookieStorage = [NSHTTPCookieStorage
    > sharedHTTPCookieStorage] ;
    > NSArray* cookies = [sharedCookieStorage cookies] ;
    > NSEnumerator* e = [cookies objectEnumerator] ;
    > NSHTTPCookie* cookie ;
    > BOOL gotGoogle = NO ;
    > while ((cookie = [e nextObject])) {
    > NSString* domain = [cookie domain] ;
    > if ([domain hasSuffix:@"google.com"]) {
    > if ([[cookie name] isEqualToString:@"LSID"]) {
    > gotGoogle = YES ;
    > break ;
    > }
    > }
    > }
    >
    > if (gotGoogle) {
    > NSLog(@"Notification: Google cookie APPEARED") ;
    > }
    > else {
    > NSLog(@"Notification: Google cookie DIS-APPEARED") ;
    > }
    > }
    >
    > - (void)check:(NSTimer*)timer {
    > NSHTTPCookieStorage* sharedCookieStorage = [NSHTTPCookieStorage
    > sharedHTTPCookieStorage] ;
    > NSArray* cookies = [sharedCookieStorage cookies] ;
    > NSEnumerator* e = [cookies objectEnumerator] ;
    > NSHTTPCookie* cookie ;
    > BOOL gotGoogle = NO ;
    > while ((cookie = [e nextObject])) {
    > NSString* domain = [cookie domain] ;
    > if ([domain hasSuffix:@"google.com"]) {
    > if ([[cookie name] isEqualToString:@"LSID"]) {
    > gotGoogle = YES ;
    > break ;
    > }
    > }
    > }
    > if (gotGoogle != _googleLoggedIn) {
    > if (gotGoogle) {
    > NSLog(@"Polling: Google cookie APPEARED") ;
    > }
    > else {
    > NSLog(@"Polling: Google cookie DIS-APPEARED") ;
    > }
    > }
    > _googleLoggedIn = gotGoogle ;
    > }
    >
    > @end
    >
    >
    > int main (int argc, const char * argv[]) {
    > NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    >
    > // Same code:
    > CookieChecker* checker = [[CookieChecker alloc] init] ;
    > [NSTimer scheduledTimerWithTimeInterval:0.20
    > target:checker
    > selector:@selector(check:)
    > userInfo:nil
    > repeats:YES] ;
    >
    > [[NSNotificationCenter defaultCenter] addObserver:checker
    >
    > selector:@selector(cookieChomp:)
    >
    > name:NSHTTPCookieManagerCookiesChangedNotification
    > object:nil] ;
    >
    > [[NSRunLoop currentRunLoop] run] ;
    >
    > [pool release];
    >
    > return 0;
    > }
  • On 2007 Dec, 24, at 10:14, Jacob Bandes-Storch wrote:

    > Alright, so it works better in a Foundation Tool... is there a
    > workaround for making it work correctly in a Cocoa application?

    I sure wish someone knew the answer to that.  Of course, I discovered
    this by "accident" when making a tool to demo the bug.

    The only answer I know of takes a long time...

    http://developer.apple.com/bugreporter/

    Jacob, do you find, as I did, that the cookie storage will be updated
    if you wait 5 seconds?  Or does it not show until you re-launch your
    app?
  • As far as I could tell, only a relaunch caused the cookie storage to
    update when cookies were added.

    > On 2007 Dec, 24, at 10:14, Jacob Bandes-Storch wrote:
    >
    >> Alright, so it works better in a Foundation Tool... is there a
    >> workaround for making it work correctly in a Cocoa application?
    >
    > I sure wish someone knew the answer to that.  Of course, I discovered
    > this by "accident" when making a tool to demo the bug.
    >
    > The only answer I know of takes a long time...
    >
    > http://developer.apple.com/bugreporter/
    >
    > Jacob, do you find, as I did, that the cookie storage will be updated
    > if you wait 5 seconds?  Or does it not show until you re-launch your
    > app?
previous month december 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
Go to today