Skip to content

Commit 995266f

Browse files
committed
gridview
0 parents  commit 995266f

13 files changed

+1036
-0
lines changed

DataService.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#import <Foundation/Foundation.h>
2+
3+
#define RESPONSE_OK 200
4+
#define RESPONSE_CLIENT_ERROR 400
5+
#define RESPONSE_SERVER_ERROR 500
6+
7+
@interface DataService : NSObject <NSURLConnectionDelegate>
8+
9+
@property(nonatomic,retain) NSURL *requestURL;
10+
@property(nonatomic) NSInteger statusCode;
11+
@property(nonatomic,readonly,getter = isInProgress) BOOL inProgress;
12+
13+
// Response properties
14+
@property(nonatomic, retain, readonly) NSDictionary *responseHeaders;
15+
@property(nonatomic, readonly) long long expectedContentLength;
16+
@property(nonatomic, retain, readonly) NSString *textEncodingName;
17+
@property(nonatomic, retain, readonly) NSString *MIMEType;
18+
@property(nonatomic, retain, readonly) NSString *suggestedFilename;
19+
20+
+ (DataService*)service;
21+
22+
-(void)requestWithURL:(NSURL*)url
23+
method:(NSString*)method
24+
headers:(NSDictionary*)headers
25+
bodyStream:(NSInputStream*)bodyStream
26+
cachePolicy:(NSURLRequestCachePolicy)cachePolicy
27+
timeoutInterval:(NSTimeInterval)timeoutInterval
28+
receiveHandler:(void (^)(id, NSNumber*, NSDictionary*))receiveHandler
29+
errorHandler:(void (^)(NSError*))errorHandler;
30+
31+
-(void)requestWithURL:(NSURL*)url
32+
method:(NSString*)method
33+
headers:(NSDictionary*)headers
34+
bodyStream:(NSInputStream*)bodyStream
35+
receiveHandler:(void (^)(id, NSNumber*, NSDictionary*))receiveHandler
36+
errorHandler:(void (^)(NSError*))errorHandler;
37+
38+
-(void)requestWithURL:(NSURL*)url
39+
method:(NSString*)method
40+
headers:(NSDictionary*)headers
41+
body:(NSData*)body
42+
receiveHandler:(void (^)(id, NSNumber*, NSDictionary*))receiveHandler
43+
errorHandler:(void (^)(NSError*))errorHandler;
44+
45+
- (void)cancel;
46+
47+
@end

