Im implementing an app that shows some Twitter data, when is working on wifi is ok, but on 3g crashes, I have come to the conclusion that is because the NSURLRequest that fetchs the data that populates the table takes longer to load so the table ends up calling an object for key, when the keys havent even loaded,
So the question is,
- how can I know when the NSURLRequest finished loading? [I checked the Class Reference but didnt see it??]
Thanks a lot!
The delegate methods are invoked on the request's corresponding NSURLConnection, e.g.
urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
You will then receive various callbacks included the finished callback as follows:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{}
Other delegate callbacks are:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection{
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
Related
I'm working on login functionality for an app at the moment and I receive a dictionary from the server after connecting. I receive the dictionary in the function
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
which I have in my model. With the dictionary info received from this, I then want to send that dictionary to the view controller, but the function has already returned by the time connectionDidFinishLoading completes.
How can I pass the data back to the view controller?
You need to set teh delegate and implement the callback methods
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:theURL];
NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self startImmediately:NO];
[urlConnection start];
The delegate methods are
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[_detailsResponse setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_detailsResponse appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"Error: %#, %#", [error localizedDescription], [error localizedFailureReason]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// Do what you want with the data here.
}
I am using NSURLConnection's sendSynchronousRequest to communicate with server. I wanted to handle authentication which can be achieved using connection delegates but delegates are not called for a synchronous request.
NSData *data = [NSURLConnection sendSynchronousRequest:UrlRequest returningResponse:&response error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
if(!error)
{
// Do something
}
else
{
// Handle error
}
});
However i thought of sending all the request asynchronously using
[NSURLConnection connectionWithRequest:menuRequest delegate:self];
But i have multiple connection in the same class and each connection's success and error are used to perform different task.If i use async request error and success are heard by delegates which are same for all the request in that class, i cannot find out which request failed and which request succeeded. I have two question
If there is a way to implement https for synchronous request.
How to find which connection failed or succeeded among multiple connections in the same class for asynchronous request.
You can achieve this in different ways.
You can put creds in url like https://username:password#domain.tld/api/user.json
You can add add you creds to NSURLCredentialStorage before synchronous connection call.
You can use code below to achieve.
- (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse *__strong*)response error:(NSError *__strong*)error
{
_finishedLoading=NO;
_receivedData=[NSMutableData new];
_error=error;
_response=response;
NSURLConnection*con=[NSURLConnection initWithRequest:request
delegate:self
startImmediately:NO];
[con start];
return _receivedData;
}
- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
//handle the challenge
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
*_response=response;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
*_error=error;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
}
I'm doing some experiment with the Foundation networking API and I'm trying to download files.
So I've created an NSURLRequest:
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.mysite.it/something.something"]];
Now I have a problem NSURLConnectionDownload.I have to implement this method
- (void)connection:(NSURLConnection *)connection didWriteData:(long long)bytesWritten totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes
At connection I created a NSURLConnection object but I don't know which methods I must implement... Any suggestion?
If you use
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self]; you'll probably want to implement 3 methods:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
and maybe
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
I recommend you to take a look here : https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html .Hope it helpes!
The is my code
theDownloadConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
and it is calling these NSURLConnection delegate methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
But it is not calling
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
This method of NSURLConnection delegate calls when I do this
[NSURLConnection connectionWithRequest:request delegate:self];
I dont understand why this is happening?
didSendBodyData is only called when the request has a body containing message data like in POST request. You are most likely executing a GET.
From the apple docs:
connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:
Sent as the body (message data) of a request is transmitted (such as
in an http POST request).
That's because its defined in NSURLConnectionDataDelegate and you are setting NSURLConnection
delegate.
My question relates to the code in my single-threaded app that updates the devices' local database data via a NSURLConnection to a web service.
My NSURLConnection initialization is not going into any of it's implemented methods and it has me puzzled.
Inside my AppDelegate.m -> applicationDidFinishLaunching method, I am creating a NSURLConnection object:
//AppDelegate.m
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
// ... Building request URL here ...
NSString *requestURL = [NSString stringWithFormat:#"%#%#", URI,urlEncodedParamStr]
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestURL]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
responseData = [[NSMutableData data] retain];
if(connection !=nil)
[connection release];
}
Execution should now proceed to any of the following appropriate NSURLConnection methods
that I implemented in AppDelegate.m:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{[responseData setLength:0];}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {[responseData appendData:data];}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{//my implementation}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {//my implementation}
But instead, execution continues, with the line directly after the init of NSURLConnection *connection, not executing any of the NSURLConnection implemented methods. I have confirmed that the request is not nil and put breakpoints in the implemented NSURLConnection methods - They are not being called.
What's going on?
Thanks as always!
You need to call
[connection start];
before the remote call will actually be started.
And even then, the next line of code will execute. It's an asynchronous call and is executed in a background thread. The response is received later and your connection... method will be called then (which can be up to the timeout (30 seconds) time later).