Having problems with uploading photos to TwitPic using OAuth in Objective C on the iPhone
I have been working on an iPhone app that has a feature of uploading photos to TwitPic. I have it working with basic authentication.
I am trying to get it working with OAuth. I am getting authentication errors. I have studied very carefully the TwitPic documentation.
I am authorising the app by displaying a UI Web View and the it returns a PIN value. I enter the PIN value in the app and request the token.
I am able to upload status updates to Twitter but not photos.
My code is based on some example code from here:
Example iPhone app using OAuth
Here is my code:
NSString *url = @"http://api.twitpic.com/2/upload.json";
NSString *oauth_header = [oAuth oAuthHeaderForMethod:@"POST" andUrl:url andParams:nil];
NSLog(@"OAuth header : %@\n\n", oauth_header);
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:url]];
[request addRequestHeader:@"User-Agent" value:@"ASIHTTPRequest"];
request.requestMethod = @"POST";
[request addRequestHeader:@"X-Auth-Service-Provider" value:@"https://api.twitter.com/1/account/verify_credentials.json"];
[request addRequestHeader:@"X-Verify-Credentials-Authorization" value:oauth_header];
NSData *imageRepresentation = UIImageJPEGRepresentation(imageToUpload, 0.8);
[request setData:imageRepresentation forKey:@"media"];
[request setPostValue:@"Some Message" forKey:@"message"];
[req开发者_JS百科uest setPostValue:TWITPIC_API_KEY forKey:@"key"];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestFailed:)];
[request start];
Here is the OAuth Header:
OAuth realm="http://api.twitter.com/", oauth_timestamp="1275492425", oauth_nonce="b686f20a18ba6763ac52b689b2ac0c421a9e4013", oauth_signature_method="HMAC-SHA1", oauth_consumer_key="zNbW3Xi3MuS7i9cpz6fw", oauth_version="1.0", oauth_token="147275699-jmrjpwk3B6mO2FX2BCc9Ci9CRBbBKYW1bOni2MYs", oauth_signature="d17HImz6VgygZgbcp845CD2qNnI%3D"
HA! I found it! We should create the header with https://api.twitter.com/1/account/verify_credentials.json and post to http://api.twitpic.com/2/upload.json! (And use GET)
NSString *fakeurl = @"https://api.twitter.com/1/account/verify_credentials.json";
NSString *oauth_header = [oAuth oAuthHeaderForMethod:@"GET" andUrl:fakeurl andParams:nil];
NSLog(@"OAuth header : %@\n\n", oauth_header);
NSString *url = @"http://api.twitpic.com/2/upload.json";
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:url]];
request.delegate = self;
[request addRequestHeader:@"User-Agent" value:@"ASIHTTPRequest"];
request.requestMethod = @"GET";
[request addRequestHeader:@"X-Verify-Credentials-Authorization" value:oauth_header];
[request addRequestHeader:@"X-Auth-Service-Provider" value:@"https://api.twitter.com/1/account/verify_credentials.json"];
NSData *imageRepresentation = UIImageJPEGRepresentation([UIImage imageNamed:@"IMG_0717.jpg"], 0.2);
if (imageRepresentation) {
NSLog(@"Pic not nil");
}
[request setData:imageRepresentation forKey:@"media"];
[request setPostValue:@"twitpic, i hate you. die painfully." forKey:@"message"];
[request setPostValue:twitPicKey forKey:@"key"];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestFailed:)];
[request start];
Use GSTwitPicEngine: https://github.com/Gurpartap/GSTwitPicEngine
Using GSTwitPicEngine:
Initialize the engine with class or as needed:
self.twitpicEngine = (GSTwitPicEngine *)[GSTwitPicEngine twitpicEngineWithDelegate:self];
Find the authorization token and supply to twitpicEngine with:
[twitpicEngine setAccessToken:token];
Then to upload image and attach a text message along with it (does not post to twitter):
[twitpicEngine uploadPicture:[UIImage imageNamed:@"mypic.png"] withMessage:@"Hello world!"]; // This message is supplied back in success delegate call in request's userInfo.
To upload image only:
[twitpicEngine uploadPicture:uploadImageView.image];
Upon end of request, one of the delegate methods is called with appropriate data and information.
GSTwitPicEngineDelegate protocol specifies two delegate methods:
- (void)twitpicDidFinishUpload:(NSDictionary *)response {
NSLog(@"TwitPic finished uploading: %@", response);
// [response objectForKey:@"parsedResponse"] gives an NSDictionary of the response one of the parsing libraries was available.
// Otherwise, use [[response objectForKey:@"request"] objectForKey:@"responseString"] to parse yourself.
if ([[[response objectForKey:@"request"] userInfo] objectForKey:@"message"] > 0 && [[response objectForKey:@"parsedResponse"] count] > 0) {
// Uncomment to update status upon successful upload, using MGTwitterEngine's instance.
// [twitterEngine sendUpdate:[NSString stringWithFormat:@"%@ %@", [[[response objectForKey:@"request"] userInfo] objectForKey:@"message"], [[response objectForKey:@"parsedResponse"] objectForKey:@"url"]]];
}
}
and
- (void)twitpicDidFailUpload:(NSDictionary *)error {
NSLog(@"TwitPic failed to upload: %@", error);
if ([[error objectForKey:@"request"] responseStatusCode] == 401) {
// UIAlertViewQuick(@"Authentication failed", [error objectForKey:@"errorDescription"], @"OK");
}
}
All set?
OAuth method to generate a header must be GET. Not POST.
Also url must be https://api.twitter.com/1/account/verify_credentials.json
Thanks, this helped me get it working too :) I also updated http://github.com/jaanus/PlainOAuth with working example code.
精彩评论