Pass json response to another view controller in iOS - ios

At first i just send data to server using GET method, I receive a response like below
2015-11-16 14:21:42.168 smartschool[1963:348015] Item actcode: ZQRTNN68
2015-11-16 14:21:42.169 smartschool[1963:348015] Item parentid: 8
How can i display the activation code to a label of the next viewController.
Here is my code:
#import "RegistrationViewController.h"
#interface RegistrationViewController ()
#end
#implementation RegistrationViewController
{
NSMutableData *mutableData;
#define URL #"http://192.168.1.166/bustracking/activation/requestActivationCode"
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(IBAction)sendDataUsingGet:(id)sender{
[self sendDataToServer : #"GET"];
}
-(void) sendDataToServer : (NSString *) method
{
NSString *parentName = parent_name.text;
NSString *contactNumber = contact_number.text;
NSString *beaconid = #"145801000095";
//NSString *beaconMacAdd = #"14:58:01:00:00:95";
if(parentName.length > 0 && contactNumber.length > 0){
NSLog (#"Getting response from server...");
NSMutableURLRequest *request = nil;
// Only Difference between POST and GET is only in the way they send parameters
if([method isEqualToString:#"GET"]){
NSString *getURL = [NSString stringWithFormat:#"%#?parent_name=%#&contact_number=%#&beacon_id=%#", URL, parentName, contactNumber, beaconid];
//url = [NSURL URLWithString: getURL];
getURL = [getURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString: getURL];
request = [NSMutableURLRequest requestWithURL:url];
NSLog(#"urlinfo: %#", url);
NSLog(#"link: %#", getURL);
}
[request setHTTPMethod:method];
[request addValue: #"application/x-www-form-urlencoded; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
NSLog(#"connection: %#", connection);
if( connection )
{
mutableData = [NSMutableData new];
}
else
{
NSLog (#"NO_CONNECTION");
return;
}
}
else
{
NSLog(#"NO_VALUES");
}
}
#pragma mark NSURLConnection delegates
-(void) connection:(NSURLConnection *) connection didReceiveResponse:(NSURLResponse *)response
{
[mutableData setLength:0];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[mutableData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog (#"NO_CONNECTION");
return;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:mutableData options:kNilOptions error:&error];
NSArray *fetchedArr = [json objectForKey:#"response"];
NSString *responseActCode;
for (NSDictionary *user in fetchedArr)
{
responseActCode = [user objectForKey:#"activation_code"];
NSLog(#"Item actcode: %#", responseActCode);
NSLog(#"Item parentid: %#", [user objectForKey:#"parent_id"]);
//NSLog(#"Item actcode: %#", [user objectForKey:#"activation_code"]);
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:responseActCode forKey:#"HighScore"];
[defaults synchronize];
NSLog(#"from data: %#", [defaults objectForKey:#"HighScore"]);
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Activation Code"
message:(#"%#", responseActCode)
delegate:nil //or self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
#end

If the returning data is in dictionary format, declare nsdictionary in header.h class on which you wan to transfer data, similarly you can use array and string, now if you are using a storyboard, below is the method.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
vc.dictionary = self.dictionary.
}
}
and you want to transfer data upon cell tap this is what you have to do.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"YOUR_SEGUE_NAME_HERE"" sender:self];
}
When "performSegueWithIdentifier" is called, this method automatically redirected to "prepareForSegue" method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath= [self.tableView indexPathForSelectedRow];
// Make sure your segue name in storyboard is the same as this line
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
now this time its array.
vc.array= [array[indexpath.row] valueforkey#"jsonkey"];
}
}

There are many ways to pass data between view controllers. Here's one example:
Create a public property in "SomeViewController" class(eg: responseActCodeString) and set that property to your activation code(eg: responseActCode).
SomeViewController *someViewController = [[SomeViewController alloc] initWithNib:#"SomeViewController " bundle:nil];
someViewController.responseActCodeString = responseActCode;
[self pushViewController:someViewController animated:YES];
You can also use notifications, user defaults as an alternatives.
Also look at this link.
For storyboards add following method in initial view controller:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"someIdentifier"]){
SomeViewController*someViewController= (SomeViewController*)segue.destinationViewController;
someViewController.responseActCodeString = responseActCode;
}
}

Related

Code keeps crashing with passing data

I'm building my first iOS app with a login system. I've built some simple things before, but this is on a whole new level. Currently I'm able to login and get some data back from the server. The app then performs a model segue to MainView with MainController attached to it.
When I log in, the app gets token and success back from the server. This token is needed for further requests to the server. However, I can't seem to figure out how to pass the token to MainController. It doesn't matter what I try, the app crashes with an unknown error.
Right now - with the code below - it throws:
2014-10-11 14:30:14.077 LoginScreen[29076:4688502] -[UINavigationController setXAuthToken:]: unrecognized selector sent to instance 0x7bfd1140
2014-10-11 14:30:14.104 LoginScreen[29076:4688502] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController setXAuthToken:]: unrecognized selector sent to instance 0x7bfd1140'
ViewController.h
#import <UIKit/UIKit.h>
#import "MainController.h"
#interface ViewController : UIViewController <UITextFieldDelegate>
#property (weak, nonatomic) IBOutlet UITextField *txtUsername;
#property (weak, nonatomic) IBOutlet UITextField *txtPassword;
- (IBAction)sigininClicked:(id)sender;
- (IBAction)backgroundTap:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)sigininClicked:(id)sender {
NSInteger success = 0;
#try {
if([[self.txtUsername text] isEqualToString:#""] || [[self.txtPassword text] isEqualToString:#""] ) {
[self alertStatus:#"Please enter Email and Password" :#"Sign in Failed!" :0];
} else {
NSString *post =[[NSString alloc] initWithFormat:#"username=%#&password=%#",[self.txtUsername text],[self.txtPassword text]];
NSLog(#"PostData: %#",post);
NSURL *url=[NSURL URLWithString:#"http://www.mywebsite.com/auth"];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[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: %ld", (long)[response statusCode]);
if ([response statusCode] >= 200 && [response statusCode] < 300)
{
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Response ==> %#", responseData);
NSError *error = nil;
NSDictionary *jsonData = [NSJSONSerialization
JSONObjectWithData:urlData
options:NSJSONReadingMutableContainers
error:&error];
success = [jsonData[#"success"] integerValue];
NSLog(#"Success: %ld",(long)success);
if(success == 1)
{
NSLog(#"Login SUCCESS");
} else {
NSString *error_msg = (NSString *) jsonData[#"error_message"];
[self alertStatus:error_msg :#"Sign in Failed!" :0];
}
} else {
//if (error) NSLog(#"Error: %#", error);
[self alertStatus:#"Connection Failed" :#"Sign in Failed!" :0];
}
}
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
[self alertStatus:#"Sign in Failed." :#"Error!" :0];
}
if (success) {
[self performSegueWithIdentifier:#"login_success" sender:self];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"login_success"]) {
MainController *controller = (MainController *)segue.destinationViewController;
controller.xAuthToken = #"test string";
}
}
- (void) alertStatus:(NSString *)msg :(NSString *)title :(int) tag
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
message:msg
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil];
alertView.tag = tag;
[alertView show];
}
- (IBAction)backgroundTap:(id)sender {
[self.view endEditing:YES];
}
-(BOOL) textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
#end
MainController.h
#import <Foundation/Foundation.h>
#interface MainController : UIViewController
#property (nonatomic,strong) NSString *xAuthToken;
#end
MainController.m
#import "MainController.h"
#interface MainController ()
#end
#implementation MainController
- (void)viewDidLoad
{
NSLog(#"%#",_xAuthToken);
}
#end
The stack trace tells you what the problem is - you are trying to set the XAuthToken property on a UINavigationController - but a UINavigationController doesn't have that property.
Your MainController instance is embedded in a UINavigationController, so that is what you get from destinationViewController in prepareForSegue.
You need to access the view controller stack -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"login_success"]) {
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
MainController *controller = (MainController *)navController.topViewController
controller.xAuthToken = #"test string";
}
}

App crashed when using QBSimpleSyncRefreshControl in tableview pull to refresh

I'm using tabview controller, one of the view controller having table view I use QBSimpleSyncRefreshControl for pull down refresh, its working fine in first time load tab controller,
when I logout my user, I reload my Tab controller (root view controller) that time app crashed unexpectedly.
This is the code I'm using
in tableview controller
QBSimpleSyncRefreshControl *refreshControl = [[QBSimpleSyncRefreshControl alloc] init];
refreshControl.delegate = self;
self.myRefreshControl = refreshControl;
[self.tvTableView addSubview:self.myRefreshControl];
i did in logout
UIStoryboard *board = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UINavigationController *Tabctrl = [board instantiateViewControllerWithIdentifier:#"vcInitialViewNavId"];
UIWindow *window = AppDelegate.window;
[window addSubview:Tabctrl.view];
window.rootViewController = Tabctrl;
If I block this line
[self.tvTableView addSubview:self.myRefreshControl];
App working fine, If unblock this app crashed when logout (Reload root view controller)
Can anyone help for this.
Full code Here:
view.h File
#interface MyTCView : UIViewController <UICollectionViewDataSource, UICollectionViewDelegate, QBRefreshControlDelegate>
{
// some declaration here
}
#property (weak, nonatomic) IBOutlet UITableView *tvTableView;
#property (nonatomic, strong) QBSimpleSyncRefreshControl *myRefreshControl;
view.m
- (void)viewDidLoad
{
[super viewDidLoad];
FeaturedItemTitle = #"";
HUD = [[MBProgressHUD alloc] initWithView:self.view];
HUD.mode = MBProgressHUDModeIndeterminate;
[self.view addSubview:HUD];
AppDelegate = (TCAppDelegate *) [UIApplication sharedApplication].delegate;
board = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
QBSimpleSyncRefreshControl *refreshControl = [[QBSimpleSyncRefreshControl alloc] init];
refreshControl.delegate = self;
self.myRefreshControl = refreshControl;
[self.tvTableView addSubview:self.myRefreshControl];
}
- (void)refreshControlDidBeginRefreshing:(QBRefreshControl *)refreshControl
{
[self GetDetails];
}
-(void) GetDetails
{
// Calling web service here
NSString *strURL = #"URL HERE";
NSURL *url = [NSURL URLWithString: strURL];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
[theRequest addValue: #"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[theRequest setHTTPMethod:methodType];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:delegate];
if ( theConnection ) {
//Connection successful
receivedData = [NSMutableData data];
} else {
//Failure
NSLog(#"Error");
}
}
//*** HTTP Connection ***//
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
receivedData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[HUD hide:YES];
[self ShowAlertMessage:ServerErrorMsg Tilte:#""];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error;
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:receivedData options:NSJSONReadingAllowFragments error:&error];
// Array of data get from Res(NSDictionary)
[tvTableView reloadData]; // Tableview Reload
[collView reloadData]; // Collectionview reload
[self.myRefreshControl endRefreshing];
[HUD hide:TRUE];
}
I think this is not the right way to logout a navigationcontroller based application, just use the standard way to load the rootController using
[self.navigationController popToRootViewControllerAnimated:YES];

How to reloadData in tableView with didSelectedRowAtIndexPath and call group of methods in it

In my app I'm starting NSURLConnection, parsing XML, initialize array from this XML, and show it in the tableView. In ViewDidLoad I appeal to the server with a query parameter 0 , and it's returned for me string, after all conversion a have in tableView 4 rows - titles, and when i push on some of this titles, all process (connection to the server, parsing, arrays initialising, ) must be repeated. In didSelectedRowAtIndexPath I have to transmit section ID (so that the server sent me the correct data). How can I do it correctly? I'm establish connection in ViewDidLoad, how can I call it again?
My .m file:
#import "catalogViewController.h"
#import "XMLReader.h"
#interface catalogViewController ()
#end
#implementation catalogViewController
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) { } return self;
}
//-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-CONNECTIONS METHOD START-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[_receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[connection release];
[_receivedData release];
NSString *errorString = [[NSString alloc] initWithFormat:#"Connection failed! Error - %# %# %#", [error localizedDescription], [error description], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]]; NSLog(#"%#",errorString);
[errorString release];
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-GET FULL DATA HERE-=-=-=-=-=-=-=-=--=-=-=-=-=-=-
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *dataString = [[NSString alloc] initWithData:_receivedData encoding:NSUTF8StringEncoding];
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-XMLPARSER PART START-=-=-=-=-=-=-=-=-=-=-=-=-=-=- //
NSString *testXMLString = [NSString stringWithContentsOfURL:myURL usedEncoding:nil error:nil];
// -=-=-=-=-=-=-=-=-=-=Parse the XML into a dictionary-=-=-=-=-=-=-=-=-=-=
NSError *parseError = nil;
_xmlDictionary = [XMLReader dictionaryForXMLString:testXMLString error:&parseError];
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-XMLPARSER PART END-=-=-=-=-=-=-=
_titleArr = [[NSArray alloc] initWithArray:[[[_xmlDictionary objectForKey:#"result"] objectForKey:#"name"] valueForKey:#"text"]];
_IDArr = [[NSArray alloc] [[[_xmlDictionary objectForKey:#"result"] objectForKey:#"id"] valueForKey:#"text"]];
_priceArr= [[NSArray alloc][[[_xmlDictionary objectForKey:#"result"] objectForKey:#"price"] valueForKey:#"text"]];
_ImageURLArr=[[NSArray alloc][[[_xmlDictionary objectForKey:#"result"] objectForKey:#"img"] valueForKey:#"text"]];
[connection release];
[_receivedData release];
[dataString release];
_didDataLoaded=TRUE;
[_myTableView reloadData]; // IBOutlet property
[self.tableView reloadData]; //default
}
//-=-=-=-=-=-=-=-=-=-=-Connection methods END-=-=-=-=-=-=-=-=-=-
- (void)viewDidLoad {
[super viewDidLoad];
_didDataLoaded=FALSE;
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-XMLPARSER PART START-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//-=-==-=-=-=-=-=-=-=-=-=-=--=-=START Shit with connection-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=
NSString* params = #"request_params";
NSURL* url = [NSURL URLWithString:#"my URL"];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0];
[request addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
request.HTTPMethod = #"POST";
request.HTTPBody = [params dataUsingEncoding:NSUTF8StringEncoding];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (connection) {
NSLog(#"Connecting...");
_receivedData = [[NSMutableData data] retain];
} else {
NSLog(#"Connecting error");
}
}
//-=-==-=-=--=-==-=-=-=-=-=--=-==---=-=--==-=-=-=-=-TableView methods-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=--=-=-=-=-=-=-=
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (_didDataLoaded == FALSE) {
return 1;
}
else return self.titleArr.count;
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { return 1; }
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"creatures"];
UIImage *creatureImage = nil;
if (_didDataLoaded == FALSE) {
cell.textLabel.text=#"Downloading...";
cell.detailTextLabel.text= #"downloading...";
} else {
cell.textLabel.text = [self.titleArr objectAtIndex:indexPath.row];
cell.detailTextLabel.text= _IDArr[indexPath.row];
NSString *img = self.ImageURLArr[indexPath.row];
creatureImage =[[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:img]]]; cell.imageView.image = creatureImage;
}
return cell;
}
#end
You can move the relevant code from viewDidLoad to a specific method, something like:
- (void)loadXMLData {
// Initiate your loading/parsing
}
In viewDidLoad just call this method:
- (void)viewDidLoad {
[super viewDidLoad];
[self loadXMLData];
}
This way you can call [self loadXMLData] multiple times.
However... be careful with calling [tableView reloadData] from inside a UITableViewDelegate method implementation, as this will cause the tableview to call (at least some of the) delegate methods, which can cause recursive loops or other odd behaviour.

Push to new ViewController from connectionDidFinishLoading

Is it possible to push to a new view controller from ConnectionDidFinishLoading ?
I have the following and it performs the ConnectionDidFinishLoading but does not push to new view controller.
-(void)connectionWithURLString:(NSMutableArray *)urlString
{
NSDate *now = [NSDate date];
int userID = [[clientDataStruct.clientData objectForKey:#"number"] intValue];
NSDate *date = self.datePicker.date;
// NSLog(#"obj: %#", urlString);
NSString *extrString = [NSString stringWithFormat:#", customerdetails:{customer_id = %d, job_date = %#, date_created = %#}",userID,date, now];
NSString *post = [NSString stringWithFormat:#"json=quote:{%#%#}", urlString, extrString ];
NSLog(#"post: %#", post);
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *value = [defaults objectForKey:#"value"];
NSString *jsonUrl = [NSString stringWithFormat:#"xxx?task=add_quote&user_id=%#&customer_id=%#",value, [clientDataStruct.clientData valueForKey:#"number"]];
[request setURL:[NSURL URLWithString:jsonUrl]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postData];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
if (!connection)
NSLog(#"Connection failed!");
}
- (void)Success
{
UIStoryboard *subVc = [UIStoryboard storyboardWithName:#"MainStoryboard_iPad" bundle:nil];
UserTableView *userTable = [subVc instantiateViewControllerWithIdentifier:#"UserTableView"];
userTable.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self.navigationController pushViewController:userTable animated:YES];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"%#", error);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self performSelectorOnMainThread:#selector(Success) withObject:Nil waitUntilDone:YES];
NSLog(#"connectionDidFinishLoading%#", connection);
}
Everything works, and returns my data and data gets added into the SQL. My NSLog shows that ConnectionDidFinishLoading. But it does not push to the new View Controller.
Thanks for the help, being scratching my head on this one.
Thanks to Fahim advise allowed me to debug further, The Navigation view broke with a returned model controller. Changed it to push and all is working
Point 1
This is not working with you because you don't have navigation controller. Make sure that you have navigation controller.
Point 2
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self performSelectorOnMainThread:#selector(LoginSuccess) withObject:Nil waitUntilDone:YES];
NSLog(#"connectionDidFinishLoading%#", connection);
}
This is something wrong. Even if user have entered incorrect username or password, you are still allowing user to get logged in.
Check the response that you are getting in connectionDidFinishLoading and then based on this response do the transition.
e.g. if you have PHP at backend your code will be
sql query here to add data
if (data added) {
echo "valid";
} else {
echo "invalid";
}
now check this response in connectionDidFinishLoading and based on this do the transition
First check that if your LoginSuccess is getting called if yes then paste this
UserTableView * userTable =[self.storyboard instantiateViewControllerWithIdentifier:#"UserTableView"];
[self.navigationController pushViewController:userTable animated:YES]
like this but replace ResultsTableView with UserTableView

UITableView is loaded multiple times, I need help please - I don't understand why

Here is ALL my code for this specific view controller. As the title of this question states, I am seeing my UITableView loaded with the same 9 values over and over again. If I place a breakpoint in connectionDidFinishLoading and wait one second I only see the data rendered to the table view once. I have tried all sorts of things to solve this; help is very much appreciated.
#implementation MasterViewController
#synthesize response;
NSMutableData* receivedData;
NSString* hostName;
NSInteger portNumber = 9999;
NSMutableDictionary* dictionary;
NSInteger maxRetryCount = 5;
int count = 0;
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(#"Succeeded! Received %d bytes of data",[data length]);
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"Connection failed! Error - %# %#",[error localizedDescription],[[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
receivedData = nil;
}
-(void) connectionDidFinishLoading:(NSURLConnection *)connection {
NSError *error = nil;
id result = [NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:&error];
if ([result isKindOfClass:[NSArray class]]) {
for (NSArray *item in result) {
NSArray *category = [item valueForKey:#"CategoryName"];
[dataArray addObject:category];
}
}
else {
NSDictionary *jsonDictionary = (NSDictionary *)result;
for(NSDictionary *item in jsonDictionary)
NSLog(#"Item: %#", item);
}
connection = nil;
[self.tableView reloadData];
NSLog(#"Finished");
}
-(BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
return YES;
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
}
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
{
return YES;
}
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSString* username = #"test";
NSString* password = #"testPwd";
NSLog(#"Attempting connection with username: %#", username);
NSMutableString *loginString = (NSMutableString*)[#"" stringByAppendingFormat:#"%#:%#", username, password];
NSString *authHeader = [#"Basic " stringByAppendingFormat:#"%#", loginString];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://%#:%i%#", hostName, portNumber, #"/api/categories"]];
NSLog(#"URL: %#", url);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url
cachePolicy: NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval: 1.0];
[request addValue:authHeader forHTTPHeaderField:#"Authorization"];
[NSURLConnection connectionWithRequest:request delegate:self];
if ([challenge previousFailureCount] <= maxRetryCount) {
NSURLCredential *credential = [NSURLCredential credentialWithUser:username password:password persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
NSLog(#"Failure count %d",[challenge previousFailureCount]);
}
}
- (void)awakeFromNib
{
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addNewItem)];
self.navigationItem.rightBarButtonItem = addButton;
self.tableView.delegate = self;
self.tableView.dataSource = self;
}
- (void)addNewItem
{
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Product"
message:#"Enter the new product name"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"OK", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)insertNewObject:(id)sender
{
if (!_objects) {
_objects = [[NSMutableArray alloc] init];
}
[_objects insertObject:[NSDate date] atIndex:0];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [dataArray count];;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
cell.textLabel.text = [dataArray objectAtIndex:indexPath.row];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[dataArray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert)
{
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *object = [dataArray objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:object];
}
}
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
UITextField *textField = [alertView textFieldAtIndex:0];
[dataArray addObject:textField.text];
[self.tableView reloadData];
NSLog(#"Plain text input: %#",textField.text);
NSLog(#"Alert View dismissed with button at index %d",buttonIndex);
}
- (void)viewWillAppear:(BOOL)animated {
self.title = #"Categories";
receivedData = [[NSMutableData alloc] init];
hostName = [[NSString alloc] initWithString:#"12.234.56.123"];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://%#:%i%#", hostName, portNumber, #"/api/categories"]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval: 1.0];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
if (connection) {
} else {
}
dataArray = [[NSMutableArray alloc] init];
}
#end
willSendRequestForAuthenticaiton is a delegate method. Yet inside your delegate method, you are generating a brand new URL request, which in turn gets handled by the willSendRequest delegate, which generates another request, etc, which continually populates your dataArray with data.
Get rid of the url request inside the delegate method and it should fix things for you.

Resources