how i get the URL inside the following method ??
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection
Hey there's a comment from Mihai Damian that worked for me:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSURL *myURL = [[connection currentRequest] URL];
Cheers
You ought to be able to do theConnection.request.URL, but you can't. Annoying, isn't it?
The simplest way is to just save the URL (or the whole NSURLRequest) that you were loading. If you're using multiple connections, you can store them in a dictionary. Note that -[NSMutableDictionary setObject:forKey:] copies keys, and NSURLConnections are not copyable; the workaround is to use CFDictionarySetValue instead:
CFDictionarySetValue((CFMutableDictionaryRef)dict, connection, request);
Of course the above answers work, and I am looking for similar solution.
Just found that NSLog([connection description]); prints something like:
< NSURLConnection: 0x9129520, http://google.com>
So it is possible to parse the string returned by [connection description], and get the url from the connection, though it is kind of dirty.
You can get URL like this
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
// release the connection, and the data object
[connection release];
// receivedData is declared as a method instance elsewhere
[receivedData release];
// inform the user
NSLog(#"Connection failed! Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
for more information you van read here.
Here is my suggestion
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
self.rssFeedConnection = nil;
NSLog(#"connectionDidFinishLoading url : %# ", connection.originalRequest.URL);
}
In Swift 2.0 iOS 9 you can do it like:
func connectionDidFinishDownloading(connection: NSURLConnection, destinationURL: NSURL) {
print(connection.currentRequest.URL!)
}
Related
I can't get rid of a EXC_BAD_ACCESS error in RestKit. I suspect its because I have an ARC project and may be releasing the request or response variable too many times, but I've spent hours on this and am not sure.
My problem sounds similar to this post, but I'm not sure where in my code to make a similar change.
My implementation file has a straightforward method to post the new object to the server. All the mapping logic is down within the implementation file for the NSObject below:
-(void) createMeeting
{
NSString* baseUrl = #"https://myapp.appspot.com/api/meeting/?format=json&username=testuser#test.com&api_key=f8s9df8as8df9s8d97";
RKObjectManager* rkoManager = [RKObjectManager objectManagerWithBaseURLString:baseUrl]; [NewMeetingRK initMap:rkoManager];
NewMeetingRK *newmtg = [NewMeetingRK alloc];
newmtg.leader = self.leaderEmail.text;
newmtg.startdate = [sqliteformatter stringFromDate:bdate];
newmtg.enddate = [sqliteformatter stringFromDate:edate];
[[RKObjectManager sharedManager] postObject:newmtg delegate:self];
And it successfully begins requestDidStartLoad:(RKRequest *)request
However it then crashes in RKResponse.m on the second to last line below (if ([[_request delegate] respondsToSelector:... with a EXC_BAD_ACCESS error.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response {
RKResponseIgnoreDelegateIfCancelled();
RKLogDebug(#"NSHTTPURLResponse Status Code: %ld", (long) [response statusCode]);
RKLogDebug(#"Headers: %#", [response allHeaderFields]);
_httpURLResponse = [response retain];
[_request invalidateTimeoutTimer];
if ([[_request delegate] respondsToSelector:#selector(request:didReceiveResponse:)]) {
[[_request delegate] request:_request didReceiveResponse:self];
}
}
Any ideas to help me? Thanks much.
EXC_BAD_ACCESS happens when a message is sent to an object that has been released.
You should pay attention to _request delegate object. NSZombieEnabled break point might help you too. How to enable zombie objects
I'm attempting to parse validated JSON from a yelp search result.
This correctly spits out the json as expected (confirmed in simulator browser and my own).
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSString *dump = [[[NSString alloc] initWithData: data encoding:NSUTF8StringEncoding] autorelease];
NSLog(#"Did Recieve data: %#", dump);
[JSONData appendData:data];
}
But when my connection finishes loading I'm having a hard time extracting the results and parsing the data:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Connection Did Finish Loading");
NSError *error = nil;
id cureLocations = [[CJSONDeserializer deserializer] deserializeAsDictionary:JSONData error:&error];
[JSONData release];
NSLog(#"Connection finished loading: %#", error);
}
I get: Connection finished loading: Error Domain=CJSONDeserializerErrorDomain Code=-11 "The operation couldn’t be completed. (CJSONDeserializerErrorDomain error -11.)"
I switched to TouchJSON from SBJSON because I wasn't able to extract it from that framework either. I've attempted loading it into Dictionaries and Arrays with null as the result. At this point I've been banging my head on the keyboard for hours and would greatly appreciate any input.
JSON sample
Update:
I am a dummy. I hadn't initialized JSONData. Please accept my apologies for wasting your time and thanks for your suggestions.
SBJSON is a pretty decent and well known parser. If it didn't parse your input, you'd probably assume it's because the input was genuinely bad. If TouchJSON isn't parsing it either, the input is definitely bad. So there's something going on with you JSONData object that's dodgy.
I would suggest you print out your JSON data to the console in your connectionDidFinishLoading method and try re-validating it. See what's actually in the data object you're passing to CJSON.
Ugh, after further review of the application it seems that I rushed to copy my samples into this project and forgot to initialize JSONData:
self.JSONData = [[[NSMutableData alloc] init]autorelease];
Then I updated my didReceiveData method:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[[self JSONData] appendData:data];
}
And everything is now working as expected. This is the second time I've run into this error. I guess I always expected the debugger to pick it up. Thanks for everyones time and assistance.
I am trying to speed up my application download speed. I used Asynchronous NSURLConnection to download contents from the server, it was working fine with one connection.
I use the code from this post to implement multiple delegate objects. Multiple NSURLConnection delegates in Objective-C
When I created 2 NSURLConnection objects, each one is trying to download different files.
The callback didReceiveData routine was called but the it only received data of the first NSURLConnection object until the first connection was done then it started to receive the data from the second NSURLConnection. I want these two connections to receive data at the same time,what should I do? Here is my current code.
-(IBAction) startDownloadClicked :(id) sender
{
while (bDownloading)
{
int nCurrentCon = 0;
while (nCurrentCon < 2)
{
[self downloadAFile:[filenameArray objectAtIndex:nCurrentCon]];
nCurrentCon++;
}
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
}
}
- (void) downloadAFile: (NSString*) filename
{
NSString* urlstr = #"ftp://myftpusername:password#hostname";
NSURLRequest* myreq = [NSURLRequest requestWithURL:[NSURL URLWithString:urlstr]];
DownloadDelegate* dd = [[DownloadDelegate alloc] init]; //create delegate object
MyURLConnection* myConnection = [[MyURLConnection alloc] initWithRequest:myreq delegate:dd
startImmediately:YES];
}
Then in my Delegate Object, I implemented these routines
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[receiveBuffer setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(#"receiving data for %#", targetFileName); //the file name were set when this delegate object is initialized.
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"Download Failed with Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"File %# - downloaded.", targetFileName);
}
Your code looks okay. I have a similar setup that works successfully (although there seems to be a limit of four concurrent conections).
The main difference between your and my code is that you use FTP while I use HTTP. Why don't you try it with HTTP connections just to see whether you have run into a restriction of FTP connections on the iPhone?
I'm not really sure why my code is throwing a EXC_BAD_ACCESS, I have followed the guidelines in Apple's documentation:
-(void)getMessages:(NSString*)stream{
NSString* myURL = [NSString stringWithFormat:#"http://www.someurl.com"];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:myURL]];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
receivedData = [[NSMutableData data] retain];
} else {
NSLog(#"Connection Failed!");
}
}
And my delegate methods
#pragma mark NSURLConnection Delegate Methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// This method is called when the server has determined that it
// has enough information to create the NSURLResponse.
// It can be called multiple times, for example in the case of a
// redirect, so each time we reset the data.
// receivedData is an instance variable declared elsewhere.
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the new data to receivedData.
// receivedData is an instance variable declared elsewhere.
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
// release the connection, and the data object
[connection release];
// receivedData is declared as a method instance elsewhere
[receivedData release];
// inform the user
NSLog(#"Connection failed! Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data
// receivedData is declared as a method instance elsewhere
NSLog(#"Succeeded! Received %d bytes of data",[receivedData length]);
// release the connection, and the data object
[connection release];
[receivedData release];
}
I get an EXC_BAD_ACCESS on didReceiveData. Even if that method simply contains an NSLog, I get the error.
Note: receivedData is an NSMutableData* in my header file
Use NSZombieEnabled break point and check which is the freed object.
Also check:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if ([response expectedContentLength] < 0)
{
NSLog(#"Connection error");
//here cancel your connection.
[connection cancel];
return;
}
}
I have followed the guidelines in Apple's documentation:
That is not true. In both of the following, you break the rules:
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error
{
// release the connection, and the data object
[connection release];
// receivedData is declared as a method instance elsewhere
[receivedData release];
// inform the user
NSLog(#"Connection failed! Error - %# %#",
[error localizedDescription],
[[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data
// receivedData is declared as a method instance elsewhere
NSLog(#"Succeeded! Received %d bytes of data",[receivedData length]);
// release the connection, and the data object
[connection release];
[receivedData release];
}
In both cases, you do not obtain the connection object with alloc, a method beginning with new or containing copy. You do not own connection in these methods. You must not release it in these methods.
It seems to me slightly dodgy that you are releasing receivedData there too. I suggest you immediately set the instance variable to nil after you release it.
[receivedData release];
receivedData = nil;
That way, it won't get accidentally released moere than once.
If you're getting the error on didRecieveData regardless of the code inside it, it looks like your delegate has been freed?
I'd check that the object that contains the getMessages method isn't being released (or autoreleased) before the connection has dfinished getting data.
EDIT: The comments below show that my above answer is wrong :)
The problem was in the recievedData variable - it was being released early. Mark suggests releasing it in the dealloc method of the object that creates the connection so he deserves all the credit for this!
There's one slight thing to lookout for there - if you release the recievedData in the dealloc method, you will leak memory if you call getMessages more than once. You will need to change getMessages slightly to this :
...
if (theConnection) {
[recievedData release]; // If we've been here before, make sure it's freed.
receivedData = [[NSMutableData data] retain];
} else {
...
I got the same error when debugging with device although there was no problem in simulation. Adding the following line of code after releasing receivedData solved the problem:
receivedData = nil;
Commenting on JeremyP, where he says that "In both of the following, you break the rules": Sheehan Alam is following Apple's code (actually, cut'n'paste) found here.
I'd also like to add (and this is something that wasn't well answered here) that the 'build and analyze' flags a "potential leak" on the NSURLConnection (which is initiated with a "[NSURLConnection alloc]"). But if one puts in a [theConnection release] on the NSURLConnection, in the same method, it will crash.
So we have something that seems to defy the 'rules' for memory management, yet works (afaik) and is in Apple's documentation..
I got EXC_BAD_ACCESS on Asynchronous call at NSURLConnection.
The code is generated by http://www.sudzc.com
I needed to add a retain to
receivedData = [[NSMutableData data] retain];
and the callback methods doesn't get bad access signal anymore.
if I add the
if ([response expectedContentLength] < 0)
{
NSLog(#"Connection error");
//here cancel your connection.
[connection cancel];
return;
}
than all my webservices are canceled, otherwise works perfectly.
While it doesn't answer the full question, I've run into this error a couple of times because I set the request's HTTPBody to an NSString instead of a NSData. Xcode tried to warn me.
i'm a beginner to iphone.i want to create a login page for my application.i cant figure out how to connect to a php page and retrieve corresponding data from mysql database to the iphone.could any one guide me how to go about it.
what does the iphone have to do with a connection between php and mysql ?
PHP will run with on a web server probably apache installed on some computer and it will connect to a MySQL db .. and u will access that php page from your iphone with a browser. Not sure what part will the iphone have in all this other than providing the browser
You might want to have a look at NSURLRequest which you can use with a NSURLConnection to send e.g. GET-Parameters to a URL. You can then implment the NSURLConnectionDelegate to respond to incoming data:
1) setup connection
receivedData =[NSMutableData data];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:20.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
2) Setup delegate methods in self:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response {
NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response;
if([httpResponse statusCode]==200)
[receivedData setLength:0];
else
NSLog(#"Http-Reponse %u",[httpResponse statusCode]);
// HANDLE ERROR!
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// append the new data to the receivedData
// receivedData is declared as a method instance elsewhere
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
// HANDLE THE CONNECTION ERROR
// release the connection, and the data object
[connection release];
// receivedData is declared as a method instance elsewhere
[receivedData release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
// receivedData contains the data
// convert to string:
NSLog(#"finished loading: %#",[[[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding] autorelease]);
[connection release];
[receivedData release];
}
You'll want to expose the authentication functionality as a web service, then use the URL Loading code posted by Felix L. to initiate an actual connection to the web service.
You'll probably want to send a response from the server as XML, if so, you'll parse that response with an NSXMLParser, otherwise you can just send the response in whatever format you'd like and parse it appropriately.