DataService.m

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
#import "DataService.h"
2+
3+
#define DATA_SERVICE_DOMAIN @"DataService"
4+
5+
@interface DataService ()
6+
7+
@property (nonatomic, retain) NSMutableData *receivedData;
8+
@property (nonatomic, retain) NSURLConnection *urlConnection;
9+
@property (nonatomic, copy) void (^onReceiveBlock)(id, NSNumber*, NSDictionary*);
10+
@property (nonatomic, copy) void (^onErrorBlock)(NSError*);
11+
12+
// Response properties: generate hidden setters
13+
@property(nonatomic, retain, readwrite) NSDictionary *responseHeaders;
14+
@property(nonatomic, readwrite) long long expectedContentLength;
15+
@property(nonatomic, retain, readwrite) NSString *textEncodingName;
16+
@property(nonatomic, retain, readwrite) NSString *MIMEType;
17+
@property(nonatomic, retain, readwrite) NSString *suggestedFilename;
18+
19+
@end
20+
21+
@implementation DataService
22+
23+
@synthesize requestURL = _requestURL;
24+
@synthesize statusCode = _statusCode;
25+
@synthesize receivedData = _receivedData;
26+
@synthesize urlConnection = _urlConnection;
27+
@synthesize onReceiveBlock = _onReceiveBlock;
28+
@synthesize onErrorBlock = _onErrorBlock;
29+
@synthesize inProgress = _inProgress;
30+
@synthesize responseHeaders = _responseHeaders;
31+
@synthesize expectedContentLength = _expectedContentLength;
32+
@synthesize textEncodingName = _textEncodingName;
33+
@synthesize MIMEType = _MIMEType;
34+
@synthesize suggestedFilename = _suggestedFilename;
35+
36+
#pragma mark - Initialization
37+
38+
+ (DataService*)service{
39+
return [[[DataService alloc] init] autorelease];
40+
}
41+
42+
#pragma mark - Request
43+
44+
-(void)requestWithURL:(NSURL*)url
45+
method:(NSString*)method
46+
headers:(NSDictionary*)headers
47+
bodyStream:(NSInputStream*)bodyStream
48+
cachePolicy:(NSURLRequestCachePolicy)cachePolicy
49+
timeoutInterval:(NSTimeInterval)timeoutInterval
50+
receiveHandler:(void (^)(id, NSNumber*, NSDictionary*))receiveHandler
51+
errorHandler:(void (^)(NSError*))errorHandler {
52+
[self retain];
53+
self.onReceiveBlock = receiveHandler;
54+
self.onErrorBlock = errorHandler;
55+
self.requestURL = url;
56+
self.responseHeaders = nil;
57+
self.expectedContentLength = 0;
58+
self.textEncodingName = nil;
59+
self.MIMEType = nil;
60+
self.suggestedFilename = nil;
61+
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.requestURL cachePolicy:cachePolicy timeoutInterval:timeoutInterval];
62+
for (NSString *header in headers) {
63+
[request addValue:[headers objectForKey:header] forHTTPHeaderField:header];
64+
}
65+
[request setHTTPShouldUsePipelining:YES];
66+
[request setHTTPMethod:method];
67+
[request setHTTPBodyStream:bodyStream];
68+
[_urlConnection cancel];
69+
[_urlConnection release];
70+
_urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
71+
[_urlConnection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
72+
[_urlConnection start];
73+
_inProgress = !!_urlConnection;
74+
if (_urlConnection) {
75+
self.receivedData = [NSMutableData data];
76+
} else {
77+
NSDictionary *errorInfo = [NSDictionary dictionaryWithObject:@"Failed to create connection" forKey:NSLocalizedDescriptionKey];
78+
self.onErrorBlock([NSError errorWithDomain:DATA_SERVICE_DOMAIN code:0 userInfo:errorInfo]);
79+
self.urlConnection = nil;
80+
[self release];
81+
}
82+
}
83+
84+
-(void)requestWithURL:(NSURL *)url
85+
method:(NSString *)method
86+
headers:(NSDictionary *)headers
87+
body:(NSData *)body
88+
receiveHandler:(void (^)(id, NSNumber *, NSDictionary*))receiveHandler
89+
errorHandler:(void (^)(NSError *))errorHandler {
90+
NSMutableDictionary *newHeaders = [NSMutableDictionary dictionaryWithDictionary:headers];
91+
if (body) {
92+
[newHeaders setObject:[NSString stringWithFormat:@"%d", [body length]] forKey:@"Content-Length"];
93+
}
94+
[self requestWithURL:url
95+
method:method
96+
headers:newHeaders
97+
bodyStream:body ? [NSInputStream inputStreamWithData:body] : nil
98+
receiveHandler:receiveHandler
99+
errorHandler:errorHandler];
100+
}
101+
102+
-(void)requestWithURL:(NSURL*)url
103+
method:(NSString*)method
104+
headers:(NSDictionary*)headers
105+
bodyStream:(NSInputStream*)bodyStream
106+
receiveHandler:(void (^)(id, NSNumber*, NSDictionary*))receiveHandler
107+
errorHandler:(void (^)(NSError*))errorHandler {
108+
[self requestWithURL:url
109+
method:method
110+
headers:headers
111+
bodyStream:bodyStream
112+
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
113+
timeoutInterval:60.0
114+
receiveHandler:receiveHandler
115+
errorHandler:errorHandler];
116+
}
117+
118+
#pragma mark - Receive
119+
120+
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response{
121+
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
122+
self.statusCode = [httpResponse statusCode];
123+
self.responseHeaders = [httpResponse allHeaderFields];
124+
self.expectedContentLength = [httpResponse expectedContentLength];
125+
self.textEncodingName = [httpResponse textEncodingName];
126+
self.MIMEType = [httpResponse MIMEType];
127+
self.suggestedFilename = [httpResponse suggestedFilename];
128+
[self.receivedData setLength:0];
129+
}
130+
131+
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data{
132+
[self.receivedData appendData:data];
133+
}
134+
135+
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error{
136+
_inProgress = NO;
137+
self.receivedData = nil;
138+
self.onReceiveBlock = nil;
139+
self.responseHeaders = nil;
140+
self.expectedContentLength = 0;
141+
self.textEncodingName = nil;
142+
self.MIMEType = nil;
143+
self.suggestedFilename = nil;
144+
self.urlConnection = nil;
145+
if (self.onErrorBlock) {
146+
// Hold on to the block so that this DataService can be used for new requests in the callback.
147+
void (^onErrorBlock)(NSError*) = [self.onErrorBlock retain];
148+
self.onErrorBlock = nil;
149+
onErrorBlock(error);
150+
[onErrorBlock release];
151+
}
152+
[self release];
153+
}
154+
155+
- (void)connectionDidFinishLoading:(NSURLConnection*)connection{
156+
_inProgress = NO;
157+
// check to see if the status code is an error code and react appropriately
158+
if (self.statusCode / 100 == RESPONSE_CLIENT_ERROR / 100 || self.statusCode / 100 == RESPONSE_SERVER_ERROR / 100) {
159+
NSString *errorString = [[[NSString alloc] initWithData:self.receivedData encoding:NSUTF8StringEncoding] autorelease];
160+
NSDictionary *errorInfo = [NSDictionary dictionaryWithObject:errorString forKey:NSLocalizedDescriptionKey];
161+
NSError *error = [NSError errorWithDomain:DATA_SERVICE_DOMAIN code:self.statusCode userInfo:errorInfo];
162+
[self connection:connection didFailWithError:error];
163+
return;
164+
}
165+
self.onErrorBlock = nil;
166+
self.urlConnection = nil;
167+
// Hold on to required values so that this DataService can be reused from the callback.
168+
NSData *receivedData = [self.receivedData retain];
169+
NSDictionary *responseHeaders = [self.responseHeaders retain];
170+
self.receivedData = nil;
171+
self.responseHeaders = nil;
172+
self.expectedContentLength = 0;
173+
self.textEncodingName = nil;
174+
self.MIMEType = nil;
175+
self.suggestedFilename = nil;
176+
if (self.onReceiveBlock) {
177+
void (^onReceiveBlock)(id, NSNumber*, NSDictionary*) = [self.onReceiveBlock retain];
178+
self.onReceiveBlock = nil;
179+
onReceiveBlock([NSData dataWithData:receivedData], [NSNumber numberWithInteger:self.statusCode], responseHeaders);
180+
[onReceiveBlock release];
181+
}
182+
[receivedData release];
183+
[responseHeaders release];
184+
[self release];
185+
}
186+
187+
#pragma mark - Cleanup
188+
189+
- (void)cancel{
190+
[self.urlConnection cancel];
191+
self.urlConnection = nil;
192+
self.requestURL = nil;
193+
self.receivedData = nil;
194+
self.onReceiveBlock = nil;
195+
self.onErrorBlock = nil;
196+
self.responseHeaders = nil;
197+
self.expectedContentLength = 0;
198+
self.textEncodingName = nil;
199+
self.MIMEType = nil;
200+
self.suggestedFilename = nil;
201+
if (_inProgress) {
202+
[self release];
203+
}
204+
_inProgress = NO;
205+
}
206+
207+
- (void)dealloc{
208+
self.receivedData = nil;
209+
self.requestURL = nil;
210+
self.onReceiveBlock = nil;
211+
self.onErrorBlock = nil;
212+
self.urlConnection = nil;
213+
self.responseHeaders = nil;
214+
self.expectedContentLength = 0;
215+
self.textEncodingName = nil;
216+
self.MIMEType = nil;
217+
self.suggestedFilename = nil;
218+
[super dealloc];
219+
}
220+
221+
@end

