Addresponse - adding to memory only (XCode) - objective-c

I'm trying to connect my project to a php file but every time this shows:
ADDRESPONSE - ADDING TO MEMORY ONLY
I have never seen it before.
this is the code i Use:
//Gets the php
FindURL = [NSString stringWithFormat:#"http://domain.com/Myfile.php?username=%#", Username.text];
// to execute php code
URLData = [NSData dataWithContentsOfURL:[NSURL URLWithString:FindURL]];
// to receive the returend value
DataResult = [[NSString alloc] initWithData:URLData encoding:NSUTF8StringEncoding];
NSLog(#"%#",DataResult);
What can i do?
Thanks in advance
Update code:
- (IBAction)UpdateList:(id)sender{
NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://domain.com/Myfile.php"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:15.0];
NSURLConnection *Connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (Connection) {
//Connect
}else{
//Error
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
DataResult = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#", DataResult);
}

I've had the same issue - check out the following, this might help you:
Log Messages I didn't asked for in Xcode 4.5 with iOS 6.0
I haven't found a solution so far, but since I now know that this Log is produced by the OS, I no longer look for its origin in my source :)

I got this log by making an NSURLRequest to an invalid URL. My app is supposed to show a UIAlertView when it catches an error on the server side, so I asked our system admin to take our entire site down so I can see what happens. He declined my request, so I typed random letters and put a .com at the end of the request URL.
Turns out we have an internal test server that doesn't seem to be accessible from my WiFi connection, so when I changed the URL to that instead, the log stopped appearing.

Related

iOS/xcode: didReceiveData empty when run on device but fine on simulator?

I am developing an iphone app which is using an API.
On the 'simulator' it works fine. On the 'device' the api calls all run but response delegates all return EMPTY.
LOG:
1) didReceiveData returns (empty NSData i.e. <20>) below for device:
append data <20>
But this for simulator:
append data <dfgdf89fgd.....>
2) The didReceiveResponse I have below returns below for the device (set NSLog to monitor NSURLConnection object). Confused why this is not complete:
1 connection <NSURLConnection: 0x147a30>
But this for the simulator:
1 connection <NSURLConnection: 0x4b76ea0, http://api.site.com/search?id=111>
3) The connectionDidFinishLoading is below for simulator
DONE. Received Bytes: 1400
But below for device:
DONE. Received Bytes: 1
My code:
I have the below code inside an API file:
- (void)fetch: (NSString *)id{
NSMutableData *receivedData = [[NSMutableData alloc]init];//initialised
self.receivedData = receivedData;//set to available globally
NSString *initialUrl = [NSString stringWithFormat: #"http://api.site.com/search?id=%#",id];
NSURL *url = [NSURL URLWithString:initialUrl];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"Token token=\"apitoken\"" forHTTPHeaderField:#"Authorization"];
[NSURLConnection connectionWithRequest:[request autorelease] delegate:self];
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"1 connection %#",connection);
NSLog(#"didReceiveResponse");
[self.receivedData setLength: 0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(#"2 connection %#",connection);
NSLog(#"append data %#",data);
[self.receivedData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//TODO error handling for connection
NSLog(#"Cannot Connect");
if ([_delegate respondsToSelector:#selector(apiFailed:)]) {
[_delegate apiFailed:[error localizedDescription]];
}
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"DONE. Received Bytes: %d", [self.receivedData length]);
NSLog(#"FULL DATA: %#",self.receivedData);
}
The simulator and device (my iphone with provisioned profile on and working) are both running off the same Wifi (my home router).
The API:
The API returns a small amount of JSON and I have tested with a different set of JSON and both device and simulator return full JSON no problem, I only cant get it to work with THIS API.
I even have the same JSON (the api returns) inside a different location and I can do the EXACT same request (with headers and authentication) and it works no problem for device. Strangely though the connection object still doesnt look right for the fake api server. On device didReceiveResponse has 1 connection <NSURLConnection: 0x1af600> still and not with the connection url (but when run on simulator it has 1 connection <NSURLConnection: 0x8193fd0, http://test-server.com:81/api-data.json>). This suggest that its a normal difference between device and simulator NSURLCONNECTION objects.
I feel it might be the authentication getting in the way but the API is completely open (assuming you have token) and works no problem with the simulator plus didFailWithError is not run..
I have declared the delegate methods inside the header file.
No idea why the connection object as well as the data object would both be having problems.
Alternative:
I tried the below inside the fetch method instead of what I have already but it also works on Simulator but same thing happens on Device.
//NSURLCONN and NSDATA in response still return empty???
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL
URLWithString:#"http://api.site.com/search?id=111"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"Token token=\"mytoken\"" forHTTPHeaderField:#"Authorization"];
NSURLConnection *connection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
I would appreciate ANY ideas on this.
thanks
For testing:
Remove caching from the request (it can do some really funny things).
Print out the HTTP status code in connection:didReceiveResponse:. Make sure you are getting 200 (you should always check the status code!)
Test the connection in some other REST client (plugins for most browsers exist).
Make sure the API is not "User-Agent" sensitive.
If "https" protocol is used, make sure the certificate is signed by a root authority known to the device.
Use the debugger to check that everything is working correctly (e.g. url is not nil, when the request is being created).
Are you sure you are using Authorization header correctly? Value Token token="..." seems strange.

how to display connection error when link is clicked from a cached page in UIWebView?

I'm working on an app with a UIWebView that goes to a single page -- we'll call it http://myPage.com -- that has a few links on it. Displaying a UIAlertView for a connection error when the user first clicks the go-to-myPage button that leads to http://myPage.com is no problem. But if there's no connection and the user clicks the go-to-myPage button, gets no UIAlertView because the cached version of http://myPage.com is returned, and then tries to follow a link from http://myPage.com, nothing happens. How can I rewrite or add to my code to display an alert in such a situation?
Here's my code:
-(void)loadWebViewWithbaseURLString:bus withURLString:us
{
self.request = [NSURLRequest requestWithURL:[NSURL URLWithString:us] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval: 20];
self.connection=[[NSURLConnection alloc] initWithRequest:self.request delegate:nil];
NSError *error=nil;
NSURLResponse *response=nil;
if (self.connection)
{
self.urlData = [ NSURLConnection sendSynchronousRequest: self.request returningResponse:&response error:&error];
NSString *htmlString = [[NSString alloc] initWithData:self.urlData encoding:NSUTF8StringEncoding];
[self.webV loadHTMLString:htmlString baseURL:[NSURL URLWithString:bus]];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] init];
alert.title = #"Unfortunately, I seem to be having a hard time connecting to the Internet. Would you mind trying again later? I'll make it worth your while, I promise.";
[alert show];
}
}
And of course the go-to-myPage code simply calls -(void)loadWebViewWithbaseURLString:bus withURLString:us with the specific URLs as arguments.
I asked the question in a clearer (I hope) way at NSURLRequest cachePolicy and connection in UIWebView and was ultimately able to figure it out myself, so I posted the answer....

NSURLConnection didReceiveData not called

I've read through tons of messages saying the same thing all over again : when you use a NSURLConnection, delegate methods are not called. I understand that Apple's doc are incomplete and reference deprecated methods, which is a shame, but I can't seem to find a solution.
Code for the request is there :
// Create request
NSURL *urlObj = [NSURL URLWithString:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:urlObj cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];
[request setValue:#"gzip" forHTTPHeaderField:#"Accept-Encoding"];
if (![NSURLConnection canHandleRequest:request]) {
NSLog(#"Can't handle request...");
return;
}
// Start connection
dispatch_async(dispatch_get_main_queue(), ^{
self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; // Edited
});
...and code for the delegate methods is here :
- (void) connection:(NSURLConnection *)_connection didReceiveResponse:(NSURLResponse *)response {
NSLog(#"Receiving response: %#, status %d", [(NSHTTPURLResponse*)response allHeaderFields], [(NSHTTPURLResponse*) response statusCode]);
self.data = [NSMutableData data];
}
- (void) connection:(NSURLConnection *)_connection didFailWithError:(NSError *)error {
NSLog(#"Connection failed: %#", error);
[self _finish];
}
- (void) connection:(NSURLConnection *)_connection didReceiveData:(NSData *)_data {
[data appendData:_data];
}
- (void)connectionDidFinishDownloading:(NSURLConnection *)_connection destinationURL:(NSURL *) destinationURL {
NSLog(#"Connection done!");
[self _finish];
}
There's not a lot of error checking here, but I've made sure of a few things :
Whatever happens, didReceiveData is never called, so I don't get any data
...but the data is transfered (I checked using tcpdump)
...and the other methods are called successfully.
If I use the NSURLConnectionDownloadDelegate instead of NSURLConnectionDataDelegate, everything works but I can't get a hold on the downloaded file (this is a known bug)
The request is not deallocated before completion by bad memory management
Nothing changes if I use a standard HTML page somewhere on the internet as my URL
The request is kicked off from the main queue
I don't want to use a third-party library, as, ultimately, these requests are to be included in a library of my own, and I'd like to minimize the dependencies. If I have to, I'll use CFNetwork directly, but it will be a huge pain in the you-know-what.
If you have any idea, it would help greatly. Thanks!
I ran into the same problem. Very annoying, but it seems that if you implement this method:
- (void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL
Then connection:didReceiveData: will never be called. You have to use connectionDidFinishLoading: instead... Yes, the docs say it is deprecated, but I think thats only because this method moved from NSURLConnectionDelegate into NSURLConnectionDataDelegate.
I like to use the sendAsynchronousRequest method.. there's less information during the connection, but the code is a lot cleaner.
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
if (data){
//do something with data
}
else if (error)
NSLog(#"%#",error);
}];
From Apple:
By default, a connection is scheduled on the current thread in the
default mode when it is created. If you create a connection with the
initWithRequest:delegate:startImmediately: method and provide NO for
the startImmediately parameter, you can schedule the connection on a
different run loop or mode before starting it with the start method.
You can schedule a connection on multiple run loops and modes, or on
the same run loop in multiple modes.
Unless there is a reason to explicitly run it in [NSRunLoop currentRunLoop],
you can remove these two lines:
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[connection start];
or change the mode to NSDefaultRunLoopMode
NSURLConnection API says " ..delegate methods are called on the thread that started the asynchronous load operation for the associated NSURLConnection object."
Because dispatch_async will start new thread, and NSURLConnection will not pass to that other threat the call backs, so do not use dispatch_async with NSURLConnection.
You do not have to afraid about frozen user interface, NSURLConnection providing only the controls of asynchronous loads.
If you have more files to download, you can start some of connection in first turn, and later they finished, in the connectionDidFinishLoading: method you can start new connections.
int i=0;
for (RetrieveOneDocument *doc in self.documents) {
if (i<5) {
[[NSURLConnection alloc] initWithRequest:request delegate:self];
i++;
}
}
..
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
ii++;
if(ii == 5) {
[[NSURLConnection alloc] initWithRequest:request delegate:self];
ii=0;
}
}
One possible reason is that the outgoing NSURLRequest has been setup to have a -HTTPMethod of HEAD. Quite hard to do that by accident though!

JSON broken in Objective-C URL Request

After pounding my head all day long, I am down to StackOverflow to pull me through.
I am making a NSURLRequest in my iPhone App ...
NSURL* url = [[self serviceUrl] URLByAppendingPathComponent:[NSString stringWithFormat:#"Json"]];
NSString* json = [NSString stringWithFormat:#"{\"id\":\"%#\"}", id];
NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:url];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[urlRequest setHTTPBody:[json dataUsingEncoding:NSUTF8StringEncoding]];
this is returning to me a JSON string, which comes back to me but it is broken in the since that the string will not parse correctly.
However if I make a normal request to the same url in the Safari browser then JSON is returned correctly. I am validating this JSON here.
So whats the deal? Is there a limit to the length of data in a NSString* that a 32Kb json file would not be stored in memory correctly? Sometimes the JSON can be parsed, which leads me to believe that I am not clearing my JSON string correctly after each request.
_json = [[NSString alloc] initWithData:_dataResponse encoding:NSUTF8StringEncoding];
NSArray* retrievedData = (NSArray*)[_json JSONValue];
// removed for brevity
_json = #"";
Other information, I am using ASP.NET MVC 3 to provide the web services for this app.
EDIT
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse
{
_loader.hidden = NO;
[_loadingIndicator startAnimating];
return request;
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
_dataResponse = [[NSMutableData alloc] init];
[_dataResponse setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_dataResponse appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"Error receiving response: %#", error);
_loader.hidden = YES;
[_loadingIndicator stopAnimating];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
_json = [[NSString alloc] initWithData:_dataResponse encoding:NSUTF8StringEncoding];
// Removed for brevity
_json = #"";
_loader.hidden = YES;
[_dataResponse release];
_dataResponse = nil;
[_loadingIndicator stopAnimating];
}
FINAL SOLUTION
I was making multiple calls to have data already stored for views in order to switch views in a tab bar controller. I wasn't checking the connection during the appending of the data, I was checking the connection when it was finished in order to store the data correctly. My final solution was to make each call sychronously after the previous one during the finished method call.
Unfortunately, nothing blatant is jumping out at me.
Some things to try that will hopefully help:
double check your NSUrlConnection pattern against this doc. The only diff I see is they're doing [[NSMutableData data] retain] instead of alloc, init. They also create NSMutableData with the connection request (not in response) and only length=0 in response. Not sure why it would matter though ...
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html
try something like Charles Proxy. It allows you to sniff the wire. You can see what's different between browser and simulator/phone access. At a minimum, you'll see what's coming over the wire in the bad cases.
add lots of logging. everytime you append data, log some details. After you convert to string and before the json call, log. Log sizes, etc... Something may offer you a hint.
the use of _json string seems a bit off. You're reallocating and then setting to empty string. You should either have an iVar that you alloc and release (not set to "") or create a #property with retain, copy.
You should definitely include charset=utf8 in you content-type header. And how do you know that the response you get is encoded as utf8? You should also set content-size header.

Xcode: Validate a URL before Loading it

Im having some trouble findig a way to validate a url on my app.
My intention is to load a URL and at the same time see if other webpage exist for example.
Load http://mysite.com/folder1/1.pdf
validate http://mysite.com/folder1/2.pdf
if folder1/2.pdf exists then load it, else validate /folder2/1.pdf
so far im loading the first pdf like this in order to be able to change the pdf number and the folder:
int numpag = 1;
NSString *baseUrl =#"http://www.cronica.com.mx/iphone/pdf_iphone/";
[pdfView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[baseUrl stringByAppendingFormat:#"folder1/%d.pdf", numpag]]]];
Thanks so much in advance!
how about this:
+ (BOOL)isValidURL:(NSURL*)url
{
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSHTTPURLResponse *res = nil;
NSError *err = nil;
[NSURLConnection sendSynchronousRequest:req returningResponse:&res error:&err];
return err!=nil && [res statusCode]!=404;
}
let me know if it works for you!
(keep in mind that this is a synchronous request and should not be executed on the main thread)
I had to change the line:
return err!=nil && [res statusCode]!=404;
to
return err==nil && [res statusCode]!=404;
for the correct Bool return. The error should remain nil.
This approach is NOT correct, You should avoid Synchronous calls as they are blocking.
Apple says: simply try and wait down to wait for response.