Skip to content

Commit

Permalink
Handling parallel requests
Browse files Browse the repository at this point in the history
Summary: Current SDK doesn't support multiple requests at the same time. To
change this I added a new container to the Facebook class that stores all the
requests. Whenever the request finishes it's work (by loading the response or by
returning an error) we remove it from the container. Since FBRequests are
autorelased they will be deleted at the end of the event loop.

Test Plan: Check if the app works + tried to call the GetMe API method twice.

Reviewers: yariv, toddkrabach, jonathan

Reviewed By: toddkrabach

CC: yariv, toddkrabach, jonathan, jimbru, lshepard, jgabbard, kamil

Differential Revision: 378930
  • Loading branch information
Kamil Kraszewski authored and Kamil Kraszewski committed Dec 15, 2011
1 parent e79d072 commit db90ce0
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 36 deletions.
20 changes: 18 additions & 2 deletions src/FBRequest.h
Expand Up @@ -19,6 +19,14 @@

@protocol FBRequestDelegate;

enum {
kFBRequestStateReady,
kFBRequestStateLoading,
kFBRequestStateComplete,
kFBRequestStateError
};
typedef NSUInteger FBRequestState;

/**
* Do not use this interface directly, instead, use method in Facebook.h
*/
Expand All @@ -29,6 +37,8 @@
NSMutableDictionary* _params;
NSURLConnection* _connection;
NSMutableData* _responseText;
FBRequestState _state;
NSError* _error;
}


Expand All @@ -51,8 +61,14 @@
* standard Objective-C object-to-string conversion facilities.
*/
@property(nonatomic,retain) NSMutableDictionary* params;
@property(nonatomic,assign) NSURLConnection* connection;
@property(nonatomic,assign) NSMutableData* responseText;
@property(nonatomic,retain) NSURLConnection* connection;
@property(nonatomic,retain) NSMutableData* responseText;
@property(nonatomic,readonly) FBRequestState state;

/**
* Error returned by the server in case of request's failure (or nil otherwise).
*/
@property(nonatomic,retain) NSError* error;


+ (NSString*)serializeURL:(NSString *)baseUrl
Expand Down
33 changes: 20 additions & 13 deletions src/FBRequest.m
Expand Up @@ -28,15 +28,20 @@

///////////////////////////////////////////////////////////////////////////////////////////////////

@interface FBRequest ()
@property (nonatomic,readwrite) FBRequestState state;
@end

@implementation FBRequest

@synthesize delegate = _delegate,
url = _url,
httpMethod = _httpMethod,
params = _params,
connection = _connection,
responseText = _responseText;

responseText = _responseText,
state = _state,
error = _error;
//////////////////////////////////////////////////////////////////////////////////////////////////
// class public

Expand Down Expand Up @@ -247,12 +252,14 @@ - (void)handleResponseData:(NSData *)data {
@selector(request:didLoadRawResponse:)]) {
[_delegate request:self didLoadRawResponse:data];
}

NSError* error = nil;
id result = [self parseJsonResponse:data error:&error];
self.error = error;

if ([_delegate respondsToSelector:@selector(request:didLoad:)] ||
[_delegate respondsToSelector:
@selector(request:didFailWithError:)]) {
NSError* error = nil;
id result = [self parseJsonResponse:data error:&error];

if (error) {
[self failWithError:error];
Expand Down Expand Up @@ -304,7 +311,7 @@ - (void)connect {
}

_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

self.state = kFBRequestStateLoading;
}

/**
Expand Down Expand Up @@ -345,19 +352,19 @@ - (NSCachedURLResponse *)connection:(NSURLConnection *)connection
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[self handleResponseData:_responseText];

[_responseText release];
_responseText = nil;
[_connection release];
_connection = nil;
self.responseText = nil;
self.connection = nil;

self.state = kFBRequestStateComplete;
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[self failWithError:error];

[_responseText release];
_responseText = nil;
[_connection release];
_connection = nil;
self.responseText = nil;
self.connection = nil;

self.state = kFBRequestStateError;
}

@end
6 changes: 3 additions & 3 deletions src/Facebook.h
Expand Up @@ -25,11 +25,11 @@
* and Graph APIs, and start user interface interactions (such as
* pop-ups promoting for credentials, permissions, stream posts, etc.)
*/
@interface Facebook : NSObject<FBLoginDialogDelegate>{
@interface Facebook : NSObject<FBLoginDialogDelegate, FBRequestDelegate>{
NSString* _accessToken;
NSDate* _expirationDate;
id<FBSessionDelegate> _sessionDelegate;
FBRequest* _request;
NSMutableSet* _requests;
FBDialog* _loginDialog;
FBDialog* _fbDialog;
NSString* _appId;
Expand Down Expand Up @@ -110,4 +110,4 @@
*/
- (void)fbDidLogout;

@end
@end
45 changes: 27 additions & 18 deletions src/Facebook.m
Expand Up @@ -30,6 +30,9 @@
static NSString* kSDK = @"ios";
static NSString* kSDKVersion = @"2";

static NSString *requestFinishedKeyPath = @"finished";
static void *finishedContext = @"finishedContext";

///////////////////////////////////////////////////////////////////////////////////////////////////

@interface Facebook ()
Expand Down Expand Up @@ -93,6 +96,7 @@ - (id)initWithAppId:(NSString *)appId

self = [super init];
if (self) {
_requests = [[NSMutableSet alloc] init];
self.appId = appId;
self.sessionDelegate = delegate;
self.urlSchemeSuffix = urlSchemeSuffix;
Expand All @@ -104,9 +108,12 @@ - (id)initWithAppId:(NSString *)appId
* Override NSObject : free the space
*/
- (void)dealloc {
for (FBRequest* _request in _requests) {
[_request removeObserver:self forKeyPath:requestFinishedKeyPath];
}
[_accessToken release];
[_expirationDate release];
[_request release];
[_requests release];
[_loginDialog release];
[_fbDialog release];
[_appId release];
Expand Down Expand Up @@ -140,15 +147,29 @@ - (FBRequest*)openUrl:(NSString *)url
[params setValue:self.accessToken forKey:@"access_token"];
}

[_request release];
_request = [[FBRequest getRequestWithParams:params
httpMethod:httpMethod
delegate:delegate
requestURL:url] retain];
FBRequest* _request = [FBRequest getRequestWithParams:params
httpMethod:httpMethod
delegate:delegate
requestURL:url];
[_requests addObject:_request];
[_request addObserver:self forKeyPath:requestFinishedKeyPath options:0 context:finishedContext];
[_request connect];
return _request;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == finishedContext) {
FBRequest* _request = (FBRequest*)object;
FBRequestState requestState = [_request state];
if (requestState == kFBRequestStateComplete || requestState == kFBRequestStateError) {
[_request removeObserver:self forKeyPath:requestFinishedKeyPath];
[_requests removeObject:_request];
}
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}

/**
* A private function for getting the app's base url.
*/
Expand Down Expand Up @@ -634,16 +655,4 @@ - (void)fbDialogNotLogin:(BOOL)cancelled {
}
}


///////////////////////////////////////////////////////////////////////////////////////////////////

//FBRequestDelegate

/**
* Handle the auth.ExpireSession api call failure
*/
- (void)request:(FBRequest*)request didFailWithError:(NSError*)error{
NSLog(@"Failed to expire the session");
}

@end

0 comments on commit db90ce0

Please sign in to comment.