I have a few methods that are posting data to a server. I am using NSURLConnection asynchronously. I am using a class variable NSMutableData and this is created in the viewDidLoad.
I have one method connection created for login and one for registration. Both just return a success booleon in response.
My question is, when the connection is complete and I receive my response, is there anyway to know which method started the connection? I.e some kind of callback to say that the login method started the connection.
Thanks
When you start the connection, store a reference to the NSURLConnection object. When the connection finishes it will pass you the connection object as a parameter, which you can check like so:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (connection==loginConnection) {
} else if (connection==regConnection) {
}
}
The other (possibly better) option is to offload all of the HTTP connection handling to a separate wrapper class. You can build your own from your existing code, or use a third-party one like ASIHTTPRequest or GTM HTTP Fetcher.
Related
In my application i need to implement verification if user has entered correct login and password or not. the login and the password are stored at the web server so i have to organize correct connection to the server. I'm an absolute beginner in everything about http requests and all that stuff. Actually i downloaded ASIHTTPRequest library and added it to my project just yesterday. My main problem is that i don't have an actual server by now (and i' m using just a conventional URL which later will be replaced with true server name but i want my code to be correct already)so i cannot test myself whether i'm doing things correctly or not.So my questions are:
1)What is the best way to organize verifying user's login and password? Should i use synchronous request or asynchronous? For all i know synchronous requests are rare in use cause they stop the application while the request is being performed but there's really nothing else needed to be done in this event so i'm a bit confused.What would you use?
2)I suppose verifying user's login and password by using http requests is pretty common task so there must be a general rule what kind of data the web server returns. I don't want to invent a wheel. should i use NSString returned by responseString to check if user's login and password match? What does server returns usually in such cases? How should my code look like? Something like
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:someUrl];
[request startSynchronous];
NSString *response = [request responseString];
if ([response isEqualToString:#"login and password match"])
//user enters next screen
else
//user is notified about the error
or something else? What would you do?
3)This request is not only i need to implement. Later i'm going to connect to the same URL with a different request. So how does the server know what kind of request is currently being used?
I really need your advice. Great thanks in advance
I have tried to answer your question,
Q:1. Synchronous or Asynchronous request model for login?
-> As per apple's documentation
A synchronous load is built on top of the asynchronous loading code made
available by the class. The calling thread is blocked while the asynchronous
loading system performs the URL load on a thread spawned specifically for
this load request.
also,
NSURLConnection provides support for downloading the contents of an
NSURLRequest in a synchronous manner using the class method
sendSynchronousRequest:returningResponse:error:. Using this method is
not recommended, because it has severe limitations:
The client application blocks until the data has been completely
received, an error is encountered, or the request times out.
Minimal support is provided for requests that require authentication.
There is no means of modifying the default behavior of response
caching or accepting server redirects.
As you are unaware of server side implementation, which may involve:
1. Redirection and other mechanisms for fulfilling the request.
2. It may require some proxy authentication or other similar stuff.
Q:2. What does server returns usually in such cases?
In general, a web service is implemented at server-side which returns XML or JSON as repsonse which you have to parse and use.
example response may look like:
for XML:
<auth>
<statusCode>0</statusCode>
<statusMessage>Login Successful.</statusMessage>
</auth>
for JSON
{
"statusCode" = "0"
"statusMessage" = "Login Successful."
}
tags(for XML) and keys(for JSON) will depend upon you sever implementation.
3. How does the server know what kind of request is currently being used?
-> The URL which you will use for request will tell server, what you are looking for?
for example
http://www.example.com/mywebapp/getItem?id="1";
Thanks,
or
http://www.example.com/mywebapp/removeItem?id="1";
The bold path item represents services which you are calling.
Does anyone know in which situations initializing a NSURLConnection returns nil instead of the created connection. The documentation says it's possible but fails to specify when this happens.
The method/message in question:
[[NSURLConnection alloc] initWithRequest:request delegate:self];
-
According to the NSURLConnection Class Reference:
Return Value: The URL connection for the URL request. Returns nil if a connection can't be initialized.
The URL Loading System Programming Guide says the following:
If NSURLConnection can’t create a connection for the request, initWithRequest:delegate: returns nil.
-
While it's possible that this method returns nil, I'm unable to come up with a scenario which triggers this. I've tried the following scenarios:
URLRequest with an empty url: connection:didFailWithError: delegate method is called with "unsupported URL" as error.
URLRequest with invalid url: connection:didFailWithError: delegate method is called with "bad URL" as error.
URLRequest with nonexistent url: connection:didFailWithError: delegate method is called with "A server with the specified hostname could not be found." as error.
Valid request but no internet: connection:didFailWithError: delegate method is called with "The Internet connection appears to be offline." as error.
nil request: causes a crash.
The initWithRequest method returned a valid NSURLConnection in each scenario (besides the last one) and called the connection:didFailWithError: with an appropriate error.
Has anybody been able to figure out which scenario does cause nil to be returned?
I believe this can also be used when it fails to load, not just initialize. (The alloc is done separately - that's where low mem would probably bite you) So (I'm guessing) it could fail because you did not have a network available (3G/Wifi) or it simply failed to connect to the server. In any event, use:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
To get the actual failure.
You may be able to simulate this with an absence of a network - or even giving it a bad URL.
I guess the answer is "Never". Seems only way for NSURLConnection to return nil is failing at [super init]. ([super init] returning nil) But as super class of NSURLConnection is NSObject and NSObjects init just returns self (never nil)
PS: That's for IOS SDK 4.0, on emulator, can be different on device.
I would try all of the above except do it during low memory conditions. IE, I think it will happen when an internal malloc fails.
I thing this is caused if the request u specified has wrong or not all essential values
NSURLConnection returns nil if it is not created inside a runLoop.
i am developing iphone application which connects to a php page using NSUrl request.The php page on the server side ,in turn,connects to the database (mysql) to perform transactions.Till now i was passing only parameters to the actual query on php page which was working fine.But when sending query from iphone end through NSUrl ,either connection fails or the query is assigned a nil value.Is there any way to send query using NSUrl or some othr method?
It sounds like you have a working server-side script that returns data in response to well-formed requests, so it's a matter of getting your NSURLConnection to make requests in the appropriate fashion. If you have a known-good request, you can inspect on the properties of the NSURLRequest object you're creating (HTTPBody, URL, etc.) and see where you're going wrong. Also pay attention to any error messages you might be receiving in your delegate methods (i.e., connection:didFailWithError:)
I've dug through a lot of topics regarding didReceiveData: method not being called - the solution is to set appropriate cachePolicy and implement willCacheResponse delegate method.
So I did, now I get didReceiveData message each time anything comes from the server.
Unfortunately I don't get didReceiveData the very first time the server responds.
In other words, the first time I get "didReceiveData" message there are 2 response objects in the "data" parameter. Every response from the server following that moment is OK.
Any help?
Just needed a clarification; Are you using any threading in your application?
If Yes, then the thread which creates the connection should receive the response from the server. The other threads will not identify the response which is returned for some other thread.
I'm writing an iPhone application that needs to get some data from a web server. I'm using NSURLConnection to do the HTTP request, which works well, but I'm having trouble unit testing my code in the case where the response has an HTTP error code (like 404 or 500).
I'm using GTM for unit testing and OCMock for mocking.
When the server returns an error, the connection does not call connection:didFailWithError: on the delegate, but calls connection:didReceiveResponse:, connection:didReceiveData:, and connectionDidFinishLoading: instead. I'm currently checking the status code on the response in connection:didReceiveResponse: and calling cancel on the connection when the status code looks like an error to prevent connectionDidFinishLoading: from being called, where a successful response would be reported.
Providing a static stubbed NSURLConnection is simple, but I want my test to change it's behaviour when one of the mock connection's methods is called. Specifically, I want the test to be able to tell when the code has called cancel on the mock connection, so the test can stop calling connection:didReceiveData: and connectionDidFinishLoading: on the delegate.
Is there a way for tests to tell if cancel has been called on the mock object? Is there a better way to test code that uses NSURLConnection? Is there a better way to handle HTTP error statuses?
Is there a better way to handle HTTP error statuses?
I think you are on the right track. I use something similar to the following code, which I found here:
if ([response respondsToSelector:#selector(statusCode)])
{
int statusCode = [((NSHTTPURLResponse *)response) statusCode];
if (statusCode >= 400)
{
[connection cancel]; // stop connecting; no more delegate messages
NSDictionary *errorInfo
= [NSDictionary dictionaryWithObject:[NSString stringWithFormat:
NSLocalizedString(#"Server returned status code %d",#""),
statusCode]
forKey:NSLocalizedDescriptionKey];
NSError *statusError
= [NSError errorWithDomain:NSHTTPPropertyStatusCodeKey
code:statusCode
userInfo:errorInfo];
[self connection:connection didFailWithError:statusError];
}
}
This cancels the connection, and calls connection:didFailWithError: in order to make http error codes behave exactly the same as any other connection error.