So in my application I use a NSURLConnection to connect to a server and retrieve text. This is how I initiate my NSURLConnection:
NSMutableURLRequest * serviceRequest = [NSMutableURLRequest requestWithURL:postUrl cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
//Some other code
[serviceRequest setValue:contentType forHTTPHeaderField:#"Content-Type"];
[serviceRequest setHTTPMethod:#"POST"];
[serviceRequest setHTTPBody:postData];
//Force to return size
[serviceRequest setValue:#"" forHTTPHeaderField:#"Accept-Encoding"];
theConnection = [[NSURLConnection alloc] initWithRequest:serviceRequest delegate:self];
Now it works fine but I am trying to get a progress bar in my application to represent the progress of this request.
Now here are my didReceiveResponse and didReceiveData methods:
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
dlSize = [response expectedContentLength];
NSLog(#"didReceiveResponse: %f", dlSize);
[self.receivedData setLength:0];
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
dlProgress = ((float) [data length] / (float) dlSize);
NSLog(#"dlProgress: %f", dlProgress);
}
So this is the issue. As you can see I have two NSLogs in there, but they are not called until the request is done. To be specific I am contacting a server to OCR something and once it is done OCRing and I get the text, that is when these two methods are called. Then the logs return something like this:
2013-07-30 22:50:09.201 app[39381:907] didReceiveResponse: 514.000000
2013-07-30 22:50:09.202 app[39381:907] dlProgress: 1.000000
2013-07-30 22:54:39.651 app[39381:907] didReceiveResponse: 305.000000
2013-07-30 22:54:39.651 app[39381:907] dlProgress: 1.000000
I am not sure why those methods aren't called during the request but maybe somebody on this site knows why? Anyway any tips/comments/suggestions are appreciated so I can get a UIProgressView hooked up with this.
Thanks!
declare in yourViewController.h NSURLResponse *response;
in this method write only:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse
{
response = aResponse;
}
after (downData is a NSMUtableData)(progresso is UIProgressView):
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[downData appendData:data];
float expectedLength = [response expectedContentLength];
float currentLength = downData.length;
progresso.progress = currentLength / expectedLength;
if (currentLength/expectedLength == 1) {
//do anything
}
}
Related
I am trying to connect to some local network of mine (hardware ).
So i find the network on the iPhone settings, and connect to it .
Now , i am trying to send a simple request to that access point .
The access point does getting my request, and send back respond, problem is, i never get the respond on the device.
If i try to send the request using Chrome browser on my mac , i do get the respond "hello world" , but not on the device.
I have tried synchronise and un-synchronise requests, non of which give me nothing. they do although send the request . what am i missing ?
sync:
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://192.168.x.x/data:moredata"]];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * tdata = [NSURLConnection sendSynchronousRequest:urlRequest
returningResponse:&response
error:&error];
NSLog(#"-%#",tdata);
and async, delegates are not being called :(did register for them with <NSURLConnectionDelegate )
NSMutableURLRequest *request = [ [NSMutableURLRequest alloc] init] ;
[request setURL:[NSURL URLWithString:#"http://192.168.x.x/data:datax"]];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO ];
[conn scheduleInRunLoop:[NSRunLoop mainRunLoop]
forMode:NSDefaultRunLoopMode];
[conn start];
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(#"+%#",response);
_responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(#"-%#",data);
[_responseData appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
return nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(#"DO");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"FAILEDERR");
}
When I'm using NSURLConnection to get data from my server, iOS still cache data. When requesting new data, iOS sending a new request to my server, but the files are still stored.
I'm using NSURLRequestReloadIgnoringCacheData and returning nil in connection:willCacheResponse:.
The problem is that I'm using my own caching object, and it's kind of dum to let iOS store a duplicate.
Should I ignore this or should I delete the cache somehow?
Update
Code for creating NSURLRequest:
request = [NSURLRequest requestWithURL:[NSURL URLWithString:URLString] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30.0];
Code for creating NSURLConnection:
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
Code for NSURlConnectionDelegate:
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return nil;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[recivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
if (_handler) _handler(response, error, nil);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (_handler) _handler(response, nil, recivedData);
recivedData = nil;
response = nil;
}
I'm sending to my server user detail and it is supposed to return a user id as a string,
the data received at my server bat I can get the string.
The code:
NSString *urlStr = [NSString stringWithFormat:#"url/////api/%#/%#",
[Email.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
[Password.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding],
nil];
NSString *content = #"field1=42&field2=Hello";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlStr]];
[request setHTTPMethod:#"GET"];
[request setHTTPBody:[content dataUsingEncoding:NSISOLatin1StringEncoding]];
[NSURLConnection connectionWithRequest:request delegate:self];
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
if (connection) {
NSLog(#"good conection");
[_receivedData appendData:_data];
NSString *DataString = [[NSString alloc] initWithData:_receivedData encoding:NSUTF8StringEncoding];
NSLog(#"foo1: %#", DataString);
NSLog(#"foo2: %#", _receivedData);
}
2014-01-03 22:27:57.322 App[962:70b] foo1:
2014-01-03 22:27:57.323 App[962:70b] foo2: (null)
Implement following NSURLConnection delegate to fetch data asynchronously.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// A response has been received, this is where we initialize the instance var you created
// so that we can append data to it in the didReceiveData method
// Furthermore, this method is called each time there is a redirect so reinitializing it
// also serves to clear it
_responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the new data to the instance variable you declared
[_responseData appendData:data];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
// Return nil to indicate not necessary to store a cached response for this connection
return nil;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// The request has failed for some reason!
}
I am developing an IOS application. setLength method crash in didReceiveResponse. What do you think is the reason for this. What should I do prevent.
- (void) callService:(NSString*)urlString
{
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL urlString]];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody:[urlString dataUsingEncoding:NSUTF8StringEncoding]];
theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if(theConnection) {
self.webData = [[NSMutableData data] retain];
}
else {
NSLog(#"connection is NULL");
}
}
#pragma mark Web service
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.webData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.webData appendData:data];
}
Usually, a crash on NSData usages are in fact an early release problem. A NSData initialized with [NS(Mutable)Data data] is an autoreleasable object, even though you called a retain on it.
To be sure this object doesn't get released before your didReceiveResponse gets called, initialize it with [[NSMutableData alloc] init]. That should do it
It looks like you got your memory management wrong.
In this case it's probably an overreleased NSMutableData. Proper management for this object should be done by the property webData. You did not post the declaration, yet it should be along the lines:
#property (retain) NSMutableData *webData;
If you synthesized the accessors they should do the retain/release for you.
To answer why the error happens nevertheless we need more code.
Try this, it may be help you:
this may be crash due to NULL response data so check your response data and set the following condition for the future purpose:
And synthesize your NSData:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
if(responseData != NULL)
{
[responseData setLength:0];
}
}
In the code below, I am looking for a way to limit the length of connected string. Let's say I only want to retrieve the first 100 characters. But I do not want to do the processing connected after retrieving. Is there a way to initialize NSString with certain length?
NSError* error = nil;
NSString *connected = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://www.somesite.com"] encoding:NSASCIIStringEncoding error:&error];
You're going to have to retrieve the data yourself instead of using NSString's convenience method to do it. If you use, say, NSURLConnection or ASIHTTPRequest you can close the connection when you've received as much data as you want.
You could use NSString methods to retrieve the first 100 characters but you would have wasted bandwidth anyway to get all the data. So why download all when you want only 100 chars.
So to get only a slice of the data coming off the server, you need count the data stream that the url response gives. For this you could use NSURLConnection -
- (void)viewDidLoad {
[super viewDidLoad];
responseData = [[NSMutableData data] retain];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://someurl.com/data.json"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if([responseData length] <= 100)
[responseData appendData:data];
else //break connection
[self connectionDidFinishLoading:connection];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
label.text = [NSString stringWithFormat:#"Connection failed: %#", [error description]];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
}
So you need to put your logic in didReceiveData. For here, you want only 100 chars, so break-off the connection after that number is reached.