DebugLog.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//
2+
// DebugLog.h
3+
//
4+
// Created by Jeremy Olmsted-Thompson on 12/22/11.
5+
// Copyright (c) 2011 JOT. All rights reserved.
6+
//
7+
8+
#import <Foundation/Foundation.h>
9+
10+
// Define DEBUG_LOG here or configure it as a preprocessor macro in your project settings. Using
11+
// project settings allows the log to automatically be disabled for release builds.
12+
13+
#ifdef DEBUG_LOG
14+
#define DLog(...) \
15+
[[DebugLog defaultLog] log:[NSString stringWithFormat:@"%s (%@: %d): %@", __PRETTY_FUNCTION__, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:__VA_ARGS__]]]
16+
#else
17+
#define DLog(...)
18+
#endif
19+
20+
#ifdef DEBUG_LOG
21+
#define DLogThread(...) \
22+
[[DebugLog defaultLog] log:[NSString stringWithFormat:@"%s (%@: %d) %@: %@", __PRETTY_FUNCTION__, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSThread currentThread], [NSString stringWithFormat:__VA_ARGS__]]]
23+
#else
24+
#define DLogThread(...)
25+
#endif
26+
27+
@interface DebugLog : NSObject {
28+
NSFileHandle *logFileHandle;
29+
}
30+
31+
-(id)initWithLogFilePath:(NSString*)path;
32+
-(void)log:(NSString*)logString;
33+
34+
+(DebugLog*)defaultLog;
35+
36+
@end

