From ea1a118b250c1abe707fe55b51a6b066e9d4343c Mon Sep 17 00:00:00 2001 From: Lucas Correa Date: Mon, 5 Mar 2012 18:06:58 -0300 Subject: [PATCH 1/4] Added method retweet --- .gitignore | 25 +++++++++++++++++++ .../MGTwitterEngine/MGTwitterEngine.h | 2 ++ .../MGTwitterEngine/MGTwitterEngine.m | 21 ++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/.gitignore b/.gitignore index e43b0f9..0e2f085 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,26 @@ +#Xcode +build/* +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +.gitignore #Xcode +build/* +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +*.xcworkspace +!default.xcworkspace +xcuserdata +profile +*.moved-aside .DS_Store + diff --git a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h index aabdf15..4aae342 100644 --- a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h +++ b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h @@ -97,6 +97,8 @@ - (NSString *)sendUpdate:(NSString *)status; // statuses/update - (NSString *)sendUpdate:(NSString *)status inReplyTo:(unsigned long)updateID; // statuses/update +- (NSString *)sendRetweet:(unsigned long)updateID; + - (NSString *)getRepliesStartingAtPage:(int)pageNum; // statuses/mentions - (NSString *)getRepliesSinceID:(unsigned long)sinceID startingAtPage:(int)pageNum count:(int)count; // statuses/mentions - (NSString *)getRepliesSinceID:(unsigned long)sinceID withMaximumID:(unsigned long)maxID startingAtPage:(int)pageNum count:(int)count; // statuses/mentions diff --git a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m index 2908ed0..5c368b4 100644 --- a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m +++ b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m @@ -1041,6 +1041,27 @@ - (NSString *)sendUpdate:(NSString *)status inReplyTo:(unsigned long)updateID } +- (NSString *)sendRetweet:(unsigned long)updateID + +{ + if (updateID == 0){ + + return nil; + } + + NSString *path = [NSString stringWithFormat:@"statuses/retweet/%u.%@", updateID, API_FORMAT]; + + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; + [params setObject:[NSString stringWithFormat:@"%@", updateID] forKey:@"id"]; + NSString *body = [self _queryStringWithBase:nil parameters:params prefixed:NO]; + + + return [self _sendRequestWithMethod:HTTP_POST_METHOD path:path + queryParameters:params body:body + requestType:MGTwitterUpdateSendRequest + responseType:MGTwitterStatus]; +} + #pragma mark - From a12961a055bc27a4a0489b584853cc9f277357ae Mon Sep 17 00:00:00 2001 From: Lucas Correa Date: Mon, 5 Mar 2012 19:48:03 -0300 Subject: [PATCH 2/4] Fix method reweet --- Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h | 2 +- Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h index 4aae342..d7f91a5 100644 --- a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h +++ b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h @@ -97,7 +97,7 @@ - (NSString *)sendUpdate:(NSString *)status; // statuses/update - (NSString *)sendUpdate:(NSString *)status inReplyTo:(unsigned long)updateID; // statuses/update -- (NSString *)sendRetweet:(unsigned long)updateID; +- (NSString *)sendRetweet:(NSString *)updateID; - (NSString *)getRepliesStartingAtPage:(int)pageNum; // statuses/mentions - (NSString *)getRepliesSinceID:(unsigned long)sinceID startingAtPage:(int)pageNum count:(int)count; // statuses/mentions diff --git a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m index 5c368b4..dc2a1d3 100644 --- a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m +++ b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m @@ -1041,23 +1041,23 @@ - (NSString *)sendUpdate:(NSString *)status inReplyTo:(unsigned long)updateID } -- (NSString *)sendRetweet:(unsigned long)updateID +- (NSString *)sendRetweet:(NSString *)updateID { if (updateID == 0){ - return nil; } + + NSString *path = [NSString stringWithFormat:@"statuses/retweet/%@.%@",updateID, API_FORMAT]; - NSString *path = [NSString stringWithFormat:@"statuses/retweet/%u.%@", updateID, API_FORMAT]; NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; [params setObject:[NSString stringWithFormat:@"%@", updateID] forKey:@"id"]; NSString *body = [self _queryStringWithBase:nil parameters:params prefixed:NO]; - + return [self _sendRequestWithMethod:HTTP_POST_METHOD path:path - queryParameters:params body:body + queryParameters:params body:body requestType:MGTwitterUpdateSendRequest responseType:MGTwitterStatus]; } From 1b5a7c61bca376a6f28b623de3a2516bccdfd5e2 Mon Sep 17 00:00:00 2001 From: Lucas Correa Date: Mon, 26 Mar 2012 18:24:22 -0300 Subject: [PATCH 3/4] Added method post with upload photo --- .../MGTwitterEngine/MGTwitterEngine.h | 1 + .../MGTwitterEngine/MGTwitterEngine.m | 238 +++++++++++------- .../SA_OAuthTwitterEngine.m | 99 ++++++++ 3 files changed, 247 insertions(+), 91 deletions(-) diff --git a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h index d7f91a5..9be419f 100644 --- a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h +++ b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.h @@ -107,6 +107,7 @@ - (NSString *)getFeaturedUsers; // statuses/features (undocumented, returns invalid JSON data) +- (NSString *)sendUpdate:(NSString *)status uploadPhoto:(UIImage *)image latitude:(double)aLatitude longitude:(double)aLongitude; // User methods diff --git a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m index dc2a1d3..521b1ab 100644 --- a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m +++ b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m @@ -14,32 +14,32 @@ #define USE_LIBXML 0 #if YAJL_AVAILABLE - #define API_FORMAT @"json" +#define API_FORMAT @"json" - #import "MGTwitterStatusesYAJLParser.h" - #import "MGTwitterMessagesYAJLParser.h" - #import "MGTwitterUsersYAJLParser.h" - #import "MGTwitterMiscYAJLParser.h" - #import "MGTwitterSearchYAJLParser.h" +#import "MGTwitterStatusesYAJLParser.h" +#import "MGTwitterMessagesYAJLParser.h" +#import "MGTwitterUsersYAJLParser.h" +#import "MGTwitterMiscYAJLParser.h" +#import "MGTwitterSearchYAJLParser.h" #else - #define API_FORMAT @"xml" - - #if USE_LIBXML - #import "MGTwitterStatusesLibXMLParser.h" - #import "MGTwitterMessagesLibXMLParser.h" - #import "MGTwitterUsersLibXMLParser.h" - #import "MGTwitterMiscLibXMLParser.h" - #else - #import "MGTwitterStatusesParser.h" - #import "MGTwitterUsersParser.h" - #import "MGTwitterMessagesParser.h" - #import "MGTwitterMiscParser.h" - #endif +#define API_FORMAT @"xml" + +#if USE_LIBXML +#import "MGTwitterStatusesLibXMLParser.h" +#import "MGTwitterMessagesLibXMLParser.h" +#import "MGTwitterUsersLibXMLParser.h" +#import "MGTwitterMiscLibXMLParser.h" +#else +#import "MGTwitterStatusesParser.h" +#import "MGTwitterUsersParser.h" +#import "MGTwitterMessagesParser.h" +#import "MGTwitterMiscParser.h" +#endif #endif #define TWITTER_DOMAIN @"twitter.com" #if YAJL_AVAILABLE - #define TWITTER_SEARCH_DOMAIN @"search.twitter.com" +#define TWITTER_SEARCH_DOMAIN @"search.twitter.com" #endif #define HTTP_POST_METHOD @"POST" #define MAX_MESSAGE_LENGTH 140 // Twitter recommends tweets of max 140 chars @@ -74,6 +74,12 @@ - (NSString *)_sendRequestWithMethod:(NSString *)method requestType:(MGTwitterRequestType)requestType responseType:(MGTwitterResponseType)responseType; +- (NSString *)_sendUploadRequestWithMethod:(NSString *)method + path:(NSString *)path + body:(NSString *)body + requestType:(MGTwitterRequestType)requestType + responseType:(MGTwitterResponseType)responseType; + // Parsing methods - (void)_parseDataForConnection:(MGTwitterHTTPURLConnection *)connection; @@ -108,7 +114,7 @@ - (MGTwitterEngine *)initWithDelegate:(NSObject*)newDel #if YAJL_AVAILABLE _searchDomain = [TWITTER_SEARCH_DOMAIN retain]; #endif - + _secureConnection = YES; _clearsCookies = NO; #if YAJL_AVAILABLE @@ -378,7 +384,7 @@ - (NSString *)_queryStringWithBase:(NSString *)base parameters:(NSDictionary *)p } NSString *name = [names objectAtIndex:i]; [str appendString:[NSString stringWithFormat:@"%@=%@", - name, [self _encodeString:[params objectForKey:name]]]]; + name, [self _encodeString:[params objectForKey:name]]]]; } } @@ -403,10 +409,10 @@ - (NSString *)_dateToHTTP:(NSDate *)date - (NSString *)_encodeString:(NSString *)string { NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, - (CFStringRef)string, - NULL, - (CFStringRef)@";/?:@&=$+{}<>,", - kCFStringEncodingUTF8); + (CFStringRef)string, + NULL, + (CFStringRef)@";/?:@&=$+{}<>,", + kCFStringEncodingUTF8); return [result autorelease]; } @@ -461,38 +467,38 @@ - (NSString *)_sendRequestWithMethod:(NSString *)method if (params) { fullPath = [self _queryStringWithBase:fullPath parameters:params prefixed:YES]; } - + #if YAJL_AVAILABLE NSString *domain = nil; NSString *connectionType = nil; if (requestType == MGTwitterSearchRequest || requestType == MGTwitterSearchCurrentTrendsRequest) - { + { domain = _searchDomain; connectionType = @"http"; - } + } else - { + { domain = _APIDomain; if (_secureConnection) - { + { connectionType = @"https"; - } + } else - { + { connectionType = @"http"; - } - } + } + } #else NSString *domain = _APIDomain; NSString *connectionType = nil; if (_secureConnection) - { + { connectionType = @"https"; - } + } else - { + { connectionType = @"http"; - } + } #endif #if SET_AUTHORIZATION_IN_HEADER @@ -510,13 +516,13 @@ - (NSString *)_sendRequestWithMethod:(NSString *)method if (!finalURL) { return nil; } - + #if DEBUG if (YES) { NSLog(@"MGTwitterEngine: finalURL = %@", finalURL); } #endif - + // Construct an NSMutableURLRequest for the URL and set appropriate request method. NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:finalURL cachePolicy:NSURLRequestReloadIgnoringCacheData @@ -540,7 +546,7 @@ - (NSString *)_sendRequestWithMethod:(NSString *)method [theRequest setValue:authValue forHTTPHeaderField:@"Authorization"]; } #endif - + // Set the request body if this is a POST request. BOOL isPOST = (method && [method isEqualToString:HTTP_POST_METHOD]); if (isPOST) { @@ -594,45 +600,45 @@ - (void)_parseDataForConnection:(MGTwitterHTTPURLConnection *)connection NSData *jsonData = [[[connection data] copy] autorelease]; MGTwitterRequestType requestType = [connection requestType]; MGTwitterResponseType responseType = [connection responseType]; - + NSURL *URL = [connection URL]; - + #if DEBUG if (NO) { NSLog(@"MGTwitterEngine: jsonData = %@ from %@", [[[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] autorelease], URL); } #endif - + switch (responseType) { case MGTwitterStatuses: case MGTwitterStatus: [MGTwitterStatusesYAJLParser parserWithJSON:jsonData delegate:self - connectionIdentifier:identifier requestType:requestType - responseType:responseType URL:URL deliveryOptions:_deliveryOptions]; + connectionIdentifier:identifier requestType:requestType + responseType:responseType URL:URL deliveryOptions:_deliveryOptions]; break; case MGTwitterUsers: case MGTwitterUser: [MGTwitterUsersYAJLParser parserWithJSON:jsonData delegate:self - connectionIdentifier:identifier requestType:requestType - responseType:responseType URL:URL deliveryOptions:_deliveryOptions]; + connectionIdentifier:identifier requestType:requestType + responseType:responseType URL:URL deliveryOptions:_deliveryOptions]; break; case MGTwitterDirectMessages: case MGTwitterDirectMessage: [MGTwitterMessagesYAJLParser parserWithJSON:jsonData delegate:self - connectionIdentifier:identifier requestType:requestType - responseType:responseType URL:URL deliveryOptions:_deliveryOptions]; + connectionIdentifier:identifier requestType:requestType + responseType:responseType URL:URL deliveryOptions:_deliveryOptions]; break; case MGTwitterMiscellaneous: [MGTwitterMiscYAJLParser parserWithJSON:jsonData delegate:self - connectionIdentifier:identifier requestType:requestType - responseType:responseType URL:URL deliveryOptions:_deliveryOptions]; + connectionIdentifier:identifier requestType:requestType + responseType:responseType URL:URL deliveryOptions:_deliveryOptions]; break; case MGTwitterSearchResults: [MGTwitterSearchYAJLParser parserWithJSON:jsonData delegate:self - connectionIdentifier:identifier requestType:requestType - responseType:responseType URL:URL deliveryOptions:_deliveryOptions]; + connectionIdentifier:identifier requestType:requestType + responseType:responseType URL:URL deliveryOptions:_deliveryOptions]; break; - default: + default: break; } } @@ -646,30 +652,30 @@ - (void)_parseDataForConnection:(MGTwitterHTTPURLConnection *)connection #if USE_LIBXML NSURL *URL = [connection URL]; - + switch (responseType) { case MGTwitterStatuses: case MGTwitterStatus: [MGTwitterStatusesLibXMLParser parserWithXML:xmlData delegate:self - connectionIdentifier:identifier requestType:requestType - responseType:responseType URL:URL]; + connectionIdentifier:identifier requestType:requestType + responseType:responseType URL:URL]; break; case MGTwitterUsers: case MGTwitterUser: [MGTwitterUsersLibXMLParser parserWithXML:xmlData delegate:self - connectionIdentifier:identifier requestType:requestType - responseType:responseType URL:URL]; + connectionIdentifier:identifier requestType:requestType + responseType:responseType URL:URL]; break; case MGTwitterDirectMessages: case MGTwitterDirectMessage: [MGTwitterMessagesLibXMLParser parserWithXML:xmlData delegate:self - connectionIdentifier:identifier requestType:requestType - responseType:responseType URL:URL]; + connectionIdentifier:identifier requestType:requestType + responseType:responseType URL:URL]; break; case MGTwitterMiscellaneous: [MGTwitterMiscLibXMLParser parserWithXML:xmlData delegate:self - connectionIdentifier:identifier requestType:requestType - responseType:responseType URL:URL]; + connectionIdentifier:identifier requestType:requestType + responseType:responseType URL:URL]; break; default: break; @@ -763,7 +769,7 @@ - (void)parsingFailedForRequest:(NSString *)requestIdentifier #if YAJL_AVAILABLE - (void)parsedObject:(NSDictionary *)dictionary forRequest:(NSString *)requestIdentifier - ofResponseType:(MGTwitterResponseType)responseType + ofResponseType:(MGTwitterResponseType)responseType { if ([self _isValidDelegateForSelector:@selector(receivedObject:forRequest:)]) [_delegate receivedObject:dictionary forRequest:requestIdentifier]; @@ -808,7 +814,7 @@ - (void)connection:(MGTwitterHTTPURLConnection *)connection didReceiveResponse:( [_connections removeObjectForKey:connectionIdentifier]; if ([self _isValidDelegateForSelector:@selector(connectionFinished:)]) [_delegate connectionFinished:connectionIdentifier]; - + } else if (statusCode == 304 || [connection responseType] == MGTwitterGeneric) { // Not modified, or generic success. if ([self _isValidDelegateForSelector:@selector(requestSucceeded:)]) @@ -937,7 +943,7 @@ - (NSString *)getFollowedTimelineSinceID:(unsigned long)sinceID startingAtPage:( - (NSString *)getFollowedTimelineSinceID:(unsigned long)sinceID withMaximumID:(unsigned long)maxID startingAtPage:(int)page count:(int)count { NSString *path = [NSString stringWithFormat:@"statuses/friends_timeline.%@", API_FORMAT]; - + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; if (sinceID > 0) { [params setObject:[NSString stringWithFormat:@"%u", sinceID] forKey:@"since_id"]; @@ -1047,14 +1053,14 @@ - (NSString *)sendRetweet:(NSString *)updateID if (updateID == 0){ return nil; } - + NSString *path = [NSString stringWithFormat:@"statuses/retweet/%@.%@",updateID, API_FORMAT]; NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; [params setObject:[NSString stringWithFormat:@"%@", updateID] forKey:@"id"]; NSString *body = [self _queryStringWithBase:nil parameters:params prefixed:NO]; - + return [self _sendRequestWithMethod:HTTP_POST_METHOD path:path queryParameters:params body:body @@ -1062,6 +1068,56 @@ - (NSString *)sendRetweet:(NSString *)updateID responseType:MGTwitterStatus]; } + +- (NSString *)sendUpdate:(NSString *)status uploadPhoto:(UIImage *)image latitude:(double)aLatitude longitude:(double)aLongitude +{ + + //https://api.twitter.com/1/help/configuration.json + //"max_media_per_upload": 1, + + NSData * imageData = (UIImagePNGRepresentation(image)); + + NSString *boundary = @"----------------------------991990ee82f7"; + + NSString *body = [[NSString alloc] init]; + body = [body stringByAppendingFormat:@"--%@\r\n", boundary]; + body = [body stringByAppendingFormat:@"Content-Disposition: form-data; name=\"media_data[]\"; filename=\"photo.png\"\r\n"]; + body = [body stringByAppendingFormat:@"Content-Type: application/octet-stream\r\n"]; + body = [body stringByAppendingFormat:@"\r\n"]; + body = [body stringByAppendingFormat:[imageData base64EncodingWithLineLength:0]]; + body = [body stringByAppendingFormat:@"\r\n--%@\r\n", boundary]; + body = [body stringByAppendingFormat:@"Content-Disposition: form-data; name=\"status\"\r\n"]; + body = [body stringByAppendingFormat:@"\r\n"]; + body = [body stringByAppendingFormat:@"%@\r\n", status]; + body = [body stringByAppendingFormat:@"--%@--\r\n", boundary]; + + if(aLatitude != 0){ + body = [body stringByAppendingFormat:@"Content-Disposition: form-data; name=\"lat\"\r\n"]; + body = [body stringByAppendingFormat:@"\r\n"]; + body = [body stringByAppendingFormat:@"%f", aLatitude]; + body = [body stringByAppendingFormat:@"\r\n"]; + body = [body stringByAppendingFormat:@"--%@--\r\n", boundary]; + } + + if(aLongitude != 0){ + body = [body stringByAppendingFormat:@"Content-Disposition: form-data; name=\"long\"\r\n"]; + body = [body stringByAppendingFormat:@"\r\n"]; + body = [body stringByAppendingFormat:@"%f", aLongitude]; + body = [body stringByAppendingFormat:@"\r\n"]; + body = [body stringByAppendingFormat:@"--%@--\r\n", boundary]; + } + + + NSString *path = [NSString stringWithFormat:@"statuses/update_with_media.%@", API_FORMAT]; + + + return [self _sendUploadRequestWithMethod:HTTP_POST_METHOD + path:path + body:body + requestType:MGTwitterUpdateSendRequest + responseType:MGTwitterStatus]; +} + #pragma mark - @@ -1077,8 +1133,8 @@ - (NSString *)getRepliesSinceID:(unsigned long)sinceID startingAtPage:(int)page - (NSString *)getRepliesSinceID:(unsigned long)sinceID withMaximumID:(unsigned long)maxID startingAtPage:(int)page count:(int)count { -// NOTE: identi.ca can't handle mentions URL yet... -// NSString *path = [NSString stringWithFormat:@"statuses/mentions.%@", API_FORMAT]; + // NOTE: identi.ca can't handle mentions URL yet... + // NSString *path = [NSString stringWithFormat:@"statuses/mentions.%@", API_FORMAT]; NSString *path = [NSString stringWithFormat:@"statuses/replies.%@", API_FORMAT]; NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; @@ -1388,7 +1444,7 @@ - (NSString *)setLocation:(NSString *)location if ([trimmedLocation length] > MAX_LOCATION_LENGTH) { trimmedLocation = [trimmedLocation substringToIndex:MAX_LOCATION_LENGTH]; } - + NSMutableDictionary *params = [NSMutableDictionary dictionaryWithCapacity:0]; [params setObject:trimmedLocation forKey:@"location"]; NSString *body = [self _queryStringWithBase:nil parameters:params prefixed:NO]; @@ -1467,10 +1523,10 @@ - (NSString *)markUpdate:(unsigned long)updateID asFavorite:(BOOL)flag NSString *path = nil; MGTwitterRequestType requestType; if (flag) - { + { path = [NSString stringWithFormat:@"favorites/create/%u.%@", updateID, API_FORMAT]; requestType = MGTwitterFavoritesEnableRequest; - } + } else { path = [NSString stringWithFormat:@"favorites/destroy/%u.%@", updateID, API_FORMAT]; requestType = MGTwitterFavoritesDisableRequest; @@ -1607,22 +1663,22 @@ - (NSString *)getSearchResultsForQuery:(NSString *)query sinceID:(unsigned long) } /* - NOTE: These parameters are also available but not implemented yet: - - lang: restricts tweets to the given language, given by an ISO 639-1 code. - - Ex: http://search.twitter.com/search.atom?lang=en&q=devo - - geocode: returns tweets by users located within a given radius of the given latitude/longitude, where the user's - location is taken from their Twitter profile. The parameter value is specified by "latitide,longitude,radius", - where radius units must be specified as either "mi" (miles) or "km" (kilometers). - - Note that you cannot use the near operator via the API to geocode arbitrary locations; however you can use this - geocode parameter to search near geocodes directly. - - Ex: http://search.twitter.com/search.atom?geocode=40.757929%2C-73.985506%2C25km - */ - + NOTE: These parameters are also available but not implemented yet: + + lang: restricts tweets to the given language, given by an ISO 639-1 code. + + Ex: http://search.twitter.com/search.atom?lang=en&q=devo + + geocode: returns tweets by users located within a given radius of the given latitude/longitude, where the user's + location is taken from their Twitter profile. The parameter value is specified by "latitide,longitude,radius", + where radius units must be specified as either "mi" (miles) or "km" (kilometers). + + Note that you cannot use the near operator via the API to geocode arbitrary locations; however you can use this + geocode parameter to search near geocodes directly. + + Ex: http://search.twitter.com/search.atom?geocode=40.757929%2C-73.985506%2C25km + */ + return [self _sendRequestWithMethod:nil path:path queryParameters:params body:nil requestType:MGTwitterSearchRequest diff --git a/Twitter+OAuth/SAOAuthTwitterEngine/SA_OAuthTwitterEngine.m b/Twitter+OAuth/SAOAuthTwitterEngine/SA_OAuthTwitterEngine.m index fcb12c6..bd3198b 100644 --- a/Twitter+OAuth/SAOAuthTwitterEngine/SA_OAuthTwitterEngine.m +++ b/Twitter+OAuth/SAOAuthTwitterEngine/SA_OAuthTwitterEngine.m @@ -343,6 +343,105 @@ - (NSString *)_sendRequestWithMethod:(NSString *)method } +- (NSString *)_sendUploadRequestWithMethod:(NSString *)method + path:(NSString *)path + body:(NSString *)body + requestType:(MGTwitterRequestType)requestType + responseType:(MGTwitterResponseType)responseType +{ + NSString *fullPath = path; + + // -------------------------------------------------------------------------------- + // modificaiton from the base clase + // the base class appends parameters here + // -------------------------------------------------------------------------------- + // if (params) { + // fullPath = [self _queryStringWithBase:fullPath parameters:params prefixed:YES]; + // } + // -------------------------------------------------------------------------------- + + NSString *urlString = [NSString stringWithFormat:@"%@://%@/%@", + (_secureConnection) ? @"https" : @"http", + @"upload.twitter.com/1", fullPath]; + NSURL *finalURL = [NSURL URLWithString:urlString]; + if (!finalURL) { + return nil; + } + + // -------------------------------------------------------------------------------- + // modificaiton from the base clase + // the base class creates a regular url request + // we're going to create an oauth url request + // -------------------------------------------------------------------------------- + // NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:finalURL + // cachePolicy:NSURLRequestReloadIgnoringCacheData + // timeoutInterval:URL_REQUEST_TIMEOUT]; + // -------------------------------------------------------------------------------- + + OAMutableURLRequest *theRequest = [[[OAMutableURLRequest alloc] initWithURL:finalURL + consumer:self.consumer + token:_accessToken + realm: nil + signatureProvider:nil] autorelease]; + if (method) { + [theRequest setHTTPMethod:method]; + } + [theRequest setHTTPShouldHandleCookies:NO]; + + // Set headers for client information, for tracking purposes at Twitter. + [theRequest setValue:_clientName forHTTPHeaderField:@"X-Twitter-Client"]; + [theRequest setValue:_clientVersion forHTTPHeaderField:@"X-Twitter-Client-Version"]; + [theRequest setValue:_clientURL forHTTPHeaderField:@"X-Twitter-Client-URL"]; + + NSString *boundary = @"----------------------------991990ee82f7"; + NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]; + [theRequest setValue:contentType forHTTPHeaderField:@"content-type"]; + + // -------------------------------------------------------------------------------- + // modificaiton from the base clase + // our version "prepares" the oauth url request + // -------------------------------------------------------------------------------- + [theRequest prepare]; + + // Set the request body if this is a POST request. + BOOL isPOST = (method && [method isEqualToString:@"POST"]); + if (isPOST) { + // Set request body, if specified (hopefully so), with 'source' parameter if appropriate. + NSString *finalBody = @""; + if (body) { + finalBody = [finalBody stringByAppendingString:body]; + } + if (_clientSourceToken) { + finalBody = [finalBody stringByAppendingString:[NSString stringWithFormat:@"%@source=%@", + (body) ? @"&" : @"?" , + _clientSourceToken]]; + } + + if (finalBody) { + [theRequest setHTTPBody:[finalBody dataUsingEncoding:NSUTF8StringEncoding]]; + } + } + + + // Create a connection using this request, with the default timeout and caching policy, + // and appropriate Twitter request and response types for parsing and error reporting. + MGTwitterHTTPURLConnection *connection; + connection = [[MGTwitterHTTPURLConnection alloc] initWithRequest:theRequest + delegate:self + requestType:requestType + responseType:responseType]; + + if (!connection) { + return nil; + } else { + [_connections setObject:connection forKey:[connection identifier]]; + [connection release]; + } + + return [connection identifier]; +} + + - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge { From ff92f8cd092b3103202376de22709f95f72e1a76 Mon Sep 17 00:00:00 2001 From: Lucas Correa Date: Thu, 14 Feb 2013 14:42:05 -0200 Subject: [PATCH 4/4] Bug fixed --- Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m index 974d7c0..5fe6937 100644 --- a/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m +++ b/Twitter+OAuth/MGTwitterEngine/MGTwitterEngine.m @@ -358,7 +358,7 @@ - (NSString *)_encodeString:(NSString *)string NSString *result = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)string, NULL, - (CFStringRef)@";/?:@&=$+{}<>,", + (CFStringRef)@";/?:@&=$+{}<>,()", kCFStringEncodingUTF8); return [result autorelease]; }