Search code examples
iphoneios5ios6global-variables

Unable to maintain session in AFNetworking client IOS 5 / 6


Hi I am using AFNetworking in my IOS app and I am unable to maintain session. I am using an AFNetworking client and using it in all requests to the server.

I have gone through the following questions: How to manage sessions with AFNetworking , but I don't plan to manipulate the cookies or the session. I intend to implement a session throughout the life cycle of the app.

My AFNetworking client's .m is as follows

@implementation MyApiClient


+(MyApiClient *)sharedClient {
    static MyApiClient *_sharedClient = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{

        _sharedClient = [[MyApiClient alloc] initWithBaseURL:[GlobalParams sharedInstance].baseUrl];
    });
    return _sharedClient;
}

-(id)initWithBaseURL:(NSURL *)url {
    self = [super initWithBaseURL:url];
    if (!self) {
        return nil;
    }
    [self registerHTTPOperationClass:[AFJSONRequestOperation class]];
    [AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/html"]];
    self.parameterEncoding = AFFormURLParameterEncoding;

    return self;

}
@end

and I make the following requests to the server on the call of "- (void)searchBarSearchButtonClicked:(UISearchBar *)search" -->>

NSString *path = [NSString stringWithFormat:@"mobile"];
    NSURLRequest *request = [[MyApiClient sharedClient] requestWithMethod:@"GET" path:path parameters:@{@"q":search.text}];

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
                                                                                        success:^(NSURLRequest *request,
                                                                                                  NSHTTPURLResponse *response, id json) {
        // code for successful return goes here
        NSLog(@"search feed %@", json);
        search_feed_json = [json objectForKey:@"searchFeed"];

        if (search_feed_json.count > 0) {
            //<#statements-if-true#>


            show_feed_json = search_feed_json;


            //reload table view to load the current non-empty activity feed into the table
            [self.tableView reloadData];

        } else {
            //<#statements-if-false#>
            NSLog(@"Response: %@", @"no feed");
        }


    } failure :^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        // code for failed request goes here
        NSLog(@"nops : %@", error);
    }];

    [operation start];

Can anyone please guide me or point out where I am wrong ? Any help would be appreciated. Thanks in advance.

Edit ::

I found my answer in the following post : https://stackoverflow.com/a/14405805/1935921

I initialised the methods listed in the answer in my GlobalParams class, which contains all the Global parameters and methods. I call the "saveCookies" method when the app does the login and the server sends the Cookies. Then these cookies are loaded every time I make any subsequent request by using the method "loadCookies". The Code looks as follows :

GlobalParams.h

#import <Foundation/Foundation.h>


@interface GlobalParams : NSObject

// Your property settings for your variables go here
// here's one example:

@property (nonatomic, assign) NSURL *baseUrl;


// This is the method to access this Singleton class
+ (GlobalParams *)sharedInstance;

- (void)saveCookies;
- (void)loadCookies;

@end

GlobalParams.m

    #import "GlobalParams.h"


    @implementation GlobalParams

    @synthesize myUserData,baseUrl;

    + (GlobalParams *)sharedInstance
    {
        // the instance of this class is stored here
        static GlobalParams *myInstance = nil;

        // check to see if an instance already exists
        if (nil == dronnaInstance) {
            myInstance  = [[[self class] alloc] init];


            myInstance.baseUrl = [NSURL URLWithString:@"http://www.test.dronna.com/"];

        }
        // return the instance of this class
        return myInstance;
    }


    - (void)saveCookies{

        NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]];
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setObject: cookiesData forKey: @"sessionCookies"];
        [defaults synchronize];

    }

    - (void)loadCookies{

        NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData: [[NSUserDefaults standardUserDefaults] objectForKey: @"sessionCookies"]];
        NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];

        for (NSHTTPCookie *cookie in cookies){
            [cookieStorage setCookie: cookie];
        }

    }

@end

then I call " [[GlobalParams sharedInstance] saveCookies]; " or " [[GlobalParams sharedInstance] loadCookies]; "(depending on read/write required in cookies) in all my server calls after defining the NSMutableRequest. I hope this helps somebody.


Solution

  • I found my answer in the following post : https://stackoverflow.com/a/14405805/1935921

    I initialised the methods listed in the answer in my GlobalParams class, which contains all the Global parameters and methods. I call the "saveCookies" method when the app does the login and the server sends the Cookies. Then these cookies are loaded every time I make any subsequent request by using the method "loadCookies". The Code looks as follows :

    GlobalParams.h

    #import <Foundation/Foundation.h>
    
    
    @interface GlobalParams : NSObject
    
    // Your property settings for your variables go here
    // here's one example:
    
    @property (nonatomic, assign) NSURL *baseUrl;
    
    
    // This is the method to access this Singleton class
    + (GlobalParams *)sharedInstance;
    
    //saving cookies
    - (void)saveCookies;
    //loading cookies
    - (void)loadCookies;
    
    @end
    

    GlobalParams.m

    #import "GlobalParams.h"
    
    
    @implementation GlobalParams
    
    @synthesize myUserData,baseUrl;
    
    + (GlobalParams *)sharedInstance
    {
        // the instance of this class is stored here
        static GlobalParams *myInstance = nil;
    
        // check to see if an instance already exists
        if (nil == dronnaInstance) {
            myInstance  = [[[self class] alloc] init];
    
    
            myInstance.baseUrl = [NSURL URLWithString:@"http://www.test.dronna.com/"];
    
        }
        // return the instance of this class
        return myInstance;
    }
    
    
    - (void)saveCookies{
    
        NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]];
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        [defaults setObject: cookiesData forKey: @"sessionCookies"];
        [defaults synchronize];
    
    }
    
    - (void)loadCookies{
    
        NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData: [[NSUserDefaults standardUserDefaults] objectForKey: @"sessionCookies"]];
        NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    
        for (NSHTTPCookie *cookie in cookies){
            [cookieStorage setCookie: cookie];
        }
    
    }