2

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.

Community
  • 1
  • 1
  • Where do you set the session identifier or coockie or something? because HTTP is stateless you need to tell the server who you are every call. – rckoenes Jun 07 '13 at 14:34
  • Thank you for your response but I am not sure, do I really need to do that ?? As far as I know, AFNetworking uses NSUrl which manages the session by default [link]http://stackoverflow.com/a/11039784 . If I am wrong than can you please tell me how to attach my session identifier in every call or the AF client. – Abhigyan Raghav Jun 07 '13 at 15:46

1 Answers1

4

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];
    }

}
Community
  • 1
  • 1