DebugLog.m

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// DebugLog.m
3+
//
4+
// Created by Jeremy Olmsted-Thompson on 12/22/11.
5+
// Copyright (c) 2011 JOT. All rights reserved.
6+
//
7+
8+
#import "DebugLog.h"
9+
10+
#define DefaultLogFileName @"DebugLog.txt"
11+
12+
@implementation DebugLog
13+
14+
-(id)initWithLogFilePath:(NSString*)path {
15+
if ((self = [super init])) {
16+
if (![[NSFileManager defaultManager] fileExistsAtPath:path]) {
17+
[[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
18+
}
19+
logFileHandle = [[NSFileHandle fileHandleForUpdatingAtPath:path] retain];
20+
[logFileHandle seekToEndOfFile];
21+
}
22+
return self;
23+
}
24+
25+
-(void)log:(NSString*)logString {
26+
NSLog(@"%@", logString);
27+
[logFileHandle writeData:[[NSString stringWithFormat:@"%@: %@\n", [NSDateFormatter localizedStringFromDate:[NSDate date] dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterLongStyle], logString] dataUsingEncoding:NSUTF8StringEncoding]];
28+
[logFileHandle synchronizeFile];
29+
}
30+
31+
+(DebugLog*)defaultLog {
32+
static DebugLog *defaultLog = nil;
33+
if (!defaultLog) {
34+
defaultLog = [[DebugLog alloc] initWithLogFilePath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:DefaultLogFileName]];
35+
}
36+
return defaultLog;
37+
}
38+
39+
@end

GridView.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//
2+
// GridView.h
3+
//
4+
// Created by Jeremy Olmsted-Thompson on 3/5/12.
5+
// Copyright (c) 2012 JOT. All rights reserved.
6+
//
7+
8+
#import <UIKit/UIKit.h>
9+
10+
typedef enum {
11+
GridViewOrientationHorizontal,
12+
GridViewOrientationVertical
13+
} GridViewOrientation;
14+
15+
@class GridView;
16+
17+
@protocol GridViewCell
18+
19+
@optional
20+
-(NSString*)reuseIdentifier;
21+
22+
@end
23+
24+
@protocol GridViewDataSource
25+
26+
-(UIView*)gridView:(GridView*)gridView viewForItemAtIndex:(NSInteger)index;
27+
28+
@optional
29+
-(BOOL)gridViewShouldReload:(GridView*)gridView;
30+
31+
@end
32+
33+
@interface GridView : UIScrollView
34+
35+
@property (nonatomic) NSInteger rowCount;
36+
@property (nonatomic) CGFloat horizontalSpacing;
37+
@property (nonatomic) CGFloat verticalSpacing;
38+
@property (nonatomic) CGFloat tileAspectRatio;
39+
@property (nonatomic) GridViewOrientation orientation;
40+
@property (nonatomic,readonly) CGSize tileSize;
41+
@property (nonatomic,assign) IBOutlet NSObject<GridViewDataSource> *dataSource;
42+
@property (nonatomic,readonly) BOOL loadingTiles;
43+
@property (nonatomic,assign) NSUInteger bufferedScreenCount;
44+
45+
-(void)loadItems;
46+
-(void)reloadData;
47+
-(id)dequeueReusableTileWithIdentifier:(NSString*)identifier;
48+
49+
@end

0 commit comments

Comments
 (0)