xcode - user login from iphone to php - objective-c

I have a piece of code in the .m file as below:
- (IBAction)btnLogin:(UIButton *)sender
{
NSString *strURL = [NSString stringWithFormat:#"http://www.myworkingdomain.com/fn_checkLogin2.php?name=%#&pass=%#", self.email.text, self.password.text];
// to execute php code
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
// to receive the returend value
NSString *strResult = [[[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding]autorelease];
if ([strResult isEqualToString:#"0"]) {
UIStoryboard *loginFailStoryBoard = [UIStoryboard storyboardWithName:#"loginFailStoryboard" bundle:nil];
UIViewController *initialFailLogin = [loginFailStoryBoard instantiateInitialViewController];
initialFailLogin.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:initialFailLogin animated:YES];
//NSLog(#"%#", strResult);
} else {
UIStoryboard *memberMenuBoard = [UIStoryboard storyboardWithName:#"memberMenuStoryboard" bundle:nil];
UIViewController *initialMemberMenu = [memberMenuBoard instantiateInitialViewController];
initialMemberMenu.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:initialMemberMenu animated:YES];
//NSLog(#"%#", strResult);
}
NSLog(#"%#", strResult);
}
#end
I am trying to determine if a person entered the right email and password and then to move on to the next view. I have the 'strResult' in my log and it shows that the php script it working correctly. It is now seems that the if..else statement that is not working due to the part [strResult isEqualToString:#"0"]
Can someone please advice where should I change to correct this so that when a member logins with the right password, he can go to the member view?
Thanks

#dan
The main thread is where all your UI elements are displayed. If you launch a connection on the main thread, your UI will become unresponsive until the connection is resolved (Unable to press buttons, unable to scroll etc...) In order to avoid that you should use another thread. There are other ways of doing it but the following code should do the trick without blocking your UI.
NSString *loginString =[NSString stringWithFormat:#"fn_checkLogin2.php?name=%#&pass=%#", self.email.text, self.password.text];
NSURL *url = [NSURL URLWithString:#"http://www.myworkingdomain.com/"];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url ];
[urlRequest setTimeoutInterval:30.0f];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest setHTTPBody:[loginString dataUsingEncoding:NSUTF8StringEncoding]];
NSOperationQueue *queue= [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
if ([data length]>0 && error==nil) {
NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"HTML = %#",html);
}
}
];
So if data is returned you can do stuff, if connection fails you can do other stuff without blocking your UI.

Related

iphone MBProgreeHUD Not worked When using POST method

When i will try to post some image or text from application to server that situation MBProgressHUD not worked. but without posting method its work perfectly. i am used below code.Please any one help me. thanks.
HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
HUD.dimBackground = YES;
HUD.delegate = self;
NSString *urlRequest =[NSString stringWithFormat:#"URL"];
NSString *pStrLegalURLString =[urlRequestn stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [[NSURL alloc] initWithString:pStrLegalURLString];
NSMutableURLRequest *request1 = [NSMutableURLRequest requestWithURL:url];
[request1 setHTTPMethod:#"POST"];
NSData *returnData1 = [ NSURLConnection sendSynchronousRequest: request1 returningResponse: nil error: nil ];
NSString *returnString1 = [[NSString alloc] initWithData:returnData1 encoding: NSUTF8StringEncoding];
Try like this:
It will work, but your problem as i guess is because of sendSynchronousRequest which is a blocking call hence if the main thread hangs up you won't see any update in UI. So try to make such calls in background.
Try one of the two approaches as I see:
Approach 1: (send request in background using selectors and do UI update in main thread)
-(void)method1 {
HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
HUD.dimBackground = YES;
HUD.delegate = self;
NSString *urlRequest =[NSString stringWithFormat:#"URL"];
NSString *pStrLegalURLString =[urlRequest stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [[NSURL alloc] initWithString:pStrLegalURLString];
NSMutableURLRequest *request1 = [NSMutableURLRequest requestWithURL:url];
[request1 setHTTPMethod:#"POST"];
// send request in background.
[self performSelectorInBackground:#selector(method2) withObject:nil];
}
-(void)method2 {
NSData *returnData1 = [ NSURLConnection sendSynchronousRequest: request1 returningResponse: nil error: nil ];
NSString *returnString1 = [[NSString alloc] initWithData:returnData1 encoding: NSUTF8StringEncoding];
[self performSelectorOnMainThread:#selector(method3) withObject:nil waitUntilDone:NO];
}
-(void)method3
{
// update ui in main thread.
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
}
Approach 2: Use Dispatch_Async and Dispatch_Sync
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void){
// Do background work here
dispatch_sync(dispatch_get_main_queue(), ^(void){
// Update UI here
});
});

Activity indicator with SBJson framework

I'm currently working on an app that uses a basic login page to check if the user has access to the app. I've made the login part with help of this tutorial which uses this frame work to use username and password from a simple web script.
I'm hoping that someone else maybe have worked with it or can help me with my issue. I wan't to show an activity indicator, I'm using MBProgressHUD as an activity indicator.
So I've experimented with it but can't get it to show the activity indicator when the app is connecting to the URL. I've done some bad connection simulating with the login process but the activity indicator won't show up when the app is connecting to the URL. It only shows on errors and the only thing that shows any kind of loading on success is that the login buttons pressed state is "active" (blue highlighted) until the loading is done.
So here's my code that runs when the user has typed in username and password and clicks on the login button:
// Login button
- (IBAction)loginBtnClicked:(id)sender
{
// Show the activity indicator
[HUD showUIBlockingIndicatorWithText:#"Loggar in..."];
#try {
if([[userNameTxtField text] isEqualToString:#""] || [[passwordTxtField text] isEqualToString:#""] ) {
// No username or password entered
[self alertStatus:#"Du måste ange användarnamn och lösenord" :#"Något gick fel!"];
// Hide activity indicator
[HUD hideUIBlockingIndicator];
} else {
NSString *post =[[NSString alloc] initWithFormat:#"username=%#&password=%#",[userNameTxtField text],[passwordTxtField text]];
NSLog(#"PostData: %#",post);
NSURL *url=[NSURL URLWithString:#"http://www.nebulon.se/json/sendus/jsonlogin.php"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
//[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Response code: %d", [response statusCode]);
if ([response statusCode] >=200 && [response statusCode] <300){
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Response ==> %#", responseData);
SBJsonParser *jsonParser = [SBJsonParser new];
NSDictionary *jsonData = (NSDictionary *) [jsonParser objectWithString:responseData error:nil];
NSLog(#"%#",jsonData);
NSInteger success = [(NSNumber *) [jsonData objectForKey:#"success"] integerValue];
NSLog(#"%d",success);
if(success == 1){
// Login success, grant user access to app
NSLog(#"Login SUCCESS");
[self loginSuccess];
// Hide activity indicator
[HUD hideUIBlockingIndicator];
// Store username
NSString *userName = [userNameTxtField text];
NSUserDefaults *UserDefaults = [NSUserDefaults standardUserDefaults];
[UserDefaults setObject:userName forKey:#"userName"];
[UserDefaults synchronize];
[self dismissViewControllerAnimated:NO completion:nil];
} else {
// Login error
NSString *error_msg = (NSString *) [jsonData objectForKey:#"error_message"];
[self alertStatus:error_msg :#"Inloggningen misslyckades"];
[self loginFailed];
// Hide activity indicator
[HUD hideUIBlockingIndicator];
}
} else {
// Login error
if (error) NSLog(#"Error: %#", error);
[self alertStatus:#"Ingen nätverksuppkoppling hittades." :#"Ett fel har inträffat!"];
[self loginFailed];
// Hide activity indicator
[HUD hideUIBlockingIndicator];
}
}
}
#catch (NSException * e) {
// Login error
NSLog(#"Exception: %#", e);
[self alertStatus:#"Inloggningen misslyckades." :#"Ett fel har inträffat!"];
[self loginFailed];
// Hide activity indicator
[HUD hideUIBlockingIndicator];
}
}
I believe the issue is due to the use of sendSynchronousRequest:returningResponse:error:
This method will be blocking the main/UI thread so the HUD never actually gets a chance to show until the method has returned, at which point the code continues and the HUD is hidden.
I think you should be looking at using an asynchronous request. and implementing the NSURLConnection delegate methods.
EDIT: Added code sample.
Assuming you're targeting iOS 5 and higher you can use the following code snippet which takes advantage of blocks with sendAsynchronousRequest:queue:completionHandler: and GCD.
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request
queue:backgroundQueue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// NOTE: This block is called on the background queue.
// Use GCD to get back onto the main thread
dispatch_async(dispatch_get_main_queue(), ^{
// This block will process the response and data on the main thread
});
}];
It really is very little work to port your existing code to use this mechanism. If you don't know how blocks work you should read the documentation as they are a very powerful language feature and are being used in an increasing amount of Apple and third-party frameworks.
I would also recommend staying AWAY from third-party networking libraries for now until you understand the nuances that can cause issues such as this.

OSX application freezes when try to set the value of TextView?

I am really new to Objective-C.
First please see the code:
Here it is the property:
#property (atomic) IBOutlet NSTextView *txtResponse;
And here it is the action:
- (IBAction)sendReq:(id)sender {
#synchronized(self)
{
request *req = [[request alloc] init];
voidCallback callback = ^(NSURLResponse *resp, NSData *data, NSError *error) {
NSString *val = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[self.txtResponse setString:val];
//NSLog(val);
};
[req setUrl:[[NSURL alloc] initWithString:#"http://foo.bar"]];
[req setCallback:callback];
[req send];
}
}
The UI freezes when I try to use [self.txtResponse setString:val];
I also tried the code without #synchronized(self)
Where is the problem?
Thanks in advance!
3rd day that I am working with objective-c and finally found the answer :)
I used the performSelectorOnMainThread and solved the problem
- (IBAction)sendReq:(id)sender {
request *req = [[request alloc] init];
voidCallback callback = ^(NSURLResponse *resp, NSData *data, NSError *error) {
NSString *val = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[self performSelectorOnMainThread:#selector(setResponseValue:) withObject:val waitUntilDone:NO];
};
[req setUrl:[[NSURL alloc] initWithString:#"http://programming.com"]];
[req setCallback:callback];
[req send];
}
- (void)setResponseValue:(NSString *)resp
{
[self.txtResponse setString:resp];
//NSLog(resp);
}

RaptureXML weird behaviour

I am getting an error (well it doesn't shows, just crashes out of app, no info on console)
that seems to happen whenever i call the method Iterate from RXML's rootXML:
-(void)valueSearch {
//FIRST CONNECTION
NSString *serverAddress = #"http://www.commix.com.br/clientes/grupoglobo/apple/valor.xml";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:serverAddress]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:10];
NSError *requestError;
NSURLResponse *urlResponse = nil;
response = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
//SECOND CONNECTION - Just an encapsulated form of the first, since i use it in other parts
// of the code
response = [self requestWithParameters:#"valor.xml"];
//i just uncommented both. but actually only one (connection) runs.
//Creation of the rooXML so i can grab the info i need
RXMLElement *rootXML = [RXMLElement elementFromXMLData:response];
//This array is where i'll keep the info from the files.
//it`s deallocated at the end in dealloc
searchResult = [[NSMutableArray alloc] init];
//This is the culprit. Atleast it seems so, since putting NSLog before and after
//revealed so.
[rootXML iterate:#"valor" usingBlock: ^(RXMLElement *valor) {
NSLog(#"valor: %#", [valor child:#"nome"].text);
[searchResult addObject:[valor child:#"nome"].text];
}];
}
The thing is, when i comment the requestWithParametersand use the normal non-encapsulated style (//FIRST CONNECTION) i don't get errors. But if i use the second, when the program reaches [rootXML iterate: [...]]it crashes there without warning.
using RaptureXML: https://github.com/ZaBlanc/RaptureXML
It also happens in another part of the code:
-(void)vehicleSearch {
NSString *path = [[NSBundle mainBundle] pathForResource:#"idArray" ofType:#"plist"];
NSMutableArray *idArray = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSMutableString *serverAddress = (#"http://www.commix.com.br/clientes/grupoglobo/apple/modelo.php?marc=%#",[idArray objectAtIndex:0]);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:serverAddress]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:10];
NSError *requestError;
NSURLResponse *urlResponse = nil;
response = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
RXMLElement *rootXML = [RXMLElement elementFromXMLData:response];
searchResult = [[NSMutableArray alloc] init];
[rootXML iterate:#"modelo" usingBlock: ^(RXMLElement *modelo) {
NSLog(#"modelo: %#", [modelo child:#"nome"].text);
[searchResult addObject:[modelo child:#"nome"].text];
}];
[idArray release];
}
Happens at the same line [rootXML iterate:].
Sorry for leaks and stuff, i'm inexperienced (thats why i'm here), Thanks!
EDIT:
ACTUALLY the culprit is the line
NSMutableString *serverAddress = (#"http://www.commix.com.br/clientes/grupoglobo/apple/modelo.php?marc=%#",[idArray objectAtIndex:0]);
if i pass the parameter directly, without variables, it works:
NSMutableString *serverAddress = (#"http://www.commix.com.br/clientes/grupoglobo/apple/modelo.php?marc=4");
it shows correctly.
Are you sure that ,[idArray objectAtIndex:0] is an NSString?
Try to use
[NSString stringWithFormat:#"http://www.commix.com.br/clientes/grupoglobo/apple/modelo.php?marc=%#",[idArray objectAtIndex:0]];`
Or even
[NSString stringWithFormat:#"http://www.commix.com.br/clientes/grupoglobo/apple/modelo.php?marc=%#",[[idArray objectAtIndex:0]stringValue]];
response = [self requestWithParameters:#"valor.xml"];
if response is a property use self.response otherwise you will have memory leak issues.

iOS Get Connection

This is my first time on this site and I am very new to coding so I was wondering if somebody could help me out.
I want to set a get request from my iphone app to my website and get the information echoed back from the website to my phone.
I have gotten this far but do not know where to go from here. Any help would be much appreciated, thanks!
- (void)myData:(id)sender
{
NSString *DataToBeSent;
sender = [sender stringByReplacingOccurrencesOfString:#"," withString:#"%20"];
[receivedData release];
receivedData = [[NSMutableData alloc] init];
DataToBeSent = [[NSString alloc] initWithFormat:#"http://194.128.xx.xxx/doCalc/getInfo.php?Data=%#",sender];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:dataToBeSent] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];
[request setHTTPMethod: #"GET"];
NSError *requestError;
NSURLResponse *urlResponse = nil;
NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
[dataToBeSent release];
}
OLD WAY
- (void)myData:(id)sender
{
NSString *dataToBeSent;
sender = [sender stringByReplacingOccurrencesOfString:#"," withString:#"%20"];
[receivedData release];
receivedData= [[NSMutableData alloc] init];
dataToBeSent= [[NSString alloc] initWithFormat:#"http://194.128.xx.xxx/doCalc/getInfo.php?Data=%#",sender];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:dataToBeSent]];
Theconn= [[NSURLConnection alloc]initWithRequest:theRequest delegate:self];
NSLog (#"test1 %#", theRequest);
NSLog (#"test2 %#", Theconn);
[dataToBeSent release];
}
Then the following methods are called and I get my data BUT if I sent another request after my first one but different data on the same connection, it would always give me the same result which shouldn't happen
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
/* appends the new data to the received data */
[receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
NSString *stringData= [[NSString alloc]
initWithData:receivedData encoding:NSUTF8StringEncoding];
NSLog(#"Got data? %#", stringData);
[self displayAlertCode:stringData];
[stringData release];
// Do unbelievably cool stuff here //
}
Assuming your data loaded properly you can convert the data into a string and do whatever you want with it.
NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
//Make sure to set the correct encoding
NSString* responseString = [[NSString alloc] initWithData:response1 encoding:NSASCIIStringEncoding];
If your server returns JSON there are 3rd party libraries that can parse the string into collections like NSArray and NSDictionary. If your server returns XML then NSXMLParser could be something you can use.
EDIT
I've changed your code to manage the memory a little differently.
.h
#property (nonatomic,retain) NSMutableData * receivedData;
#property (nonatomic,retain) NSURLConnection * Theconn;
.m
#synthesize receivedData;
#synthesize Theconn;
//A bunch of cool stuff
- (void)myData:(id)sender
{
//If you already have a connection running stop the existing one
if(self.Theconn != nil){
[self.Theconn cancel];
}
sender = [sender stringByReplacingOccurrencesOfString:#"," withString:#"%20"];
//This will release your old receivedData and give you a new one
self.receivedData = [[[NSMutableData alloc] init] autorelease];
NSString *dataToBeSent = [NSString stringWithFormat:#"http://194.128.xx.xxx/doCalc/getInfo.php? Data=%#",sender];
NSURLRequest *theRequest= [NSURLRequest requestWithURL:[NSURL URLWithString:dataToBeSent]];
//This will release your old NSURLConnection and give you a new one
self.Theconn = [NSURLConnection connectionWithRequest:theRequest delegate:self];
NSLog (#"test1 %#", theRequest);
NSLog (#"test2 %#", Theconn);
}
//...
//Your delegate methods
//...
- (void) dealloc{
[receivedData release];
[Theconn release];
[super dealloc];
}