How to reload tableview when getting data from database? - iphone

- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSString *country=[[NSUserDefaults standardUserDefaults]objectForKey:#"namecountry"];
//url's
NSURL *url = [NSURL URLWithString:#"someurl"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:country forKey:#"c_name"];
[request setRequestMethod:#"POST"];
[request setValidatesSecureCertificate:NO];
[request setDelegate:self];
[request startSynchronous];
NSString *response = [request responseString];
NSLog(#"%#",response);
res=[response componentsSeparatedByString:#","];
NSLog(#"%#",[res objectAtIndex:18]);
show=[NSString stringWithFormat:#"%#",[res objectAtIndex:18]];
float f=[show floatValue];
show=[NSString stringWithFormat:#"%.2f %%",f];
[self.tableView reloadData];
}
I've read posts and try lots of different ways but can't find the correct solution.So here is my problem: I have 3 tab bar items this one is the middle one.When i click it shows the tableview and it has detailTextLabel.text . I want to update the tableview when the user press the the tab bar i want him to see the updated one.
Now i try several ways as you can see [self.tableView reloadData]; i put it all the methods in the UITableView class can anybody tell me what is wrong i am doing in this?

in your .h file you have something like this: NSArray* myData
in the .m file the tableView gets data from this myData array
all you have to do is set the new data to the array your tableView uses as a datasource.
self.myData = res; right before you reload data

Related

How to add observer for array in other class

I am building an iOS app in which I want to allow people to order stuff from stores that are registered in my database. To allow my users to see products, companies, etcetera, I need to download array's with the requested information. This is how I do that:
- (void)getOrderItems {
_dbAction = #"getOrderItems";
NSString *post = [NSString stringWithFormat:#"controller=%#&action=%#&orderNumber=%#", #"BakkerFunctions", #"getOrderItems", self.orderNumber];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSURL *url = [NSURL URLWithString:#"http://www.mysite.nl/API/"];
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Current-Type"];
[request setHTTPBody:postData];
[request setURL:url];
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 {
NSArray *orderItemsFromDatabase = [[NSArray alloc] init];
orderItemsFromDatabase = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:NULL][#"itemsFromDatabase"];
NSString *datastring = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"%# Array:%#", datastring, orderItemsFromDatabase);
//convert array from database in array of custom objects
NSMutableArray *orderItems = [[NSMutableArray alloc] init];
for (int i = 0; i < orderItemsFromDatabase.count; i++) {
[orderItems addObject:
[[Item alloc] initWithItemName:[[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"itemName"]
itemDescription:[[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"itemDescription"]
itemCode:[[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"itemCode"]
itemBarCode:[[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"itemBarCode"]
itemPrice:[[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"itemPrice"]
itemQuantity:[[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"itemQuantity"]
itemUserRemark:[[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"itemUserRemark"]
itemCompany:[[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"itemCompany"]
productImageNumber:[[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"productImageNumber"]
category:[[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"category"]
itemImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://www.imagine-app.nl/ProductImages/%#%#", [[orderItemsFromDatabase objectAtIndex:i]objectForKey:#"productImageNumber"], #".jpg"]]]]]];
}
self.orderItems = [NSArray arrayWithArray:orderItems];
}
the getOrderItems method is a method inside the custom class I have for each order. when the user selects an orders, this method gets called to download the products that belong to this order. Now this process works all fine, but the problem is that the data gets receiver when my TableView already set itself up.
I want to add an observer to check if the amount of products in this array changes, and if it does, i want to update the tableview. I have searched for hours on SO an google, but not much is said about this and nothing useful to me.
any help would be much appreciated! thank you in advance
A simple solution would be to use a MBProgressHUD or a similar control which will display a message saying that please wait while the data is being downloaded. Once, the data is downloaded it will trigger a callback meaning that it has downloaded the data and then you can refresh your UITableView to reflect all the data.
Override the orderItems setter and reload the table in there.
- (void)setOrderItems:(NSArray*)items
{
_items = items;
[self.tableView reloadData];
}
I'm not adding an observer anymore, As soon as my custom class finished processing the received data, it calls the orders view controller. That made that the data is loaded before the tableview is set up and the problem is solved.

UIActivityIndicator

When I start UIActivityIndicatorView using StartAnimating method:
[ActivityIcon startAnimating];
it disable all user interactions so when the user Tap on Cancel button which should abort the download process and hide the UIActivityIndicator it does not work!!!
any suggestions would be appreciated.
Edit:
I am using separate thread to download the files in the background. All progress reporting and UI interaction I made it through:
[self performSelectorOnMainThread:#selector(RefreshScreen:) withObject:nil waitUntilDone:YES];
and RefreshScreen method is the one who interact with the UI elements.
try change this line: [request startSynchronous]; to: [request startAsynchronous];
EDIT
- (IBAction)grabURLInBackground:(id)sender
{
NSURL *url = [NSURL URLWithString:#"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
// Use when fetching binary data
NSData *responseData = [request responseData];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}

iPhone:Connection delegates not called

In my app,everything works fine when run for first time.When I navigate through other views and went back to the same view,I used viewwillappear to call functions.
On this run,the connection request line gets executed but the connection delegates like didReceiveResponse,didreceivedata,didfinishloading,didFailWithError are not being called.
-(void)viewWillAppear:(BOOL)animated{
[self recentOrderselection];
[self recentOrderStatus];
[super viewWillAppear:animated];
[self.tableview reloadData];
}
-(void)recentOrderStatus{
..................
NSData *requestData = [NSData dataWithBytes:[json1 UTF8String] length:[json1 length]];
[request setValue:#"text/plain" forHTTPHeaderField:#"content-type"];
[request setHTTPBody: requestData];
connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
NSLog(#"URL>>>%#",url);//Got correct URL in log
}
You should always put [super viewWillAppear:animated]; at first line
And check whether the viewWillAppear function is called when you came back to same view

ASIHTTPRequest time out

Hello
I am sending some values to the server using ASIHTTPRequest. All works fine until yesterday that the requestFinished didnt work. (when the app send the request on the server an activity indicator and a new view added to the main view and when the request finished is removing the views). I added requestFailed to test if is failed and I get this error:
[3438:207] Error Domain=ASIHTTPRequestErrorDomain Code=2 "The request timed out" UserInfo=0x5ad25c0
Its weird because the same code was working fine yesterday. I am sure that they didnt make any changes on the server's side.
this is the code:
- (IBAction)convert:(id)sender{
//Get the email from the textfield
NSString *email1 = email.text;
//Save the last used email to load it on the next app launch
[[NSUserDefaults standardUserDefaults] setValue:email1 forKey:#"email"];
//Get the current URL from webview
NSString *currentURL= webView.request.URL.relativeString;
lbl.text = currentURL;
//Count the length of Label
int strL= [lbl.text length];
//The url that the requests will be send.
NSURL *url = [NSURL URLWithString:#"the website"];
//Indicator and its view are loading on the screen
[ind startAnimating];
[self.view addSubview:indView];
//ASIHTTPRequests
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
NSString *watch = [lbl.text substringWithRange:NSMakeRange(23,strL-23)];
NSString *link = [NSString stringWithFormat:#"http://youtube.com/%#",watch];
[request setShouldRedirect:YES];
[request setPostValue:watch forKey:#"url"];
[request setPostValue:email1 forKey:#"email"];
[request setPostValue:format forKey:#"format"];
[request setPostValue:quality forKey:#"quality"];
[request setDelegate:self];
[request startAsynchronous];
NSLog(#"%# %# %# %#",watch,email1,format,quality);
click=NO;
}
and this is the requestFinished:
- (void)requestFinished:(ASIFormDataRequest *)request{
NSString *responseString = [request responseString];
NSLog(#"%#",responseString);
NSLog(#"%#",lbl.text);
NSLog(#"requested finished");
[ind stopAnimating];
[indView removeFromSuperview];
[setView removeFromSuperview];
}
Did you try to increase the timeout value on the request? By default it is 10 seconds, you can make it larger by doing this right before the startAsynchronous call:
[request setTimeOutSeconds:60];

UITabBar with UIWebView problem with switching views

I have an app which has UITabBar with 5 views, each attached to a different UIWebView. Each of the WebViews responds to:
webViewDidStartLoad:(UIWebView *)webView
webViewDidFinishLoad:(UIWebView *)webView
Those two are responsible for displaying a loading screen (separate image for each tab, toggled visible or not) and activity indicator.
It all works fine when the page is loaded to WebView. User taps a link on the page, loading image is displayed along with the activity indicator. When the page is loaded they both disappear and new website is presented.
The problem is when user taps on one of the TabBar items. App intercepts the event and launches a method in appropriate view, which is refreshing the page.
The problem: after the tap view changes immediately to the other WebView, however loading screen takes a long time to appear (from what I gather it only shows when the page passed to homeView starts loading) and I can't figure out why. Displaying loading items is the first thing the app should do after method is called.
Here is the code that calls a method from TabBar controller:
[hv performSelector:#selector(goToPage) withObject:nil afterDelay:0.0];
and here is the goToPage method:
- (void) goToPage
{
homeView.delegate = self;
self.showLoading;
NSURL *url = [NSURL URLWithString: [NSString stringWithFormat: #"%#/seed.php", appURL]];
NSString *body = [NSString stringWithFormat: #"uid=%#", uID];
NSData *data = [body dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
[request setHTTPMethod: #"POST"];
[request setHTTPBody: data];
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
[request release];
NSString *seedString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSArray *seedArray = [seedString componentsSeparatedByString:#":::"];
NSString *eventNumber = [[seedArray objectAtIndex:0] retain];
NSString *passedSid = [[seedArray objectAtIndex:1] retain];
if (!seedString) {
// can't connect
NSLog(#"Can't connect.");
}else {
// connected
NSLog(#"Events: %#", eventNumber);
if(![evtNo isEqualToString:eventNumber]){
evtNo = eventNumber;
if(![evtNo isEqualToString:#"0"]){
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
}
}
}
NSURL *urlView = [NSURL URLWithString: [NSString stringWithFormat: #"%#/index.php", appURL]];
NSString *bodyView = [NSString stringWithFormat: #"sid=%#", passedSid];
NSData *dataView = [bodyView dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *requestView = [[NSMutableURLRequest alloc]initWithURL:urlView];
[requestView setHTTPMethod: #"POST"];
[requestView setHTTPBody: dataView];
[homeView loadRequest: requestView];
if([evtNo isEqualToString:#"0"]){
// clearing badge
[[[[[self tabBarController] viewControllers] objectAtIndex: 0] tabBarItem] setBadgeValue: nil];
}else{
[[[[[self tabBarController] viewControllers] objectAtIndex: 0] tabBarItem] setBadgeValue: evtNo];
}
}
The goal I have is to display the loading image the moment user taps the TabBar item and remain visible until page stops loading.
The solution to this issue was to launch the method goToPage without the delay, display loading screen in goToPage and move the time consuming bits into another method inside that class, launched using persormSelector.