iPhone Objective-C: combining methods together - iphone

I'm a complete noob at objective-C, so this might be a very silly question to a lot of you.
Currently, I have a view with a 'SignIn' button, which when clicked, activates a sigupUp IBAction that I have defined below. Basically, this method needs to make a JSON call and get back some data about the user.
So, right now, my code looks something like this:
-(IBAction)signIn:(id)sender{
//run registration API call
//establish connection
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.apicallhere.com/api/auth"]]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
[request setHTTPBody:postData];
[[NSURLConnection alloc]initWithRequest:request delegate:self];
responseData = [[NSMutableData data] retain];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{[responseData setLength:0];}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{[responseData appendData:data];}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{/*NSLog(#"%#",error);*/}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSString *response=[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
....code carries on from here.
}
As you can see, the problem with my code is that even though it is initiated via the 'SignUp' method, it finishes with the 'connectionDidFinishLoading' method. I want to have all this code in a single method. Not 2 separate ones, as I want to be able to return a boolean verifying if the connection was successful or not.
If someone could please tell me how to code up this procedure into a single method, I would really appreciate it.

If you really want the code all in one method, you're talking about potentially blocking all of the UI and so forth on a synchronous HTTP request method and response call.
The method to put this all "inline" is sendSynchronousRequest:returningResponse:error on NSURLConnection
[NSURLConnection sendSynchronousRequest:returningResponse:error:]
i.e.
NSError *error;
NSURLResponse *response;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
... do something with the NSURLResponse to enjoy with your data appropriately...
I would personally encourage you to look at an alternative for most of this sort of thing towards the asynchronous methods.

Related

connection:willCacheResponse will never get called

I'm working on an iPhone App which involves downloading data from a web server. All things are working fine except the method connection:willCacheResponse: will never get called. But others like connection:didReceiveResponse:, connection:didReceiveData:, connection:didFailWithError:, connectionDidFinishLoading: all working fine. I made the connection like following:
- (void)makeConnection
{
NSURL *url = [NSURL URLWithString:#"http://www.abc.com"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60];
[request setHTTPMethod:#"POST"];
NSString *postString = [NSString stringWithFormat:#"%#", string];
[request setValue:[NSString stringWithFormat:#"%d", [postString length]] forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
NSCachedURLResponse *newCachedResponse = cachedResponse;
NSDictionary *newCachedResponseUserInfo = [NSDictionary dictionaryWithObject:[NSDate date] forKey:#"Cached Date"];
newCachedResponse = [[NSCachedURLResponse alloc] initWithResponse:[cachedResponse response] data:[cachedResponse data] userInfo:newCachedResponseUserInfo storagePolicy:[cachedResponse storagePolicy]];
return newCachedResponse;
}
I also try to change the policy to NSURLRequestUseProtocolCachePolicy, but nothing help. Also tried to put a break point in
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
but nothing happened.
Am I missing something? Thank you in advance.
connection:willCacheResponse: is only called if the response contains a Cache-Control header, according to Appleā€™s documentation:
The delegate receives connection:willCacheResponse: messages only for protocols that support caching.

iPhone [request setTimeoutInterval:10] not working, app freezes

When I chnage to port number I'm connecting to to test the timout, my app freezes.
I am calling [request setTimeoutInterval:10];, which I assume should be 10 seconds. But, the app hangs. Could it have something to do with it being a local server?
Code:
// call this when program first starts
-(void) nSendMessage : (NSString *) name Password: (NSString *) password page: (NSString *) page
{
// set the url
NSString *address = #"http://localhost:1075/update";
address=[ address stringByAppendingString: page];
NSMutableURLRequest *request =
[[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:address]];
// post or get
[request setHTTPMethod:#"POST"];
// data to send
NSString *postString = #"username=iusername&password=ipassword";
NSString *sendString=[postString stringByReplacingOccurrencesOfString:#"iusername" withString: name];
sendString=[sendString stringByReplacingOccurrencesOfString:#"ipassword" withString: password];
[request setValue:[NSString
stringWithFormat:#"%d", [sendString length]]
forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:[sendString
dataUsingEncoding:NSUTF8StringEncoding]];
[request setTimeoutInterval:10];
[[NSURLConnection alloc]
initWithRequest:request delegate:self];
//
//THE PROGRAM FREEZES HERE
//
NSData *urlData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *response = [[NSString alloc] initWithData:urlData encoding:NSASCIIStringEncoding];
// Phrase repl
[self nUpdateDisplay:response];
}
Your question looks like a dupe of this one:
iPhone SDK: URL request not timing out
So to summarise: the timeout lower limit is at least four minutes, even if you pass in a smaller value.
And as detailed at the above link, using the asynchronous method is usually the best option. If you use synchronous, as you are doing above, and you're in the main runloop, you will block your UI completely, which will cause the 'hang' effect.

How to get data back from webserver with NSMutableURLRequest

I try to build an app for user that enter his data and this data will be post to a webserver for save in a Database. This web server returns some data back like Id or something else.
How I can receive the data the webserver returns back?
The transfer works already with NSMutableURLRequest. But I search for a sollution to read the answer from the web server and display it on a label.
Have a look at the delegate methods of NSURLConnection.
Example of how it could be done. Original source
NSString *post = #"key1=val1&key2=val2";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:#"http://www.someurl.com"]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if (conn)
{
receivedData = [[NSMutableData data] retain];
}
else
{
// inform the user that the download could not be made
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[receivedData appendData:data];
}
- (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]);
NSString *aStr = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];
NSLog(aStr);
// release the connection, and the data object
[receivedData release];
}

connection didReceiveData called twice while posting a Url in iphone?

I am new to iphone development.I have posted the URL with the user-name and password. I am able to print the data in "connection didReceiveData " method.But i see "connection didReceiveData" method called twice.I don't know ,where i am going wrong. Here is my code
- (void)viewDidLoad {
[super viewDidLoad];
NSString *post = [NSString stringWithFormat:#"&domain=school.edu&userType=2&referrer=http://apps.school.edu/navigator/index.jsp&username=%#&password=%#",#"xxxxxxx",#"xxxxxx"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://secure.school.edu/login/process.do"]]];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
[request setHTTPBody:postData];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
if(conn)
{
NSLog(#"Connection Successful");
}
else
{
NSLog(#"Connection could not be made");
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data{
NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"the data %#",string);
}
The whole HTML page is printed twice in the console.So please help me out.Thanks.
You may receive the response data in chunks, which is why NSURLConnection's documentation states:
"The delegate should concatenate the contents of each data object delivered to build up the complete data for a URL load."
Use an instance of NSMutableData for this and only process the complete data once you receive the -connectionDidFinishLoading: message.
As MacOS Developer Library states, connection:didReceiveData can be called multiple times if data is received in chunks. That means you have to save all the chunks in some variable and do data processing in connectionDidFinishLoading method. e.g.
NSMutableData *receivedData = [[NSMutableData alloc] init];
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the new data to receivedData.
[receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do something with the data, for example log:
NSLog(#"data: %#", [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding]
}

get return result after post to server (from iphone)

I make iphone application, post parametes to JSP (test.jsp in server) from iphone. The following is my codes:
NSData *postData = [#"&test=123&field=456" dataUsingEncoding:NSUTF8StringEncoding];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
// Init and set fields of the URLRequest
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"POST"];
[request setURL:[NSURL URLWithString:[NSString stringWithString:#"http://mydomain.com/test.jsp"]]];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
// Return data of the request
NSData *receivedData = [[NSMutableData data] retain];
}
[request release];
But my problem is: I can not get return result from JSP server.
How I can setup in JSP to get return result in iPhone? and in iPhone too?
Thank all
Do you implement this in your delegate:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
Data won't just magically appear in your receivedData instance. You need to implement the delegate methods for NSURLConnection. Take a look at Apple's documentation on how to this all properly.