In my UITableViewController there are custom cells populated from JSON. Each cell has a UILabel showing a text value (#"valoracion"). When the user selects a row, a detail view from the cell object is shown. At this detail view, the user can change the value of valoracion. If the user goes back to the UITableViewController, valoracion should show the new value, but actually it shows the old value.
What should I do to update valoracion in the UITableViewController, when the user goes back from the detail view to the UITableViewController.
UPDATED***
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell =[tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell ==nil){
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"Cell"];
}
//cell.backgroundColor = [UIColor clearColor];
cell.nombreEmpresaLabel.text = [[categorias objectAtIndex:indexPath.row] objectForKey:#"nombreEmpresa"];
//[[cell contentView] setBackgroundColor:[UIColor clearColor]];
//cell.textLabel.backgroundColor = nil;
// cell.detailTextLabel.backgroundColor=nil;
cell.textLabel.textColor = [UIColor whiteColor];
cell.direccionEmpresaLabel.text= [[categorias objectAtIndex:indexPath.row] objectForKey:#"direccionEmpresa"];
NSMutableString *logo = [[NSMutableString alloc]initWithString:#"http://mujercanariasigloxxi.appgestion.eu/logos/"];
NSString *imageURL = [[categorias objectAtIndex:indexPath.row] objectForKey:#"strImagen"];
cell.meGustaHits.text = [[categorias objectAtIndex:indexPath.row] objectForKey:#"valoracionEmpresa"];
if(imageURL != nil && ![imageURL isEqual:[NSNull null]])
{
[logo appendString:imageURL];
NSURL *logoURL = [NSURL URLWithString:logo];
NSData *logoData = [NSData dataWithContentsOfURL:logoURL];
cell.logoImage.image = [UIImage imageWithData:logoData];
}
else{
cell.logoImage.image = [UIImage imageNamed:#"icono80"];
}
return cell;
}
Inside viewDidLoad method:
//URL definition where php file is hosted
int categoriaID = [[categoriaDescription objectForKey:#"idCategoria"] intValue];
NSString *string = [NSString stringWithFormat:#"%d", categoriaID];
NSLog(#"CATEGORIA ID STGRING %#",string);
NSMutableString *ms = [[NSMutableString alloc] initWithString:#"http://mujercanariasigloxxi.appgestion.eu/app_php_files/empresaslist.php?id="];
[ms appendString:string];
// URL request
NSLog(#"URL = %#",ms);
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:ms]];
//URL connection to the internet
[[NSURLConnection alloc]initWithRequest:request delegate:self];
And now the JSON delegate methods and didSelecRowAtIndexpath method:
//methods to perform the connection and population of data
-(void)connection: (NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
data = [[NSMutableData alloc]init];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)thedata
{
[data appendData:thedata];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//if data received network indicator not visible
[UIApplication sharedApplication].networkActivityIndicatorVisible=NO;
//array waterfalls populated via JSON from database
categorias = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
NSLog(#"THE DA TA &#",categorias);
[self.tableView reloadData];
}
//only in case of error
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:#"Error" message:#"The download could not complete - please make sure you are connected to eithre 3G or WiFi" delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[errorView show];
//if no connection network indicator not visible
[UIApplication sharedApplication].networkActivityIndicatorVisible=NO;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetalleEmpresaViewController *detailViewController =[self.storyboard instantiateViewControllerWithIdentifier:#"detailEmpresaViewController"];
detailViewController.title =[[categorias objectAtIndex:indexPath.row]objectForKey:#"idCategoria"];
detailViewController.detalleDescription = [categorias objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailViewController animated:YES];
}
Try call [tableview reloadData] method and make sure that you have correct implementation of tableview delegate methods.
If place where you change and save your JSON is another, than tableViewController, then put reloadData method in viewDidAppear of tableViewController class. If you saving JSON in other method of same tableViewController, then place reloadData in last line of this method.
Related
I have a table view with an image view behind it. I'm trying to figure out how to blur the image behind the table view similar to how it looks when you open control center.
Here is my view:
And here is the code for it:
#import "ToursAndConferencesViewController.h"
#import "RSSChannel.h"
#import "RSSItem.h"
#import "WebViewController.h"
#import "DTCustomColoredAccessory.h"
#import "SVProgressHUD.h"
#implementation ToursAndConferencesViewController
{
UIActivityIndicatorView *loadingIndicator;
}
#synthesize webViewController;
- (void)viewDidLoad
{
UIImageView *background = [[UIImageView alloc]init];
background.image = [UIImage imageNamed:#"plain_app-background.png"];
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
[self.tableView setBackgroundView:background];
self.title = #"Tours & Conferences";
[[SVProgressHUD appearance]setHudBackgroundColor:[UIColor blackColor]];
[[SVProgressHUD appearance]setHudForegroundColor:[UIColor whiteColor]];
[SVProgressHUD showWithStatus:#"Loading"];
// [SVProgressHUD showWithStatus:#"Loading" maskType:SVProgressHUDMaskTypeGradient];
}
- (void)viewDidDisappear:(BOOL)animated
{
[SVProgressHUD dismiss];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"%# found a %# element", self, elementName);
if ([elementName isEqual:#"channel"])
{
// If the parser saw a channel, create new instance, store in our ivar
channel = [[RSSChannel alloc]init];
// Give the channel object a pointer back to ourselves for later
[channel setParentParserDelegate:self];
// Set the parser's delegate to the channel object
[parser setDelegate:channel];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// return 0;
NSLog(#"channel items %d", [[channel items]count]);
return [[channel items]count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// return nil;
UIImageView *image = [[UIImageView alloc]init];
image.image = [UIImage imageNamed:#"CellImage.png"];
UIImageView *background = [[UIImageView alloc]init];
background.image = [UIImage imageNamed:#"plain_app-background.png"];
UIImageView *highlightedCellImage = [[UIImageView alloc]init];
highlightedCellImage.image = [UIImage imageNamed:#"HighlightedCellImage"];
UIColor *kfbBlue = [UIColor colorWithRed:8.0/255.0f green:77.0/255.0f blue:139.0/255.0f alpha:1];
UIColor *kfbLightBlue = [UIColor colorWithRed:24.0/255.0f green:89.0/255.0f blue:147.0/255.0f alpha:1];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"UITableViewCell"];
cell.textLabel.font=[UIFont systemFontOfSize:16.0];
}
RSSItem *item = [[channel items]objectAtIndex:[indexPath row]];
[[cell textLabel]setText:[item title]];
NSLog(#"Date: %#", [item date]);
tableView.backgroundColor = [UIColor clearColor];
[self.tableView setSeparatorColor:kfbBlue];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.highlightedTextColor = kfbBlue;
cell.textLabel.font = [UIFont fontWithName:#"FranklinGothicStd-ExtraCond" size:20.0];
cell.textLabel.textColor = kfbLightBlue;
// cell.backgroundView = image;
cell.backgroundColor = [UIColor clearColor];
// cell.selectedBackgroundView = highlightedCellImage;
tableView.backgroundView = background;
DTCustomColoredAccessory *accessory = [DTCustomColoredAccessory accessoryWithColor:cell.textLabel.textColor];
accessory.highlightedColor = kfbBlue;
cell.accessoryView =accessory;
return cell;
}
- (void)fetchEntries
{
// Create a new data container for the stuff that comes back from the service
xmlData = [[NSMutableData alloc]init];
// Construct a URL that will ask the service for what you want -
// note we can concatenate literal strings together on multiple lines in this way - this results in a single NSString instance
NSURL *url = [NSURL URLWithString:#"http://kyfbnewsroom.com/category/conferences/feed"];
// Put that URL into an NSURLRequest
NSURLRequest *req = [NSURLRequest requestWithURL:url];
// Create a connection that will exchange this request for data from the URL
connection = [[NSURLConnection alloc]initWithRequest:req delegate:self startImmediately:YES];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self)
{
[self fetchEntries];
}
return self;
}
// This method will be called several times as the data arrives
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
// Add the incoming chunk of data to the container we are keeping
// The data always comes in the correct order
[xmlData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
/* We are just checking to make sure we are getting the XML
NSString *xmlCheck = [[NSString alloc]initWithData:xmlData encoding:NSUTF8StringEncoding];
NSLog(#"xmlCheck = %#", xmlCheck);*/
// [loadingIndicator stopAnimating];
[SVProgressHUD dismiss];
// Create the parser object with the data received from the web service
NSXMLParser *parser = [[NSXMLParser alloc]initWithData:xmlData];
// Give it a delegate - ignore the warning here for now
[parser setDelegate:self];
//Tell it to start parsing - the document will be parsed and the delegate of NSXMLParser will get all of its delegate messages sent to it before this line finishes execution - it is blocking
[parser parse];
// Get rid of the XML data as we no longer need it
xmlData = nil;
// Reload the table.. for now, the table will be empty
[[self tableView]reloadData];
NSLog(#"%#\n %#\n %#\n", channel, [channel title], [channel infoString]);
}
- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error
{
// Release the connection object, we're done with it
connection = nil;
// Release the xmlData object, we're done with it
xmlData = nil;
[SVProgressHUD dismiss];
// Grab the description of the error object passed to us
NSString *errorString = [NSString stringWithFormat:#"Fetch failed: %#", [error localizedDescription]];
// Create and show an alert view with this error displayed
UIAlertView *av = [[UIAlertView alloc]initWithTitle:#"Error" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[[webViewController webView]loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"about:blank"]]];
// Push the web view controller onto the navigation stack - this implicitly creates the web view controller's view the first time through
// [[self navigationController]pushViewController:webViewController animated:YES];
[self.navigationController pushViewController:webViewController animated:YES];
// Grab the selected item
RSSItem *entry = [[channel items]objectAtIndex:[indexPath row]];
// Construct a URL with the link string of the item
NSURL *url = [NSURL URLWithString:[entry link]];
// Construct a request object with that URL
NSURLRequest *req = [NSURLRequest requestWithURL:url];
// Load the request into the web view
[[webViewController webView]loadRequest:req];
webViewController.hackyURL = url;
// Set the title of the web view controller's navigation item
// [[webViewController navigationItem]setTitle:[entry title]];
}
#end
Set your tableView to [UIColor clearColor];
Then download apple's UIImage+ImageEffects category files that contain helper methods to blur images.
You can follow this tutorial for code samples on image blurring
Here is my final result which is an image behind my tableView:
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have an RSS feed in my app and I'm trying to figure out how to implement pull to refresh. Here is my code:
#import "ActionAlertsViewController.h"
#import "RSSChannel.h"
#import "RSSItem.h"
#import "WebViewController.h"
#import "DTCustomColoredAccessory.h"
#import "SVProgressHUD.h"
#implementation ActionAlertsViewController
{
UIActivityIndicatorView *loadingIndicator;
}
#synthesize webViewController;
- (void)viewDidLoad
{
UIImageView *background = [[UIImageView alloc]init];
background.image = [UIImage imageNamed:#"plain_app-background.png"];
self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
[self.tableView setBackgroundView:background];
self.title = #"Action Alerts";
[[SVProgressHUD appearance]setHudBackgroundColor:[UIColor blackColor]];
[[SVProgressHUD appearance]setHudForegroundColor:[UIColor whiteColor]];
[SVProgressHUD showWithStatus:#"Loading"];
}
- (void)viewDidDisappear:(BOOL)animated
{
[SVProgressHUD dismiss];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"%# found a %# element", self, elementName);
if ([elementName isEqual:#"channel"])
{
// If the parser saw a channel, create new instance, store in our ivar
channel = [[RSSChannel alloc]init];
// Give the channel object a pointer back to ourselves for later
[channel setParentParserDelegate:self];
// Set the parser's delegate to the channel object
[parser setDelegate:channel];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// return 0;
NSLog(#"channel items %d", [[channel items]count]);
return [[channel items]count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// return nil;
UIImageView *image = [[UIImageView alloc]init];
image.image = [UIImage imageNamed:#"CellImage.png"];
UIImageView *background = [[UIImageView alloc]init];
background.image = [UIImage imageNamed:#"plain_app-background.png"];
UIImageView *highlightedCellImage = [[UIImageView alloc]init];
highlightedCellImage.image = [UIImage imageNamed:#"HighlightedCellImage"];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"UITableViewCell"];
cell.textLabel.font=[UIFont systemFontOfSize:16.0];
}
RSSItem *item = [[channel items]objectAtIndex:[indexPath row]];
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"EEE, dd MMM yyyy HH:mm:ssZ"];
NSDate *pubDate = [formatter dateFromString:[item date]];
[formatter setDateStyle:NSDateFormatterMediumStyle];
NSString *dateString = [formatter stringFromDate:pubDate];
NSLog(#"Date String: %#", dateString);
[[cell textLabel]setText:[item title]];
[[cell detailTextLabel]setText:dateString];
NSLog(#"Date: %#", [item date]);
tableView.backgroundColor = [UIColor clearColor];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.highlightedTextColor = [UIColor blueColor];
cell.textLabel.font = [UIFont fontWithName:#"FranklinGothicStd-ExtraCond" size:20.0];
cell.textLabel.textColor = [UIColor whiteColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.highlightedTextColor = [UIColor blueColor];
cell.detailTextLabel.font = [UIFont fontWithName:#"FranklinGothicStd-ExtraCond" size:14.0];
cell.detailTextLabel.textColor = [UIColor whiteColor];
cell.backgroundView = image;
cell.selectedBackgroundView = highlightedCellImage;
tableView.backgroundView = background;
DTCustomColoredAccessory *accessory = [DTCustomColoredAccessory accessoryWithColor:cell.textLabel.textColor];
accessory.highlightedColor = [UIColor blueColor];
cell.accessoryView =accessory;
return cell;
}
- (void)fetchEntries
{
// Create a new data container for the stuff that comes back from the service
xmlData = [[NSMutableData alloc]init];
// Construct a URL that will ask the service for what you want
NSURL *url = [NSURL URLWithString:#"http://kyfbnewsroom.com/category/public-affairs/notifications/feed/"];
// Put that URL into an NSURLRequest
NSURLRequest *req = [NSURLRequest requestWithURL:url];
// Create a connection that will exchange this request for data from the URL
connection = [[NSURLConnection alloc]initWithRequest:req delegate:self startImmediately:YES];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self)
{
[self fetchEntries];
}
return self;
}
// This method will be called several times as the data arrives
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
// Add the incoming chunk of data to the container we are keeping
// The data always comes in the correct order
[xmlData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
/* We are just checking to make sure we are getting the XML
NSString *xmlCheck = [[NSString alloc]initWithData:xmlData encoding:NSUTF8StringEncoding];
NSLog(#"xmlCheck = %#", xmlCheck);*/
[SVProgressHUD dismiss];
// Create the parser object with the data received from the web service
NSXMLParser *parser = [[NSXMLParser alloc]initWithData:xmlData];
[parser setDelegate:self];
[parser parse];
// Get rid of the XML data as we no longer need it
xmlData = nil;
// Reload the table.. for now, the table will be empty
NSMutableArray *notActionAlerts = [NSMutableArray array];
for (RSSItem *object in channel.items) {
if (!object.isActionAlert) {
[notActionAlerts addObject:object];
}
}
for (RSSItem *object in notActionAlerts) {
[channel.items removeObject:object];
}
[[self tableView]reloadData];
NSLog(#"%#\n %#\n %#\n", channel, [channel title], [channel infoString]);
}
- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error
{
// Release the connection object, we're done with it
connection = nil;
// Release the xmlData object, we're done with it
xmlData = nil;
[SVProgressHUD dismiss];
// Grab the description of the error object passed to us
NSString *errorString = [NSString stringWithFormat:#"Fetch failed: %#", [error localizedDescription]];
// Create and show an alert view with this error displayed
UIAlertView *av = [[UIAlertView alloc]initWithTitle:#"Error" message:errorString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[[webViewController webView]loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"about:blank"]]];
// Push the web view controller onto the navigation stack - this implicitly creates the web view controller's view the first time through
// [[self navigationController]pushViewController:webViewController animated:YES];
[self.navigationController pushViewController:webViewController animated:YES];
// Grab the selected item
RSSItem *entry = [[channel items]objectAtIndex:[indexPath row]];
// Construct a URL with the link string of the item
NSURL *url = [NSURL URLWithString:[entry link]];
// Construct a request object with that URL
NSURLRequest *req = [NSURLRequest requestWithURL:url];
// Load the request into the web view
[[webViewController webView]loadRequest:req];
webViewController.hackyURL = url;
// Set the title of the web view controller's navigation item
// [[webViewController navigationItem]setTitle:[entry title]];
}
#end
If you're using storyboard for that you have native support for pull-to-refresh.
Only change Refreshing to enabled and then you can hook up an action for this event.
I am working on an app for a game server company and part of the app requires the user to see a list of his or her game servers and whether or not they are online, offline, how many players on them, the server name, etc. This data is all found in a PHP file hosted on the web updated from a MySQL database which when viewed, outputs JSON.
Using the code below, this doesn't seem to work. I load the view and right away get a "Thread 1: signal SIGABRT" error on the line with NSDictionary *myServer = [servers objectAtIndex:indexPath.row];. When removing indexPath.row and replacing it with either a 0 or 1, the data is displayed on the UITableView in my Storyboard, except it is displayed 4 times in a row and only for that entry in the JSON file (either 0 or 1). I can't keep it at a fixed number as the client might have 100 servers, or just 5 servers which is why I need something like indexPath.row. Below, I also attached exactly what the JSON looks like when given from the server and accessed directly from the app's code
I'd really appreciate it if someone could please let me know what the problem is and propose a solution unique to my situation to get rid of this SIGABRT error and once we do, make sure it doesn't show 4 times in the TableView like it is now.
My header file:
#import <UIKit/UIKit.h>
#import "ServerDetailViewController.h"
#interface SecondViewController : UITableViewController {
IBOutlet UITableView *mainTableView;
NSDictionary *news;
NSMutableData *data;
}
#property (weak, nonatomic) IBOutlet UIBarButtonItem *refreshServersButton;
- (IBAction)refreshServers:(id)sender;
#end
My main file:
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"REDACTED"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
data = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
news = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
[mainTableView reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Unable to load server list. Make sure you are connect to either 3G or Wi-Fi or try again later." delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil, nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [news count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIColor *colorGreen = [UIColor colorWithRed:91.0f/255.0f green:170.0f/255.0f blue:101.0f/255.0f alpha:1.0f];
UIColor *colorRed = [UIColor redColor];
static NSString *CellIdentifier = #"MainCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UILabel *serverName = (UILabel *)[cell viewWithTag:100];
UILabel *serverPlayers = (UILabel *)[cell viewWithTag:101];
UILabel *serverStatus = (UILabel *)[cell viewWithTag:102];
UILabel *serverOfflineName = (UILabel *)[cell viewWithTag:103];
serverPlayers.textColor = [UIColor grayColor];
NSDictionary *resultDict = [news objectForKey:#"result"];
NSArray *servers = [resultDict objectForKey:#"servers"];
NSDictionary *myServer = [servers objectAtIndex:indexPath.row];
NSString *titleOfServer = [myServer objectForKey:#"title"];
NSNumber *statusOfServer = [NSNumber numberWithInt:[[myServer objectForKey:#"status"] intValue]];
NSNumber *playersOnServer = [NSNumber numberWithInt:[[myServer objectForKey:#"players"] intValue]];
if ([[statusOfServer stringValue] isEqualToString:#"0"]) {
serverName.text = #"";
serverOfflineName.text = titleOfServer;
serverStatus.textColor = colorRed;
serverStatus.text = #"OFFLINE";
serverPlayers.text = #"";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else if ([[statusOfServer stringValue] isEqualToString:#"1"]) {
serverName.text = titleOfServer;
serverOfflineName.text = #"";
serverStatus.textColor = colorGreen;
serverStatus.text = #"ONLINE";
serverPlayers.text = [playersOnServer stringValue];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else if ([[statusOfServer stringValue] isEqualToString:#"2"]) {
serverName.text = #"";
serverOfflineName.text = titleOfServer;
serverStatus.textColor = [UIColor blueColor];
serverStatus.text = #"BUSY";
serverPlayers.text = #"";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else if ([[statusOfServer stringValue] isEqualToString:#"3"]) {
serverName.text = #"";
serverOfflineName.text = titleOfServer;
serverStatus.textColor = [UIColor grayColor];
serverStatus.text = #"SUSPENDED";
serverPlayers.text = #"";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else if ([[statusOfServer stringValue] isEqualToString:#"-1"]) {
serverName.text = #"";
serverOfflineName.text = titleOfServer;
serverStatus.textColor = [UIColor orangeColor];
serverStatus.text = #"CRITICAL ERROR";
serverPlayers.text = #"";
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ServerDetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"detail"];
[self.navigationController pushViewController:detail animated:YES];
}
- (IBAction)refreshServers:(id)sender {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"REDACTED"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
#end
JSON code from server: {"status":"OK","error":"","debug":"2 server(s)","result":{"servers":[{"id":1,"title":"Test","players":0,"slots":10,"status":3},{"id":2,"title":"Creative Spawn","players":0,"slots":5,"status":-1}]}}
From your code, this looks like the source of error.(However, I didn't read the whole thing.)
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [news count]; //counted number of items in your whole json object.
}
and in your cellForRowAtIndexPath:(NSIndexPath *)indexPath
NSDictionary *resultDict = [news objectForKey:#"result"];
NSArray *servers = [resultDict objectForKey:#"servers"];
// you used a different array(an item of the whole json array).
// Since news object has more items than servers, it caused an out of bound here.
NSDictionary *myServer = [servers objectAtIndex:indexPath.row];
Try doing following to your code
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *resultDict = [news objectForKey:#"result"];
NSArray *servers = [resultDict objectForKey:#"servers"];
return [servers count]; //counted number of items in your whole json object.
}
TL;DR
The reason for the crash, you're using the news.count as the number of rows in the table, yet referencing the indexPath.row in the servers array (which it isn't guaranteed to be).
There's a few things here:
Firstly, this is not a very proficient way of networking, since you support iOS5, I would suggest using the following method (or something similar) :
[NSURLConnection sendAsynchronousRequest:theRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
NSString *dataString = [[NSString alloc] initWithBytes:[data bytes] length:[[data bytes] length] encoding:NSUTF8StringEncoding];
}];
Secondly, I would strongly recommend the MVC model, managing data is not something for a controller - as someone has mentioned, the code at the moment isn't as easy reading as it could be (as well as maintaining it!).
Thirdly, I would recommend you employ more defensive coding, below are the points I've spotted while reading through:
news, well rather [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];,, isn't guaranteed to return a dictionary at all; although it is treated as such
The reason for the crash, you're using the news.count as the number of rows in the table, yet referencing the indexPath.row in the servers array (which it isn't guaranteed to be).
If I were you, I'd probably start with simplifying the networking, followed by created a simple model (for example Server), have the model parse the JSON that's relevant to it. I'd go so far as to include a static method in your Server model, say 'retrieveServers', that returns an NSArray of Server objects.
That way, all your controller is doing is:
[self setNews:[Server retrieveServers]];
[_tableView reloadData];
Rather than having a lot of irrelevant code in your controller - this will increase maintainability and readability.
If you were so inclined, you could take another step, and provide custom accessors, rather than referencing the members directly via the model, for example:
Server *currentServer = nil;
if( self.news.count > indexPath.row ) {
currentServer = [_news objectAtIndex:indexPath.row];
}
[serverPlayers setText:(currentServer ? [currentServer getPlayers] : [Server defaultPlayerValue]]
The code above is being safe with checking that the array has at least the same number of elements in it as we need, and secondly, when assigning the value to the table cell (which may be re-used, and so needs to be set to sane values for every possible branch of execution). The advantages of doing the above: readability, centralised default value, maintainability.
I apologise if this seems rather overkill (TL;DR added ;/), trying to provide some pointers, which would aid in debugging if you see no other reason to employ the tips above.
Now I know what an NSRangeException is. What I dont get is why on the first run through of my code it's fine, but when the same code (and variables) are setup the second time it fails. Even stepping through the code I can't see where it is differing from the first run through.
The whole code gets a set of JSON values from my php api (basically just client information, units booked in, date, etc.) It used to just display it in a UITableView, I decided to group my table by the date it was booked in (Apple should have a nicer way to do this in my opinion, perhaps extending their UITableView?)
my .h
#interface LTBViewController : UIViewController {
IBOutlet UITableView *mainTableView;
NSArray *tickets; //for storing our serialized JSON
NSMutableData *data; //for appending our JSON as we're getting it
NSString *token; //for security authentication with our custom API
NSMutableArray *days; //for storing any days with bookings retrieved from tickets
NSMutableDictionary *groupedTickets; //for storing tickets to correlate to days
NSArray *filteredArray; //for our finalized output
}
#end
most of my .m (the important parts)
- (void)viewDidAppear:(BOOL)animated
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://myurl.com/api/api.php?api=%#&function=%#", token, #"active"]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
//[[NSURLConnection alloc] initWithRequest:request delegate:self]; old way of doing it
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//initialize from our settings file and make sure we're authenticated
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
token = [defaults objectForKey:#"api_token"];
NSLog(#"%#",token);
//initialize our sorting arrays
days = [[NSMutableArray alloc] init];
groupedTickets = [[NSMutableDictionary alloc] init];
filteredArray = [[NSArray alloc] init];
}
- (void)groupTable {
NSUInteger count = 0;
for (LTBViewController *ticket in tickets)
{
NSString *date = [[tickets objectAtIndex:count] objectForKey:#"dateIn"];
if (![days containsObject:date])
{
[days addObject:date];
[groupedTickets setObject:[NSMutableArray arrayWithObject:ticket] forKey:date];
}
else
{
[((NSMutableArray*)[groupedTickets objectForKey:date]) addObject:ticket];
}
count +=1;
}
count = 0;
[mainTableView reloadData];
}
//for when we get a response
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
data = [[NSMutableData alloc] init];
}
//for getting data
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)thedata
{
[data appendData:(thedata)];
}
//for when connection finished
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
tickets = [NSJSONSerialization JSONObjectWithData:data options:NO error:nil];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[self groupTable]; //starts our grouping methods
}
//for when connection fails
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Could not connect to server" delegate:nil cancelButtonTitle:#"dismiss" otherButtonTitles:nil, nil];
[errorView show];
}
//overriding the "delete" text for our UITableView
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
return #"Close Ticket";
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *date = [days objectAtIndex:section];
return date;
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return [days count];
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *date = [days objectAtIndex:section];
NSLog(#"%#", date);
return [[groupedTickets objectForKey:date] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
tableView.layer.cornerRadius = 5.0; //rounds our table corners
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:#"MainCell"];
}
//I'm sure theres a better way to do this but it works for now
NSString *date = [days objectAtIndex:[indexPath section]];
NSPredicate *search = [NSPredicate predicateWithFormat:#"dateIn == %#", date];
filteredArray = [tickets filteredArrayUsingPredicate:search];
//this right here is what fails the second time through at index 1
cell.textLabel.text = [NSString stringWithFormat:#"%#",[[filteredArray objectAtIndex:[indexPath row]] objectForKey:#"ticketnumber"] ];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", [[filteredArray objectAtIndex:[indexPath row]] objectForKey:#"customerName"]];
return cell;
}
When an item is clicked it moves to another view controller (that works alright) but when the back button is pressed from it is where this code fails. I would be appreciative of any extra sets of eyes going over it and helping me find my error. (or a better way of doing this)
Thanks!
Got it. I thought when I reassigned values to my NSMutableArray days and NSMutableDictionary groupedTickets it would just overwrite the previous values.
I performed release on view will disappear and it works now.
Still if there's a better way to do this I'd be interested in learning it.
Why doesn't my program work in NSURLConnection before tableView?
// MyLoxFileTVContoller.m
#import "MyLoxFileTVContoller.h"
#import "xml_myloxfile.h"
#import "DetailViewController.h"
#implementation MyLoxFileTVContoller
#synthesize myloxfileArray;
#synthesize exportId_data_Array,readFG_data_Array,receiverId_data_Array,referenceId_data_Array,referenceName_data_Array,reportFullPath_data_Array,reportName_data_Array,senderId_data_Array,senderName_data_Array,sentDate_data_Array,subject_data_Array;
#synthesize detailViewController;
#synthesize window = _window;
#synthesize navigationController;
#synthesize delegate;
#synthesize unReadCount;
#synthesize webData;
-(void)doParse{
NSLog(#"doParse"); //debug
[myloxfileArray removeAllObjects];
NSString *soapMessage = [NSString stringWithFormat:
#"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:con=\"http://controller.exportingreportwebservice.lox.org/\">\n"
"<soapenv:Header/>\n"
"<soapenv:Body>\n"
"<con:getReport>\n"
"<arg0>%#</arg0>\n"
"</con:getReport>\n"
"</soapenv:Body>\n"
//"</soapenv:Envelope>\n", nameInput.text
"</soapenv:Envelope>\n", #"2711"
];
//NSLog(soapMessage);
NSURL *url = [NSURL URLWithString:#"http://iloxley.loxley.co.th:8081/ExportingReportWebservice/ExportingReportWebservice?wsdl"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:#"%d", [soapMessage length]];
[theRequest addValue: #"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection )
{
NSLog(#"if theConnection"); //debug
webData = [NSMutableData data];
}
else
{
NSLog(#"theConnection is NULL");
}
NSLog(#"end doParse"); //debug
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(#"connection didReceiveResponse"); //debug
[webData setLength: 0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(#"connection didReceiveData"); //debug
[webData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"ERROR with theConenction");
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"connectionDidFinishLoading"); //debug
NSLog(#"DONE. Received Bytes: %d", [webData length]);
NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
//NSLog(#"theXML = %# ", theXML);
//NSLog(#"webData = %# ", webData);
//NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithContentsOfURL:theXML];
NSXMLParser *nsXmlParser = [[NSXMLParser alloc] initWithData: webData];
// create and init our delegate
xml_myloxfile_Parser *parser = [[xml_myloxfile_Parser alloc] initXMLParser];
//set delegate
[nsXmlParser setDelegate:parser];
//parsing...
BOOL success = [nsXmlParser parse];
if (success) {
NSLog(#"if success"); //debug
exportId_data_Array = [parser getExportId_data_Array];
readFG_data_Array = [parser getReadFG_data_Array];
receiverId_data_Array = [parser getReceiverId_data_Array];
referenceId_data_Array = [parser getReferenceId_data_Array];
referenceName_data_Array = [parser getReferenceName_data_Array];
reportFullPath_data_Array = [parser getReportFullPath_data_Array];
reportName_data_Array = [parser getReportName_data_Array];
senderId_data_Array = [parser getSenderId_data_Array];
senderName_data_Array = [parser getSenderName_data_Array];
sentDate_data_Array = [parser getSentDate_data_Array];
subject_data_Array = [parser getSubject_data_Array];
items_exportId = exportId_data_Array;
items_readFG = readFG_data_Array;
items_receiverId = receiverId_data_Array;
items_referenceId = referenceId_data_Array;
items_referenceName = referenceName_data_Array;
items_reportFullPath = reportFullPath_data_Array;
items_reportName = reportName_data_Array;
items_senderId = senderId_data_Array;
items_senderName = senderName_data_Array;
items_sentDate = sentDate_data_Array;
items_subject = subject_data_Array;
NSLog(#"items_subject = %# ", items_subject);
} else {
NSLog(#"fail");
}
}
-(void) loadView
{
NSLog(#"loadView"); //debug
if (items_subject == nil) {
//items_subject = [NSMutableArray arrayWithObjects:#"1",#"2",#"3",nil];
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"numberOfSectionsInTableView"); //debug
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"tableView numberOfRowsInSection"); //debug
// Return the number of rows in the section.
NSLog(#"[items_subject count] = %d ", [items_subject count]);
return [items_subject count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"tableView cellForRowAtIndexPath"); //debug
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
//cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
cell.textLabel.text = [NSString stringWithFormat:#"%#" ,[items_subject objectAtIndex:indexPath.row]];
// Populate the cell's detail text label.
NSString *detailText = [NSString stringWithFormat:#"date: %# from: %# reference: %#",
[[items_sentDate objectAtIndex:indexPath.row] lowercaseString],[[items_senderName objectAtIndex:indexPath.row] lowercaseString],[[items_referenceName objectAtIndex:indexPath.row] lowercaseString]];
[[cell detailTextLabel] setText:detailText];
//CGAffineTransform translate = CGAffineTransformMakeTranslation(10.0, 0.0);
//[[cell detailTextLabel] setTransform:translate];
//unReadCount = 0;
if([[items_readFG objectAtIndex:indexPath.row] isEqualToString:#"N"]){
cell.textLabel.textColor = [UIColor redColor];
unReadCount = unReadCount+1;
}else{
cell.textLabel.textColor = [UIColor blackColor];
unReadCount = unReadCount;
}
NSLog(#"unReadCount = %d ",unReadCount);
//Adding A Badge Number
//[[UIApplication sharedApplication] setApplicationIconBadgeNumber:unReadCount];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"tableView didSelectRowAtIndexPath"); //debug
//sof2
DetailViewController *detailController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
[detailController changeExportIdText:[exportId_data_Array objectAtIndex:indexPath.row]];
[detailController changeReadFGText:[readFG_data_Array objectAtIndex:indexPath.row]];
[detailController changeReceiverIdText:[receiverId_data_Array objectAtIndex:indexPath.row]];
[detailController changeReferenceIdText:[referenceId_data_Array objectAtIndex:indexPath.row]];
[detailController changeReferenceNameText:[referenceName_data_Array objectAtIndex:indexPath.row]];
[detailController changeReportFullPathText:[reportFullPath_data_Array objectAtIndex:indexPath.row]];
[detailController changeReportNameText:[reportName_data_Array objectAtIndex:indexPath.row]];
[detailController changeSenderIdText:[senderId_data_Array objectAtIndex:indexPath.row]];
[detailController changeSenderNameText:[senderName_data_Array objectAtIndex:indexPath.row]];
[detailController changeSentDateText:[sentDate_data_Array objectAtIndex:indexPath.row]];
[detailController changeSubjectText:[subject_data_Array objectAtIndex:indexPath.row]];
//[tableView deselectRowAtIndexPath:indexPath animated:YES];
if([delegate respondsToSelector:#selector(showItemDetails:)])
{
//[delegate showItemDetails:[subject_data_Array objectAtIndex:indexPath.row]];
[delegate showItemDetails:[NSString stringWithFormat:#"%#||%#||%#||%#||%#||%#||%#||%#||%#||%#||%#"
,[exportId_data_Array objectAtIndex:indexPath.row]
,[readFG_data_Array objectAtIndex:indexPath.row]
,[receiverId_data_Array objectAtIndex:indexPath.row]
,[referenceId_data_Array objectAtIndex:indexPath.row]
,[referenceName_data_Array objectAtIndex:indexPath.row]
,[reportFullPath_data_Array objectAtIndex:indexPath.row]
,[reportName_data_Array objectAtIndex:indexPath.row]
,[senderId_data_Array objectAtIndex:indexPath.row]
,[senderName_data_Array objectAtIndex:indexPath.row]
,[sentDate_data_Array objectAtIndex:indexPath.row]
,[subject_data_Array objectAtIndex:indexPath.row]
]];//test multi var'
}
// Alert will pop up when using Simulator or iPod Touch for example
/*
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[note_subject_data_Array objectAtIndex:indexPath.row] message:#"Test" delegate:nil cancelButtonTitle:#"Close" otherButtonTitles:nil];
[alert show];
*/
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete;
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
NSLog(#"viewDidLoad"); //debug
[self doParse];
[super viewDidLoad];
}
- (void)viewDidUnload
{
NSLog(#"viewDidUnload"); //debug
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return YES;
}
#end
The log:
2012-09-11 15:27:15.377 MyLoxFile[2698:f803] loadView
2012-09-11 15:27:15.378 MyLoxFile[2698:f803] viewDidLoad
2012-09-11 15:27:15.379 MyLoxFile[2698:f803] doParse
2012-09-11 15:27:15.382 MyLoxFile[2698:f803] if theConnection
2012-09-11 15:27:15.382 MyLoxFile[2698:f803] end doParse
2012-09-11 15:27:15.385 MyLoxFile[2698:f803] numberOfSectionsInTableView
2012-09-11 15:27:15.386 MyLoxFile[2698:f803] tableView numberOfRowsInSection
2012-09-11 15:27:15.391 MyLoxFile[2698:f803] [items_subject count] = 0
2012-09-11 15:27:15.454 MyLoxFile[2698:f803] connection didReceiveResponse
2012-09-11 15:27:15.455 MyLoxFile[2698:f803] connection didReceiveData
2012-09-11 15:27:15.455 MyLoxFile[2698:f803] connectionDidFinishLoading
2012-09-11 15:27:15.455 MyLoxFile[2698:f803] DONE. Received Bytes: 1948
2012-09-11 15:27:15.457 MyLoxFile[2698:f803] if success
2012-09-11 15:27:15.457 MyLoxFile[2698:f803] items_subject = (
"Surgical Report ",
"Genotype Report",
"HPV Report"
)
It has data in array but not have in tableView numberOfRowsInSection
Before this code i use XML (not WSDL) it's work
This is My Code -> http://www.vasuta.com/ios/MyLoxFile.zip
It seems like your tableview is load et call its delegates methods before your NSURLConnection finished downloading.
You have launch NSURLConnection by
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
so the connection is asynchronous. You can't be sure whether it finishes before or after your tableview loads its view.
But your can always do a check in your tableview methods to make your app work. For example:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int nbCount = [items_subject count];
if (nbCount == 0)
return 1;
else
return [items_subject count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int nbCount = [items_subject count];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
if (nbCount ==0)
cell.textLabel.text == #"Loading";
else
{
// your configuration
cell.textLabel.text = [NSString stringWithFormat:#"%#" ,[items_subject objectAtIndex:indexPath.row]];
}
return cell;
}
In your method "ConnectionDidFinishLoading", then your can call [tableview reloaddata] to update your tableview.
[EDIT] on 12/09/2012
I've got your code work(not a nice solution), you should rethink how you organize your viewControllers.
add the IBOutlet TableView to myloxfileController.tableView.
add this line myloxfileContoller.tableView = myloxfileTable; after the line myloxfileContoller.view = myloxfileContoller.tableView; in - (void)viewDidLoad of the interface ViewController .
reload tableview data when connection finished.
add this line [self.tableView reloadData]; after the line items_subject = subject_data_Array; in -(void)connectionDidFinishLoading:(NSURLConnection *)connection of the interface MyLoxFileTVController .
This will work because when the download finished, you reloadData of the IBOutlet TableView.
Have you used [uitableview reloadData] after updating your NSArray?
replace with
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"tableView numberOfRowsInSection"); //debug
// Return the number of rows in the section.
NSLog(#"[items_subject count] = %# ", [items_subject count]);
return [items_subject count];
}