Reputation: 1637
I am trying to make Twitter work in my app and everything works fine except the code does not seem to recognize an error from Twitter. If the username/password are not valid, I get an error message through this function:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString* strData = [[[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSASCIIStringEncoding] autorelease];
NSLog(@"Received data: %@", strData ) ;
return ;
}
It prints: Received data: Could not authenticate you. .
However, the app continues to the post a tweet view I have and ignores the error. Obviously, I do not have something setup right to detect such an error from twitter so my question is how do I get Xcode to recognize an error like this? This uses basic http auth btw and don't mention anything about OAuth...just trying to get this to work for now.
-(void) onLogin:(id)sender
{
[loading1 startAnimating];
NSString *postURL = @"http://twitter.com/account/verify_credentials.xml";
NSMutableURLRequest *request = [ [ NSMutableURLRequest alloc ] initWithURL: [ NSURL URLWithString:postURL ] ];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if (!theConnection)
{
UIAlertView* aler = [[UIAlertView alloc] initWithTitle:@"Network Error" message:@"Failed to Connect to twitter" delegate:nil cancelButtonTitle:@"Close" otherButtonTitles:nil];
[aler show];
[aler release];
}
else
{
receivedData = [[NSMutableData data] retain];
}
[request release];
}
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] == 0 && ![challenge proposedCredential])
{
NSURLCredential *newCredential;
newCredential=[NSURLCredential credentialWithUser:txtUsername.text
password:txtPassword.text
persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
}
else
{
isAuthFailed = YES;
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
Upvotes: 0
Views: 4650
Reputation: 1637
ok so I can now get an error response or a authentication response in xml. now, how do I say, use this response as a triggering factor for connectionDidFailWithError because if twitter send me back an error, I want to give an in-app error.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
NSXMLParser* parser = [[NSXMLParser alloc] initWithData:data];
[parser setDelegate:self];
[parser parse];
return;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSMutableString *)string
{
NSLog(@"response: %@", string);
}
Upvotes: 0
Reputation: 3282
Your delegate needs to implement...
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
Which should get call if the server you are trying to connect to requires authentication. Here's some example code from a program of mine...
-(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
if ([challenge previousFailureCount] == 0) {
NSURLCredential *newCredential;
newCredential=[NSURLCredential credentialWithUser:_username
password:_password
persistence:NSURLCredentialPersistenceNone];
[[challenge sender] useCredential:newCredential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
NSLog(@"Bad Username Or Password");
}
}
}
Upvotes: 3
Reputation: 58478
The method - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
is called zero or more times depending on how much data is available.
In the case of a web request, it is likely that it'll be called more than once. What you need to do is create an NSMutableData
object and store it as an instance variable. Then when this method is called you need to append the new data to your NSMutableData
object, like so:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//myMutableData should be an instance of NSMutableData and stored as an instance variable in your class. Don't forget to initialise it.
[myMutableData appendData:data];
}
If you don't do this, you could be missing parts of the response.
I don't know exactly how your performing the request or what kind of response you're getting back, but ideally, you will want a response formatted in XML or JSON, and you should use a parser to turn the response into something you can use.
That way, you would be able to extract error codes, messages, etc and act upon them accordingly.
Finally, if you're going to be using Twitter from your application, consider using a prebuilt library like MGTwitterEngine. It'll save you a lot of grief and hassle. Also, even though you said not to mention it, MGTwitterEngine supports OAuth now, as well, which would save you having to patch your code once the basic auth is turned off.
Upvotes: 0