Skip to content

Commit

Permalink
Moving towards a more framework-ish way.
Browse files Browse the repository at this point in the history
This commit adds two new classes and a new protocol:

* TKPostsRequest: Responsible for retrieve and parse Tumblr posts, based on options passed.
* TKPostsResponse: Response created by TKPostsRequest after it successfully retrieved and parsed Tumblr posts.
* TKPostsRequestDelegate: Protocol a class should implement to be a TKPostsRequest delegate.
  • Loading branch information
Igor Sutton committed Dec 15, 2011
1 parent 3293242 commit 207be2d
Show file tree
Hide file tree
Showing 12 changed files with 743 additions and 79 deletions.
58 changes: 58 additions & 0 deletions TKPostsRequest.h
@@ -0,0 +1,58 @@
//
// Copyright (c) 2011 TumblrKit
//
// 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.
//

#import "TKRequest.h"

@class TKPostsRequest;
@class TKPostsResponse;
@class TKPost;

@protocol TKPostsRequestDelegate <NSObject>

- (void)postsRequest:(TKPostsRequest *)request didReceiveResponse:(TKPostsResponse *)response;
- (void)postsRequest:(TKPostsRequest *)request didFailWithError:(NSError *)error;

@end

@interface TKPostsRequest : TKRequest <NSXMLParserDelegate>
{
@private
NSDictionary *_options;
NSMutableArray *_receivedPosts;
NSXMLParser *_parser;
NSString *_currentElementName;
TKPost *_currentPost;
}

#pragma mark - API

@property (nonatomic, assign) id<TKPostsRequestDelegate> delegate;
@property (readonly) NSDictionary *options;

- (id)initWithOptions:(NSDictionary *)options delegate:(id<TKPostsRequestDelegate>)delegate;

@end

extern NSString *TKPostsRequestDomainKey;
extern NSString *TKPostsRequestPostIDKey;
extern NSString *TKPostsRequestStartAtIndexKey;
extern NSString *TKPostsRequestNumberOfPostsKey;
146 changes: 146 additions & 0 deletions TKPostsRequest.m
@@ -0,0 +1,146 @@
//
// Copyright (c) 2011 TumblrKit
//
// 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.
//

#import "TKPostsRequest.h"
#import "TKPostsResponse.h"
#import "TKPost.h"

@implementation TKPostsRequest

@synthesize delegate = _delegate;

#pragma mark - NSObject

- (void)dealloc;
{
[_receivedPosts release]; _receivedPosts = nil;
[_options release]; _options = nil;
[_parser release]; _parser = nil;
[super dealloc];
}

