Objective-C library for working with App.net.
Objective-C C
Latest commit 877d35e Nov 15, 2012 Brent Royal-Gordon Fix bug making ANResponse.marker not work
@synthesize strikes again!
Permalink
Failed to load latest commit information.
ANAccessTokenInformationRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANAccessTokenInformationRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANAnnotation.h
ANAnnotation.m
ANAuthenticatedRequest.h Turn requiresAccessToken into a class method Oct 25, 2012
ANAuthenticatedRequest.m
ANAuthenticator.h
ANAuthenticator.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANCompletions.h Support for stream markers Nov 14, 2012
ANCreateFilterRequest.h Add ability to create and delete filters Oct 21, 2012
ANCreateFilterRequest.m
ANCreatePostRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANCreatePostRequest.m
ANDefines.h
ANDeleteFilterRequest.h Add ability to create and delete filters Oct 21, 2012
ANDeleteFilterRequest.m Add ability to create and delete filters Oct 21, 2012
ANDeleteFiltersForUserRequest.h
ANDeleteFiltersForUserRequest.m Add ability to create and delete filters Oct 21, 2012
ANDeletePostRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANDeletePostRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANDraft.h Support for draft entities Nov 7, 2012
ANDraft.m Support for draft entities Nov 7, 2012
ANEntity.h
ANEntity.m
ANFilter.h
ANFilter.m Add filter-updating request Oct 21, 2012
ANFilterRequest.h Support for filter reading requests Oct 21, 2012
ANFilterRequest.m
ANFiltersForCurrentUserRequest.h
ANFiltersForCurrentUserRequest.m Support for filter reading requests Oct 21, 2012
ANFollowUserRequest.h
ANFollowUserRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANFollowersForUserRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANFollowersForUserRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANFollowingsForUserRequest.h
ANFollowingsForUserRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANIdentifiedResource.h Extract a common superclass for ANUser and ANPost Sep 1, 2012
ANIdentifiedResource.m Add an ID number to descriptions of ANIdentifiedResources Nov 12, 2012
ANImage.h
ANImage.m Retina support in ANImage Nov 12, 2012
ANMuteUserRequest.h
ANMuteUserRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANMutingsForUserRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANMutingsForUserRequest.m
ANPost.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANPost.m
ANPostRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANPostRequest.m Turn requiresAccessToken into a class method Oct 25, 2012
ANPostsByUserRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANPostsByUserRequest.m
ANPostsInGlobalStreamRequest.h
ANPostsInGlobalStreamRequest.m
ANPostsInUserStreamRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANPostsInUserStreamRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANPostsInUserUnifiedStreamRequest.h Add support for the new unified stream endpoint Oct 25, 2012
ANPostsInUserUnifiedStreamRequest.m Add support for the new unified stream endpoint Oct 25, 2012
ANPostsMentioningUserRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANPostsMentioningUserRequest.m
ANPostsReplyingToPostRequest.h
ANPostsReplyingToPostRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANPostsStarredByUserRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANPostsStarredByUserRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANPostsWithTagRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANPostsWithTagRequest.m Turn requiresAccessToken into a class method Oct 25, 2012
ANRepostPostRequest.h
ANRepostPostRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANRequest.h Make ANRequest.session mutable Oct 26, 2012
ANRequest.m
ANRequestReturningPostList.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANRequestReturningPostList.m
ANResource+Magic.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANResource+Magic.m Wrap associated objects in a nice API Nov 12, 2012
ANResource.h Note which requests require authentication Oct 25, 2012
ANResource.m Wrap associated objects in a nice API Nov 12, 2012
ANResponse.h Fix bug making ANResponse.marker not work Nov 15, 2012
ANResponse.m Fix bug making ANResponse.marker not work Nov 15, 2012
ANSession+ANResource_Private.h
ANSession+Requests.h Support for stream markers Nov 14, 2012
ANSession+Requests.m
ANSession.h Support for stream markers Nov 14, 2012
ANSession.m Avoid iOS 6/Mountain Lion-only construct Nov 15, 2012
ANSource.h
ANSource.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANStarPostRequest.h
ANStarPostRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANStreamMarker.h Support for stream markers Nov 14, 2012
ANStreamMarker.m Support for stream markers Nov 14, 2012
ANUnfollowUserRequest.h
ANUnfollowUserRequest.m
ANUnmuteUserRequest.h
ANUnmuteUserRequest.m
ANUnrepostPostRequest.h
ANUnrepostPostRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUnstarPostRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUnstarPostRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUpdateFilterRequest.h Add filter-updating request Oct 21, 2012
ANUpdateFilterRequest.m Add filter-updating request Oct 21, 2012
ANUpdateStreamMarkerRequest.h Support for stream markers Nov 14, 2012
ANUpdateStreamMarkerRequest.m
ANUser.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUser.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUserCounts.h
ANUserCounts.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUserDescription.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUserDescription.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUserRequest.h
ANUserRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUsernameRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUsernameRequest.m
ANUsersMatchingSearchQueryRequest.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUsersMatchingSearchQueryRequest.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ANUsersWithPostRepostedRequest.h
ANUsersWithPostRepostedRequest.m
ANUsersWithPostStarredRequest.h
ANUsersWithPostStarredRequest.m
AppNetKit.h Support for filter reading requests Oct 21, 2012
AppNetKit.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
ISO8601DateFormatter.h Initial check-in Aug 19, 2012
ISO8601DateFormatter.m
NSDictionary+Parameters.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
NSDictionary+Parameters.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
NSDictionary+dictionaryWithObjectsForKeys.h
NSDictionary+dictionaryWithObjectsForKeys.m
NSObject+AssociatedObject.h Wrap associated objects in a nice API Nov 12, 2012
NSObject+AssociatedObject.m Wrap associated objects in a nice API Nov 12, 2012
NSString+AppNetExtensions.h Declare AppNetKit to be MIT-licensed Oct 17, 2012
NSString+AppNetExtensions.m Declare AppNetKit to be MIT-licensed Oct 17, 2012
README.md Declare AppNetKit to be MIT-licensed Oct 17, 2012
_ANIdentifiedResourceSet.h
_ANIdentifiedResourceSet.m

