diff --git a/STTwitter/STHTTPRequest+STTwitter.h b/STTwitter/STHTTPRequest+STTwitter.h index 4c49843..40988c9 100644 --- a/STTwitter/STHTTPRequest+STTwitter.h +++ b/STTwitter/STHTTPRequest+STTwitter.h @@ -11,7 +11,8 @@ @interface STHTTPRequest (STTwitter) + (STHTTPRequest *)twitterRequestWithURLString:(NSString *)urlString - stTwitterProgressBlock:(void(^)(id json))progressBlock + stTwitterUploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock + stTwitterDownloadProgressBlock:(void(^)(id json))downloadProgressBlock stTwitterSuccessBlock:(void(^)(NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json))successBlock stTwitterErrorBlock:(void(^)(NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock; diff --git a/STTwitter/STHTTPRequest+STTwitter.m b/STTwitter/STHTTPRequest+STTwitter.m index 0756a1d..5580520 100644 --- a/STTwitter/STHTTPRequest+STTwitter.m +++ b/STTwitter/STHTTPRequest+STTwitter.m @@ -21,13 +21,13 @@ + (NSError *)errorFromResponseData:(NSData *)responseData { NSError *jsonError = nil; NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&jsonError]; - + NSString *message = nil; NSInteger code = 0; if([json isKindOfClass:[NSDictionary class]]) { // assume {"errors":[{"message":"Bad Authentication data","code":215}]} - + id errors = [json valueForKey:@"errors"]; if([errors isKindOfClass:[NSArray class]] && [(NSArray *)errors count] > 0) { NSDictionary *errorDictionary = [errors lastObject]; @@ -40,7 +40,7 @@ + (NSError *)errorFromResponseData:(NSData *)responseData { message = errors; } } - + if(message) { NSError *error = [NSError errorWithDomain:NSStringFromClass([self class]) code:code userInfo:@{NSLocalizedDescriptionKey : message}]; return error; @@ -50,10 +50,11 @@ + (NSError *)errorFromResponseData:(NSData *)responseData { } + (STHTTPRequest *)twitterRequestWithURLString:(NSString *)urlString - stTwitterProgressBlock:(void(^)(id json))progressBlock + stTwitterUploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock + stTwitterDownloadProgressBlock:(void(^)(id json))downloadProgressBlock stTwitterSuccessBlock:(void(^)(NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json))successBlock stTwitterErrorBlock:(void(^)(NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { - + __block STHTTPRequest *r = [self requestWithURLString:urlString]; __weak STHTTPRequest *wr = r; @@ -61,15 +62,17 @@ + (STHTTPRequest *)twitterRequestWithURLString:(NSString *)urlString r.timeoutSeconds = 0; + r.uploadProgressBlock = uploadProgressBlock; + r.downloadProgressBlock = ^(NSData *data, NSInteger totalBytesReceived, NSInteger totalBytesExpectedToReceive) { - if(progressBlock == nil) return; + if(downloadProgressBlock == nil) return; NSError *jsonError = nil; id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError]; if(json) { - progressBlock(json); + downloadProgressBlock(json); return; } @@ -87,10 +90,10 @@ + (STHTTPRequest *)twitterRequestWithURLString:(NSString *)urlString NSError *jsonError = nil; id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError]; if(json == nil) { -// errorBlock(wr.responseHeaders, jsonError); + // errorBlock(wr.responseHeaders, jsonError); return; // not enough information to say it's an error } - progressBlock(json); + downloadProgressBlock(json); } }; @@ -132,8 +135,8 @@ + (STHTTPRequest *)twitterRequestWithURLString:(NSString *)urlString STLog(@"-- body: %@", wr.responseString); -// BOOL isCancellationError = [[error domain] isEqualToString:@"STHTTPRequest"] && ([error code] == kSTHTTPRequestCancellationError); -// if(isCancellationError) return; + // BOOL isCancellationError = [[error domain] isEqualToString:@"STHTTPRequest"] && ([error code] == kSTHTTPRequestCancellationError); + // if(isCancellationError) return; errorBlock(wr.requestHeaders, wr.responseHeaders, error); }; diff --git a/STTwitter/STTwitterAPI.h b/STTwitter/STTwitterAPI.h index adb2f41..79a97f9 100644 --- a/STTwitter/STTwitterAPI.h +++ b/STTwitter/STTwitterAPI.h @@ -115,26 +115,28 @@ NS_ENUM(NSUInteger, STTwitterAPIErrorCode) { #pragma mark Generic methods to GET and POST - (id)fetchResource:(NSString *)resource - HTTPMethod:(NSString *)HTTPMethod - baseURLString:(NSString *)baseURLString - parameters:(NSDictionary *)params - progressBlock:(void (^)(id request, id response))progressBlock // TODO: handle progressBlock? - successBlock:(void (^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response))successBlock - errorBlock:(void (^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock; + HTTPMethod:(NSString *)HTTPMethod + baseURLString:(NSString *)baseURLString + parameters:(NSDictionary *)params +uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock +downloadProgressBlock:(void (^)(id request, id response))downloadProgressBlock + successBlock:(void (^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response))successBlock + errorBlock:(void (^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock; - (id)getResource:(NSString *)resource - baseURLString:(NSString *)baseURLString - parameters:(NSDictionary *)parameters - progressBlock:(void(^)(id json))progressBlock - successBlock:(void(^)(NSDictionary *rateLimits, id json))successBlock - errorBlock:(void(^)(NSError *error))errorBlock; + baseURLString:(NSString *)baseURLString + parameters:(NSDictionary *)parameters +downloadProgressBlock:(void(^)(id json))progredownloadProgressBlockssBlock + successBlock:(void(^)(NSDictionary *rateLimits, id json))successBlock + errorBlock:(void(^)(NSError *error))errorBlock; - (id)postResource:(NSString *)resource - baseURLString:(NSString *)baseURLString - parameters:(NSDictionary *)parameters - progressBlock:(void(^)(id json))progressBlock - successBlock:(void(^)(NSDictionary *rateLimits, id response))successBlock - errorBlock:(void(^)(NSError *error))errorBlock; + baseURLString:(NSString *)baseURLString + parameters:(NSDictionary *)parameters +uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock +downloadProgressBlock:(void(^)(id json))downloadProgressBlock + successBlock:(void(^)(NSDictionary *rateLimits, id response))successBlock + errorBlock:(void(^)(NSError *error))errorBlock; #pragma mark Timelines @@ -372,6 +374,7 @@ NS_ENUM(NSUInteger, STTwitterAPIErrorCode) { longitude:(NSString *)longitude placeID:(NSString *)placeID displayCoordinates:(NSNumber *)displayCoordinates + uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock successBlock:(void(^)(NSDictionary *status))successBlock errorBlock:(void(^)(NSError *error))errorBlock; @@ -382,6 +385,7 @@ NS_ENUM(NSUInteger, STTwitterAPIErrorCode) { placeID:(NSString *)placeID latitude:(NSString *)latitude longitude:(NSString *)longitude + uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock successBlock:(void(^)(NSDictionary *status))successBlock errorBlock:(void(^)(NSError *error))errorBlock; @@ -455,18 +459,18 @@ NS_ENUM(NSUInteger, STTwitterAPIErrorCode) { */ - (id)postStatusesFilterUserIDs:(NSArray *)userIDs - keywordsToTrack:(NSArray *)keywordsToTrack - locationBoundingBoxes:(NSArray *)locationBoundingBoxes - delimited:(NSNumber *)delimited - stallWarnings:(NSNumber *)stallWarnings - progressBlock:(void(^)(id response))progressBlock - stallWarningBlock:(void(^)(NSString *code, NSString *message, NSUInteger percentFull))stallWarningBlock - errorBlock:(void(^)(NSError *error))errorBlock; + keywordsToTrack:(NSArray *)keywordsToTrack + locationBoundingBoxes:(NSArray *)locationBoundingBoxes + delimited:(NSNumber *)delimited + stallWarnings:(NSNumber *)stallWarnings + progressBlock:(void(^)(id response))progressBlock + stallWarningBlock:(void(^)(NSString *code, NSString *message, NSUInteger percentFull))stallWarningBlock + errorBlock:(void(^)(NSError *error))errorBlock; // convenience - (id)postStatusesFilterKeyword:(NSString *)keyword - progressBlock:(void(^)(id response))progressBlock - errorBlock:(void(^)(NSError *error))errorBlock; + progressBlock:(void(^)(id response))progressBlock + errorBlock:(void(^)(NSError *error))errorBlock; /* GET statuses/sample @@ -475,10 +479,10 @@ NS_ENUM(NSUInteger, STTwitterAPIErrorCode) { */ - (id)getStatusesSampleDelimited:(NSNumber *)delimited - stallWarnings:(NSNumber *)stallWarnings - progressBlock:(void(^)(id response))progressBlock - stallWarningBlock:(void(^)(NSString *code, NSString *message, NSUInteger percentFull))stallWarningBlock - errorBlock:(void(^)(NSError *error))errorBlock; + stallWarnings:(NSNumber *)stallWarnings + progressBlock:(void(^)(id response))progressBlock + stallWarningBlock:(void(^)(NSString *code, NSString *message, NSUInteger percentFull))stallWarningBlock + errorBlock:(void(^)(NSError *error))errorBlock; /* GET statuses/firehose @@ -489,11 +493,11 @@ NS_ENUM(NSUInteger, STTwitterAPIErrorCode) { */ - (id)getStatusesFirehoseWithCount:(NSString *)count - delimited:(NSNumber *)delimited - stallWarnings:(NSNumber *)stallWarnings - progressBlock:(void(^)(id response))progressBlock - stallWarningBlock:(void(^)(NSString *code, NSString *message, NSUInteger percentFull))stallWarningBlock - errorBlock:(void(^)(NSError *error))errorBlock; + delimited:(NSNumber *)delimited + stallWarnings:(NSNumber *)stallWarnings + progressBlock:(void(^)(id response))progressBlock + stallWarningBlock:(void(^)(NSString *code, NSString *message, NSUInteger percentFull))stallWarningBlock + errorBlock:(void(^)(NSError *error))errorBlock; /* GET user @@ -502,14 +506,14 @@ NS_ENUM(NSUInteger, STTwitterAPIErrorCode) { */ - (id)getUserStreamDelimited:(NSNumber *)delimited - stallWarnings:(NSNumber *)stallWarnings + stallWarnings:(NSNumber *)stallWarnings includeMessagesFromFollowedAccounts:(NSNumber *)includeMessagesFromFollowedAccounts - includeReplies:(NSNumber *)includeReplies - keywordsToTrack:(NSArray *)keywordsToTrack - locationBoundingBoxes:(NSArray *)locationBoundingBoxes - progressBlock:(void(^)(id response))progressBlock - stallWarningBlock:(void(^)(NSString *code, NSString *message, NSUInteger percentFull))stallWarningBlock - errorBlock:(void(^)(NSError *error))errorBlock; + includeReplies:(NSNumber *)includeReplies + keywordsToTrack:(NSArray *)keywordsToTrack + locationBoundingBoxes:(NSArray *)locationBoundingBoxes + progressBlock:(void(^)(id response))progressBlock + stallWarningBlock:(void(^)(NSString *code, NSString *message, NSUInteger percentFull))stallWarningBlock + errorBlock:(void(^)(NSError *error))errorBlock; /* GET site @@ -518,13 +522,13 @@ includeMessagesFromFollowedAccounts:(NSNumber *)includeMessagesFromFollowedAccou */ - (id)getSiteStreamForUserIDs:(NSArray *)userIDs - delimited:(NSNumber *)delimited - stallWarnings:(NSNumber *)stallWarnings - restrictToUserMessages:(NSNumber *)restrictToUserMessages - includeReplies:(NSNumber *)includeReplies - progressBlock:(void(^)(id response))progressBlock - stallWarningBlock:(void(^)(NSString *code, NSString *message, NSUInteger percentFull))stallWarningBlock - errorBlock:(void(^)(NSError *error))errorBlock; + delimited:(NSNumber *)delimited + stallWarnings:(NSNumber *)stallWarnings + restrictToUserMessages:(NSNumber *)restrictToUserMessages + includeReplies:(NSNumber *)includeReplies + progressBlock:(void(^)(id response))progressBlock + stallWarningBlock:(void(^)(NSString *code, NSString *message, NSUInteger percentFull))stallWarningBlock + errorBlock:(void(^)(NSError *error))errorBlock; #pragma mark Direct Messages diff --git a/STTwitter/STTwitterAPI.m b/STTwitter/STTwitterAPI.m index 856fe16..1976e33 100644 --- a/STTwitter/STTwitterAPI.m +++ b/STTwitter/STTwitterAPI.m @@ -247,15 +247,17 @@ - (id)fetchResource:(NSString *)resource HTTPMethod:(NSString *)HTTPMethod baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)params - progressBlock:(void (^)(id request, id response))progressBlock - successBlock:(void (^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response))successBlock - errorBlock:(void (^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { +uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock +downloadProgressBlock:(void(^)(id request, id response))downloadProgressBlock + successBlock:(void(^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response))successBlock + errorBlock:(void(^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { return [_oauth fetchResource:resource HTTPMethod:HTTPMethod baseURLString:baseURLString parameters:params - progressBlock:progressBlock + uploadProgressBlock:uploadProgressBlock + downloadProgressBlock:downloadProgressBlock successBlock:successBlock errorBlock:errorBlock]; } @@ -263,7 +265,8 @@ - (id)fetchResource:(NSString *)resource - (id)getResource:(NSString *)resource baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)parameters - progressBlock:(void(^)(id json))progressBlock +//uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock +downloadProgressBlock:(void(^)(id json))downloadProgressBlock successBlock:(void(^)(NSDictionary *rateLimits, id json))successBlock errorBlock:(void(^)(NSError *error))errorBlock { @@ -271,19 +274,21 @@ - (id)getResource:(NSString *)resource HTTPMethod:@"GET" baseURLString:baseURLString parameters:parameters - progressBlock:^(id request, id response) { - if(progressBlock) progressBlock(response); - } successBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response) { - if(successBlock) successBlock(responseHeaders, response); - } errorBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { - if(errorBlock) errorBlock(error); - }]; + uploadProgressBlock:nil + downloadProgressBlock:^(id request, id response) { + if(downloadProgressBlock) downloadProgressBlock(response); + } successBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response) { + if(successBlock) successBlock(responseHeaders, response); + } errorBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { + if(errorBlock) errorBlock(error); + }]; } - (id)postResource:(NSString *)resource baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)parameters - progressBlock:(void(^)(id json))progressBlock +uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock +downloadProgressBlock:(void(^)(id json))downloadProgressBlock successBlock:(void(^)(NSDictionary *rateLimits, id response))successBlock errorBlock:(void(^)(NSError *error))errorBlock { @@ -291,28 +296,31 @@ - (id)postResource:(NSString *)resource HTTPMethod:@"POST" baseURLString:baseURLString parameters:parameters - progressBlock:^(id request, id response) { - if(progressBlock) progressBlock(response); - } successBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response) { - if(successBlock) successBlock(responseHeaders, response); - } errorBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { - if(errorBlock) errorBlock(error); - }]; + uploadProgressBlock:uploadProgressBlock + downloadProgressBlock:^(id request, id response) { + if(downloadProgressBlock) downloadProgressBlock(response); + } successBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response) { + if(successBlock) successBlock(responseHeaders, response); + } errorBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { + if(errorBlock) errorBlock(error); + }]; } - (void)postResource:(NSString *)resource baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)parameters - progressBlock:(void(^)(id json))progressBlock + uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock +downloadProgressBlock:(void(^)(id json))downloadProgressBlock errorBlock:(void(^)(NSError *error))errorBlock { [_oauth fetchResource:resource HTTPMethod:@"POST" baseURLString:baseURLString parameters:parameters - progressBlock:^(id request, id response) { - if(progressBlock) progressBlock(response); - } successBlock:nil + uploadProgressBlock:uploadProgressBlock + downloadProgressBlock:^(id request, id response) { + if(downloadProgressBlock) downloadProgressBlock(response); + } successBlock:nil errorBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { errorBlock(error); }]; @@ -321,16 +329,17 @@ - (void)postResource:(NSString *)resource - (void)getResource:(NSString *)resource baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)parameters - progressBlock:(void(^)(id json))progressBlock +downloadProgressBlock:(void(^)(id json))downloadProgressBlock errorBlock:(void(^)(NSError *error))errorBlock { [_oauth fetchResource:resource HTTPMethod:@"GET" baseURLString:baseURLString parameters:parameters - progressBlock:^(id request, id response) { - if(progressBlock) progressBlock(response); - } successBlock:nil + uploadProgressBlock:nil + downloadProgressBlock:^(id request, id response) { + if(downloadProgressBlock) downloadProgressBlock(response); + } successBlock:nil errorBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { errorBlock(error); }]; @@ -345,11 +354,12 @@ - (void)getAPIResource:(NSString *)resource [self getResource:resource baseURLString:kBaseURLStringAPI parameters:parameters - progressBlock:progressBlock +downloadProgressBlock:progressBlock successBlock:successBlock errorBlock:errorBlock]; } +// convenience - (void)getAPIResource:(NSString *)resource parameters:(NSDictionary *)parameters successBlock:(void(^)(NSDictionary *rateLimits, id json))successBlock @@ -358,13 +368,14 @@ - (void)getAPIResource:(NSString *)resource [self getResource:resource baseURLString:kBaseURLStringAPI parameters:parameters - progressBlock:nil +downloadProgressBlock:nil successBlock:successBlock errorBlock:errorBlock]; } - (void)postAPIResource:(NSString *)resource parameters:(NSDictionary *)parameters + uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock progressBlock:(void(^)(id json))progressBlock successBlock:(void(^)(NSDictionary *rateLimits, id json))successBlock errorBlock:(void(^)(NSError *error))errorBlock { @@ -372,11 +383,13 @@ - (void)postAPIResource:(NSString *)resource [self postResource:resource baseURLString:kBaseURLStringAPI parameters:parameters - progressBlock:progressBlock + uploadProgressBlock:uploadProgressBlock + downloadProgressBlock:progressBlock successBlock:successBlock errorBlock:errorBlock]; } +// convenience - (void)postAPIResource:(NSString *)resource parameters:(NSDictionary *)parameters successBlock:(void(^)(NSDictionary *rateLimits, id json))successBlock @@ -385,7 +398,8 @@ - (void)postAPIResource:(NSString *)resource [self postResource:resource baseURLString:kBaseURLStringAPI parameters:parameters - progressBlock:nil + uploadProgressBlock:nil + downloadProgressBlock:nil successBlock:successBlock errorBlock:errorBlock]; } @@ -425,9 +439,9 @@ - (void)profileImageFor:(NSString *)screenName errorBlock:(void(^)(NSError *error))errorBlock { - [self getUserInformationFor:screenName - successBlock:^(NSDictionary *response) { - NSString *imageURLString = [response objectForKey:@"profile_image_url"]; + [self getUserInformationFor:screenName + successBlock:^(NSDictionary *response) { + NSString *imageURLString = [response objectForKey:@"profile_image_url"]; __block STHTTPRequest *r = [STHTTPRequest requestWithURLString:imageURLString]; __weak STHTTPRequest *wr = r; @@ -447,9 +461,9 @@ - (void)profileImageFor:(NSString *)screenName r.errorBlock = ^(NSError *error) { errorBlock(error); }; - } errorBlock:^(NSError *error) { - errorBlock(error); - }]; + } errorBlock:^(NSError *error) { + errorBlock(error); + }]; } #pragma mark Timelines @@ -480,9 +494,9 @@ - (void)getStatusesMentionTimelineWithCount:(NSString *)count } - (void)getMentionsTimelineSinceID:(NSString *)sinceID - count:(NSUInteger)count - successBlock:(void(^)(NSArray *statuses))successBlock - errorBlock:(void(^)(NSError *error))errorBlock { + count:(NSUInteger)count + successBlock:(void(^)(NSArray *statuses))successBlock + errorBlock:(void(^)(NSError *error))errorBlock { [self getStatusesMentionTimelineWithCount:[@(count) description] sinceID:nil @@ -619,7 +633,7 @@ - (void)getTimeline:(NSString *)timeline - (void)getUserTimelineWithScreenName:(NSString *)screenName sinceID:(NSString *)sinceID maxID:(NSString *)maxID - count:(NSUInteger)count + count:(NSUInteger)count successBlock:(void(^)(NSArray *statuses))successBlock errorBlock:(void(^)(NSError *error))errorBlock { @@ -640,11 +654,11 @@ - (void)getUserTimelineWithScreenName:(NSString *)screenName } - (void)getUserTimelineWithScreenName:(NSString *)screenName - count:(NSUInteger)count + count:(NSUInteger)count successBlock:(void(^)(NSArray *statuses))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getUserTimelineWithScreenName:screenName + [self getUserTimelineWithScreenName:screenName sinceID:nil maxID:nil count:count @@ -835,6 +849,7 @@ - (void)postStatusUpdate:(NSString *)status longitude:(NSString *)longitude placeID:(NSString *)placeID displayCoordinates:(NSNumber *)displayCoordinates + uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock successBlock:(void(^)(NSDictionary *status))successBlock errorBlock:(void(^)(NSError *error))errorBlock { @@ -852,11 +867,14 @@ - (void)postStatusUpdate:(NSString *)status md[@"media[]"] = [mediaDataArray objectAtIndex:0]; md[kSTPOSTDataKey] = @"media[]"; - [self postAPIResource:@"statuses/update_with_media.json" parameters:md successBlock:^(NSDictionary *rateLimits, id response) { - successBlock(response); - } errorBlock:^(NSError *error) { - errorBlock(error); - }]; + [self postResource:@"statuses/update_with_media.json" + baseURLString:kBaseURLStringAPI + parameters:md + uploadProgressBlock:uploadProgressBlock + downloadProgressBlock:nil + successBlock:^(NSDictionary *rateLimits, id response) { + successBlock(response); + } errorBlock:errorBlock]; } - (void)postStatusUpdate:(NSString *)status @@ -865,6 +883,7 @@ - (void)postStatusUpdate:(NSString *)status placeID:(NSString *)placeID latitude:(NSString *)latitude longitude:(NSString *)longitude + uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock successBlock:(void(^)(NSDictionary *status))successBlock errorBlock:(void(^)(NSError *error))errorBlock { @@ -884,6 +903,7 @@ - (void)postStatusUpdate:(NSString *)status longitude:longitude placeID:placeID displayCoordinates:@(YES) + uploadProgressBlock:uploadProgressBlock successBlock:^(NSDictionary *status) { successBlock(status); } errorBlock:^(NSError *error) { @@ -1076,8 +1096,8 @@ - (void)getSearchTweetsWithQuery:(NSString *)q maxID:(NSString *)maxID // eg. "54321" includeEntities:(NSNumber *)includeEntities callback:(NSString *)callback // eg. "processTweets" - successBlock:(void(^)(NSDictionary *searchMetadata, NSArray *statuses))successBlock - errorBlock:(void(^)(NSError *error))errorBlock { + successBlock:(void(^)(NSDictionary *searchMetadata, NSArray *statuses))successBlock + errorBlock:(void(^)(NSError *error))errorBlock { NSMutableDictionary *md = [NSMutableDictionary dictionary]; @@ -1108,8 +1128,8 @@ - (void)getSearchTweetsWithQuery:(NSString *)q } - (void)getSearchTweetsWithQuery:(NSString *)q - successBlock:(void(^)(NSDictionary *searchMetadata, NSArray *statuses))successBlock - errorBlock:(void(^)(NSError *error))errorBlock { + successBlock:(void(^)(NSDictionary *searchMetadata, NSArray *statuses))successBlock + errorBlock:(void(^)(NSError *error))errorBlock { [self getSearchTweetsWithQuery:q geocode:nil @@ -1164,23 +1184,24 @@ - (id)postStatusesFilterUserIDs:(NSArray *)userIDs return [self postResource:@"statuses/filter.json" baseURLString:kBaseURLStringStream parameters:md - progressBlock:^(id json) { - - NSDictionary *stallWarning = [[self class] stallWarningDictionaryFromJSON:json]; - if(stallWarning && stallWarningBlock) { - stallWarningBlock([stallWarning valueForKey:@"code"], - [stallWarning valueForKey:@"message"], - [[stallWarning valueForKey:@"percent_full"] integerValue]); - } else { - progressBlock(json); - } - - } successBlock:^(NSDictionary *rateLimits, id response) { - // reaching successBlock for a stream request is an error - errorBlock(response); - } errorBlock:^(NSError *error) { - errorBlock(error); - }]; + uploadProgressBlock:nil + downloadProgressBlock:^(id json) { + + NSDictionary *stallWarning = [[self class] stallWarningDictionaryFromJSON:json]; + if(stallWarning && stallWarningBlock) { + stallWarningBlock([stallWarning valueForKey:@"code"], + [stallWarning valueForKey:@"message"], + [[stallWarning valueForKey:@"percent_full"] integerValue]); + } else { + progressBlock(json); + } + + } successBlock:^(NSDictionary *rateLimits, id response) { + // reaching successBlock for a stream request is an error + errorBlock(response); + } errorBlock:^(NSError *error) { + errorBlock(error); + }]; } // convenience @@ -1214,23 +1235,23 @@ - (id)getStatusesSampleDelimited:(NSNumber *)delimited return [self getResource:@"statuses/sample.json" baseURLString:kBaseURLStringStream parameters:md - progressBlock:^(id json) { - - NSDictionary *stallWarning = [[self class] stallWarningDictionaryFromJSON:json]; - if(stallWarning && stallWarningBlock) { - stallWarningBlock([stallWarning valueForKey:@"code"], - [stallWarning valueForKey:@"message"], - [[stallWarning valueForKey:@"percent_full"] integerValue]); - } else { - progressBlock(json); - } - - } successBlock:^(NSDictionary *rateLimits, id json) { - // reaching successBlock for a stream request is an error - errorBlock(json); - } errorBlock:^(NSError *error) { - errorBlock(error); - }]; + downloadProgressBlock:^(id json) { + + NSDictionary *stallWarning = [[self class] stallWarningDictionaryFromJSON:json]; + if(stallWarning && stallWarningBlock) { + stallWarningBlock([stallWarning valueForKey:@"code"], + [stallWarning valueForKey:@"message"], + [[stallWarning valueForKey:@"percent_full"] integerValue]); + } else { + progressBlock(json); + } + + } successBlock:^(NSDictionary *rateLimits, id json) { + // reaching successBlock for a stream request is an error + errorBlock(json); + } errorBlock:^(NSError *error) { + errorBlock(error); + }]; } // GET statuses/firehose @@ -1249,23 +1270,23 @@ - (id)getStatusesFirehoseWithCount:(NSString *)count return [self getResource:@"statuses/firehose.json" baseURLString:kBaseURLStringStream parameters:md - progressBlock:^(id json) { - - NSDictionary *stallWarning = [[self class] stallWarningDictionaryFromJSON:json]; - if(stallWarning && stallWarningBlock) { - stallWarningBlock([stallWarning valueForKey:@"code"], - [stallWarning valueForKey:@"message"], - [[stallWarning valueForKey:@"percent_full"] integerValue]); - } else { - progressBlock(json); - } - - } successBlock:^(NSDictionary *rateLimits, id json) { - // reaching successBlock for a stream request is an error - errorBlock(json); - } errorBlock:^(NSError *error) { - errorBlock(error); - }]; + downloadProgressBlock:^(id json) { + + NSDictionary *stallWarning = [[self class] stallWarningDictionaryFromJSON:json]; + if(stallWarning && stallWarningBlock) { + stallWarningBlock([stallWarning valueForKey:@"code"], + [stallWarning valueForKey:@"message"], + [[stallWarning valueForKey:@"percent_full"] integerValue]); + } else { + progressBlock(json); + } + + } successBlock:^(NSDictionary *rateLimits, id json) { + // reaching successBlock for a stream request is an error + errorBlock(json); + } errorBlock:^(NSError *error) { + errorBlock(error); + }]; } // GET user @@ -1295,23 +1316,23 @@ - (id)getUserStreamDelimited:(NSNumber *)delimited return [self getResource:@"user.json" baseURLString:kBaseURLStringUserStream parameters:md - progressBlock:^(id json) { - - NSDictionary *stallWarning = [[self class] stallWarningDictionaryFromJSON:json]; - if(stallWarning && stallWarningBlock) { - stallWarningBlock([stallWarning valueForKey:@"code"], - [stallWarning valueForKey:@"message"], - [[stallWarning valueForKey:@"percent_full"] integerValue]); - } else { - progressBlock(json); - } - - } successBlock:^(NSDictionary *rateLimits, id json) { - // reaching successBlock for a stream request is an error - errorBlock(json); - } errorBlock:^(NSError *error) { - errorBlock(error); - }]; + downloadProgressBlock:^(id json) { + + NSDictionary *stallWarning = [[self class] stallWarningDictionaryFromJSON:json]; + if(stallWarning && stallWarningBlock) { + stallWarningBlock([stallWarning valueForKey:@"code"], + [stallWarning valueForKey:@"message"], + [[stallWarning valueForKey:@"percent_full"] integerValue]); + } else { + progressBlock(json); + } + + } successBlock:^(NSDictionary *rateLimits, id json) { + // reaching successBlock for a stream request is an error + errorBlock(json); + } errorBlock:^(NSError *error) { + errorBlock(error); + }]; } // GET site @@ -1337,23 +1358,23 @@ - (id)getSiteStreamForUserIDs:(NSArray *)userIDs return [self getResource:@"site.json" baseURLString:kBaseURLStringSiteStream parameters:md - progressBlock:^(id json) { - - NSDictionary *stallWarning = [[self class] stallWarningDictionaryFromJSON:json]; - if(stallWarning && stallWarningBlock) { - stallWarningBlock([stallWarning valueForKey:@"code"], - [stallWarning valueForKey:@"message"], - [[stallWarning valueForKey:@"percent_full"] integerValue]); - } else { - progressBlock(json); - } - - } successBlock:^(NSDictionary *rateLimits, id json) { - // reaching successBlock for a stream request is an error - errorBlock(json); - } errorBlock:^(NSError *error) { - errorBlock(error); - }]; + downloadProgressBlock:^(id json) { + + NSDictionary *stallWarning = [[self class] stallWarningDictionaryFromJSON:json]; + if(stallWarning && stallWarningBlock) { + stallWarningBlock([stallWarning valueForKey:@"code"], + [stallWarning valueForKey:@"message"], + [[stallWarning valueForKey:@"percent_full"] integerValue]); + } else { + progressBlock(json); + } + + } successBlock:^(NSDictionary *rateLimits, id json) { + // reaching successBlock for a stream request is an error + errorBlock(json); + } errorBlock:^(NSError *error) { + errorBlock(error); + }]; } #pragma mark Direct Messages @@ -1382,9 +1403,9 @@ - (void)getDirectMessagesSinceID:(NSString *)sinceID // convenience - (void)getDirectMessagesSinceID:(NSString *)sinceID - count:(NSUInteger)count - successBlock:(void(^)(NSArray *messages))successBlock - errorBlock:(void(^)(NSError *error))errorBlock { + count:(NSUInteger)count + successBlock:(void(^)(NSArray *messages))successBlock + errorBlock:(void(^)(NSError *error))errorBlock { NSString *countString = count > 0 ? [@(count) description] : nil; @@ -1438,10 +1459,10 @@ - (void)getDirectMessagesShowWithID:(NSString *)messageID - (void)postDestroyDirectMessageWithID:(NSString *)messageID includeEntities:(NSNumber *)includeEntities - successBlock:(void(^)(NSDictionary *message))successBlock - errorBlock:(void(^)(NSError *error))errorBlock { + successBlock:(void(^)(NSDictionary *message))successBlock + errorBlock:(void(^)(NSError *error))errorBlock { - NSMutableDictionary *md = [NSMutableDictionary dictionary]; + NSMutableDictionary *md = [NSMutableDictionary dictionary]; md[@"id"] = messageID; if(includeEntities) md[@"include_entities"] = [includeEntities boolValue] ? @"1" : @"0"; @@ -1456,7 +1477,7 @@ - (void)postDirectMessage:(NSString *)status to:(NSString *)screenName successBlock:(void(^)(NSDictionary *message))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - NSMutableDictionary *md = [NSMutableDictionary dictionaryWithObject:status forKey:@"text"]; + NSMutableDictionary *md = [NSMutableDictionary dictionaryWithObject:status forKey:@"text"]; [md setObject:screenName forKey:@"screen_name"]; [self postAPIResource:@"direct_messages/new.json" parameters:md successBlock:^(NSDictionary *rateLimits, id response) { @@ -1516,7 +1537,7 @@ - (void)getFriendsIDsForUserID:(NSString *)userID } - (void)getFriendsIDsForScreenName:(NSString *)screenName - successBlock:(void(^)(NSArray *friends))successBlock + successBlock:(void(^)(NSArray *friends))successBlock errorBlock:(void(^)(NSError *error))errorBlock { [self getFriendsIDsForUserID:nil @@ -1564,7 +1585,7 @@ - (void)getFollowersIDsForUserID:(NSString *)userID } - (void)getFollowersIDsForScreenName:(NSString *)screenName - successBlock:(void(^)(NSArray *followers))successBlock + successBlock:(void(^)(NSArray *followers))successBlock errorBlock:(void(^)(NSError *error))errorBlock { [self getFollowersIDsForUserID:nil @@ -1666,8 +1687,8 @@ - (void)postFriendshipsCreateForScreenName:(NSString *)screenName } - (void)postFollow:(NSString *)screenName - successBlock:(void(^)(NSDictionary *user))successBlock - errorBlock:(void(^)(NSError *error))errorBlock { + successBlock:(void(^)(NSDictionary *user))successBlock + errorBlock:(void(^)(NSError *error))errorBlock { [self postFriendshipsCreateForScreenName:screenName orUserID:nil successBlock:^(NSDictionary *user) { successBlock(user); @@ -1695,9 +1716,9 @@ - (void)postFriendshipsDestroyScreenName:(NSString *)screenName } - (void)postUnfollow:(NSString *)screenName - successBlock:(void(^)(NSDictionary *user))successBlock - errorBlock:(void(^)(NSError *error))errorBlock { - + successBlock:(void(^)(NSDictionary *user))successBlock + errorBlock:(void(^)(NSError *error))errorBlock { + [self postFriendshipsDestroyScreenName:screenName orUserID:nil successBlock:^(NSDictionary *user) { successBlock(user); } errorBlock:^(NSError *error) { @@ -1816,7 +1837,7 @@ - (void)getFriendsListForUserID:(NSString *)userID } - (void)getFriendsForScreenName:(NSString *)screenName - successBlock:(void(^)(NSArray *friends))successBlock + successBlock:(void(^)(NSArray *friends))successBlock errorBlock:(void(^)(NSError *error))errorBlock { [self getFriendsListForUserID:nil @@ -1867,10 +1888,10 @@ - (void)getFollowersListForUserID:(NSString *)userID // convenience - (void)getFollowersForScreenName:(NSString *)screenName - successBlock:(void(^)(NSArray *followers))successBlock + successBlock:(void(^)(NSArray *followers))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getFollowersListForUserID:nil + [self getFollowersListForUserID:nil orScreenName:screenName cursor:nil skipStatus:nil @@ -1993,7 +2014,7 @@ - (void)postAccountUpdateProfileWithName:(NSString *)name - (void)postUpdateProfile:(NSDictionary *)profileData successBlock:(void(^)(NSDictionary *myInfo))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self postAPIResource:@"account/update_profile.json" parameters:profileData successBlock:^(NSDictionary *rateLimits, id response) { + [self postAPIResource:@"account/update_profile.json" parameters:profileData successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -2222,8 +2243,8 @@ - (void)getUsersShowForUserID:(NSString *)userID } - (void)getUserInformationFor:(NSString *)screenName - successBlock:(void(^)(NSDictionary *user))successBlock - errorBlock:(void(^)(NSError *error))errorBlock { + successBlock:(void(^)(NSDictionary *user))successBlock + errorBlock:(void(^)(NSError *error))errorBlock { [self getUsersShowForUserID:nil orScreenName:screenName includeEntities:nil successBlock:^(NSDictionary *user) { successBlock(user); @@ -3740,7 +3761,7 @@ - (void)postUsersReportSpamForScreenName:(NSString *)screenName // GET help/configuration - (void)getHelpConfigurationWithSuccessBlock:(void(^)(NSDictionary *currentConfiguration))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getAPIResource:@"help/configuration.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"help/configuration.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3750,7 +3771,7 @@ - (void)getHelpConfigurationWithSuccessBlock:(void(^)(NSDictionary *currentConfi // GET help/languages - (void)getHelpLanguagesWithSuccessBlock:(void (^)(NSArray *languages))successBlock errorBlock:(void (^)(NSError *))errorBlock { - [self getAPIResource:@"help/languages.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"help/languages.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3760,7 +3781,7 @@ - (void)getHelpLanguagesWithSuccessBlock:(void (^)(NSArray *languages))successBl // GET help/privacy - (void)getHelpPrivacyWithSuccessBlock:(void(^)(NSString *tos))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getAPIResource:@"help/privacy.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"help/privacy.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { successBlock([response valueForKey:@"privacy"]); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3770,7 +3791,7 @@ - (void)getHelpPrivacyWithSuccessBlock:(void(^)(NSString *tos))successBlock // GET help/tos - (void)getHelpTermsOfServiceWithSuccessBlock:(void(^)(NSString *tos))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getAPIResource:@"help/tos.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"help/tos.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { successBlock([response valueForKey:@"tos"]); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3779,12 +3800,12 @@ - (void)getHelpTermsOfServiceWithSuccessBlock:(void(^)(NSString *tos))successBlo // GET application/rate_limit_status - (void)getRateLimitsForResources:(NSArray *)resources // eg. statuses,friends,trends,help - successBlock:(void(^)(NSDictionary *rateLimits))successBlock - errorBlock:(void(^)(NSError *error))errorBlock { - NSDictionary *d = nil; - if (resources) + successBlock:(void(^)(NSDictionary *rateLimits))successBlock + errorBlock:(void(^)(NSError *error))errorBlock { + NSDictionary *d = nil; + if (resources) d = @{ @"resources" : [resources componentsJoinedByString:@","] }; - [self getAPIResource:@"application/rate_limit_status.json" parameters:d successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"application/rate_limit_status.json" parameters:d successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3816,7 +3837,7 @@ - (void)_getActivityAboutMeSinceID:(NSString *)sinceID if(modelVersion) md[@"model_version"] = [modelVersion boolValue] ? @"true" : @"false"; if(sendErrorCodes) md[@"send_error_codes"] = [sendErrorCodes boolValue] ? @"1" : @"0"; - [self getAPIResource:@"activity/about_me.json" parameters:md successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"activity/about_me.json" parameters:md successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3846,7 +3867,7 @@ - (void)_getActivityByFriendsSinceID:(NSString *)sinceID if(latestResults) md[@"latest_results"] = [latestResults boolValue] ? @"true" : @"false"; if(sendErrorCodes) md[@"send_error_codes"] = [sendErrorCodes boolValue] ? @"1" : @"0"; - [self getAPIResource:@"activity/by_friends.json" parameters:md successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"activity/by_friends.json" parameters:md successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3860,7 +3881,7 @@ - (void)_getStatusesActivitySummaryForStatusID:(NSString *)statusID NSString *resource = [NSString stringWithFormat:@"statuses/%@/activity/summary.json", statusID]; - [self getAPIResource:resource parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:resource parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { NSArray *favoriters = [response valueForKey:@"favoriters"]; NSArray *repliers = [response valueForKey:@"repliers"]; @@ -3884,7 +3905,7 @@ - (void)_getConversationShowForStatusID:(NSString *)statusID NSDictionary *d = @{@"id":statusID}; - [self getAPIResource:@"conversation/show.json" parameters:d successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"conversation/show.json" parameters:d successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3895,7 +3916,7 @@ - (void)_getConversationShowForStatusID:(NSString *)statusID - (void)_getDiscoverHighlightWithSuccessBlock:(void(^)(NSDictionary *metadata, NSArray *modules))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getAPIResource:@"discover/highlight.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"discover/highlight.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { NSDictionary *metadata = [response valueForKey:@"metadata"]; NSArray *modules = [response valueForKey:@"modules"]; @@ -3910,7 +3931,7 @@ - (void)_getDiscoverHighlightWithSuccessBlock:(void(^)(NSDictionary *metadata, N - (void)_getDiscoverUniversalWithSuccessBlock:(void(^)(NSDictionary *metadata, NSArray *modules))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getAPIResource:@"discover/universal.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"discover/universal.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { NSDictionary *metadata = [response valueForKey:@"metadata"]; NSArray *modules = [response valueForKey:@"modules"]; @@ -3925,7 +3946,7 @@ - (void)_getDiscoverUniversalWithSuccessBlock:(void(^)(NSDictionary *metadata, N - (void)_getMediaTimelineWithSuccessBlock:(void(^)(NSArray *statuses))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getAPIResource:@"statuses/media_timeline.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"statuses/media_timeline.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { @@ -3937,7 +3958,7 @@ - (void)_getMediaTimelineWithSuccessBlock:(void(^)(NSArray *statuses))successBlo - (void)_getUsersRecommendationsWithSuccessBlock:(void(^)(NSArray *recommendations))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getAPIResource:@"users/recommendations.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"users/recommendations.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3948,7 +3969,7 @@ - (void)_getUsersRecommendationsWithSuccessBlock:(void(^)(NSArray *recommendatio - (void)_getTimelineHomeWithSuccessBlock:(void(^)(id response))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getAPIResource:@"timeline/home.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"timeline/home.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3969,7 +3990,7 @@ - (void)_getStatusesMentionsTimelineWithCount:(NSString *)count if(includeEntities) md[@"include_entities"] = [includeEntities boolValue] ? @"true" : @"false"; if(includeMyRetweet) md[@"include_my_retweet"] = [includeMyRetweet boolValue] ? @"true" : @"false"; - [self getAPIResource:@"statuses/mentions_timeline.json" parameters:md successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"statuses/mentions_timeline.json" parameters:md successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -3980,7 +4001,7 @@ - (void)_getStatusesMentionsTimelineWithCount:(NSString *)count - (void)_getTrendsAvailableWithSuccessBlock:(void(^)(NSArray *places))successBlock errorBlock:(void(^)(NSError *error))errorBlock { - [self getAPIResource:@"trends/available.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { + [self getAPIResource:@"trends/available.json" parameters:nil successBlock:^(NSDictionary *rateLimits, id response) { successBlock(response); } errorBlock:^(NSError *error) { errorBlock(error); @@ -4037,13 +4058,14 @@ - (void)_postAccountGenerateWithADC:(NSString *)adc [self postResource:@"account/generate.json" baseURLString:@"https://api.twitter.com/1" parameters:md - progressBlock:^(id json) { - // - } successBlock:^(NSDictionary *rateLimits, id response) { - successBlock(response); - } errorBlock:^(NSError *error) { - errorBlock(error); - }]; + uploadProgressBlock:nil + downloadProgressBlock:^(id json) { + // + } successBlock:^(NSDictionary *rateLimits, id response) { + successBlock(response); + } errorBlock:^(NSError *error) { + errorBlock(error); + }]; } @end diff --git a/STTwitter/STTwitterAppOnly.m b/STTwitter/STTwitterAppOnly.m index ade9299..a08af74 100644 --- a/STTwitter/STTwitterAppOnly.m +++ b/STTwitter/STTwitterAppOnly.m @@ -60,7 +60,8 @@ - (void)invalidateBearerTokenWithSuccessBlock:(void(^)())successBlock baseURLString:@"https://api.twitter.com" parameters:@{ @"access_token" : _bearerToken } useBasicAuth:YES - progressBlock:nil + uploadProgressBlock:nil + downloadProgressBlock:nil successBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json) { if([json isKindOfClass:[NSDictionary class]] == NO) { @@ -115,7 +116,8 @@ - (void)verifyCredentialsWithSuccessBlock:(void(^)(NSString *username))successBl baseURLString:@"https://api.twitter.com" parameters:@{ @"grant_type" : @"client_credentials" } useBasicAuth:YES - progressBlock:nil + uploadProgressBlock:nil + downloadProgressBlock:nil successBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json) { NSString *tokenType = [json valueForKey:@"token_type"]; @@ -168,13 +170,14 @@ - (STHTTPRequest *)getResource:(NSString *)resource // NSString *requestID = [[NSUUID UUID] UUIDString]; __block STHTTPRequest *r = [STHTTPRequest twitterRequestWithURLString:urlString - stTwitterProgressBlock:^(id json) { - if(progressBlock) progressBlock(r, json); - } stTwitterSuccessBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json) { - successBlock(r, requestHeaders, responseHeaders, json); - } stTwitterErrorBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { - errorBlock(r, requestHeaders, responseHeaders, error); - }]; + stTwitterUploadProgressBlock:nil + stTwitterDownloadProgressBlock:^(id json) { + if(progressBlock) progressBlock(r, json); + } stTwitterSuccessBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json) { + successBlock(r, requestHeaders, responseHeaders, json); + } stTwitterErrorBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { + errorBlock(r, requestHeaders, responseHeaders, error); + }]; if(_bearerToken) { [r setHeaderWithName:@"Authorization" value:[NSString stringWithFormat:@"Bearer %@", _bearerToken]]; } @@ -188,7 +191,8 @@ - (id)fetchResource:(NSString *)resource HTTPMethod:(NSString *)HTTPMethod baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)params - progressBlock:(void(^)(id r, id json))progressBlock +uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock +downloadProgressBlock:(void(^)(id r, id json))downloadProgressBlock successBlock:(void(^)(id r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json))successBlock errorBlock:(void(^)(id r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { @@ -201,7 +205,7 @@ - (id)fetchResource:(NSString *)resource return [self getResource:resource baseURLString:baseURLString parameters:params - progressBlock:progressBlock + progressBlock:downloadProgressBlock successBlock:successBlock errorBlock:errorBlock]; @@ -210,7 +214,8 @@ - (id)fetchResource:(NSString *)resource return [self postResource:resource baseURLString:baseURLString parameters:params - progressBlock:progressBlock + uploadProgressBlock:uploadProgressBlock + downloadProgressBlock:downloadProgressBlock successBlock:successBlock errorBlock:errorBlock]; @@ -224,20 +229,22 @@ - (id)postResource:(NSString *)resource baseURLString:(NSString *)baseURLString // no trailing slash parameters:(NSDictionary *)params useBasicAuth:(BOOL)useBasicAuth - progressBlock:(void(^)(id request, id json))progressBlock +uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock +downloadProgressBlock:(void(^)(id request, id json))downloadProgressBlock successBlock:(void(^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json))successBlock errorBlock:(void(^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, resource]; __block STHTTPRequest *r = [STHTTPRequest twitterRequestWithURLString:urlString - stTwitterProgressBlock:^(id json) { - if(progressBlock) progressBlock(r, json); - } stTwitterSuccessBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json) { - successBlock(r, requestHeaders, responseHeaders, json); - } stTwitterErrorBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { - errorBlock(r, requestHeaders, responseHeaders, error); - }]; + stTwitterUploadProgressBlock:uploadProgressBlock + stTwitterDownloadProgressBlock:^(id json) { + if(downloadProgressBlock) downloadProgressBlock(r, json); + } stTwitterSuccessBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json) { + successBlock(r, requestHeaders, responseHeaders, json); + } stTwitterErrorBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { + errorBlock(r, requestHeaders, responseHeaders, error); + }]; r.POSTDictionary = params; @@ -264,7 +271,8 @@ - (id)postResource:(NSString *)resource - (STHTTPRequest *)postResource:(NSString *)resource baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)params - progressBlock:(void(^)(id r, id json))progressBlock + uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock + downloadProgressBlock:(void(^)(id r, id json))downloadProgressBlock successBlock:(void(^)(id r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json))successBlock errorBlock:(void(^)(id r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { @@ -272,7 +280,8 @@ - (STHTTPRequest *)postResource:(NSString *)resource baseURLString:baseURLString parameters:params useBasicAuth:NO - progressBlock:progressBlock + uploadProgressBlock:uploadProgressBlock + downloadProgressBlock:downloadProgressBlock successBlock:successBlock errorBlock:errorBlock]; } diff --git a/STTwitter/STTwitterOAuth.h b/STTwitter/STTwitterOAuth.h index 52e7931..4f24659 100644 --- a/STTwitter/STTwitterOAuth.h +++ b/STTwitter/STTwitterOAuth.h @@ -68,13 +68,13 @@ NS_ENUM(NSUInteger, STTwitterOAuthErrorCode) { @end @interface NSString (STTwitterOAuth) -+ (NSString *)random32Characters; -- (NSString *)signHmacSHA1WithKey:(NSString *)key; -- (NSDictionary *)parametersDictionary; -- (NSString *)urlEncodedString; ++ (NSString *)st_random32Characters; +- (NSString *)st_signHmacSHA1WithKey:(NSString *)key; +- (NSDictionary *)st_parametersDictionary; +- (NSString *)st_urlEncodedString; @end @interface NSURL (STTwitterOAuth) -- (NSString *)normalizedForOauthSignatureString; -- (NSArray *)rawGetParametersDictionaries; +- (NSString *)st_normalizedForOauthSignatureString; +- (NSArray *)st_rawGetParametersDictionaries; @end diff --git a/STTwitter/STTwitterOAuth.m b/STTwitter/STTwitterOAuth.m index aad5cdd..4e5ef1c 100644 --- a/STTwitter/STTwitterOAuth.m +++ b/STTwitter/STTwitterOAuth.m @@ -97,8 +97,8 @@ + (NSArray *)encodedParametersDictionaries:(NSArray *)parameters { NSString *key = [[d allKeys] lastObject]; NSString *value = [[d allValues] lastObject]; - NSString *encodedKey = [key urlEncodedString]; - NSString *encodedValue = [value urlEncodedString]; + NSString *encodedKey = [key st_urlEncodedString]; + NSString *encodedValue = [value st_urlEncodedString]; [encodedParameters addObject:@{encodedKey : encodedValue}]; } @@ -159,7 +159,7 @@ - (NSString *)loginTypeDescription { - (NSString *)oauthNonce { if(_testOauthNonce) return _testOauthNonce; - return [NSString random32Characters]; + return [NSString st_random32Characters]; } + (NSString *)signatureBaseStringWithHTTPMethod:(NSString *)httpMethod url:(NSURL *)url allParametersUnsorted:(NSArray *)parameters { @@ -186,8 +186,8 @@ + (NSString *)signatureBaseStringWithHTTPMethod:(NSString *)httpMethod url:(NSUR NSString *signatureBaseString = [NSString stringWithFormat:@"%@&%@&%@", [httpMethod uppercaseString], - [[url normalizedForOauthSignatureString] urlEncodedString], - [encodedParametersString urlEncodedString]]; + [[url st_normalizedForOauthSignatureString] st_urlEncodedString], + [encodedParametersString st_urlEncodedString]]; return signatureBaseString; } @@ -204,8 +204,8 @@ + (NSString *)oauthSignatureWithHTTPMethod:(NSString *)httpMethod url:(NSURL *)u Note that there are some flows, such as when obtaining a request token, where the token secret is not yet known. In this case, the signing key should consist of the percent encoded consumer secret followed by an ampersand character '&'. */ - NSString *encodedConsumerSecret = [consumerSecret urlEncodedString]; - NSString *encodedTokenSecret = [tokenSecret urlEncodedString]; + NSString *encodedConsumerSecret = [consumerSecret st_urlEncodedString]; + NSString *encodedTokenSecret = [tokenSecret st_urlEncodedString]; NSString *signingKey = [NSString stringWithFormat:@"%@&", encodedConsumerSecret]; @@ -213,7 +213,7 @@ + (NSString *)oauthSignatureWithHTTPMethod:(NSString *)httpMethod url:(NSURL *)u signingKey = [signingKey stringByAppendingString:encodedTokenSecret]; } - NSString *oauthSignature = [signatureBaseString signHmacSHA1WithKey:signingKey]; + NSString *oauthSignature = [signatureBaseString st_signHmacSHA1WithKey:signingKey]; return oauthSignature; } @@ -261,10 +261,11 @@ - (void)postTokenRequest:(void(^)(NSURL *url, NSString *oauthToken))successBlock baseURLString:@"https://api.twitter.com" parameters:@{} oauthCallback:theOAuthCallback - progressBlock:nil + uploadProgressBlock:nil + downloadProgressBlock:nil successBlock:^(STHTTPRequest *r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id body) { - NSDictionary *d = [body parametersDictionary]; + NSDictionary *d = [body st_parametersDictionary]; NSString *s = [NSString stringWithFormat:@"https://api.twitter.com/oauth/authorize?%@", body]; @@ -286,7 +287,8 @@ - (void)postReverseOAuthTokenRequest:(void(^)(NSString *authenticationHeader))su baseURLString:@"https://api.twitter.com" parameters:@{@"x_auth_mode" : @"reverse_auth"} oauthCallback:nil - progressBlock:nil + uploadProgressBlock:nil + downloadProgressBlock:nil successBlock:^(STHTTPRequest *r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id body) { successBlock(body); @@ -309,7 +311,7 @@ - (void)postXAuthAccessTokenRequestWithUsername:(NSString *)username baseURLString:@"https://api.twitter.com" parameters:d successBlock:^(STHTTPRequest *request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSString *body) { - NSDictionary *dict = [body parametersDictionary]; + NSDictionary *dict = [body st_parametersDictionary]; // https://api.twitter.com/oauth/authorize?oauth_token=OAUTH_TOKEN&oauth_token_secret=OAUTH_TOKEN_SECRET&user_id=USER_ID&screen_name=SCREEN_NAME @@ -339,7 +341,7 @@ - (void)postAccessTokenRequestWithPIN:(NSString *)pin baseURLString:@"https://api.twitter.com" parameters:d successBlock:^(STHTTPRequest *request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSString *body) { - NSDictionary *dict = [body parametersDictionary]; + NSDictionary *dict = [body st_parametersDictionary]; // https://api.twitter.com/oauth/authorize?oauth_token=OAUTH_TOKEN&oauth_token_secret=OAUTH_TOKEN_SECRET&user_id=USER_ID&screen_name=SCREEN_NAME @@ -385,7 +387,7 @@ - (void)signRequest:(STHTTPRequest *)r isMediaUpload:(BOOL)isMediaUpload oauthCa // "In the HTTP request the parameters are URL encoded, but you should collect the raw values." // https://dev.twitter.com/docs/auth/creating-signature - NSMutableArray *oauthAndPOSTandGETParameters = [[r.url rawGetParametersDictionaries] mutableCopy]; + NSMutableArray *oauthAndPOSTandGETParameters = [[r.url st_rawGetParametersDictionaries] mutableCopy]; [oauthAndPOSTandGETParameters addObjectsFromArray:oauthAndPOSTParameters]; NSString *signature = [[self class] oauthSignatureWithHTTPMethod:httpMethod @@ -412,7 +414,7 @@ - (void)signRequest:(STHTTPRequest *)r { - (STHTTPRequest *)getResource:(NSString *)resource baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)params - progressBlock:(void (^)(STHTTPRequest *r, id json))progressBlock + downloadProgressBlock:(void (^)(STHTTPRequest *r, id json))downloadProgressBlock successBlock:(void (^)(STHTTPRequest *r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json))successBlock errorBlock:(void (^)(STHTTPRequest *r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { @@ -434,13 +436,14 @@ - (STHTTPRequest *)getResource:(NSString *)resource // __block NSString *requestID = [[NSUUID UUID] UUIDString]; __block STHTTPRequest *r = [STHTTPRequest twitterRequestWithURLString:urlString - stTwitterProgressBlock:^(id json) { - if(progressBlock) progressBlock(r, json); - } stTwitterSuccessBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json) { - successBlock(r, requestHeaders, responseHeaders, json); - } stTwitterErrorBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { - errorBlock(r, requestHeaders, responseHeaders, error); - }]; + stTwitterUploadProgressBlock:nil + stTwitterDownloadProgressBlock:^(id json) { + if(downloadProgressBlock) downloadProgressBlock(r, json); + } stTwitterSuccessBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json) { + successBlock(r, requestHeaders, responseHeaders, json); + } stTwitterErrorBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { + errorBlock(r, requestHeaders, responseHeaders, error); + }]; [self signRequest:r]; @@ -453,7 +456,8 @@ - (id)fetchResource:(NSString *)resource HTTPMethod:(NSString *)HTTPMethod baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)params - progressBlock:(void(^)(id r, id json))progressBlock +uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock +downloadProgressBlock:(void(^)(id r, id json))downloadProgressBlock successBlock:(void(^)(id r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json))successBlock errorBlock:(void(^)(id r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { @@ -466,7 +470,7 @@ - (id)fetchResource:(NSString *)resource return [self getResource:resource baseURLString:baseURLString parameters:params - progressBlock:progressBlock + downloadProgressBlock:downloadProgressBlock successBlock:successBlock errorBlock:errorBlock]; @@ -475,7 +479,9 @@ - (id)fetchResource:(NSString *)resource return [self postResource:resource baseURLString:baseURLString parameters:params - progressBlock:progressBlock + oauthCallback:nil + uploadProgressBlock:uploadProgressBlock + downloadProgressBlock:downloadProgressBlock successBlock:successBlock errorBlock:errorBlock]; @@ -489,20 +495,22 @@ - (STHTTPRequest *)postResource:(NSString *)resource baseURLString:(NSString *)baseURLString // no trailing slash parameters:(NSDictionary *)params oauthCallback:(NSString *)oauthCallback - progressBlock:(void(^)(STHTTPRequest *r, id json))progressBlock + uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock + downloadProgressBlock:(void(^)(STHTTPRequest *r, id json))downloadProgressBlock successBlock:(void(^)(STHTTPRequest *r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response))successBlock errorBlock:(void(^)(STHTTPRequest *r, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { NSString *urlString = [NSString stringWithFormat:@"%@/%@", baseURLString, resource]; __block STHTTPRequest *r = [STHTTPRequest twitterRequestWithURLString:urlString - stTwitterProgressBlock:^(id json) { - if(progressBlock) progressBlock(r, json); - } stTwitterSuccessBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json) { - successBlock(r, requestHeaders, responseHeaders, json); - } stTwitterErrorBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { - errorBlock(r, requestHeaders, responseHeaders, error); - }]; + stTwitterUploadProgressBlock:uploadProgressBlock + stTwitterDownloadProgressBlock:^(id json) { + if(downloadProgressBlock) downloadProgressBlock(r, json); + } stTwitterSuccessBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, id json) { + successBlock(r, requestHeaders, responseHeaders, json); + } stTwitterErrorBlock:^(NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { + errorBlock(r, requestHeaders, responseHeaders, error); + }]; r.POSTDictionary = params; @@ -530,6 +538,7 @@ - (STHTTPRequest *)postResource:(NSString *)resource return r; } +// convenience - (STHTTPRequest *)postResource:(NSString *)resource baseURLString:(NSString *)baseURLString // no trailing slash parameters:(NSDictionary *)params @@ -541,11 +550,13 @@ - (STHTTPRequest *)postResource:(NSString *)resource baseURLString:baseURLString parameters:params oauthCallback:nil - progressBlock:progressBlock + uploadProgressBlock:nil + downloadProgressBlock:progressBlock successBlock:successBlock errorBlock:errorBlock]; } +// convenience - (STHTTPRequest *)postResource:(NSString *)resource baseURLString:(NSString *)baseURLString // no trailing slash parameters:(NSDictionary *)params @@ -557,11 +568,13 @@ - (STHTTPRequest *)postResource:(NSString *)resource baseURLString:baseURLString parameters:params oauthCallback:oauthCallback - progressBlock:nil + uploadProgressBlock:nil + downloadProgressBlock:nil successBlock:successBlock errorBlock:errorBlock]; } +// convenience - (STHTTPRequest *)postResource:(NSString *)resource baseURLString:(NSString *)baseURLString // no trailing slash parameters:(NSDictionary *)params @@ -572,7 +585,8 @@ - (STHTTPRequest *)postResource:(NSString *)resource baseURLString:baseURLString parameters:params oauthCallback:nil - progressBlock:nil + uploadProgressBlock:nil + downloadProgressBlock:nil successBlock:successBlock errorBlock:errorBlock]; } @@ -581,7 +595,7 @@ - (STHTTPRequest *)postResource:(NSString *)resource @implementation NSURL (STTwitterOAuth) -- (NSArray *)rawGetParametersDictionaries { +- (NSArray *)st_rawGetParametersDictionaries { NSString *q = [self query]; @@ -600,7 +614,7 @@ - (NSArray *)rawGetParametersDictionaries { return ma; } -- (NSString *)normalizedForOauthSignatureString { +- (NSString *)st_normalizedForOauthSignatureString { return [NSString stringWithFormat:@"%@://%@%@", [self scheme], [self host], [self path]]; } @@ -608,22 +622,22 @@ - (NSString *)normalizedForOauthSignatureString { @implementation NSString (STTwitterOAuth) -+ (NSString *)randomString { ++ (NSString *)st_randomString { CFUUIDRef cfuuid = CFUUIDCreate (kCFAllocatorDefault); NSString *uuid = (__bridge_transfer NSString *)(CFUUIDCreateString (kCFAllocatorDefault, cfuuid)); CFRelease (cfuuid); return uuid; } -+ (NSString *)random32Characters { - NSString *randomString = [self randomString]; ++ (NSString *)st_random32Characters { + NSString *randomString = [self st_randomString]; NSAssert([randomString length] >= 32, @""); return [randomString substringToIndex:32]; } -- (NSString *)signHmacSHA1WithKey:(NSString *)key { +- (NSString *)st_signHmacSHA1WithKey:(NSString *)key { unsigned char buf[CC_SHA1_DIGEST_LENGTH]; CCHmac(kCCHmacAlgSHA1, [key UTF8String], [key length], [self UTF8String], [self length], buf); @@ -631,7 +645,7 @@ - (NSString *)signHmacSHA1WithKey:(NSString *)key { return [data base64Encoding]; } -- (NSDictionary *)parametersDictionary { +- (NSDictionary *)st_parametersDictionary { NSArray *parameters = [self componentsSeparatedByString:@"&"]; @@ -649,7 +663,7 @@ - (NSDictionary *)parametersDictionary { return md; } -- (NSString *)urlEncodedString { +- (NSString *)st_urlEncodedString { // https://dev.twitter.com/docs/auth/percent-encoding-parameters // http://tools.ietf.org/html/rfc3986#section-2.1 diff --git a/STTwitter/STTwitterOS.m b/STTwitter/STTwitterOS.m index efbdd2c..6e7ae89 100644 --- a/STTwitter/STTwitterOS.m +++ b/STTwitter/STTwitterOS.m @@ -152,6 +152,7 @@ - (id)fetchAPIResource:(NSString *)resource baseURLString:(NSString *)baseURLString httpMethod:(NSInteger)httpMethod parameters:(NSDictionary *)params + uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock // ignored completionBlock:(void (^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response))completionBlock errorBlock:(void (^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { @@ -275,7 +276,8 @@ - (id)fetchResource:(NSString *)resource HTTPMethod:(NSString *)HTTPMethod baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)params - progressBlock:(void (^)(id request, id response))progressBlock // TODO: handle progressBlock? +uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock // ignored +downloadProgressBlock:(void (^)(id request, id response))progressBlock // FIXME: how to handle progressBlock? successBlock:(void (^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response))successBlock errorBlock:(void (^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock { @@ -299,6 +301,7 @@ - (id)fetchResource:(NSString *)resource baseURLString:baseURLStringWithTrailingSlash httpMethod:slRequestMethod parameters:d + uploadProgressBlock:uploadProgressBlock completionBlock:successBlock errorBlock:errorBlock]; } @@ -368,7 +371,8 @@ - (void)postReverseAuthAccessTokenWithAuthenticationHeader:(NSString *)authentic HTTPMethod:@"POST" baseURLString:@"https://api.twitter.com" parameters:d - progressBlock:nil + uploadProgressBlock:nil + downloadProgressBlock:nil successBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response) { NSDictionary *d = [[self class] parametersDictionaryFromAmpersandSeparatedParameterString:response]; diff --git a/STTwitter/STTwitterProtocol.h b/STTwitter/STTwitterProtocol.h index 7c0a389..3e1ae25 100644 --- a/STTwitter/STTwitterProtocol.h +++ b/STTwitter/STTwitterProtocol.h @@ -20,7 +20,8 @@ HTTPMethod:(NSString *)HTTPMethod baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)params - progressBlock:(void(^)(id request, id response))progressBlock +uploadProgressBlock:(void(^)(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite))uploadProgressBlock +downloadProgressBlock:(void(^)(id request, id response))progressBlock successBlock:(void(^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response))successBlock errorBlock:(void(^)(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error))errorBlock; diff --git a/demo_cli/clitter.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate b/demo_cli/clitter.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate index d1f8f4c..c6ff866 100644 Binary files a/demo_cli/clitter.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate and b/demo_cli/clitter.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/demo_ios/STTwitterDemoIOS.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate b/demo_ios/STTwitterDemoIOS.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate index 6b02b14..700b1d2 100644 Binary files a/demo_ios/STTwitterDemoIOS.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate and b/demo_ios/STTwitterDemoIOS.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/demo_osx/STTwitterDemoOSX.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate b/demo_osx/STTwitterDemoOSX.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate index 7598fc0..c50b1d3 100644 Binary files a/demo_osx/STTwitterDemoOSX.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate and b/demo_osx/STTwitterDemoOSX.xcodeproj/project.xcworkspace/xcuserdata/nst.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/demo_osx/STTwitterDemoOSX.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/demo_osx/STTwitterDemoOSX.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index eb1a525..1ed6c96 100644 --- a/demo_osx/STTwitterDemoOSX.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/demo_osx/STTwitterDemoOSX.xcodeproj/xcuserdata/nst.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -13,5 +13,67 @@ moduleName = ""> + + + + + + + + + + + + + + diff --git a/demo_osx/STTwitterDemoOSX/STClientVC.m b/demo_osx/STTwitterDemoOSX/STClientVC.m index 4d76171..e5bdc41 100644 --- a/demo_osx/STTwitterDemoOSX/STClientVC.m +++ b/demo_osx/STTwitterDemoOSX/STClientVC.m @@ -25,30 +25,33 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil - (IBAction)postTweet:(id)sender { - + self.twitterPostTweetStatus = @"-"; - + if(_twitterPostMediaURL) { - + [_twitter postStatusUpdate:_twitterPostTweetText inReplyToStatusID:nil mediaURL:_twitterPostMediaURL placeID:nil latitude:_twitterPostLatitude longitude:_twitterPostLongitude - successBlock:^(NSDictionary *status) { - - self.twitterPostTweetText = @""; - self.twitterPostTweetStatus = @"OK"; - self.twitterPostLatitude = nil; - self.twitterPostLongitude = nil; - self.twitterPostMediaURL = nil; - } errorBlock:^(NSError *error) { - self.twitterPostTweetStatus = error ? [error localizedDescription] : @"Unknown error"; - }]; - + + uploadProgressBlock:^(NSInteger bytesWritten, NSInteger totalBytesWritten, NSInteger totalBytesExpectedToWrite) { + NSLog(@"%lu %lu %lu", bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + } successBlock:^(NSDictionary *status) { + + self.twitterPostTweetText = @""; + self.twitterPostTweetStatus = @"OK"; + self.twitterPostLatitude = nil; + self.twitterPostLongitude = nil; + self.twitterPostMediaURL = nil; + } errorBlock:^(NSError *error) { + self.twitterPostTweetStatus = error ? [error localizedDescription] : @"Unknown error"; + }]; + } else { - + [_twitter postStatusUpdate:_twitterPostTweetText inReplyToStatusID:nil latitude:_twitterPostLatitude @@ -57,7 +60,7 @@ - (IBAction)postTweet:(id)sender { displayCoordinates:@(YES) trimUser:nil successBlock:^(NSDictionary *status) { - + self.twitterPostTweetText = @""; self.twitterPostTweetStatus = @"OK"; self.twitterPostLatitude = nil; @@ -101,7 +104,7 @@ - (IBAction)chooseMedia:(id)sender { [panel setAllowedFileTypes:@[ @"png", @"PNG", @"jpg", @"JPG", @"jpeg", @"JPEG", @"gif", @"GIF"] ]; NSWindow *mainWindow = [[NSApplication sharedApplication] mainWindow]; - + [panel beginSheetModalForWindow:mainWindow completionHandler:^(NSInteger result) { if (result != NSFileHandlingPanelOKButton) return; diff --git a/demo_osx/STTwitterDemoOSX/STConsoleVC.m b/demo_osx/STTwitterDemoOSX/STConsoleVC.m index c3e9dc2..afa25dd 100644 --- a/demo_osx/STTwitterDemoOSX/STConsoleVC.m +++ b/demo_osx/STTwitterDemoOSX/STConsoleVC.m @@ -43,16 +43,16 @@ - (IBAction)changeHTTPMethodAction:(id)sender { } - (NSString *)curlDescriptionWithEndpoint:(NSString *)endPoint baseURLString:(NSString *)baseURLString parameters:(NSDictionary *)parameters requestHeaders:(NSDictionary *)requestHeaders { -/* - $ curl -i -H "Authorization: OAuth oauth_consumer_key="7YBPrscvh0RIThrWYVeGg", \ - oauth_nonce="DA5E6B1E-E98D-4AFB-9AAB-18A463F2", \ - oauth_signature_method="HMAC-SHA1", \ - oauth_timestamp="1381908706", \ - oauth_version="1.0", \ - oauth_token="1294332967-UsaIUBcsC4JcHv9tIYxk5EktsVisAtCLNVGKghP", \ - oauth_signature="gnmc02ohamTvTmkTppz%2FbH8OjAs%3D"" \ - "https://api.twitter.com/1.1/statuses/home_timeline.json?count=10" - */ + /* + $ curl -i -H "Authorization: OAuth oauth_consumer_key="7YBPrscvh0RIThrWYVeGg", \ + oauth_nonce="DA5E6B1E-E98D-4AFB-9AAB-18A463F2", \ + oauth_signature_method="HMAC-SHA1", \ + oauth_timestamp="1381908706", \ + oauth_version="1.0", \ + oauth_token="1294332967-UsaIUBcsC4JcHv9tIYxk5EktsVisAtCLNVGKghP", \ + oauth_signature="gnmc02ohamTvTmkTppz%2FbH8OjAs%3D"" \ + "https://api.twitter.com/1.1/statuses/home_timeline.json?count=10" + */ if([baseURLString hasSuffix:@"/"]) baseURLString = [baseURLString substringToIndex:[baseURLString length]-1]; @@ -70,7 +70,7 @@ - (NSString *)curlDescriptionWithEndpoint:(NSString *)endPoint baseURLString:(NS [urlString appendFormat:@"?%@", parameterString]; } - + return [NSString stringWithFormat:@"curl -i -H \"Authorization: %@\" \"%@\"", [requestHeaders valueForKey:@"Authorization"], urlString]; } @@ -95,50 +95,56 @@ - (IBAction)sendRequestAction:(id)sender { self.rootNode = nil; [_outlineView reloadData]; - [_twitter fetchResource:_genericAPIEndpoint HTTPMethod:_genericHTTPMethod baseURLString:_genericBaseURLString parameters:parameters progressBlock:nil successBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response) { - - NSString *curlDescription = [self curlDescriptionWithEndpoint:_genericAPIEndpoint baseURLString:_genericBaseURLString parameters:parameters requestHeaders:requestHeaders]; - - self.curlTextViewAttributedString = [[NSAttributedString alloc] initWithString:curlDescription attributes:attributes]; - self.responseHeadersTextViewAttributedString = [[NSAttributedString alloc] initWithString:[responseHeaders description] attributes:attributes]; - - JSONSyntaxHighlight *jsh = [[JSONSyntaxHighlight alloc] initWithJSON:response]; - - NSMutableDictionary *keyAttributes = [jsh.keyAttributes mutableCopy]; - [keyAttributes addEntriesFromDictionary:attributes]; - - NSMutableDictionary *stringAttributes = [jsh.stringAttributes mutableCopy]; - [stringAttributes addEntriesFromDictionary:attributes]; - - NSMutableDictionary *nonStringAttributes = [jsh.nonStringAttributes mutableCopy]; - [nonStringAttributes addEntriesFromDictionary:attributes]; - - jsh.keyAttributes = keyAttributes; - jsh.stringAttributes = stringAttributes; - jsh.nonStringAttributes = nonStringAttributes; - - self.bodyTextViewAttributedString = [jsh highlightJSONWithPrettyPrint:YES]; - - self.rootNode = [BAVPlistNode plistNodeFromObject:response key:@"Root"]; - - [_outlineView reloadData]; - - } errorBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { - NSString *s = @"error"; - if(error) { - s = [error localizedDescription]; - } - - NSString *requestHeadersDescription = requestHeaders ? [requestHeaders description] : @""; - NSString *responseHeadersDescription = responseHeaders ? [responseHeaders description] : @""; - self.curlTextViewAttributedString = [[NSAttributedString alloc] initWithString:requestHeadersDescription attributes:attributes]; - self.responseHeadersTextViewAttributedString = [[NSAttributedString alloc] initWithString:responseHeadersDescription attributes:attributes]; - - self.bodyTextViewAttributedString = [[NSAttributedString alloc] initWithString:s attributes:attributes]; - - self.rootNode = nil; - [_outlineView reloadData]; - }]; + [_twitter fetchResource:_genericAPIEndpoint + HTTPMethod:_genericHTTPMethod + baseURLString:_genericBaseURLString + parameters:parameters + uploadProgressBlock:nil + downloadProgressBlock:nil + successBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, id response) { + + NSString *curlDescription = [self curlDescriptionWithEndpoint:_genericAPIEndpoint baseURLString:_genericBaseURLString parameters:parameters requestHeaders:requestHeaders]; + + self.curlTextViewAttributedString = [[NSAttributedString alloc] initWithString:curlDescription attributes:attributes]; + self.responseHeadersTextViewAttributedString = [[NSAttributedString alloc] initWithString:[responseHeaders description] attributes:attributes]; + + JSONSyntaxHighlight *jsh = [[JSONSyntaxHighlight alloc] initWithJSON:response]; + + NSMutableDictionary *keyAttributes = [jsh.keyAttributes mutableCopy]; + [keyAttributes addEntriesFromDictionary:attributes]; + + NSMutableDictionary *stringAttributes = [jsh.stringAttributes mutableCopy]; + [stringAttributes addEntriesFromDictionary:attributes]; + + NSMutableDictionary *nonStringAttributes = [jsh.nonStringAttributes mutableCopy]; + [nonStringAttributes addEntriesFromDictionary:attributes]; + + jsh.keyAttributes = keyAttributes; + jsh.stringAttributes = stringAttributes; + jsh.nonStringAttributes = nonStringAttributes; + + self.bodyTextViewAttributedString = [jsh highlightJSONWithPrettyPrint:YES]; + + self.rootNode = [BAVPlistNode plistNodeFromObject:response key:@"Root"]; + + [_outlineView reloadData]; + + } errorBlock:^(id request, NSDictionary *requestHeaders, NSDictionary *responseHeaders, NSError *error) { + NSString *s = @"error"; + if(error) { + s = [error localizedDescription]; + } + + NSString *requestHeadersDescription = requestHeaders ? [requestHeaders description] : @""; + NSString *responseHeadersDescription = responseHeaders ? [responseHeaders description] : @""; + self.curlTextViewAttributedString = [[NSAttributedString alloc] initWithString:requestHeadersDescription attributes:attributes]; + self.responseHeadersTextViewAttributedString = [[NSAttributedString alloc] initWithString:responseHeadersDescription attributes:attributes]; + + self.bodyTextViewAttributedString = [[NSAttributedString alloc] initWithString:s attributes:attributes]; + + self.rootNode = nil; + [_outlineView reloadData]; + }]; } #pragma mark - NSOutlineViewDataSource