#pragma mark - NSXMLParserDelegate

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;
{
_currentElementName = elementName;

if ([elementName isEqualToString:@"post"])
_currentPost = [[TKPost postWithAttributes:attributeDict] retain];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
{
if ([elementName isEqualToString:@"post"]) {
[_receivedPosts addObject:_currentPost];
[_currentPost release];
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
{
static NSDictionary *elementToSelectorDict = nil;

if (!elementToSelectorDict) {
elementToSelectorDict = [[NSDictionary alloc] initWithObjectsAndKeys:
@"appendToText:", @"text",
@"appendToCaption:",@"caption",
@"appendToPlayer:", @"player",
@"appendToBody:", @"body",
@"setURLWithString:", @"url",
nil];
}

NSString *key = [[_currentElementName componentsSeparatedByString:@"-"] lastObject];
SEL selector = NSSelectorFromString([elementToSelectorDict objectForKey:key]);
if (selector && [_currentPost respondsToSelector:selector]) {
[_currentPost performSelector:selector withObject:string];
}
}

- (void)parserDidEndDocument:(NSXMLParser *)parser;
{
[_currentPost release]; _currentPost = nil;
TKPostsResponse *response = [[[TKPostsResponse alloc] initWithPosts:_receivedPosts] autorelease];
[self.delegate postsRequest:self didReceiveResponse:response];
}

#pragma mark - TKRequest

- (NSURL *)URL;
{
NSMutableDictionary *options = [_options mutableCopy];
NSString *domain = [options objectForKey:TKPostsRequestDomainKey];
[options removeObjectForKey:TKPostsRequestDomainKey];
NSMutableString *URLString = [NSMutableString stringWithFormat:@"http://%@/api/read?", domain];

NSMutableArray *queryStringArray = [NSMutableArray array];
for (NSString *key in [options allKeys]) {
NSString *value = [options objectForKey:key];
[queryStringArray addObject:[NSString stringWithFormat:@"%@=%@", key, value]];
}

[URLString appendString:[queryStringArray componentsJoinedByString:@"&"]];
NSURL *URL = [NSURL URLWithString:URLString];
return URL;
}

- (void)connectionDidFinishLoadingData:(NSData *)data;
{
_parser = [[NSXMLParser alloc] initWithData:data];
[_parser setDelegate:self];
[_parser parse];
}

- (void)connectionDidFailWithError:(NSError *)error;
{
[self.delegate postsRequest:self didFailWithError:error];
}

#pragma mark - API

- (id)initWithOptions:(NSDictionary *)options delegate:(id<TKPostsRequestDelegate>)delegate;
{
if (!(self = [self init]))
return nil;

if (![options objectForKey:TKPostsRequestDomainKey])
[NSException raise:@"TKPostsRequestDomainKey is mandatory" format:@"TKPostsRequestDomainKey is mandatory"];

_receivedPosts = [[NSMutableArray alloc] init];
_options = [options retain];
_delegate = delegate;

return self;
}

- (NSDictionary *)options;
{
return _options;
}

@end

NSString const * TKPostsRequestDomainKey = @"domain";
NSString const * TKPostsRequestPostIDKey = @"id";
NSString const * TKPostsRequestStartAtIndexKey = @"start";
NSString const * TKPostsRequestNumberOfPostsKey = @"num";
31 changes: 31 additions & 0 deletions TKPostsResponse.h
@@ -0,0 +1,31 @@
//
// Copyright (c) 2011 TumblrKit
//
// 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.
//

@interface TKPostsResponse : NSObject

@property (nonatomic, retain) NSArray *posts;

#pragma mark - API

- (id)initWithPosts:(NSArray *)posts;

@end
49 changes: 49 additions & 0 deletions TKPostsResponse.m
@@ -0,0 +1,49 @@
//
// Copyright (c) 2011 TumblrKit
//
// 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.
//

#import "TKPostsResponse.h"

@implementation TKPostsResponse

@synthesize posts = _posts;

#pragma mark - NSObject

- (void)dealloc;
{
[_posts release]; _posts = nil;
[super dealloc];
}

#pragma mark - API

- (id)initWithPosts:(NSArray *)posts;
{
if (!(self = [self init]))
return nil;

_posts = [posts retain];

return self;
}

@end
47 changes: 26 additions & 21 deletions Test.m → TKRequest.h
@@ -1,5 +1,5 @@
// //
// Copyright (c) 2010, 2011 TumblrKit // Copyright (c) 2011 TumblrKit
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal // of this software and associated documentation files (the "Software"), to deal
Expand All @@ -20,31 +20,36 @@
// THE SOFTWARE. // THE SOFTWARE.
// //


#import <Cocoa/Cocoa.h> @class TKRequest;
#import "TKTumblr.h"
#import "TKTumblrConnection.h"
#import "TKTumblrRequest.h"
#import "TKTumblrResponse.h"


@protocol TKRequestable <NSObject>


int main(int argc, char **argv) { @optional
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - (void)connectionDidFinishLoadingData:(NSData *)data;
- (void)connectionDidFailWithError:(NSError *)error;


TKTumblrRequest *req = [[TKTumblrRequest alloc] initWithURL:[NSURL URLWithString:@"http://igorsutton.com"]]; @optional
req.postFilter = TKPostFilterText; - (NSData *)HTTPBody;
req.startIndex = 2;
req.numberOfPosts = 1;
req.postType = TKPostTypeLink;


TKTumblrConnection *conn = [[TKTumblrConnection alloc] init]; @required
- (NSURL *)URL;


TKTumblrResponse *res = nil; @end
NSError *error = nil;


[conn sendSynchronousRequest:req returningResponse:&res error:&error]; #if TARGET_OS_MAC
@interface TKRequest : NSObject <TKRequestable,NSURLConnectionDelegate>
#elif TARGET_OS_IPHONE
@interface TKRequest : NSObject <TKRequestable,NSURLConnectionDelegate,NSURLConnectionDataDelegate>
#endif
{
@protected
NSURLConnection *_connection;
NSMutableData *_receivedData;
}


Log(@"%@", res.posts); #pragma mark - API
Log(@"%@", [req URLForWrite]);


[pool drain]; - (void)start;
} - (void)cancel;

@end

0 comments on commit 207be2d

Please sign in to comment.