Skip to content

Commit

Permalink
refactored to use blocks instead of delegates.
Browse files Browse the repository at this point in the history
  • Loading branch information
akashkgarg committed Aug 25, 2012
1 parent c7011ac commit daedc31
Show file tree
Hide file tree
Showing 12 changed files with 807 additions and 646 deletions.
261 changes: 203 additions & 58 deletions README.md
Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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.
Expand Down
18 changes: 12 additions & 6 deletions objc-appdotnet.xcodeproj/project.pbxproj
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -43,10 +44,12 @@
/* Begin PBXFileReference section */
3801A75C15E50C6900CF720C /* ISO8601DateFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ISO8601DateFormatter.h; sourceTree = "<group>"; };
3801A75D15E50C6900CF720C /* ISO8601DateFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ISO8601DateFormatter.m; sourceTree = "<group>"; };
3801A76015E52CD300CF720C /* ADNURLConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADNURLConnection.h; sourceTree = "<group>"; };
3801A76115E52CD300CF720C /* ADNURLConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADNURLConnection.m; sourceTree = "<group>"; };
3801A76315E5ABA200CF720C /* ADNPost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADNPost.h; sourceTree = "<group>"; };
3801A76415E5ABA200CF720C /* ADNPost.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADNPost.m; sourceTree = "<group>"; };
3859D34915E9575E00F5D15F /* ADNScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADNScope.h; sourceTree = "<group>"; };
3859D34A15E9575E00F5D15F /* ADNScope.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADNScope.m; sourceTree = "<group>"; };
3859D34D15E979EA00F5D15F /* ADNURLRequest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ADNURLRequest.h; sourceTree = "<group>"; };
3859D34E15E979EA00F5D15F /* ADNURLRequest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ADNURLRequest.m; sourceTree = "<group>"; };
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; };
Expand Down Expand Up @@ -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 = "<group>";
Expand Down Expand Up @@ -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;
};
Expand Down
2 changes: 1 addition & 1 deletion objc-appdotnet/AppDelegate.h
Expand Up @@ -9,7 +9,7 @@
#import <Cocoa/Cocoa.h>
#import "app.net/AppDotNet.h"

@interface AppDelegate : NSObject <NSApplicationDelegate, ADNDelegate>
@interface AppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;

Expand Down

0 comments on commit daedc31

Please sign in to comment.