README.md

AppNetKit

AppNetKit is an Objective-C library for communicating with the App.net Stream API. It is completely asynchronous, using blocks to notify you of completions.

AppNetKit covers the Token, Users, and Posts parts of the App.net API—all the portions available as of late August 2012.

Synopsis

ANSession.defaultSession.accessToken = myOAuthToken;

// Get the latest posts in the user's incoming post stream...
[ANSession.defaultSession postsInStreamWithCompletion:^(ANResponse * response, NSArray * posts, NSError * error) {
    if(!posts) {
        [self doSomethingWithError:error];
        return;
    }

    // Grab the most recent post.
    ANPost * latestPost = posts[0];

    // Compose a reply...
    ANDraft * newPost = [latestPost draftReply];
    newPost.text = [newPost.text appendString:@"Me too!"];  // The default text includes an @mention

    // And post it.
    [newPost createPostViaSession:ANSession.defaultSession completion:^(ANResponse * response, ANPost * post, NSError * error) {
        if(!post) {
            [self doSomethingWithError:error];
        }
    }];
}];

Quick Tour

ANAuthenticator

This is an OAuth helper singleton. Set the client ID and redirect URL, then use the other methods to help you generate OAuth URLs and parse out the accessToken from the response.

ANSession

ANSession is the central object in AppNetKit. Through it, you can fetch users and posts from App.net, create and delete posts, and do everything else the API permits.

You can create your own session using [[ANSession alloc] init] as usual, but if your app only requires one session, you can use [ANSession defaultSession] as a shortcut. Set your session's accessToken property to an OAuth token, then you can start working with App.net.

ANSession includes methods to perform most requests on the App.net API, from "fetch a user with a specific name" (-userWithUsername:completion:) to "fetch all posts with a specific hashtag between these two post IDs" (-postsWithTag:betweenID:andID:completion:).

