diff --git a/README.md b/README.md index 4281d9e..c544ea0 100644 --- a/README.md +++ b/README.md @@ -14,51 +14,213 @@ readily used in your applications. To use in your own projects, you will need everything inside the "app.net" folder. That folder contains all App.Net objects as well as the main API interface. JSON parsing is done using JSONKit, which is also included in the -project's source. +project's source. I will soon replace this NSJSONSerialization, but for now +still using JSONKit. The main API entry-point to access the App.Net API is the `AppDotNet` object. An example of usage is shown in AppDelegate.m of the included project. - AppDotNet *engine = [[AppDotNet alloc] initWithDelegate:self accessToken:token]; + AppDotNet *engine = [[AppDotNet alloc] initWithAccessToken:token]; + + [engine checkCurrentTokenWithBlock:^(ADNScope *scope, ADNUser *user, NSError *e) { + if (e) { + [self requestFailed:e]; + } else { + [self receivedUser:user]; + } + }]; + + [engine userWithID:6581 block:^(ADNUser *user, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUser:user]; + } + + }]; + + [engine userWithUsername:@"blablah" block:^(ADNUser *user, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUser:user]; + } + + }]; + + [engine followUserWithID:6581 block:^(ADNUser *user, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUser:user]; + } + }]; + + [engine unfollowUserWithID:6581 block:^(ADNUser *user, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUser:user]; + } + }]; + + [engine followedByMeWithBlock:^(NSArray *users, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUsers:users]; + } + }]; + + [engine followedByUsername:@"@terhechte" block:^(NSArray *users, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUsers:users]; + } + }]; + + [engine followedByUsername:@"doesntexistthisuser" block:^(NSArray *users, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUsers:users]; + } + }]; + + + [engine followersOfMeWithBlock:^(NSArray *users, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUsers:users]; + } + }]; + + [engine followersOfUsername:@"@akg" block:^(NSArray *users, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUsers:users]; + } + }]; + + + [engine muteUserWithUsername:@"@terhechte" block:^(ADNUser *user, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUser:user]; + } + }]; + + [engine muteUserWithUsername:@"@spacekatgal" block:^(ADNUser *user, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUser:user]; + } + }]; + + [engine mutedUsersWithBlock:^(NSArray *users, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUsers:users]; + } + }]; + + [engine unmuteUserWithUsername:@"@terhechte" block:^(ADNUser *user, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUser:user]; + } + }]; + + [engine unmuteUserWithUsername:@"@spacekatgal" block:^(ADNUser *user, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedUser:user]; + } + }]; + + [engine writePost:@"HELLO WORLD! #testing" replyToPostWithID:-1 annotations:nil links:nil block:^(ADNPost *post, NSError *error) { + if (error) { + [self requestFailed:error]; + } else { + [self receivedPost:post]; + } + }]; + + [engine postWithID:50 block:^(ADNPost *post, NSError *error) { + if (error) + [self requestFailed:error]; + else + [self receivedPost:post]; + }]; + + [engine deletePostWithID:50 block:^(ADNPost *post, NSError *error) { + if (error) + [self requestFailed:error]; + else + [self receivedPost:post]; + }]; + + [engine repliesToPostWithID:121511 block:^(NSArray *posts, NSError *error) { + if (error) + [self requestFailed:error]; + else + [self receivedPosts:posts]; + }]; + + [engine repliesToPostWithID:50 block:^(NSArray *posts, NSError *error) { + if (error) + [self requestFailed:error]; + else + [self receivedPosts:posts]; + }]; + + [engine postsByMeWithBlock:^(NSArray *posts, NSError *error) { + if (error) + [self requestFailed:error]; + else + [self receivedPosts:posts]; + }]; + + [engine postsMentioningMeWithBlock:^(NSArray *posts, NSError *error) { + if (error) + [self requestFailed:error]; + else + [self receivedPosts:posts]; + }]; + + [engine myStreamSinceID:152000 beforeID:-1 count:10 includeUser:NO includeAnnotations:NO includeReplies:NO block:^(NSArray *posts, NSError *error) { + if (error) + [self requestFailed:error]; + else + [self receivedPosts:posts]; + }]; + + [engine globalStreamSinceID:-1 beforeID:-1 count:10 includeUser:NO includeAnnotations:NO includeReplies:NO block:^(NSArray *posts, NSError *error) { + if (error) + [self requestFailed:error]; + else + [self receivedPosts:posts]; + }]; + + [engine taggedPostsWithTag:@"gamedev" sinceID:-1 beforeID:-1 count:20 includeUser:NO includeAnnotations:NO includeReplies:NO block:^(NSArray *posts, NSError *error) { + if (error) + [self requestFailed:error]; + else + [self receivedPosts:posts]; + }]; - [engine checkCurrentToken]; - [engine getUserWithUsername:@"@terhechte"]; - - [engine followUserWithUsername:@"@terhechte"]; - [engine unfollowUserWithID:6581]; - - [engine followedByMe]; - [engine followedByUsername:@"@terhechte"]; - - [engine followersOfMe]; - [engine followersOfUsername:@"@akg"]; - - [engine muteUserWithUsername:@"@terhechte"]; - [engine unmuteUserWithUsername:@"@terhechte"]; - [engine unmuteUserWithUsername:@"@spacekatgal"]; - - [engine mutedUsers]; - - [engine writePost:@"HELLLO WORLD!" - replyToPostWithID:-1 annotations:nil links:nil]; - - [engine postsByMe]; - - [engine postsMentioningMe]; - - [engine myStreamSinceID:152000 beforeID:-1 - count:10 includeUser:NO includeAnnotations:NO includeReplies:NO]; - - [engine globalStreamSinceID:-1 beforeID:-1 - count:10 includeUser:NO includeAnnotations:NO includeReplies:NO]; - - [engine taggedPostsWithTag:@"gamedev" sinceID:-1 beforeID:-1 - count:20 includeUser:NO includeAnnotations:NO includeReplies:NO]; *NOTE*: You initialize the main AppDotNet interface with an access token for -your app and a delegate. The delegate is used for callbacks, see the "Client -Delegate Callbacks" section below. The access token is received after proper -OAuth2 authentication of your app, see "Authentication" section below. +your app. The responses from the App.Net API are then returned to you via the +blocks that are passed into each API call. The access token is received after proper OAuth2 authentication of your app, see "Authentication" section below. ### Authentication @@ -72,28 +234,10 @@ that are better suited for this: You may use the any standard OAuth2 authentication method. All that is required for objc-appdotnet is the access token you receive. -### Client Delegate Callbacks - -All API calls are notified asynchronously to the client using delegate -callbacks. Your client must implement the ADNDelegate protocol, which contains -specific callback functions when objects are received from App.Net API calls. - -Each call to the `AppDotNet` object will make underlying calls to the App.Net -REST API. Each call can make multiple callbacks for example if an API call -returns both a `User` and a `Post`, then both `receivedUser:withRequestUUID` -and `receivedPost:withRequestUUID:` delegate methods are called giving you the -`User` and `Post` objects respectively. - -Since all calls are asynchronous, each call to `AppDotNet` will return a unique -identifier as an `NSString*`. This can be used by the client application to -keep track of which delegate callbacks correspond to which API calls. Each -delegate callback contains a `withRequestUUID` parameter, which contains the -unique identifier corresponding to that API call. - ### Error Handling -If there is an error with the API request, the delegate method -`requestFailed:forRequestUUID` is called. This contains an `NSError` object. +If there is an error with the API request, each call's block parameter "error" +will be not nil. The error object is an instance of `NSError` class. The error will either be an "HTTP" error or an error within the ADN API. Error type is indicated by the domain string "HTTP" or "ADN". Status code of error is also encoded in the `NSError` object. See the `AppDelegate.m` implementation @@ -111,6 +255,7 @@ if things are not properly formatted, it's likely that the app will crash. stream methods do not work. - Latest App.Net changes include responses that contain a "meta" value. This information is ignored currently. +- Using JSONKit for JSON parsing instead of NSJSONSerialization Please let me know if you find any bugs/issues while using this library. I'd be more than happy to hear from you. diff --git a/objc-appdotnet.xcodeproj/project.pbxproj b/objc-appdotnet.xcodeproj/project.pbxproj index 4271191..d6226ce 100644 --- a/objc-appdotnet.xcodeproj/project.pbxproj +++ b/objc-appdotnet.xcodeproj/project.pbxproj @@ -8,8 +8,9 @@ /* Begin PBXBuildFile section */ 3801A75E15E50C6900CF720C /* ISO8601DateFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 3801A75D15E50C6900CF720C /* ISO8601DateFormatter.m */; }; - 3801A76215E52CD400CF720C /* ADNURLConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 3801A76115E52CD300CF720C /* ADNURLConnection.m */; }; 3801A76515E5ABA200CF720C /* ADNPost.m in Sources */ = {isa = PBXBuildFile; fileRef = 3801A76415E5ABA200CF720C /* ADNPost.m */; }; + 3859D34B15E9575E00F5D15F /* ADNScope.m in Sources */ = {isa = PBXBuildFile; fileRef = 3859D34A15E9575E00F5D15F /* ADNScope.m */; }; + 3859D34F15E979EA00F5D15F /* ADNURLRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 3859D34E15E979EA00F5D15F /* ADNURLRequest.m */; }; 38BD926F15E428BE00278431 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 38BD926D15E428BE00278431 /* InfoPlist.strings */; }; 38BD927115E428BE00278431 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 38BD927015E428BE00278431 /* main.m */; }; 38BD927515E428BE00278431 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 38BD927315E428BE00278431 /* Credits.rtf */; }; @@ -43,10 +44,12 @@ /* Begin PBXFileReference section */ 3801A75C15E50C6900CF720C /* ISO8601DateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISO8601DateFormatter.h; sourceTree = ""; }; 3801A75D15E50C6900CF720C /* ISO8601DateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ISO8601DateFormatter.m; sourceTree = ""; }; - 3801A76015E52CD300CF720C /* ADNURLConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADNURLConnection.h; sourceTree = ""; }; - 3801A76115E52CD300CF720C /* ADNURLConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADNURLConnection.m; sourceTree = ""; }; 3801A76315E5ABA200CF720C /* ADNPost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADNPost.h; sourceTree = ""; }; 3801A76415E5ABA200CF720C /* ADNPost.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADNPost.m; sourceTree = ""; }; + 3859D34915E9575E00F5D15F /* ADNScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADNScope.h; sourceTree = ""; }; + 3859D34A15E9575E00F5D15F /* ADNScope.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADNScope.m; sourceTree = ""; }; + 3859D34D15E979EA00F5D15F /* ADNURLRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADNURLRequest.h; sourceTree = ""; }; + 3859D34E15E979EA00F5D15F /* ADNURLRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADNURLRequest.m; sourceTree = ""; }; 38BD926015E428BE00278431 /* objc-appdotnet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "objc-appdotnet.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 38BD926415E428BE00278431 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 38BD926715E428BE00278431 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; @@ -173,11 +176,13 @@ 38BD933615E4524F00278431 /* ADNFilter.m */, 38BD933815E454A700278431 /* ADNImage.h */, 38BD933915E454A700278431 /* ADNImage.m */, - 3801A76015E52CD300CF720C /* ADNURLConnection.h */, - 3801A76115E52CD300CF720C /* ADNURLConnection.m */, 3801A76315E5ABA200CF720C /* ADNPost.h */, 3801A76415E5ABA200CF720C /* ADNPost.m */, 38CE750A15E652D50048C231 /* ADNConstants.h */, + 3859D34915E9575E00F5D15F /* ADNScope.h */, + 3859D34A15E9575E00F5D15F /* ADNScope.m */, + 3859D34D15E979EA00F5D15F /* ADNURLRequest.h */, + 3859D34E15E979EA00F5D15F /* ADNURLRequest.m */, ); path = app.net; sourceTree = ""; @@ -272,8 +277,9 @@ 38BD933715E4524F00278431 /* ADNFilter.m in Sources */, 38BD933A15E454A700278431 /* ADNImage.m in Sources */, 3801A75E15E50C6900CF720C /* ISO8601DateFormatter.m in Sources */, - 3801A76215E52CD400CF720C /* ADNURLConnection.m in Sources */, 3801A76515E5ABA200CF720C /* ADNPost.m in Sources */, + 3859D34B15E9575E00F5D15F /* ADNScope.m in Sources */, + 3859D34F15E979EA00F5D15F /* ADNURLRequest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/objc-appdotnet/AppDelegate.h b/objc-appdotnet/AppDelegate.h index ac28ecf..3ddc680 100644 --- a/objc-appdotnet/AppDelegate.h +++ b/objc-appdotnet/AppDelegate.h @@ -9,7 +9,7 @@ #import #import "app.net/AppDotNet.h" -@interface AppDelegate : NSObject +@interface AppDelegate : NSObject @property (assign) IBOutlet NSWindow *window; diff --git a/objc-appdotnet/AppDelegate.m b/objc-appdotnet/AppDelegate.m index 3a71375..1a7fea6 100644 --- a/objc-appdotnet/AppDelegate.m +++ b/objc-appdotnet/AppDelegate.m @@ -30,67 +30,227 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification // redirect me to the specified redirect_url. That url will contain in it's // GET parameter the access_token, which I copy and paste here. - //NSString *client_id = @""; - //NSString *redirect_uri = @""; - //NSString *scopes = @"stream%20email%20write_post%20follow%20messages%20export"; + /* + NSString *client_id = @""; + NSString *redirect_uri = @"https://github.com/akashkgarg/objc-appdotnet"; + NSString *scopes = @"stream%20email%20write_post%20follow%20messages%20export"; - //NSString *uri = [NSString stringWithFormat:@"https://alpha.app.net/oauth/authenticate?client_id=%@&response_type=token&redirect_uri%@&scope=%@", client_id, redirect_uri, scopes]; + NSString *uri = [NSString stringWithFormat:@"https://alpha.app.net/oauth/authenticate?client_id=%@&response_type=token&redirect_uri%@&scope=%@", client_id, redirect_uri, scopes]; - //NSURL *url = [NSURL URLWithString:uri]; - //[[NSWorkspace sharedWorkspace] openURL:url]; + NSURL *url = [NSURL URLWithString:uri]; + [[NSWorkspace sharedWorkspace] openURL:url]; + */ - NSString *token = @"AQAAAAAAAFhsSvxsSxprq-3kK4PY3c_JvSaF7nApwPHxhHaY7qGwxZIKJd6EFdRGdlZYO0s6mat3UIWQ6tY1qMOGjRecPEnnAQ"; + NSString *token = @"AQAAAAAAAIAnhVGQcxX_8pt0_O7DMrVrlRL1jyZ4dKcvN8JOqrS4fudYChJxC_YcmtzM7ThrbsDkd4qlm3qlEn--mZE5ma5iBw"; - AppDotNet *engine = [[AppDotNet alloc] initWithDelegate:self accessToken:token]; + AppDotNet *engine = [[AppDotNet alloc] initWithAccessToken:token]; - //[engine checkCurrentToken]; - //[engine getUserWithID:6581]; +// [engine checkCurrentTokenWithBlock:^(ADNScope *scope, ADNUser *user, NSError *e) { +// if (e) { +// [self requestFailed:e]; +// } else { +// [self receivedUser:user]; +// } +// }]; - [engine getUserWithUsername:@"@blahblah"]; +// [engine userWithID:6581 block:^(ADNUser *user, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUser:user]; +// } +// +// }]; - //[engine followUserWithID:6581]; - //[engine unfollowUserWithID:6581]; +// [engine userWithUsername:@"blablah" block:^(ADNUser *user, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUser:user]; +// } +// +// }]; - //[engine followedByMe]; - //[engine followedByUsername:@"@terhechte"]; +// [engine followUserWithID:6581 block:^(ADNUser *user, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUser:user]; +// } +// }]; - //[engine followersOfMe]; - //[engine followersOfUsername:@"@akg"]; +// [engine unfollowUserWithID:6581 block:^(ADNUser *user, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUser:user]; +// } +// }]; + +// [engine followedByMeWithBlock:^(NSArray *users, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUsers:users]; +// } +// }]; +// +// [engine followedByUsername:@"@terhechte" block:^(NSArray *users, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUsers:users]; +// } +// }]; +// +// [engine followedByUsername:@"doesntexistthisuser" block:^(NSArray *users, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUsers:users]; +// } +// }]; - //[engine muteUserWithUsername:@"@terhechte"]; - //[engine unmuteUserWithUsername:@"@terhechte"]; - //[engine unmuteUserWithUsername:@"@spacekatgal"]; - //[engine mutedUsers]; +// [engine followersOfMeWithBlock:^(NSArray *users, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUsers:users]; +// } +// }]; +// +// [engine followersOfUsername:@"@akg" block:^(NSArray *users, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUsers:users]; +// } +// }]; - //[engine writePost:@"HELLLO WORLD!" replyToPostWithID:-1 annotations:nil links:nil]; - //[engine postWithID:50]; - //[engine deletePostWithID:50]; +// [engine muteUserWithUsername:@"@terhechte" block:^(ADNUser *user, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUser:user]; +// } +// }]; +// +// [engine muteUserWithUsername:@"@spacekatgal" block:^(ADNUser *user, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUser:user]; +// } +// }]; - //[engine repliesToPostWithID:121511]; - //[engine repliesToPostWithID:50]; - //[engine postsByMe]; +// [engine mutedUsersWithBlock:^(NSArray *users, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUsers:users]; +// } +// }]; +// +// [engine unmuteUserWithUsername:@"@terhechte" block:^(ADNUser *user, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUser:user]; +// } +// }]; +// +// [engine unmuteUserWithUsername:@"@spacekatgal" block:^(ADNUser *user, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedUser:user]; +// } +// }]; - //[engine postsMentioningMe]; +// [engine writePost:@"HELLO WORLD! #testing" replyToPostWithID:-1 annotations:nil links:nil block:^(ADNPost *post, NSError *error) { +// if (error) { +// [self requestFailed:error]; +// } else { +// [self receivedPost:post]; +// } +// }]; - //[engine myStreamSinceID:152000 beforeID:-1 count:10 includeUser:NO includeAnnotations:NO includeReplies:NO]; +// [engine postWithID:50 block:^(ADNPost *post, NSError *error) { +// if (error) +// [self requestFailed:error]; +// else +// [self receivedPost:post]; +// }]; +// +// [engine deletePostWithID:50 block:^(ADNPost *post, NSError *error) { +// if (error) +// [self requestFailed:error]; +// else +// [self receivedPost:post]; +// }]; - //[engine globalStreamSinceID:-1 beforeID:-1 count:10 includeUser:NO includeAnnotations:NO includeReplies:NO]; +// [engine repliesToPostWithID:121511 block:^(NSArray *posts, NSError *error) { +// if (error) +// [self requestFailed:error]; +// else +// [self receivedPosts:posts]; +// }]; +// +// [engine repliesToPostWithID:50 block:^(NSArray *posts, NSError *error) { +// if (error) +// [self requestFailed:error]; +// else +// [self receivedPosts:posts]; +// }]; - //[engine taggedPostsWithTag:@"gamedev" sinceID:-1 beforeID:-1 count:20 includeUser:NO includeAnnotations:NO includeReplies:NO]; +// [engine postsByMeWithBlock:^(NSArray *posts, NSError *error) { +// if (error) +// [self requestFailed:error]; +// else +// [self receivedPosts:posts]; +// }]; +// +// [engine postsMentioningMeWithBlock:^(NSArray *posts, NSError *error) { +// if (error) +// [self requestFailed:error]; +// else +// [self receivedPosts:posts]; +// }]; + +// [engine myStreamSinceID:152000 beforeID:-1 count:10 includeUser:NO includeAnnotations:NO includeReplies:NO block:^(NSArray *posts, NSError *error) { +// if (error) +// [self requestFailed:error]; +// else +// [self receivedPosts:posts]; +// }]; + +// [engine globalStreamSinceID:-1 beforeID:-1 count:10 includeUser:NO includeAnnotations:NO includeReplies:NO block:^(NSArray *posts, NSError *error) { +// if (error) +// [self requestFailed:error]; +// else +// [self receivedPosts:posts]; +// }]; + + [engine taggedPostsWithTag:@"gamedev" sinceID:-1 beforeID:-1 count:20 includeUser:NO includeAnnotations:NO includeReplies:NO block:^(NSArray *posts, NSError *error) { + if (error) + [self requestFailed:error]; + else + [self receivedPosts:posts]; + }]; } //------------------------------------------------------------------------------ -- (void) receivedUser:(ADNUser *)user forRequestUUID:(NSString *)uuid +- (void) receivedUser:(ADNUser *)user { NSLog(@"Got User with username: %@", user.username); } //------------------------------------------------------------------------------ -- (void) requestFailed:(NSError *)error forRequestUUID:(NSString *)uuid +- (void) requestFailed:(NSError *)error { NSLog(@"Failed!"); @@ -102,13 +262,14 @@ - (void) requestFailed:(NSError *)error forRequestUUID:(NSString *)uuid NSLog(@"ADN Error: %ld - %@", code, [userInfo objectForKey:@"message"]); } else if ([domain compare:@"HTTP"] == NSOrderedSame) { NSLog(@"HTTP Error: %ld - %@", code, [userInfo objectForKey:@"message"]); + } else { + } - } //------------------------------------------------------------------------------ -- (void) receivedUsers:(NSArray *)users forRequestUUID:(NSString *)uuid +- (void) receivedUsers:(NSArray *)users { for (ADNUser *user in users) { NSLog(@"got user: %@", user.username); @@ -117,14 +278,14 @@ - (void) receivedUsers:(NSArray *)users forRequestUUID:(NSString *)uuid //------------------------------------------------------------------------------ -- (void) receivedPost:(ADNPost *)post forRequestUUID:(NSString *)uuid +- (void) receivedPost:(ADNPost *)post { NSLog(@"Got Post: %@", post.text); } //------------------------------------------------------------------------------ -- (void) receivedPosts:(NSArray *)posts forRequestUUID:(NSString *)uuid +- (void) receivedPosts:(NSArray *)posts { for (ADNPost *post in posts) { NSLog(@"got post: %ld - %@", post.postId, post.text); diff --git a/objc-appdotnet/app.net/ADNScope.h b/objc-appdotnet/app.net/ADNScope.h new file mode 100644 index 0000000..d139546 --- /dev/null +++ b/objc-appdotnet/app.net/ADNScope.h @@ -0,0 +1,13 @@ +// +// ADNScope.h +// objc-appdotnet +// +// Created by Akash Garg on 8/25/12. +// Copyright (c) 2012 Akash Garg. All rights reserved. +// + +#import + +@interface ADNScope : NSObject + +@end diff --git a/objc-appdotnet/app.net/ADNScope.m b/objc-appdotnet/app.net/ADNScope.m new file mode 100644 index 0000000..7fafacf --- /dev/null +++ b/objc-appdotnet/app.net/ADNScope.m @@ -0,0 +1,13 @@ +// +// ADNScope.m +// objc-appdotnet +// +// Created by Akash Garg on 8/25/12. +// Copyright (c) 2012 Akash Garg. All rights reserved. +// + +#import "ADNScope.h" + +@implementation ADNScope + +@end diff --git a/objc-appdotnet/app.net/ADNURLConnection.h b/objc-appdotnet/app.net/ADNURLConnection.h deleted file mode 100644 index 498f565..0000000 --- a/objc-appdotnet/app.net/ADNURLConnection.h +++ /dev/null @@ -1,60 +0,0 @@ -// -// ADNURLConnection.h -// objc-appdotnet -// -// Created by Akash Garg on 8/22/12. -// Copyright (c) 2012 Akash Garg. All rights reserved. -// - -#import - -//------------------------------------------------------------------------------ - -// Unique powers of two for each flag so that we can bitwise OR them to get the -// combination of response types. -enum ADNResponseType { - LIST = 0x01, // top level is a list - DICT = 0x02, // top level is a dictionary - IS_USER = 0x04, // If data IS the "user" object - HAS_USER = 0x08, // If data has a "user" object - HAS_SCOPES = 0x10, // Has info about token "scopes" - IS_POST = 0x20, -}; - -//------------------------------------------------------------------------------ - -@interface ADNURLConnection : NSURLConnection -{ - // The response data. - NSMutableData *_data; - - // The response type, useful for parsing the response data. - enum ADNResponseType _responseType; - - // UUID for the connection. - NSString *_uuid; -} - -@property (readonly) NSMutableData *data; -@property (readonly) enum ADNResponseType responseType; -@property (readonly) NSString *uuid; -@property (retain) NSHTTPURLResponse *response; - -//------------------------------------------------------------------------------ - -+ (id) connectionWithRequest:(NSURLRequest*)request - delegate:(id)delegate - responseType:(enum ADNResponseType)type; - -- (id) initWithRequest:(NSURLRequest *)request - delegate:(id)delegate - responseType:(enum ADNResponseType)type; - -//------------------------------------------------------------------------------ - -- (void) resetDataLength; -- (void) appendData:(NSData*)data; - -//------------------------------------------------------------------------------ - -@end diff --git a/objc-appdotnet/app.net/ADNURLConnection.m b/objc-appdotnet/app.net/ADNURLConnection.m deleted file mode 100644 index 90b0cc0..0000000 --- a/objc-appdotnet/app.net/ADNURLConnection.m +++ /dev/null @@ -1,73 +0,0 @@ -// -// ADNURLConnection.m -// objc-appdotnet -// -// Created by Akash Garg on 8/22/12. -// Copyright (c) 2012 Akash Garg. All rights reserved. -// - -#import "ADNURLConnection.h" - -@implementation ADNURLConnection - -@synthesize data = _data; -@synthesize responseType = _responseType; -@synthesize uuid = _uuid; -@synthesize response; - -//------------------------------------------------------------------------------ - -+ (id) connectionWithRequest:(NSURLRequest*)request - delegate:(id)delegate - responseType:(enum ADNResponseType)type -{ - return [[[ADNURLConnection alloc] initWithRequest:request - delegate:delegate - responseType:type] autorelease]; -} - -//------------------------------------------------------------------------------ - -- (id) initWithRequest:(NSURLRequest *)request - delegate:(id)delegate - responseType:(enum ADNResponseType)type -{ - self = [super initWithRequest:request delegate:delegate]; - _data = [[NSMutableData alloc] initWithCapacity:0]; - _responseType = type; - - // Create UUID for connection. - CFUUIDRef uuidObj = CFUUIDCreate(nil); - _uuid = (NSString*)CFUUIDCreateString(nil, uuidObj); - CFRelease(uuidObj); - - return self; -} - -//------------------------------------------------------------------------------ - -- (void) dealloc -{ - [_data release]; - [_uuid release]; - [self.response release]; - [super dealloc]; -} - -//------------------------------------------------------------------------------ - -- (void) resetDataLength -{ - [_data setLength:0]; -} - -//------------------------------------------------------------------------------ - -- (void) appendData:(NSData*)data -{ - [_data appendData:data]; -} - -//------------------------------------------------------------------------------ - -@end diff --git a/objc-appdotnet/app.net/ADNURLRequest.h b/objc-appdotnet/app.net/ADNURLRequest.h new file mode 100644 index 0000000..103a50f --- /dev/null +++ b/objc-appdotnet/app.net/ADNURLRequest.h @@ -0,0 +1,13 @@ +// +// ADNURLRequest.h +// objc-appdotnet +// +// Created by Akash Garg on 8/25/12. +// Copyright (c) 2012 Akash Garg. All rights reserved. +// + +#import + +@interface ADNURLRequest : NSMutableURLRequest + +@end diff --git a/objc-appdotnet/app.net/ADNURLRequest.m b/objc-appdotnet/app.net/ADNURLRequest.m new file mode 100644 index 0000000..c8df1e3 --- /dev/null +++ b/objc-appdotnet/app.net/ADNURLRequest.m @@ -0,0 +1,13 @@ +// +// ADNURLRequest.m +// objc-appdotnet +// +// Created by Akash Garg on 8/25/12. +// Copyright (c) 2012 Akash Garg. All rights reserved. +// + +#import "ADNURLRequest.h" + +@implementation ADNURLRequest + +@end diff --git a/objc-appdotnet/app.net/AppDotNet.h b/objc-appdotnet/app.net/AppDotNet.h index fa56876..8c6d026 100644 --- a/objc-appdotnet/app.net/AppDotNet.h +++ b/objc-appdotnet/app.net/AppDotNet.h @@ -13,33 +13,18 @@ #import "ADNHashTag.h" #import "ADNImage.h" #import "ADNMention.h" +#import "ADNScope.h" #import "ADNConstants.h" //------------------------------------------------------------------------------ -// Note that all delegate methods have a "forRequestUUID" field, that contains -// the unique UUID for each API call you request from the your client -// application. This is because multiple callbacks can be triggered for a -// particular API request and to keep track of which calls go with which -// request, you can use the RequestUUID. -// -// Each API request call also returns the RequestUUID that you can keep track -// of in your client application. - -@protocol ADNDelegate - -// Callback when something fails while making a API request. -- (void) requestFailed:(NSError*)error forRequestUUID:(NSString*)uuid; - -- (void) receivedUser:(ADNUser*)user forRequestUUID:(NSString*)uuid; - -- (void) receivedUsers:(NSArray*)users forRequestUUID:(NSString*)uuid; - -- (void) receivedPost:(ADNPost*)post forRequestUUID:(NSString*)uuid; - -- (void) receivedPosts:(NSArray*)posts forRequestUUID:(NSString*)uuid; - -@end +// Typedefs for block support. +typedef void (^ADNReceivedScopeAndUser)(ADNScope *scope, ADNUser *user, + NSError *e); +typedef void (^ADNReceivedUser)(ADNUser *user, NSError *error); +typedef void (^ADNReceivedUsers)(NSArray *users, NSError *error); +typedef void (^ADNReceivedPost)(ADNPost *post, NSError *error); +typedef void (^ADNReceivedPosts)(NSArray *posts, NSError *error); //------------------------------------------------------------------------------ @@ -50,91 +35,68 @@ // OAuth 2.0 stuff NSString *_accessToken; - - // Delegate callbacks. - id _delegate; - - // Active connections. - NSMutableDictionary *_connections; } @property (retain) NSString* clientName; @property (retain) NSString* clientVersion; @property (readonly) NSString* accessToken; -- (AppDotNet*) initWithDelegate:(id)delegate - accessToken:(NSString*)token; +// Use this if you do not want to implement your own delegate class, but +// instead want to call all API methods with blocks instead. +- (AppDotNet*) initWithAccessToken:(NSString*)token; //------------------------------------------------------------------------------ #pragma mark - #pragma mark App.Net API Methods. //------------------------------------------------------------------------------ -// All API methods return a NSString* which indicates a unique key for the -// request made. Each API method request can trigger multiple callbacks. The -// callbacks will contain the key from which the request was made. This is so -// that the user end application can keep track of which callbacks are -// associated with which requests in the case that multiple requests are sent -// asynchronously from the client. +// All API methods require a completion block that will be called with the +// response data from app.net. If the response fails, the NSError object will +// be non-nil. + +- (void) checkCurrentTokenWithBlock:(ADNReceivedScopeAndUser)block; //------------------------------------------------------------------------------ -// Checks the current client's token permission. -// Delegate Methods Called: -// receivedUser:forRequestUUID: -- (NSString*) checkCurrentToken; +// Retrieving a user with given userid or name. +- (void) userWithID:(NSUInteger)uid block:(ADNReceivedUser)block; +- (void) userWithUsername:(NSString*)username block:(ADNReceivedUser)block; +- (void) meWithBlock:(ADNReceivedUser)block; //------------------------------------------------------------------------------ -// Get a user with the given ID. -// Delegate Methods Called: -// receivedUser:forRequestUUID: -- (NSString*) getUserWithID:(NSUInteger)uid; -- (NSString*) getUserWithUsername:(NSString*)username; -- (NSString*) getMe; - // Follow the user with the given uid. -// Delegate Methods Called: -// receivedUser:forRequestUUID: -- (NSString*) followUserWithID:(NSUInteger)uid; -- (NSString*) followUserWithUsername:(NSString*)username; +- (void) followUserWithID:(NSUInteger)uid block:(ADNReceivedUser)block; +- (void) followUserWithUsername:(NSString*)username + block:(ADNReceivedUser)block; // Unfollow a user with the given uid. -// Delegate Methods Called: -// receivedUser:forRequestUUID: -- (NSString*) unfollowUserWithID:(NSUInteger)uid; -- (NSString*) unfollowUserWithUsername:(NSString*)username; +- (void) unfollowUserWithID:(NSUInteger)uid block:(ADNReceivedUser)block; +- (void) unfollowUserWithUsername:(NSString*)username + block:(ADNReceivedUser)block; //------------------------------------------------------------------------------ // Get the list of users the given user is following. -// Delegate Methods Called: -// receivedUsers:forRequestUUID: -- (NSString*) followedByID:(NSUInteger)uid; -- (NSString*) followedByUsername:(NSString*)username; -- (NSString*) followedByMe; +- (void) followedByID:(NSUInteger)uid block:(ADNReceivedUsers)block; +- (void) followedByUsername:(NSString*)username block:(ADNReceivedUsers)block; +- (void) followedByMeWithBlock:(ADNReceivedUsers)block; // Get a list of users following the given user. -// Delegate Methods Called: -// receivedUsers:forRequestUUID: -- (NSString*) followersOfID:(NSUInteger)uid; -- (NSString*) followersOfUsername:(NSString*)username; -- (NSString*) followersOfMe; +- (void) followersOfID:(NSUInteger)uid block:(ADNReceivedUsers)block; +- (void) followersOfUsername:(NSString*)username block:(ADNReceivedUsers)block; +- (void) followersOfMeWithBlock:(ADNReceivedUsers)block; //------------------------------------------------------------------------------ // Mute/Unmute methods. -// Delegate Methods Called: -// receivedUser:forRequestUUID: -- (NSString*) muteUserWithID:(NSUInteger)uid; -- (NSString*) muteUserWithUsername:(NSString*)username; -- (NSString*) unmuteUserWithID:(NSUInteger)uid; -- (NSString*) unmuteUserWithUsername:(NSString*)username; +- (void) muteUserWithID:(NSUInteger)uid block:(ADNReceivedUser)block; +- (void) muteUserWithUsername:(NSString*)username block:(ADNReceivedUser)block; +- (void) unmuteUserWithID:(NSUInteger)uid block:(ADNReceivedUser)block; +- (void) unmuteUserWithUsername:(NSString*)username block:(ADNReceivedUser)blk; // Get the list of muted users. -// Delegate Methods Called: -// receivedUsers:forRequestUUID: -- (NSString*) mutedUsers; +- (void) mutedUsersWithBlock:(ADNReceivedUsers)block; //------------------------------------------------------------------------------ @@ -143,42 +105,35 @@ // annotations - dictionary of additional annotations in post. Can be nil. // links - an array of ADNLink objects that define the behavior of links in the // post text. Can be nil if no special formatting is required. -// Delegate Methods Called: -// receivedPost:forRequestUUID: -- (NSString*) writePost:(NSString*)text - replyToPostWithID:(NSInteger)postId - annotations:(NSDictionary*)annotations - links:(NSArray*)links; +- (void) writePost:(NSString*)text + replyToPostWithID:(NSInteger)postId + annotations:(NSDictionary*)annotations + links:(NSArray*)links + block:(ADNReceivedPost)block; //------------------------------------------------------------------------------ - // Retrieving a post. -// Delegate Methods Called: -// receivedPost:forRequestUUID: -- (NSString*) postWithID:(NSUInteger)postId; -- (NSString*) deletePostWithID:(NSUInteger)postId; +- (void) postWithID:(NSUInteger)postId block:(ADNReceivedPost)block; +- (void) deletePostWithID:(NSUInteger)postId block:(ADNReceivedPost)block; // All replies to a post with given postID. -// Delegate Methods Called: -// receivedPosts:forRequestUUID: -- (NSString*) repliesToPostWithID:(NSUInteger)postId; +- (void) repliesToPostWithID:(NSUInteger)postId block:(ADNReceivedPosts)block; //------------------------------------------------------------------------------ // All posts by a given user. -// Delegate Methods Called: -// receivedPosts:forRequestUUID: -- (NSString*) postsByUserWithUsername:(NSString*)username; -- (NSString*) postsByUserWithID:(NSUInteger)uid; -- (NSString*) postsByMe; +- (void) postsByUserWithUsername:(NSString*)username + block:(ADNReceivedPosts)blk; +- (void) postsByUserWithID:(NSUInteger)uid block:(ADNReceivedPosts)block; +- (void) postsByMeWithBlock:(ADNReceivedPosts)block; // All posts mentioning a given user. -// Delegate Methods Called: -// receivedPosts:forRequestUUID: -- (NSString*) postsMentioningUserWithUsername:(NSString*)username; -- (NSString*) postsMentioningUserWithID:(NSUInteger)uid; -- (NSString*) postsMentioningMe; +- (void) postsMentioningUserWithUsername:(NSString*)username + block:(ADNReceivedPosts)block; +- (void) postsMentioningUserWithID:(NSUInteger)uid + block:(ADNReceivedPosts)block; +- (void) postsMentioningMeWithBlock:(ADNReceivedPosts)block; //------------------------------------------------------------------------------ @@ -193,37 +148,34 @@ // includeUser - Should the nested User object be included in the Post? // includeAnnotations - Should the post annotations be included in the Post? // includeReplies - Should reply Posts be included in the results? -// Delegate Methods Called: -// receivedPosts:forRequestUUID: -- (NSString*) myStreamSinceID:(NSInteger)sinceId +- (void) myStreamSinceID:(NSInteger)sinceId beforeID:(NSInteger)beforeId count:(NSUInteger)count includeUser:(BOOL)includeUser includeAnnotations:(BOOL)includeAnnotations - includeReplies:(BOOL)includeReplies; + includeReplies:(BOOL)includeReplies + block:(ADNReceivedPosts)block; // Get post's in the global stream. See "myStreamSinceID:" above for meaning // of parameters. -// Delegate Methods Called: -// receivedPosts:forRequestUUID: -- (NSString*) globalStreamSinceID:(NSInteger)sinceId +- (void) globalStreamSinceID:(NSInteger)sinceId beforeID:(NSInteger)beforeId count:(NSUInteger)count includeUser:(BOOL)includeUser includeAnnotations:(BOOL)includeAnnotations - includeReplies:(BOOL)includeReplies; + includeReplies:(BOOL)includeReplies + block:(ADNReceivedPosts)block; // All posts with a given hashtag. See "myStreamSinceID:" above for meaning // of paramters. -// Delegate Methods Called: -// receivedPosts:forRequestUUID: -- (NSString*) taggedPostsWithTag:(NSString*)tag +- (void) taggedPostsWithTag:(NSString*)tag sinceID:(NSInteger)sinceId beforeID:(NSInteger)beforeId count:(NSUInteger)count includeUser:(BOOL)includeUser includeAnnotations:(BOOL)includeAnnotations - includeReplies:(BOOL)includeReplies; + includeReplies:(BOOL)includeReplies + block:(ADNReceivedPosts)block; @end diff --git a/objc-appdotnet/app.net/AppDotNet.m b/objc-appdotnet/app.net/AppDotNet.m index 41faf3a..80d6014 100644 --- a/objc-appdotnet/app.net/AppDotNet.m +++ b/objc-appdotnet/app.net/AppDotNet.m @@ -8,7 +8,7 @@ #import "AppDotNet.h" #import "JSONKit.h" -#import "ADNURLConnection.h" +#import "ADNURLRequest.h" #import "ADNLink.h" @implementation AppDotNet @@ -40,102 +40,103 @@ - (NSError*) parseError:(NSData*)data //------------------------------------------------------------------------------ -- (void) parseUser:(NSDictionary*)userdict reportWithID:(NSString*)uuid +- (NSArray*) parseUserArray:(NSArray*)jsonResp { - // Create the user - ADNUser *user = [ADNUser userFromJSONDictionary:userdict]; - - // report to delegate. - [_delegate receivedUser:user forRequestUUID:uuid]; + NSMutableArray *result = [NSMutableArray array]; + for (NSDictionary *dict in jsonResp) { + ADNUser *user = [ADNUser userFromJSONDictionary:dict]; + [result addObject:user]; + } + return result; } //------------------------------------------------------------------------------ -- (void) parsePost:(NSDictionary*)postDict reportWithID:(NSString*)uuid +- (NSArray*) parsePostArray:(NSArray*)jsonResp { - // create the post - ADNPost *post = [ADNPost postFromJSONDictionary:postDict]; + NSMutableArray *result = [NSMutableArray array]; + for (NSDictionary *dict in jsonResp) { + ADNPost *post = [ADNPost postFromJSONDictionary:dict]; + [result addObject:post]; + } + return result; +} - // report to delegate. - [_delegate receivedPost:post forRequestUUID:uuid]; +//------------------------------------------------------------------------------ + +- (void) processResponse:(NSDictionary*)jsonResp error:(NSError*)error + receivedUserBlock:(ADNReceivedUser)block +{ + if (error) { + block(nil, error); + } else { + ADNUser *user = [ADNUser userFromJSONDictionary:jsonResp]; + block(user, nil); + } } //------------------------------------------------------------------------------ -- (void) parseArray:(NSArray*)array - responseType:(NSUInteger)responseType - reportWithID:(NSString*)uuid +- (void) processResponse:(NSDictionary*)jsonResp error:(NSError*)error + receivedPostBlock:(ADNReceivedPost)block { - NSMutableArray *result = [NSMutableArray array]; + if (error) { + block(nil, error); + } else { + ADNPost *post = [ADNPost postFromJSONDictionary:jsonResp]; + block(post, nil); + } +} - // List is all users. - if (responseType & IS_USER) { - for (NSDictionary *dict in array) { - ADNUser *user = [ADNUser userFromJSONDictionary:dict]; - [result addObject:user]; - } - // report to delegate. - [_delegate receivedUsers:result forRequestUUID:uuid]; +//------------------------------------------------------------------------------ + +- (void) processResponse:(NSArray*)jsonResp error:(NSError*)error + receivedUsersBlock:(ADNReceivedUsers)block +{ + if (error) { + block(nil, error); + } else { + NSArray *users = [self parseUserArray:jsonResp]; + block(users, nil); } +} - // List is all posts. - if (responseType & IS_POST) { - for (NSDictionary *dict in array) { - ADNPost *post = [ADNPost postFromJSONDictionary:dict]; - [result addObject:post]; - } - // report to delegate. - [_delegate receivedPosts:result forRequestUUID:uuid]; +//------------------------------------------------------------------------------ + +- (void) processResponse:(NSArray*)jsonResp error:(NSError*)error + receivedPostsBlock:(ADNReceivedPosts)block +{ + if (error) { + block(nil, error); + } else { + NSArray *posts = [self parsePostArray:jsonResp]; + block(posts, nil); } } //------------------------------------------------------------------------------ -- (void) parseDataForConnection:(ADNURLConnection*)connection +- (void) parseADNResponse:(NSData*)data + block:(void (^) (id jsonResp, NSError *err))block { - NSData *data = connection.data; - NSUInteger responseType = (NSUInteger)connection.responseType; - NSString *uuid = connection.uuid; - // First of all, check if there is an error in the response. NSError *error = [self parseError:data]; if (error) { - // Inform delegate and finish processing. - [_delegate requestFailed:error forRequestUUID:uuid]; - return; - } + block(nil, error); + } else { + id dataObj = [[data objectFromJSONData] objectForKey:DATA_KEY]; - if (responseType & DICT) { - NSDictionary *dataDict = [[data objectFromJSONData] objectForKey:DATA_KEY]; - - NSAssert(dataDict, @"No valid dictionary"); - - if (responseType & HAS_USER) { - NSDictionary *userDict = [dataDict objectForKey:USER_KEY]; - NSAssert(userDict, @"No valid dictionary for user"); - // parse the user and report to delegate. - [self parseUser:userDict reportWithID:uuid]; - } else if (responseType & IS_USER) { - // parse the user and report to delegate. - [self parseUser:dataDict reportWithID:uuid]; - } else if (responseType & IS_POST) { - // parse post and report. - [self parsePost:dataDict reportWithID:uuid]; - } + NSAssert(dataObj, @"No valid object!"); - } else if (responseType & LIST) { - NSArray *array = [[data objectFromJSONData] objectForKey:DATA_KEY]; - [self parseArray:array responseType:responseType reportWithID:uuid]; + block(dataObj, nil); } - - // TODO: Handle parsing HAS_SCOPES return type. } //------------------------------------------------------------------------------ #pragma mark Private Helper Methods //------------------------------------------------------------------------------ -- (void) setHeader:(NSMutableURLRequest*)request +- (void) setHeader:(ADNURLRequest*)request { NSString *val = [NSString stringWithFormat:@"Bearer %@", _accessToken]; [request setValue:val forHTTPHeaderField:ADN_AUTH_HEADER]; @@ -163,12 +164,11 @@ - (NSString*) assembleParamString:(NSDictionary*)params //------------------------------------------------------------------------------ -- (NSMutableURLRequest*) createRequest:(NSString*)uri +- (ADNURLRequest*) createRequest:(NSString*)uri { NSString *fulluri = [NSString stringWithFormat:@"%@%@", ADN_API_URL, uri]; NSURL *url = [NSURL URLWithString:fulluri]; - NSMutableURLRequest *request = - [[NSMutableURLRequest alloc] initWithURL:url]; + ADNURLRequest *request = [[ADNURLRequest alloc] initWithURL:url]; [self setHeader:request]; return request; @@ -179,8 +179,7 @@ - (NSMutableURLRequest*) createRequest:(NSString*)uri // This will create a GET request but also sets the appropriate GET paramets // from the dictionary of parameters given. It assumes that the keys and values // of the given "params" dictionary are all NSString. -- (NSMutableURLRequest*) createRequest:(NSString*)uri - params:(NSDictionary*)params +- (ADNURLRequest*) createRequest:(NSString*)uri params:(NSDictionary*)params { NSString *paramString = @""; @@ -189,7 +188,7 @@ - (NSMutableURLRequest*) createRequest:(NSString*)uri NSString *fulluri = [NSString stringWithFormat:@"%@?%@", uri, paramString]; - NSMutableURLRequest *request = [self createRequest:fulluri]; + ADNURLRequest *request = [self createRequest:fulluri]; return request; } @@ -200,10 +199,9 @@ - (NSMutableURLRequest*) createRequest:(NSString*)uri // sent content of the BODY to include values in the key value pairs of the // given dictionary. Assumes that the keys and values in the dictionary are // strings. -- (NSMutableURLRequest*) createPostRequest:(NSString*)uri - params:(NSDictionary*)params +- (ADNURLRequest*) createPostRequest:(NSString*)uri params:(NSDictionary*)params { - NSMutableURLRequest *request = [self createRequest:uri]; + ADNURLRequest *request = [self createRequest:uri]; [request setHTTPMethod:@"POST"]; @@ -221,9 +219,9 @@ - (NSMutableURLRequest*) createPostRequest:(NSString*)uri //------------------------------------------------------------------------------ -- (NSMutableURLRequest*) createDeleteRequest:(NSString*)uri +- (ADNURLRequest*) createDeleteRequest:(NSString*)uri { - NSMutableURLRequest *request = [self createRequest:uri]; + ADNURLRequest *request = [self createRequest:uri]; [request setHTTPMethod:@"DELETE"]; @@ -232,35 +230,50 @@ - (NSMutableURLRequest*) createDeleteRequest:(NSString*)uri //------------------------------------------------------------------------------ -- (NSString*) sendRequest:(NSMutableURLRequest*)request - responseType:(enum ADNResponseType)responseType -{ - ADNURLConnection *connection = - [ADNURLConnection connectionWithRequest:request delegate:self - responseType:responseType]; - - // Preserve the connection. - [_connections setObject:connection forKey:connection.uuid]; - - return connection.uuid; -} - -//------------------------------------------------------------------------------ - -- (void) destroyConnection:(ADNURLConnection*)connection -{ - [_connections removeObjectForKey:[connection uuid]]; +- (void) sendRequest:(ADNURLRequest*)request + block:(void (^)(id jsonResp, NSError *err))block +{ + [NSURLConnection sendAsynchronousRequest:request + queue:NSOperationQueue.mainQueue + completionHandler:^(NSURLResponse *response, + NSData *data, + NSError *error) { + NSHTTPURLResponse *httpresp = (NSHTTPURLResponse*)response; + // Check if we have an error + if (error) { + block(nil, error); + } else { + NSInteger statusCode = [httpresp statusCode]; + if (statusCode >= 400) { + // Assume failure and report to user. + + // Convert data response into string. + NSString *body = [data length] ? + [NSString stringWithUTF8String:[data bytes]] : + @""; + NSMutableDictionary *info = [NSMutableDictionary dictionary]; + [info setObject:httpresp forKey:@"response"]; + [info setObject:body forKey:MESSAGE_KEY]; + + NSError *error = [NSError errorWithDomain:@"HTTP" + code:statusCode + userInfo:info]; + block(nil, error); + } else { + // parse the response and call the completion block from + // parsing method. + [self parseADNResponse:data block:block]; + } + } + }]; } //------------------------------------------------------------------------------ -- (AppDotNet*) initWithDelegate:(id)delegate - accessToken:(NSString*)token +- (AppDotNet*) initWithAccessToken:(NSString*)token { self = [super init]; - _delegate = delegate; _accessToken = [token retain]; - _connections = [[NSMutableDictionary dictionary] retain]; return self; } @@ -269,7 +282,6 @@ - (AppDotNet*) initWithDelegate:(id)delegate - (void) dealloc { [_accessToken release]; - [_connections release]; [_clientVersion release]; [_clientName release]; @@ -280,194 +292,213 @@ - (void) dealloc #pragma mark API Methods //------------------------------------------------------------------------------ - -- (NSString*) checkCurrentToken +- (void) checkCurrentTokenWithBlock:(ADNReceivedScopeAndUser)block { - NSMutableURLRequest *request = [self createRequest:@"/stream/0/token"]; - enum ADNResponseType responseType = DICT | HAS_USER | HAS_SCOPES; - return [self sendRequest:request responseType:responseType]; + ADNURLRequest *request = [self createRequest:@"/stream/0/token"]; + + [self sendRequest:request block:^(NSDictionary *jsonResp, NSError *err) { + if (err) { + block(nil, nil, err); + } else { + NSDictionary *userDict = [jsonResp objectForKey:USER_KEY]; + ADNUser *user = [ADNUser userFromJSONDictionary:userDict]; + + block(nil, user, nil); + } + }]; } //------------------------------------------------------------------------------ -- (NSString*) getUserWithUsername:(NSString*)username +- (void) userWithUsername:(NSString*)username block:(ADNReceivedUser)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/users/%@", username]; - NSMutableURLRequest *request = [self createRequest:uri]; - - enum ADNResponseType responseType = DICT | IS_USER; - - return [self sendRequest:request responseType:responseType]; + ADNURLRequest *request =[self createRequest:uri]; + + [self sendRequest:request block:^(NSDictionary *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedUserBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) getUserWithID:(NSUInteger)uid +- (void) userWithID:(NSUInteger)uid block:(ADNReceivedUser)block { NSString *str = [NSString stringWithFormat:@"%ld", uid]; - return [self getUserWithUsername:str]; + [self userWithUsername:str block:block]; } //------------------------------------------------------------------------------ -- (NSString*) getMe +- (void) meWithBlock:(ADNReceivedUser)block { - return [self getUserWithUsername:MY_USERID]; + [self userWithUsername:MY_USERID block:block]; } //------------------------------------------------------------------------------ -- (NSString*) followUserWithUsername:(NSString*)username +- (void) followUserWithUsername:(NSString*)username + block:(ADNReceivedUser)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/users/%@/follow", username]; - NSMutableURLRequest *request = [self createPostRequest:uri params:nil]; + ADNURLRequest *request = [self createPostRequest:uri params:nil]; - enum ADNResponseType responseType = DICT | IS_USER; - - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSDictionary *jsonResp, NSError *err) { + [self processResponse:jsonResp error:err receivedUserBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) followUserWithID:(NSUInteger)uid +- (void) followUserWithID:(NSUInteger)uid block:(ADNReceivedUser)block { NSString *str = [NSString stringWithFormat:@"%ld", uid]; - return [self followUserWithUsername:str]; + [self followUserWithUsername:str block:block]; } //------------------------------------------------------------------------------ -- (NSString*) unfollowUserWithUsername:(NSString*)username +- (void) unfollowUserWithUsername:(NSString*)username + block:(ADNReceivedUser)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/users/%@/follow", username]; - NSMutableURLRequest *request = [self createDeleteRequest:uri]; - - enum ADNResponseType responseType = DICT | IS_USER; + ADNURLRequest *request = [self createDeleteRequest:uri]; - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSDictionary *jsonResp, NSError *err) { + [self processResponse:jsonResp error:err receivedUserBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) unfollowUserWithID:(NSUInteger)uid +- (void) unfollowUserWithID:(NSUInteger)uid + block:(ADNReceivedUser)block { NSString *str = [NSString stringWithFormat:@"%ld", uid]; - return [self unfollowUserWithUsername:str]; + [self unfollowUserWithUsername:str block:block]; } //------------------------------------------------------------------------------ -- (NSString*) followedByUsername:(NSString*)username +- (void) followedByUsername:(NSString*)username + block:(ADNReceivedUsers)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/users/%@/following", username]; - NSMutableURLRequest *request = [self createRequest:uri]; - - enum ADNResponseType responseType = LIST | IS_USER; + ADNURLRequest *request = [self createRequest:uri]; - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSArray *jsonResp, NSError *err) { + [self processResponse:jsonResp error:err receivedUsersBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) followedByID:(NSUInteger)uid +- (void) followedByID:(NSUInteger)uid + block:(ADNReceivedUsers)block { NSString *str = [NSString stringWithFormat:@"%ld", uid]; - return [self followedByUsername:str]; + [self followedByUsername:str block:block]; } //------------------------------------------------------------------------------ -- (NSString*) followedByMe +- (void) followedByMeWithBlock:(ADNReceivedUsers)block { - return [self followedByUsername:MY_USERID]; + return [self followedByUsername:MY_USERID block:block]; } //------------------------------------------------------------------------------ -- (NSString*) followersOfUsername:(NSString*)username +- (void) followersOfUsername:(NSString*)username + block:(ADNReceivedUsers)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/users/%@/followers", username]; - NSMutableURLRequest *request = [self createRequest:uri]; + ADNURLRequest *request = [self createRequest:uri]; - enum ADNResponseType responseType = LIST | IS_USER; - - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSArray *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedUsersBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) followersOfID:(NSUInteger)uid +- (void) followersOfID:(NSUInteger)uid + block:(ADNReceivedUsers)block { NSString *str = [NSString stringWithFormat:@"%ld", uid]; - return [self followersOfUsername:str]; + [self followersOfUsername:str block:block]; } //------------------------------------------------------------------------------ -- (NSString*) followersOfMe +- (void) followersOfMeWithBlock:(ADNReceivedUsers)block { - return [self followersOfUsername:MY_USERID]; + [self followersOfUsername:MY_USERID block:block]; } //------------------------------------------------------------------------------ -- (NSString*) muteUserWithUsername:(NSString *)username +- (void) muteUserWithUsername:(NSString*)username + block:(ADNReceivedUser)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/users/%@/mute", username]; - NSMutableURLRequest *request = [self createPostRequest:uri params:nil]; - - enum ADNResponseType responseType = DICT | IS_USER; + ADNURLRequest *request = [self createPostRequest:uri params:nil]; - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSDictionary *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedUserBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) muteUserWithID:(NSUInteger)uid +- (void) muteUserWithID:(NSUInteger)uid + block:(ADNReceivedUser)block { NSString *str = [NSString stringWithFormat:@"%ld", uid]; - return [self muteUserWithUsername:str]; + [self muteUserWithUsername:str block:block]; } //------------------------------------------------------------------------------ -- (NSString*) unmuteUserWithUsername:(NSString *)username +- (void) unmuteUserWithUsername:(NSString *)username + block:(ADNReceivedUser)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/users/%@/mute", username]; - NSMutableURLRequest *request = [self createDeleteRequest:uri]; - - enum ADNResponseType responseType = DICT | IS_USER; - - return [self sendRequest:request responseType:responseType]; + ADNURLRequest *request = [self createDeleteRequest:uri]; + + [self sendRequest:request block:^(NSDictionary *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedUserBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) unmuteUserWithID:(NSUInteger)uid +- (void) unmuteUserWithID:(NSUInteger)uid block:(ADNReceivedUser)block { NSString *str = [NSString stringWithFormat:@"%ld", uid]; - return [self muteUserWithUsername:str]; + [self muteUserWithUsername:str block:block]; } //------------------------------------------------------------------------------ -- (NSString*) writePost:(NSString*)text - replyToPostWithID:(NSInteger)postId - annotations:(NSDictionary*)annotations - links:(NSArray*)links +- (void) writePost:(NSString*)text + replyToPostWithID:(NSInteger)postId + annotations:(NSDictionary*)annotations + links:(NSArray*)links + block:(ADNReceivedPost)block { NSString *uri = @"/stream/0/posts"; @@ -492,120 +523,127 @@ - (NSString*) writePost:(NSString*)text [postValues setObject:text forKey:TEXT_KEY]; - NSMutableURLRequest *request = [self createPostRequest:uri - params:postValues]; - - enum ADNResponseType responseType = DICT | IS_POST; + ADNURLRequest *request = [self createPostRequest:uri params:postValues]; - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSDictionary *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedPostBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) postWithID:(NSUInteger)postId +- (void) postWithID:(NSUInteger)postId + block:(ADNReceivedPost)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/posts/%ld", postId]; - NSMutableURLRequest *request = [self createRequest:uri]; + ADNURLRequest *request = [self createRequest:uri]; - enum ADNResponseType responseType = DICT | IS_POST; - - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSDictionary *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedPostBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) deletePostWithID:(NSUInteger)postId +- (void) deletePostWithID:(NSUInteger)postId + block:(ADNReceivedPost)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/posts/%ld", postId]; - NSMutableURLRequest *request = [self createDeleteRequest:uri]; - - enum ADNResponseType responseType = DICT | IS_POST; + ADNURLRequest *request = [self createDeleteRequest:uri]; - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSDictionary *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedPostBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) repliesToPostWithID:(NSUInteger)postId +- (void) repliesToPostWithID:(NSUInteger)postId + block:(ADNReceivedPosts)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/posts/%ld/replies", postId]; - NSMutableURLRequest *request = [self createRequest:uri]; - - enum ADNResponseType responseType = LIST | IS_POST; + ADNURLRequest *request = [self createRequest:uri]; - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSArray *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedPostsBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) postsByUserWithUsername:(NSString*)username +- (void) postsByUserWithUsername:(NSString*)username + block:(ADNReceivedPosts)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/users/%@/posts/", username]; - NSMutableURLRequest *request = [self createRequest:uri]; + ADNURLRequest *request = [self createRequest:uri]; - enum ADNResponseType responseType = LIST | IS_POST; - - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSArray *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedPostsBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) postsByUserWithID:(NSUInteger)uid +- (void) postsByUserWithID:(NSUInteger)uid + block:(ADNReceivedPosts)block { NSString *str = [NSString stringWithFormat:@"%ld", uid]; - return [self postsByUserWithUsername:str]; + [self postsByUserWithUsername:str block:block]; } //------------------------------------------------------------------------------ -- (NSString*) postsByMe +- (void) postsByMeWithBlock:(ADNReceivedPosts)block { - return [self postsByUserWithUsername:MY_USERID]; + [self postsByUserWithUsername:MY_USERID block:block]; } //------------------------------------------------------------------------------ -- (NSString*) postsMentioningUserWithUsername:(NSString*)username +- (void) postsMentioningUserWithUsername:(NSString*)username + block:(ADNReceivedPosts)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/users/%@/mentions", username]; - NSMutableURLRequest *request = [self createRequest:uri]; - - enum ADNResponseType responseType = LIST | IS_POST; + ADNURLRequest *request = [self createRequest:uri]; - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSArray *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedPostsBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) postsMentioningUserWithID:(NSUInteger)uid +- (void) postsMentioningUserWithID:(NSUInteger)uid + block:(ADNReceivedPosts)block { NSString *str = [NSString stringWithFormat:@"%ld", uid]; - return [self postsMentioningUserWithUsername:str]; + [self postsMentioningUserWithUsername:str block:block]; } //------------------------------------------------------------------------------ -- (NSString*) postsMentioningMe +- (void) postsMentioningMeWithBlock:(ADNReceivedPosts)block; { - return [self postsMentioningUserWithUsername:MY_USERID]; + return [self postsMentioningUserWithUsername:MY_USERID block:block]; } //------------------------------------------------------------------------------ -- (NSString*) mutedUsers +- (void) mutedUsersWithBlock:(ADNReceivedUsers)block { NSString *uri = @"/stream/0/users/me/muted"; - NSMutableURLRequest *request = [self createRequest:uri]; - enum ADNResponseType responseType = LIST | IS_USER; - return [self sendRequest:request responseType:responseType]; + ADNURLRequest *request = [self createRequest:uri]; + [self sendRequest:request block:^(NSArray *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedUsersBlock:block]; + }]; } //------------------------------------------------------------------------------ @@ -645,12 +683,13 @@ - (NSDictionary*) postParamsSinceID:(NSInteger)sinceId //------------------------------------------------------------------------------ -- (NSString*) myStreamSinceID:(NSInteger)sinceId - beforeID:(NSInteger)beforeId - count:(NSUInteger)count - includeUser:(BOOL)includeUser - includeAnnotations:(BOOL)includeAnnotations - includeReplies:(BOOL)includeReplies +- (void) myStreamSinceID:(NSInteger)sinceId + beforeID:(NSInteger)beforeId + count:(NSUInteger)count + includeUser:(BOOL)includeUser + includeAnnotations:(BOOL)includeAnnotations + includeReplies:(BOOL)includeReplies + block:(ADNReceivedPosts)block { NSString *uri = @"/stream/0/posts/stream"; @@ -663,21 +702,22 @@ - (NSString*) myStreamSinceID:(NSInteger)sinceId includeReplies:includeReplies]; // Create the Get request with parameters. - NSMutableURLRequest *request = [self createRequest:uri params:params]; - - enum ADNResponseType responseType = LIST | IS_POST; + ADNURLRequest *request = [self createRequest:uri params:params]; - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSArray *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedPostsBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) globalStreamSinceID:(NSInteger)sinceId - beforeID:(NSInteger)beforeId - count:(NSUInteger)count - includeUser:(BOOL)includeUser - includeAnnotations:(BOOL)includeAnnotations - includeReplies:(BOOL)includeReplies +- (void) globalStreamSinceID:(NSInteger)sinceId + beforeID:(NSInteger)beforeId + count:(NSUInteger)count + includeUser:(BOOL)includeUser + includeAnnotations:(BOOL)includeAnnotations + includeReplies:(BOOL)includeReplies + block:(ADNReceivedPosts)block { NSString *uri = @"/stream/0/posts/stream/global"; @@ -690,22 +730,23 @@ - (NSString*) globalStreamSinceID:(NSInteger)sinceId includeReplies:includeReplies]; // Create the Get request with parameters. - NSMutableURLRequest *request = [self createRequest:uri params:params]; + ADNURLRequest *request = [self createRequest:uri params:params]; - enum ADNResponseType responseType = LIST | IS_POST; - - return [self sendRequest:request responseType:responseType]; + [self sendRequest:request block:^(NSArray *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedPostsBlock:block]; + }]; } //------------------------------------------------------------------------------ -- (NSString*) taggedPostsWithTag:(NSString*)tag - sinceID:(NSInteger)sinceId - beforeID:(NSInteger)beforeId - count:(NSUInteger)count - includeUser:(BOOL)includeUser - includeAnnotations:(BOOL)includeAnnotations - includeReplies:(BOOL)includeReplies +- (void) taggedPostsWithTag:(NSString*)tag + sinceID:(NSInteger)sinceId + beforeID:(NSInteger)beforeId + count:(NSUInteger)count + includeUser:(BOOL)includeUser + includeAnnotations:(BOOL)includeAnnotations + includeReplies:(BOOL)includeReplies + block:(ADNReceivedPosts)block { NSString *uri = [NSString stringWithFormat:@"/stream/0/posts/tag/%@", tag]; @@ -718,74 +759,11 @@ - (NSString*) taggedPostsWithTag:(NSString*)tag includeReplies:includeReplies]; // Create the Get request with parameters. - NSMutableURLRequest *request = [self createRequest:uri params:params]; - - enum ADNResponseType responseType = LIST | IS_POST; - - return [self sendRequest:request responseType:responseType]; -} - -//------------------------------------------------------------------------------ -#pragma mark NSURLConnection Methods -//------------------------------------------------------------------------------ - -- (void) connection:(ADNURLConnection*)connection - didReceiveResponse:(NSURLResponse*)response -{ - // We got a response, so we start by emptying out the data. - [connection resetDataLength]; - - connection.response = (NSHTTPURLResponse*)response; -} - -//------------------------------------------------------------------------------ - -- (void) connection:(ADNURLConnection*)connection didReceiveData:(NSData*)data -{ - // Got some new data, so just append it. - [connection appendData:data]; -} - -//------------------------------------------------------------------------------ - -- (void) connection:(ADNURLConnection*)connection - didFailWithError:(NSError*)error -{ - // Inform the delegate and release connection. - [_delegate requestFailed:error forRequestUUID:connection.uuid]; - [self destroyConnection:connection]; -} - -//------------------------------------------------------------------------------ - -- (void) connectionDidFinishLoading:(ADNURLConnection*)connection -{ - // Once this method is invoked, "data" contains the complete result - NSMutableData *data = connection.data; - - // Check status code. - NSInteger statusCode = [[connection response] statusCode]; - if (statusCode >= 400){ - // Assume failure and report to delegate. - - // Convert response data to string. - NSString *body = - [data length] ? [NSString stringWithUTF8String:[data bytes]] : @""; - NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys: - [connection response], @"response", - body, @"body", - nil]; - NSError *error = [NSError errorWithDomain:@"HTTP" - code:statusCode - userInfo:info]; - - // Report to delegate. - [_delegate requestFailed:error forRequestUUID:connection.uuid]; - } else { - [self parseDataForConnection:connection]; - } + ADNURLRequest *request = [self createRequest:uri params:params]; - [self destroyConnection:connection]; + [self sendRequest:request block:^(NSArray *jsonResp, NSError *error) { + [self processResponse:jsonResp error:error receivedPostsBlock:block]; + }]; } //------------------------------------------------------------------------------