Error creating row in tableview.
My table view is loaded with a json.
I saw many examples here, however none were able to solve
my code
NSMutableArray *myArray = [NSMutableArray arrayWithArray:news];
[myArray insertObject:#"teste" atIndex:0];
NSMutableArray *path = [NSMutableArray arrayWithObject:[NSIndexPath indexPathForRow:[news count]-1 inSection:1]];
[self.tableView insertRowsAtIndexPaths:path withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
error displayed
2013-05-30 23:15:17.345 lerJson[1141:c07] * Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableView.m:908
2013-05-30 23:15:17.347 lerJson[1141:c07] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert row 11 into section 1, but there are only 1 sections after the update'
** First throw call stack:
(0x1c95012 0x10d2e7e 0x1c94e78 0xb68665 0xb670b 0xc4945 0xc4973 0x476d 0x76d78 0x789eb 0x2e185a 0x2e099b 0x2e20df 0x2e4d2d 0x2e4cac 0x2dca28 0x49972 0x49e53 0x27d4a 0x19698 0x1bf0df9 0x1bf0ad0 0x1c0abf5 0x1c0a962 0x1c3bbb6 0x1c3af44 0x1c3ae1b 0x1bef7e3 0x1bef668 0x16ffc 0x26ad 0x25d5)
libc++abi.dylib: terminate called throwing an exception
My full code j2_ViewController.h
#import "j2_ViewController.h"
#interface j2_ViewController ()
#end
#implementation j2_ViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self carregaDados];
}
-(void)carregaDados
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url2 = [[NSURL alloc] initWithString:[#"http://localhost:3000/json.aspx?ind=0&tot=12" stringByAddingPercentEscapesUsingEncoding:NSISOLatin1StringEncoding]];
NSURLRequest *request = [NSURLRequest requestWithURL:url2];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
-(void)carregaDados2
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url2 = [[NSURL alloc] initWithString:[#"http://localhost:3000/json.aspx?ind=12&tot=12" stringByAddingPercentEscapesUsingEncoding:NSISOLatin1StringEncoding]];
NSURLRequest *request = [NSURLRequest requestWithURL:url2];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSError *jsonParsingError = nil;
NSMutableData *myData = [[NSMutableData alloc]init];
[myData appendData:response];
NSMutableArray *news2;
news2 = [NSJSONSerialization JSONObjectWithData:myData options:nil error:&jsonParsingError];
//NSLog(#"LOG: %#", news2);
NSMutableArray *myArray = [NSMutableArray arrayWithArray:news];
[myArray addObjectsFromArray:news2];
NSLog(#"LOG: %#", myArray);
news = myArray;
//NSLog(#"Erro: %#", jsonParsingError);
[tableViewjson reloadData];
}
- (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;
NSError *e = nil;
news = [NSJSONSerialization JSONObjectWithData:data options:nil error:&e];
[tableViewjson reloadData];
//NSLog(#"erro=%#",e);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Erro" message:#"Não foi possivle fazer o download - cheque sua conexão 3g ou wi-fi" delegate:nil cancelButtonTitle:#"cancelar" otherButtonTitles:nil];
[alert show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSInteger teste = [news count];
return teste;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"celula";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [[news objectAtIndex:indexPath.row] objectForKey:#"nome"];
return cell;
}
//chama essa função quando o scroll atinge seu final
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
NSInteger currentOffset = scrollView.contentOffset.y;
NSInteger maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height;
if(maximumOffset - currentOffset <= -40)
{
//carega mais dados
//[self carregaDados2];
[self.tableView beginUpdates];
NSMutableArray *myArray = [NSMutableArray arrayWithArray:news];
[myArray insertObject:#"teste" atIndex:0];
NSMutableArray *path = [NSMutableArray arrayWithObject:[NSIndexPath indexPathForRow:[news count]-1 inSection:1]];
[self.tableView insertRowsAtIndexPaths:path withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
}
#end
My delegation has not changed
You also need to update your datasource like this:
[news insertObject:#"teste" atIndex:0];
I assume you only have 1 section.
change this code: NSMutableArray *path = [NSMutableArray arrayWithObject:[NSIndexPath indexPathForRow:[news count] inSection:1]];
to this code: NSMutableArray *path = [NSMutableArray arrayWithObject:[NSIndexPath indexPathForRow:[news count] inSection:0]];
sections and rows starts at 0.
Related
I understand that I need to change the data in the data source before calling reloadData. My problem is that I'm not sure how this is done and why my getData method doesn't overwrite the current cells. Is it necessary to use subviews for this? Or is there a way to reset the cells when refresh is called to just create a new set of data?
#property (nonatomic,strong) NSMutableArray *objectHolderArray;
#end
#implementation MartaViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self getData];
//to add the UIRefreshControl to UIView
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:#"Please Wait..."];
[refreshControl addTarget:self action:#selector(refresh:) forControlEvents:UIControlEventValueChanged];
}
- (void)getData
{
NSURL *blogURL = [NSURL URLWithString:JSON_URL];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization
JSONObjectWithData:jsonData options:0 error:&error];
for (NSDictionary *bpDictionary in dataDictionary) {
Object *currenHotel = [[Object alloc]Station:[bpDictionary objectForKey:#"station"] Status:[bpDictionary objectForKey:#"status"]];
[self.objectHolderArray addObject:currenHotel];
}
}
- (IBAction)refresh:(UIRefreshControl *)sender {
[self getData];
[self.tableView reloadData];
[sender endRefreshing];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section
{
return [self.objectHolderArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MartaViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
Object *currentHotel = [self.objectHolderArray
objectAtIndex:indexPath.row];
cell.lblStation.text = currentHotel.station;
cell.lblStatus.text = currentHotel.status;
return cell;
}
-(NSMutableArray *)objectHolderArray{
if(!_objectHolderArray) _objectHolderArray = [[NSMutableArray alloc]init];
return _objectHolderArray;
}
#end
Because you are adding objects to self.objectHolderArray instead of overwriting in getData method. Try this
- (void)getData
{
NSURL *blogURL = [NSURL URLWithString:JSON_URL];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization
JSONObjectWithData:jsonData options:0 error:&error];
[self.objectHolderArray removeAllObjects];
for (NSDictionary *bpDictionary in dataDictionary) {
Object *currenHotel = [[Object alloc]Station:[bpDictionary objectForKey:#"station"] Status:[bpDictionary objectForKey:#"status"]];
[self.objectHolderArray addObject:currenHotel];
}
}
First initialize the array in viewDidLoad self.objectArray = [NSMutlabelArray alloc] init] and when you are refreshing the table view remove all objects from object array using [self.orderArray removeAllObject] the copy new content in new array.
I have created a app that fetches information from a blog and shows it in the app. After i fetch the data it is supposed to be shown on the table view. It shows the things that i have posted but the things are in alphabetical order rather than the time i posted the thing.
Here is the code
#implementation EventsTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.firstLettersArray = [NSMutableArray array];
self.eventsDictionary = [NSMutableDictionary dictionary];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self searchForEvents];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[self searchForEvents];
}
- (void)searchForEvents
{
[self.searchBar resignFirstResponder];
NSString *eventsSearchUrlString = [NSString stringWithFormat:#"https://www.googleapis.com/blogger/v3/blogs/1562818803553764290/posts?key=AIzaSyBTOxz-vPHgzIkw9k88hDKd99ILTaXTt0Y"];
NSURL *eventsSearchUrl = [NSURL URLWithString:eventsSearchUrlString];
NSURLRequest *eventsSearchUrlRequest = [NSURLRequest requestWithURL:eventsSearchUrl];
NSURLSession *sharedUrlSession = [NSURLSession sharedSession];
NSURLSessionDataTask *searchEventsTask =
[sharedUrlSession dataTaskWithRequest:eventsSearchUrlRequest completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error)
{
dispatch_async(dispatch_get_main_queue(),
^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
if(error)
{
UIAlertView *searchAlertView = [[UIAlertView alloc] initWithTitle:#"Error" message:error.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[searchAlertView show];
}
else
{
NSString *resultString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Search results: %#", resultString);
NSError *jsonParseError = nil;
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonParseError];
if(jsonParseError)
{
UIAlertView *jsonParseErrorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:jsonParseError.localizedDescription delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[jsonParseErrorAlert show];
}
else
{
for(NSString *key in jsonDictionary.keyEnumerator)
{
NSLog(#"First level key: %#", key);
}
[self.firstLettersArray removeAllObjects];
[self.eventsDictionary removeAllObjects];
NSArray *searchResultsArray = [jsonDictionary objectForKey:#"items"];
//NSLog(#"test%#",searchResultsArray);
for(NSDictionary *eventsInfoDictionary in searchResultsArray)
{
Events *event = [[Events alloc] init];
event.eventName = [eventsInfoDictionary objectForKey:#"title"];
event.eventDescription =[eventsInfoDictionary objectForKey:#"content"];
NSLog(#"Event Name : %#",event.eventName);
NSLog(#"Event Description : %#",event.eventDescription);
NSString *eventsFirstLetter = [event.eventName substringToIndex:1];
NSMutableArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:eventsFirstLetter];
if(!eventsWithFirstLetter)
{
eventsWithFirstLetter = [NSMutableArray array];
[self.firstLettersArray addObject:eventsFirstLetter];
}
[eventsWithFirstLetter addObject:event];
[self.eventsDictionary setObject:eventsWithFirstLetter forKey:eventsFirstLetter];
if ([event.eventDescription containsString:#"<br />"]) {
NSString* eventDescrip = event.eventDescription;
NSString* stringWithoutHTMLtags = [eventDescrip stringByReplacingOccurrencesOfString:#"<br />" withString:#""];
event.eventDescription = stringWithoutHTMLtags;
}
NSLog(#"Event Name : %#",event.eventName);
NSLog(#"Event Description : %#",event.eventDescription);
}
[self.firstLettersArray sortUsingSelector:#selector(compare:)];
[self.tableView reloadData];
}
}
});
}];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[searchEventsTask resume];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.firstLettersArray.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *firstLetter = [self.firstLettersArray objectAtIndex:section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
return eventsWithFirstLetter.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"eventTitleCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *firstLetter = [self.firstLettersArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
Events *event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
cell.textLabel.text = event.eventName;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
/*
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = cell.textLabel.text;
NSLog(#"Row selected %#",cellText);*/
NSString *firstLetter = [self.firstLettersArray objectAtIndex:indexPath.section];
NSArray *eventsWithFirstLetter = [self.eventsDictionary objectForKey:firstLetter];
Events *event = [eventsWithFirstLetter objectAtIndex:indexPath.row];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle: nil];
DescriptionViewController *descriptionViewController = (DescriptionViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: #"descriptionController"];
descriptionViewController.eventNameDesc = event.eventDescription;
descriptionViewController.navigationItem.title = event.eventName;
[self.navigationController pushViewController:descriptionViewController animated:YES];
}
#end
You are trying to sort firstLettersArray which contain Events objects by using standard sort: function which doesn't know how to work with your custom objects.
You can use sortedArrayUsingComparator: function like this:
[firstLettersArray sortedArrayUsingComparator:^NSComparisonResult(Events *obj1, Events *obj2) {
// return object comparison result here
}];
Edit: Also you need to have NSDate property in Events class and feel it with event created time. I believe event created time should be contained in eventsInfoDictionary. Eventually you will be able to compare obj1 and obj2 using NSDate property.
i think this line not working
[self.firstLettersArray sortUsingSelector:#selector(compare:)];
use this line of code may help you....
sortedArray = [anArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
I'm trying to filter the data of my Table View which is calling a JSON-file and parses the data to the Table View. I'm getting some strange errors. Here's my code:
#import "FacebookViewController.h"
#import "RNBlurModalView.h"
#import "FacebookPost.h"
#import "TwitterPost.h"
#define CELL_CONTENT_WIDTH 320.0f
#define CELL_CONTENT_MARGIN 10.0f
#define FONT_SIZE 14.0f
#interface FacebookViewController ()
{
NSInteger refreshIndex;
NSArray *fbPost;
NSArray *pic;
}
#end
#implementation FacebookViewController
#synthesize tweets;
- (void)refreshChannels:(id)sender {
if (tweets.count == 0) return;
// disable UI
self.title = #"Updating...";
self.navigationController.view.userInteractionEnabled = YES;
refreshIndex = 0;
}
- (void) reloadFB {
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *button = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh
target:self
action:#selector(refreshChannels:)];
self.navigationItem.rightBarButtonItem = button;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Menu" style:UIBarButtonItemStyleBordered target:self action:#selector(showMenu)];
UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(swipeHandler:)];
[self.view addGestureRecognizer:gestureRecognizer];
self.myTableView.separatorColor = [UIColor clearColor];
[self issueLoadRequest];
}
- (void)swipeHandler:(UIPanGestureRecognizer *)sender
{
[[self sideMenu] showFromPanGesture:sender];
}
#pragma mark -
#pragma mark Button actions
- (void)showMenu
{
[[self sideMenu] show];
}
#pragma mark - Table view data source
- (void)issueLoadRequest
{
if (changeData.selectedSegmentIndex == 1) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://my-site-facebookparse.php?person=Person"]];
[self performSelectorOnMainThread:#selector(receiveData:) withObject:data waitUntilDone:YES];
});
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://my-site-twitterparse.php?person=Person"]];
[self performSelectorOnMainThread:#selector(receiveData:) withObject:data waitUntilDone:YES];
});
}
}
- (void)receiveData:(NSData *)data {
if (changeData.selectedSegmentIndex == 1) {
self.tweets = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
[self.myTableView reloadData];
} else {
self.tweets1 = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
[self.myTableView reloadData];
}
}
- (void)receiveTwitter:(NSData *)data {
// When we have the data, we serialize it into native cocoa objects. (The outermost element from twitter is
// going to be an array. I JUST KNOW THIS. Reload the tableview once we have the data.
self.tweets1 = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
[self.myTableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (changeData.selectedSegmentIndex == 1) {
return self.tweets.count;
} else {
return self.tweets1.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"FacebookPost";
// The element in the array is going to be a dictionary. I JUST KNOW THIS. The key for the tweet is "text".
NSDictionary *tweet = [self.tweets objectAtIndex:indexPath.row];
NSDictionary *tweet1 = [self.tweets1 objectAtIndex:indexPath.row];
FacebookPost *cell = (FacebookPost *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"FacebookPost" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (changeData.selectedSegmentIndex == 1) {
cell.fbPost.text = [tweet objectForKey:#"message"];
} else {
cell.fbPost.text = [tweet1 objectForKey:#"tweet"];
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 90;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (changeData.selectedSegmentIndex == 1) {
//Open the link
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
NSString * storyLink = [[tweets objectAtIndex: storyIndex] objectForKey:#"message"];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:storyLink]];
RNBlurModalView *modal = [[RNBlurModalView alloc] initWithViewController:self title:#"Message" message:storyLink];
[modal show];
NSString *formattedJSON = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:[self.tweets objectAtIndex:indexPath.row] options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding];
NSLog(#"tweet:\n%#", formattedJSON);
} else {
//Öppna länken eller liknande
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
NSString * storyLink = [[tweets objectAtIndex: storyIndex] objectForKey:#"tweet"];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:storyLink]];
RNBlurModalView *modal = [[RNBlurModalView alloc] initWithViewController:self title:#"Message" message:storyLink];
[modal show];
// Spit out some pretty JSON for the tweet that was tapped. Neato.
NSString *formattedJSON = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:[self.tweets objectAtIndex:indexPath.row] options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding];
NSLog(#"tweet:\n%#", formattedJSON);
}
}
#end
The table view data is downloading the Twitter post on the launch, even if I have set it to download the Facebook posts. It's very strange... Please help me fix this!
There's a couple of things you need to do. Firstly, you need to set the selected segment index. Before you call [self issueLoadRequest] in viewDidLoad, you should set the selected index like this:
changeData.selectedSegmentIndex = 0;
This will set the first segment to be the selected segment. Also, you'll need to make sure the correct data is loaded when you change the selected segment. To do that, you should add the following to viewDidLoad:
[changeData addTarget:self action:#selector(segmentedControlSelectedIndexChanged:) forControlEvents:UIControlEventValueChanged];
And the companying method, segmentedControlSelectedIndexChanged:
- (void)segmentedControlSelectedIndexChanged:(id)sender
{
[self issueLoadRequest];
}
Now whenever you changed between the Facebook segment and the Twitter segment, it will call the corresponding API, download the data, and update the table view. Depending on the speed on your connection, there may be a small, but noticeable delay between selecting the segment and the table view updating.
I'm usin Kal https://github.com/klazuka/Kal to implement a calendar. I'm using storyboard, so I add KalViewController as a child to the container view controller.
kal.delegate = self;
kal.dataSource = dataSource;
dataSource = [[CalendarDataSourceDelegate alloc] init];
kal = [[KalViewController alloc] init];
[self addChildViewController:kal];
[kal didMoveToParentViewController:self];
[self.calendarioView addSubview:kal.view];
[clickEvent insertPrintAdd:zona_competicion];
I use an external object as datasource delegate, but after fetching data from my backend by webservice, I don't know how to call delegates to load calendar with fetched data:
#implementation CalendarDataSourceDelegate
- (id)init
{
if ((self = [super init])) {
items = [[NSMutableArray alloc] init];
matches = [[NSMutableArray alloc] init];
buffer = [[NSMutableData alloc] init];
}
[self fetchHolidays];
return self;
}
- (eventMatch *)eventAtIndexPath:(NSIndexPath *)indexPath
{
return [items objectAtIndex:indexPath.row];
}
#pragma mark UITableViewDataSource protocol conformance
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"MyCell";
eventNoAddedCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[eventNoAddedCell alloc] initWithStyle:UITableViewCellSelectionStyleNone reuseIdentifier:identifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
}
eventMatch *event = [self eventAtIndexPath:indexPath];
cell.escudoLocal.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#.png",event.equipoLocal ]];
cell.escudoVis.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#.png",event.equipoVisitante ]];
cell.equipoLocal.text = event.equipoLocal;
cell.equipoVisitante.text = event.equipoVisitante;
cell.competicion.text = event.competicion;
cell.jornada.text = event.jornada;
cell.hora.text = event.hora;
cell.canalesTV.text = event.canalesTV;
[self fetchHolidays];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [items count];
}
#pragma mark Fetch from the internet
- (void)fetchHolidays
{
NSString *urlStr = [NSString stringWithFormat:#"http://backend.exular.net/contenido/webservices/xlr_ws_calendario.php?idp=105"];
dataReady = NO;
[matches removeAllObjects];
conn = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]] delegate:self];
[conn start];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[buffer setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[buffer appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error=nil;
NSDictionary *tempDic = [NSJSONSerialization JSONObjectWithData:buffer options:kNilOptions error:&error];
NSArray *array = [tempDic valueForKey:#"nodes"];
NSDateFormatter *fmt = [[NSDateFormatter alloc] init] ;
[fmt setDateFormat:#"dd/MM/yyyy"];
for (NSDictionary *jornada in array) {
NSDate *d = [fmt dateFromString:[jornada objectForKey:#"fecha"]];
[matches addObject:[eventMatch equipoVisitante:[jornada valueForKey:#"id_visitante"] equipoLocal:[jornada valueForKey:#"id_local"] resultadoVisitante:[jornada valueForKey:#"res_visitante"] resultadoLocal:[jornada valueForKey:#"res_local"] canalesTV:[jornada valueForKey:#"cadenas"] date:d time:[jornada valueForKey:#"hora"] jornada:[jornada valueForKey:#"jornada"] competicion:[jornada valueForKey:#"competicion"]]]; }
dataReady = YES;
[callback loadedDataSource:self];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"HolidaysCalendarDataSource connection failure: %#", error);
}
#pragma mark KalDataSource protocol conformance
- (void)presentingDatesFrom:(NSDate *)fromDate to:(NSDate *)toDate delegate:(id<KalDataSourceCallbacks>)delegate
{
/*
* In this example, I load the entire dataset in one HTTP request, so the date range that is
* being presented is irrelevant. So all I need to do is make sure that the data is loaded
* the first time and that I always issue the callback to complete the asynchronous request
* (even in the trivial case where we are responding synchronously).
*/
if (dataReady) {
[callback loadedDataSource:self];
return;
}
callback = delegate;
[self fetchHolidays];
}
- (NSArray *)markedDatesFrom:(NSDate *)fromDate to:(NSDate *)toDate
{
if (!dataReady)
return [NSArray array];
return [[self matchesFrom:fromDate to:toDate] valueForKeyPath:#"date"];
}
- (void)loadItemsFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate
{
if (!dataReady)
return;
[items addObjectsFromArray:[self matchesFrom:fromDate to:toDate]];
}
- (void)removeAllItems
{
[items removeAllObjects];
}
#pragma mark -
- (NSArray *)matchesFrom:(NSDate *)fromDate to:(NSDate *)toDate
{
NSMutableArray *matchesUpdate = [NSMutableArray array];
for (eventMatch *match in matches)
if (IsDateBetweenInclusive(match.date, fromDate, toDate))
[matchesUpdate addObject:match];
return matches;
}
- (void)dealloc
{
matches=nil;
}
First, I find strange that you alloc your KalViewController after using it, I would do it just in the opposite order:
kal = [[KalViewController alloc] init];
kal.delegate = self;
kal.dataSource = dataSource;
And then why don't you just call?:
[kal reloadData];
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];
}