These requests all take a completion handler--a block that will be called when the request has been completed. Completion handlers usually take three parameters:

  1. An ANResponse object containing metadata about your request. This parameter will be nil unless your app has enabled the "response_envelope" migration.

  2. The data you requested, as either a single ANResource object or an array of ANResource objects. If the request failed, this parameter will be nil.

  3. An NSError object. If the request succeeded, this parameter will be nil.

Some calls to retrieve posts take a pair of post IDs, and return only posts between those two IDs. The higher post ID should always be the first of those two parameters. If you don't want to provide one of these post IDs, pass the ANUnspecifiedPostID constant instead.

Calls to retrieve user-related data often take a user ID. If you want data for the currently logged-in user, you can pass the ANMeUserID constant for these parameters.

ANSession also manages UIApplication's network activity indicator. This should probably be configurable in various ways, not the least because it's the only way in which this library depends on iOS-specific APIs.

ANResource, ANUser, and ANPost

ANResource represents anything the server sends as a JSON object. Each ANResource has a representation property, which contains the object's JSON data parsed into Objective-C dictionaries, arrays, strings, etc. Each resource type has properties that convert this raw data to appropriate data types--from NSString for text data to NSTimeZone for an ANUser's timezone property.

Because ANResources represent data from the server, you cannot change them in any way, and you should not attempt to allocate them yourself. Instead, use ANRequest objects, ANSession methods, or helper methods on ANResource subclasses to retrieve them from App.net.

ANUser and ANPost are subclasses for the Stream API's User and Post objects, respectively. These classes (or rather their superclass, ANIdentifiedResource) are uniqued—fetching the same post or user from a given ANSession will always return the same ANUser or ANPost instance. That means that an ANUser or ANPost that you already have may be updated. Use key-value observing or register for the ANResourceDidUpdateNotification to find out when this happens.

Many ANResource objects have helper methods to perform common operations with them; for instance, ANUser has a -followWithCompletion: method, and ANPost has a -replyPostsWithCompletion: method. These are convenience methods which simply call the equivalent ANSession methods (in these cases, -followUserWithID:completion: and -postsReplyingToPostWithID:betweenID:andID:completion:).

Certain ANResource objects conform to the ANTextualResource protocol. These objects include a text property with plain text, an HTML property with HTML markup, and an entities property with entities covering portions of the plain text. You can use the same code to handle all ANTextualResources.

Related to resource objects is ANDraft, which represents a post that hasn't yet been created. You can create a draft yourself by using [[ANDraft alloc] init], or you can use a convenience method on another class, like -[ANPost replyDraft]. Post a reply with either -[ANDraft createPostViaSession:completion:] or -[ANSession createPostFromDraft:completion:].

ANRequest and subclasses

ANRequest subclasses represent specific API requests. You don't normally have to use them--ANSession has APIs for common requests--but they are public API, and using them directly can give you finer control than ANSession allows.

Create an ANRequest with the -initWithSession: constructor, then set whatever properties are available on that request and call -sendRequestWithCompletion: to perform the request. You can reuse the same request as many times as you'd like.

ANMutableRequest and ANMutableAuthenticatedRequest are also available for your use. These allow you to create your own requests to custom URLs. AppNetKit itself uses them to fetch images for the ANImage resource.

NSString+AppNetExtensions

AppNetKit adds two methods to NSString. -appNetUsernameString prepends an @ character to a username, and -appNetTagString prepends a # character.

Author

Brent Royal-Gordon, Architechies brent@architechies.com, @brent on App.net.

Please let me know if you use AppNetKit in a project. I'm curious about what people will do with this!

Bugs

A lot of the code in this library has never actually been run as I write this, so it's likely to have plenty of bugs. If you want to write unit tests to exercise all this code, I'll be happy to pull them in. (Packaging this mess as an Xcode project might be a good idea, too...)

Also note that my own development is for iOS 6; I don't believe there are any iOS 6-only APIs in AppNetKit, but it's possible a call or two snuck in. Again, patches are welcome.

If you find a problem, file an issue or write a patch and send it to me (preferably as a pull request, but I'm not picky).

Copyright

This software is licensed under the MIT license:

Copyright (C) 2012 Architechies.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.