UITableview sorted in sections by distinct date - objective-c

I am getting events from a Shared Google Calendar into my App using JSON. On some dates there are 2 or more events. As you can see here - the dates (found under {gd$when}, {startDate} are in a long format (2013-04-28T19:00:00.000+02:00).
I would need each section to be a date in the format dd-MM-yy. Then the cell.textLabel.Text would be the Title/$t, and the cell.detailTextLabel.Text would be the time (hh:mm) from gd$when/startTime. I would only want to show those that are equal to or after todays date.
I have played around with it, to match a tutorial on raywenderlich.com. My code right now looks like this, but I haven't yet implemented it into a tableviewcontroller
#define kBgQueue dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define googleURL [NSURL URLWithString: #"http://www.google.com/calendar/feeds/kao1d80fd2u5kh7268caop11o4%40group.calendar.google.com/public/full?alt=json"]
#import "ViewController.h"
#interface ViewController () {
IBOutlet UILabel* humanReadble;
IBOutlet UILabel* jsonSummary;
}
#end
#implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:googleURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
//parse out the JSON data
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSArray* feed = [json valueForKeyPath:#"feed.entry"];
NSLog(#"feed: %#", feed);
for (int i=0; i<[feed count]; i++) {
NSDictionary* event = [feed objectAtIndex:i];
NSString* eventTitle = [event valueForKeyPath:#"title.$t"];
NSLog(#"Title: %#", eventTitle);
}
}
#end
If anybody can give a pointer - especially as to how I would create the sections from the date, it would be highly appreciated

Where as my suggestion says to you create the number of section as you get number of dates you get, and in each section you have to put number of events that would be the number of rows at each section. which you will declare at
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
and after this put the view for each header like this-
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
headerView=[[UIView alloc] init];
headerView.tag=section+1000;
headerView.backgroundColor=[UIColor clearColor];
UILabel *labelInHeader=[[UILabel alloc] init];
labelInHeader.backgroundColor=[UIColor clearColor];
labelInHeader.adjustsFontSizeToFitWidth=YES;
labelInHeader.minimumScaleFactor=13.00;
labelInHeader.textColor=[UIColor blackColor];
labelInHeader.textAlignment=NSTextAlignmentCenter;
labelInHeader.font=[UIFont fontWithName:FONTCENTURYGOTHICBOLD size:20.0];
labelInHeader.frame=CGRectMake(30, 0, 229,47);
labelInHeader.lineBreakMode=NSLineBreakByWordWrapping;
labelInHeader.numberOfLines=2;
[headerView addSubview:labelInHeader];
return headerView;
}
Hope this helps.

Related

Populating Custom TableViewCell from Twitter using JSON Serialization

I am new to Objective-C. I spent countless hours being stuck on getting a blank tableview, I am desperate at this point.
I am loading twitter data through a JSON call, using their API. I store everything in a NSDictionary, run a for loop to select only "text" values. I store the filtered dictionary in an object which I later use in the TableView initialization.
I created a subclass of UItableViewCell for my custom cell.
My dataSources and delegates seem to be well connected as well (that is what I think at least)
I am having a hard time finding my problem. If someone could help me out please.
#import "ViewController.h"
#import "myCell.h"
#import <TwitterKit/TwitterKit.h>
#interface ViewController ()
#end
#implementation ViewController
#synthesize myTableView;
NSMutableArray *tweetObject;
NSDictionary *dictionary;
NSString *name;
NSString *text;
- (void)viewDidLoad {
tweetObject = [[NSMutableArray alloc] init];
[super viewDidLoad];
self.myTableView.dataSource = self;
self.myTableView.delegate = self;
text = #"text";
[[Twitter sharedInstance] logInGuestWithCompletion:^(TWTRGuestSession *guestSession, NSError *error) {
if (guestSession) {
// make API calls that do not require user auth
NSString *statusesShowEndpoint = #"https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=goofernator";
NSError *clientError;
NSURLRequest *request = [[[Twitter sharedInstance] APIClient]
URLRequestWithMethod:#"GET"
URL:statusesShowEndpoint
parameters:0
error:&clientError];
if (request) {
[[[Twitter sharedInstance] APIClient]
sendTwitterRequest:request
completion:^(NSURLResponse *response,
NSData *data,
NSError *connectionError) {
if (data) {
// handle the response data e.g.
NSError *jsonError;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:data
options:0
error:&jsonError];
for (NSDictionary *dataDict in json) {
NSString *text = [dataDict valueForKeyPath: #"text"];
dictionary = [NSDictionary dictionaryWithObjectsAndKeys:text,#"bodytext",nil];
[tweetObject addObject:dictionary];
}
}
else {
NSLog(#"Error: %#", connectionError);
}
}];
}
else {
NSLog(#"Error: %#", clientError);
}
} else {
NSLog(#"error: %#", [error localizedDescription]);
}
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return tweetObject.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
myCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell=[[myCell alloc]initWithStyle:
UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSDictionary *tmpDict = [self.tweetObject objectAtIndex:indexPath.row];
cell.txtLblOutput.text = [tmpDict objectForKey:text];
[tableView reloadData];
return cell;
}
#end
Here you can see the way my storyboard is put together and the references I am using
http://postimg.org/image/79w7pqmu3/
http://postimg.org/image/ixq9kabyz/
You should call [tableView reloadData]; in your request completion handler, after you've filled your array. Check if you receive any data. Does the array get filled with dictionary objects?
But mate, seriously, you need to read some good books about coding, your code really lacks understanding of what you're doing. Please, remove [tableView reloadData]; from the - ...cellForRowAtIndexPath:... method.

TableView Controller using JSON NSURL

Good afternoon,
I'm trying to use a TableView Controller to display X number of items from my MySQL database but I'm a little bit lost at the moment.
I have another project where I can show the data using JSON output data, but I don't know how to add that code to my project in order to show the data from my database. That's the code I used:
#implementation HomeModel
- (void)downloadItems
{
// Download the json file
NSURL *jsonFileUrl = [NSURL URLWithString:#"http://website.com/service.php"];
// Create the request
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:jsonFileUrl];
// Create the NSURLConnection
[NSURLConnection connectionWithRequest:urlRequest delegate:self];
}
#pragma mark NSURLConnectionDataProtocol Methods
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// Initialize the data object
_downloadedData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Append the newly downloaded data
[_downloadedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// Create an array to store the locations
NSMutableArray *_locations = [[NSMutableArray alloc] init];
// Parse the JSON that came in
NSError *error;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:_downloadedData options:NSJSONReadingAllowFragments error:&error];
// Loop through Json objects, create question objects and add them to our questions array
for (int i = 0; i < jsonArray.count; i++)
{
NSDictionary *jsonElement = jsonArray[i];
// Create a new location object and set its props to JsonElement properties
Location *newLocation = [[Location alloc] init];
newLocation.name = jsonElement[#"user"];
newLocation.address = jsonElement[#"imagen"];
newLocation.latitude = jsonElement[#"date"];
// Add this question to the locations array
[_locations addObject:newLocation];
}
// Ready to notify delegate that data is ready and pass back items
if (self.delegate)
{
[self.delegate itemsDownloaded:_locations];
}
}
#end
Currently that's my code:
TableViewController.m
#import "CarTableViewController.h"
#import "CarTableViewCell.h"
#import "CarTableViewController.h"
#import "CarDetailViewController.h"
#implementation CarTableViewController
#synthesize carMakes = _carMakes;
#synthesize carModels = _carModels;
#synthesize carImages = _carImages;
- (void)viewDidLoad
{
[super viewDidLoad];
self.carMakes = [[NSArray alloc]
initWithObjects:#"Chevy",
#"BMW",
#"Toyota",
#"Volvo",
#"Smart", nil];
self.carModels = [[NSArray alloc]
initWithObjects:#"Volt",
#"Mini",
#"Venza",
#"S60",
#"Fortwo", nil];
self.carImages = [[NSArray alloc]
initWithObjects:#"chevy_volt.jpg",
#"mini_clubman.jpg",
#"toyota_venza.jpg",
#"volvo_s60.jpg",
#"smart_fortwo.jpg", nil];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.carModels count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"carTableCell";
CarTableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CarTableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Configure the cell...
cell.makeLabel.text = [self.carMakes
objectAtIndex: [indexPath row]];
cell.modelLabel.text = [self.carModels
objectAtIndex:[indexPath row]];
UIImage *carPhoto = [UIImage imageNamed:
[self.carImages objectAtIndex: [indexPath row]]];
cell.carImage.image = carPhoto;
return cell;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowCarDetails"])
{
CarDetailViewController *detailViewController =
[segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView
indexPathForSelectedRow];
detailViewController.carDetailModel = [[NSArray alloc]
initWithObjects: [self.carMakes
objectAtIndex:[myIndexPath row]],
[self.carModels objectAtIndex:[myIndexPath row]],
[self.carImages objectAtIndex:[myIndexPath row]],
nil];
}
}
#end
TableViewController.h
#import <UIKit/UIKit.h>
#interface CarTableViewController : UITableViewController
#property (nonatomic, strong) NSArray *carImages;
#property (nonatomic, strong) NSArray *carMakes;
#property (nonatomic, strong) NSArray *carModels;
#end
How can I add the first code (results from my database) to the other project? I'm lost at the moment and I will appreciate a lot if you can give me some light on this problem, because I want to edit the info from the storyboard as I have in the second project.
Thanks in advance.
Regards.
Thanks in advance.
It's because you don't connect to your database directly from your iphone. In general ou have a web service (also call API) for expose your data (in JSON format for example). So you have to build an API, in PHP, Ruby or Node, for expose the data of your database and access it.
EDIT:
What i see is in your HomeModel, you can set a delegate, this delegate have a function itemsDownloaded where you pass the data get from your API.
So you want your CarTableViewController to be that delegate for receive those data.
First you have to have an object HomeModel, in your TableViewController.h add:
#property (strong, nonatomic) HomeModel *homeModel;
Now you have to call the code that get the data from your server. Something like
- (void)viewDidLoad
{
[super viewDidLoad];
homeModel = [HomeModel new];
homeModel.delegate = self;
[homeModel downloadItems];
}
And finally you have to implement itemsDownloaded in your CarTableViewController. Do something like this:
- (void)itemsDownloaded:(NSArray *)items
{
self.carMakes = items; // Problem here
[self.tableView reloadData];
}
But the problem is HomeModel parse something different from what you have in carMakes, you have to adapt the Loop through Json objects in HomeModel.
You may wanna try AFNetworking which is a library easier to use than NSURLConnection.

Hiding an autocomplete UITableView that was created programmatically

I'm building an application with an autocomplete UITableView from this tutorial. I have the autocomplete functionality working properly, but I would like the UITableView-autocomplete drop down to disappear when the word is clicked on or when it is touched up outside. I'm not sure how to set up a delegate when the object is set up programmatically. I've only done this using the interface builder.
.h
#interface slrpViewController : UIViewController<UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource>
{
NSMutableArray *dataArray;
NSMutableData *receivedData;
NSMutableArray *pastUrls;
NSMutableArray *autocompleteUrls;
UITableView *autocompleteTableView;
}
#property(nonatomic, retain) IBOutlet UITextField *eWordEntered;
#property (nonatomic, retain) NSMutableArray *pastUrls;
#property (nonatomic, retain) NSMutableArray *autocompleteUrls;
#property (retain, nonatomic) NSMutableData *responseData;
#property (nonatomic, retain) UITableView *autocompleteTableView;
-(void)setReceivedData:(NSMutableData*)pReceivedData;
-(NSMutableData *) getReceivedData;
-(void) getAutoCompleteArray;
-(void)searchAutocompleteEntriesWithSubstring:(NSString *)substring;
.m
- (void)viewDidLoad
{
[super viewDidLoad];
[self getAutoCompleteArray];
pastUrls = [[NSMutableArray alloc] init];
NSLog(#"In the viewDidLoad and pasturl is: %#", self.pastUrls);
self.autocompleteUrls = [[NSMutableArray alloc] init];
autocompleteTableView = [[UITableView alloc] initWithFrame:CGRectMake(210, 225, 310, 120) style:UITableViewStylePlain];
self.autocompleteTableView.delegate = self;
self.autocompleteTableView.dataSource = self;
autocompleteTableView.scrollEnabled = YES;
autocompleteTableView.hidden = YES;
[self.view addSubview:autocompleteTableView];
-(void)setReceivedData:(NSMutableData*)pReceivedData
{
receivedData = pReceivedData;
}
-(NSMutableData *) getReceivedData{
return receivedData;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{[receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *e = nil;
NSError *error = nil;
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData: receivedData options: NSJSONReadingMutableContainers error: &e];
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:receivedData
options:kNilOptions
error:&error];
seneca_word.ids = [jsonDict objectForKey:#"ids"];
NSArray *array_ids = [jsonDict objectForKey:#"ids"];
NSString *ids = array_ids[0];
seneca_word.ids = ids;
for (id key in jsonDict)
{
NSLog(#"key: %#, value: %#", key, [jsonDict objectForKey:key]);
NSLog(#"The value of bases by itself is: %#", [jsonDict objectForKey:#"bases"]);
}
if (!jsonArray)
{
NSLog(#"Error parsing JSON: %#", e);
}
else
{
if([jsonDict objectForKey:#"english"] != nil){
pastUrls = [jsonDict objectForKey:#"bases"];
}
else{
//Some of JSON object that I don't want to use here
}//else
}//(void)connectionDidFinishLoading
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring {
[autocompleteUrls removeAllObjects];
for(NSString *curString in pastUrls) {
NSRange substringRange = [curString rangeOfString:substring];
if (substringRange.location == 0) {
[autocompleteUrls addObject:curString];
}
}
[autocompleteTableView reloadData];
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
autocompleteTableView.hidden = NO;
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
return YES;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
return autocompleteUrls.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier];
}
cell.textLabel.text = [autocompleteUrls objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
self.eWordEntered.text = selectedCell.textLabel.text;
if(tableView == autocompleteTableView){
//The autocomplete table view is the one that fired the didSelect delegate method
//So hide the autocomplete table.
//do whatever else you need to do to empty the autocompleteTableView's data source
//or/and simply hide the table after that
[autocompleteTableView setHidden:YES];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//When the user clicks outside of the uitableview it will disappear
[autocompleteTableView setHidden:YES];
}
As you can see I populate the autocomplete UITableView with JSON data that I'm getting from a RESTful API.
I'm getting the warning, Assigning to 'id<UITableViewDelegate>' from incompatible type 'ViewController *const __strong' for the lines:
self.autocompleteTableView.delegate = self;
self.autocompleteTableView.dataSource = self;
I imagine once I get the delegate stuff sorted out I'll be able to do what I want. I did some research and tried to create a delegate class but wasn't able to get that solution working. I'm not even sure if that's the right way to go about this as I usually do this stuff by interface builder and not programmatically. Any direction or help is greatly appreciated. Thanks!
You should be using the tableView's didSelectCellAtIndexPathRow delegate method to identify user taps on a cell from a tableView. It's ok if you created your tableView progammatically.
Simply make sure the UIViewController conforms to the UITableViewDelegate and UITableViewDataSource` protocols.
make sure you set the tableView's delegate and dataSource property to self.
Implement the didSelectCellAtIndexPathRow delegate method in your viewController's .m file like so:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
Then inside that delegate method you need to help detect from which tableView your didSelect method got fired from as you only want to hide the autocomplete table when the user selects a cell from that table. So you do a simple tableView check like so:
if(tableView == autocompleteTableView){
//The autocomplete table view is the one that fired the didSelect delegate method
//So hide the autocomplete table.
//do whatever else you need to do to empty the autocompleteTableView's data source
//or/and simply hide the table after that
[autocompleteTableView setHidden:YES];
}
You probably also want to make sure that you set the autocompleteTableView hidden property to NO when the user types in something in the textfield so that the auto complete can show appear again.
And thats all buddy.
try setting self.autocompleteTableView.hidden = YES;

Memory management with GCD, NSMutableArray and UITableView [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I'm now been stuck with this error "EXC_BAD_ACCESS" for hours and I can't seem to find what's wrong. Hopefully some of you will find it.
I'm downloadning a file containing json-data, save it as a custom NSObject in an NSMutableArray and then present it in a UITableView. It's when I going to present it in the UITableView I encounter problems.
ViewController.h
#property (nonatomic, retain) NSMutableArray *menuItems;
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
menuItems = [[NSMutableArray alloc] init];
}
- (void)viewDidAppear:(BOOL)animated
{
[self downloadMenu];
}
-(void)downloadMenu
{
dispatch_queue_t fetchfromServerQueue = dispatch_queue_create("fetchfromServer", NULL);
[self createProgressionAlertWithMessage:#"Fetching menu"];
dispatch_async(fetchfromServerQueue, ^{
NSURL *menuURL = [NSURL URLWithString:#"anURL"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:menuURL];
NSError *error = nil;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
responseArray = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
menuItems = [[NSMutableArray alloc] initWithCapacity:[responseArray count]];
for (int i = 0; i<[responseArray count]; i++) {
NSDictionary *menuObject = [responseArray objectAtIndex:i];
NSString *x = [NSString stringWithFormat:#"%#", [menuObject objectForKey:#"x"]];
NSString *y = [NSString stringWithFormat:#"%#", [menuObject objectForKey:#"y"]];
NSString *z = [NSString stringWithFormat:#"%#", [menuObject objectForKey:#"z"]];
MenuItem *menuItem = [[MenuItem alloc] initWithX:x andY:y andZ:z];
[menuItems addObject:menuItem];
[menuItem release];
}
dispatch_async(dispatch_get_main_queue(), ^{
[progressAlert dismissWithClickedButtonIndex:0 animated:YES];
[menuTable reloadData];
});
});
dispatch_release(fetchfromServerQueue);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [menuItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
MenuItem *menuItem = (MenuItem *)[menuItems objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%#", [menuItem x]];
return cell;
}
On "cell.textLabel.text = [NSString stringWithFormat:#"%#", [menuItem x]];" I get "EXC_BAD_ACCESS (code=1,address=0xXXXXXXXX)".
I don't use ARC and can't convert to it in a near future with this project. That make it a problem due to my lack of knowledge with memory management.
Any idea of what's wrong?
Thx!
#### #### #### #### #### #### #### #### ####
This is how MenuItem looks like:
#import <Foundation/Foundation.h>
#interface MenuItem : NSObject
{
NSString *x;
NSString *y;
NSString *z;
}
-(id)initWithX:(NSString *)x_ andY:(NSString *)y_ andZ:(NSString *)z_;
-(NSString *)x;
-(NSString *)y;
-(NSString *)z;
#property(retain, nonatomic) NSString *x;
#property(retain, nonatomic) NSString *y;
#property(retain, nonatomic) NSString *z;
#end
#import "MenuItem.h"
#implementation MenuItem
#synthesize x;
#synthesize y;
#synthesize z;
-(id)initWithX:(NSString *)x_ andY:(NSString *)y_ andZ:(NSString *)z_
{
self = [super init];
if(self)
{
x = x_;
y = y_;
z = z_;
}
return self;
}
-(void)dealloc
{
[x release];
[y release];
[z release];
[super dealloc];
}
-(NSString *)x
{
return x;
}
-(NSString *)y
{
return y;
}
-(NSString *)z
{
return z;
}
#end
I don't see anything obvious, perhaps something in menuItem is causing the issue? What does [menuItem x] do?
In general, run the app with the zombies instrument: cmd-i, then select Zombies. This will give you a trace of the allocations/releases of the object which is throwing the EXC_BAD_ACCESS.
Good luck.
This is a bit weird:
-(void)downloadMenu
{
dispatch_queue_t fetchfromServerQueue = dispatch_queue_create("fetchfromServer", NULL);
dispatch_async(fetchfromServerQueue, ^{
...
});
dispatch_release(fetchfromServerQueue);
}
You create a queue and give it an async task to do. While that task goes off to do some work you then immediately free the queue. This could cause a few issues if the async task doesn't finish before you release it.
You might want to hold off on the release until after the work in the async call is completed.

UIPickerview gives questionmarks back instead of data

EDIT
I have a UIPickerview and I want do fill it up with data from my NSMutualArray. I have tested if something is in my array with NSLog and i get the data back. But it will not fill up my pickerviewer
I have this methods for my pickerviewer.
- (NSString *)pickView:(UIPickerView *)pickview titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [dataArray objectAtIndex:row];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;// assuming a single spinning wheel of strings (not split into left/right for example)
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [json count]; // the number of strings that your parser finds and adds to the array
}
To get my data out of my JSON I use these two methods. And i call the start function in my viewdidload.
-(void) getData:(NSData *) data{
NSError *error;
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
}
-(void) start {
NSURL *url = [NSURL URLWithString:kGETUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
[self getData:data];
}
I have also a button which hides and shows my UIPickerviewer.
-(IBAction)setPicker:(id)sender{
if (pickview.hidden == TRUE) {
[pickview setHidden:NO];
[pickview setDelegate:self];
[pickview setDataSource:self];
[pickview reloadAllComponents];
}else {
[pickview setHidden:YES];
[pickview setDelegate:self];
[pickview setDataSource:self];
[pickview reloadAllComponents];
}
}
I use this method for filling up my array.
-(void) fillArray{
dataArray = [[NSMutableArray alloc] init];
for (int i=0; i<[json count]; i++) {
NSDictionary *info = [json objectAtIndex:i];
[dataArray addObject:[info objectForKey:#"Use_naam"]];
}
NSLog(#"%#\n",dataArray);
}
And i call it in my viewdidload.
- (void)viewDidLoad
{
[super viewDidLoad];
[self start];
[self fillArray];
// Do any additional setup after loading the view, typically from a nib.
}
Anybody knows what I am doing wrong ?
When you see a number of question marks matching the expected number of rows it's usually the methods that returns the title or view for the rows that are missing.
This can either be because the UIPickerViews delegate is not set (you did that) or because the signature is not correct.
Your signature is off. It needs to be exactly:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
^^^^
Most commonly people forget that you have to set the UIPickerView delegate and datasource.