Objective-c Parse JSON Response - objective-c

I have been doing a lot of reading but I have not been able to find anything close to what I am trying to do. I am getting a JSON response and populating a UITableView with the results. When the user selects the row on the UITableView I want to grab the corresponding "id" value that is associated with the name displayed. Example JSON response:
{"active":true,"created_at":"2012-05-12T03:04:21Z","description":"Test 1",
"id":11,"name":"This Is A Test","updated_at":"2012-05-12T03:04:21Z"}
So I set the UITableView row with a name of This Is A Test and when the user selects that I want to return the number 11 as being selected. In the didSelectRowAtIndexPath function I can pull the
UITableViewCell *selectedCell = [self.tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = selectedCell.textLabel.text;
sc.selectedCategory = cellText;
Which will give me the name of the object but how can I call the dictionary again and get the value of "id" where the name matches the selected cell? I am pretty new to objective-c but have been doing java for years. Any examples would be great.
Thanks in advance!

What you have there is a dictionary. You need to cast the Array objectAtIndex (tableview index path) as an NSDictionary object and then use valueForKey.
Something like the following in the didSelectRowAtIndexPath:
NSDictionary *selRow = (NSDictionary *)[myArray objectAtIndex:indexPath.row];
NSInteger myID = [[selRow valueForKey#"id"] intValue];

Related

Search for object in NSMutableArray and change value for that object

I have project where user can add some Items to TableView. My data source for this TableView are objects with 2 properties NSString * nameOfItem and NSNumber * numberOfItem. Is any possibility to check my NSMutableArray if it contain string #"someString" as property nameOfItem and if yes than change numberOfItem +1 ?
UPDATE:
I try to do it with for(...in...) but it works just when i have only one object in my NSMutableArray. If i have more objects there it create one new object and than change value to ++ on old one:
Here is some code what i tried:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString*nameToCheck = [NSString stringWithFormat:#"%#", [self.ivc.objects objectAtIndex:indexPath.row]];
for (Items *itemNamed in self.ivc.shoppingList.items) {
if ([itemNamed.nameOfItem isEqualToString:nameToCheck]) {
[itemNamed setNumberOfItem:[NSNumber numberWithInt:[itemNamed.numberOfItem integerValue]+1.0]];
} else {
Items *item = [Items new];
[item setNameOfItem:name];
[item setNumberOfItem:#(1)];
[self.ivc.shoppingList.items insertObject:item atIndex:0];
}
I want to create new one only if is not yet in that list.
Any help appreciated.
I don't know something like this but you can use a NSDictionary instead of NSArray using the name property as a key. And if you don't want to do that, you can sort the array and make a binary search for element.

Populate NSTableView with unknown number of columns

I have a NSTableview and a button. NSTableview has a unknown number of columns.
The first column has a image well and 2 text boxes, the others (again, unknown number) are normal textbox columns.
The button opens up a file open dialogue. Once I choose the files (.jpg) I would like to process them.
So far everything is made (chose files, columns, etc..) what is missing is the populating of the table:
I have the loop that goes through all the selected files. What is the best way to do this:
display the image in the image well of the first cell,
type the filename in the first textbox of the first cell,
type the filepath in the second cell of the textbox,
type "YES" in all other columns.
My difficulty is that I have no idea how many columns will be there since it depends from the user. The number of columns will not change during Runtime. they are set up at startup based on the configuration. if the configuration is changed then the app should be reloaded.
I am a beginner in Objective-C/Cocoa programming.
EDIT:
additional info as requested:
It is a view based NSTableView
each column represents an action that has to be taken in a later moment on an image. the program user can decide what and how many actions to take, thats the reason for a unknown amount of columns in the table view.
You can add columns programmatically using addTableColumn:. This method takes an NSTableColumn instance that you can create in your code.
The rest of your architecture (displaying images, etc.) does not particularly change from "normal" code just because the columns have been added dynamically.
Here is a snippet that should get you started:
NSTableColumn* tc = [[NSTableColumn alloc] init];
NSString *columnIdentifier = #"NewCol"; // Make a distinct one for each column
NSString *columnHeader = #"New Column"; // Or whatever you want to show the user
[[tc headerCell ] setStringValue: columnHeader];
tc.identifier = columnIdentifier;
// You may need this one, too, to get it to show.
self.dataTableview.headerView.needsDisplay = YES;
When populating the table, and assuming that the model is an array (in self.model) of NSDictionary objects, it could go something like this;
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSString *columnIdentifier = tableColumn.identifier;
NSDictionary *rowDict = [self.model objectAtIndex: row];
NSString *value = [rowDict valueForKey: columnIdentifier]; // Presuming the value is stored as a string
// Show the value in the view
}
More in the docs.
When user adds a column or row, you should reflect it in your model (by binding or by code), so you know the size of your table, when you need to populating it.
set tableView.delegate (in code or in Interface Builder), reference here
implement:
- (NSView*) tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn*)tableColumn row:(NSInteger)row
{
Item* itemView = [tableView makeViewWithIdentifier:#"rowItem" owner:self];
/*Here you populate your cell view*/
id entryObject = [self.entries objectAtIndex:row];
[itemView setEntry:entryObject];
return itemView;
}
and then invoke [tableView reloadData];
maybe for you better to use this method
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
Just see the NSTableViewDataSource and NSTableViewDelegate

Build an array with input from tableviewcell UITextfield

I have a tableview with dynamical amount of cells, based on an array who is build up by a JSON.
tableData = [NSJSONSerialization JSONObjectWithData:dataWebService options:kNilOptions error:&error];
This little line gets all the data I need to build my tableview.
In the tableview I have a textfield in every cell with predefined text from my JSON. The user can change this value before he proceed to the next segue (storyboard).
The question is how I can store this usertyped values in an array an replace the excisting values in my tableData array before I send this arraobject to the next segue.
And keep in mind that the user input must not change when the user scroll in the tableview.
Maybe this is basic, but I cannot figure a nice way to do this.
This is an example of the JSON.
(
{
defaultval = 8;
dtype = long;
id = "#franr";
label = "Faktura nr.";
},
{
defaultval = 8;
dtype = long;
id = "#tilnr";
label = "Til faktura";
}
The tableview look like this:
(I cannot post images)
Fra faktura 8
Til faktura 8
The user can change the values (number 8) to any numbers. So I need to replace the numbers of defaultVal in my JSON array.
Thanks.
Since its a UITEXTFIELD, you can use OnTextChange Event
[textField addTarget:self action:#selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
or
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string
, or lose focus
- (BOOL)textFieldShouldReturn:(UITextField *)textField
please keep in mind you need to set the delegate of the textfield to self & add the respective protocals.
In order to keep the data after scrolling, you should modify the data source (the array) after each input from the user. You can do dis in the UITextFieldDelegate's textFieldDidEndEditing: method (of course, you have to be the delegate for each text field: textField.delegate = self;).
You should also implement a UIScrollViewDelegate method, for dismissing the keyboard when the table begins to scroll (e.g. scrollViewWillBeginDragging:).
EDIT:
Your array must be containing NSDictionaries, which are not mutable, so I recommend, you create your own class having those attributes (defaultval, dtype ...), so you can edit the data source. I don't think you can modify your array the way it is now.
The code with custom object would be something like:
- (void)textFieldDidEndEditing:(UITextField *)textField {
UITableViewCell *cell = textField.superview.superview;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
MyObject *currentObject = [tableData objectAtIndex:indexPath.row];
currentObject.defaultVal = textField.text.intValue;
}

Objective-C UITableView index

How do I read always the most upper line (cell.textLabel.text) in a UITableView?
I have two slightly different approaches;
1:
UITableViewCell *cell2 = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText2 = cell2.textLabel.text;
NSLog (#" cellText2 = %#", cellText2);
2:
NSMutableString *newidea = [self.array objectAtIndex:indexPath.row];
NSLog (#"newidea = %#", newidea);
Both codes are inside the method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
self.array is same array that fills up the tableView.
The former approach always shows text from the sixth cell. The latter approach always shows text from the fifth cell. In my tableview there is four cells at a time.#
What I want to get is the text from the most upper cell.
I think you have the wrong approach. You don't read values from cells, instead you let the cells read values from your data array. A cell can always have an arbitrary value since they are reused. Even if you have 30 "cells" in your table view there may only be 5 existing actual cells. When a cell goes outside the table view when you scroll, it is moved to the bottom and reused as the next cell. That's why you always have to set the values for each cell on the index path.
Instead you should get the value in the first cell from your data array if you have one. When the table view asks what title the cell att indexPath.row == 0 should have, you give it to it in cellForRowAtIndexPath, for example from an array called "_cellTitles" containing 30 strings for 30 different cells.
If you want to get the text from the "most upper" visible cell, then you can call indexPathsForVisibleRows on the table view. The first object in the returned array is the index path for the most upper visible cell. You can check the string in your array at index indexPath.row.
Example:
NSArray *visibleRows = [self.tableView indexPathsForVisibleRows];
NSIndexPath *firstVisibleCell = [visibleRows objectAtIndex:0];
NSString *firstVisibleCellTitle = [_myDataArray objectAtIndex:indexPath.row];
If you always want to read from first row, instead of indexPath just say 1 there. That way it will always read from the first row.

Displaying array in uitableview

I have an array created like this:
[currentQuizArrayQuestions insertObject:[quizArrayQuestions objectAtIndex:randomIndex] atIndex:0];
How do I access its data to display in the table?
I'm trying this:
NSString *cellValue = [currentQuizArrayQuestions objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
I know it's wrong, but how do I get to the data array object stored in the currentQuizArrayQuestions array.
You need to implement the cellForRowAtIndexPath method. See this tutorial on UITableViews: http://adeem.me/blog/2009/05/19/iphone-programming-tutorial-part-1-uitableview-using-nsarray/
That one uses a UITableViewController, but the idea is the same.
Edit:
To use a different array, do the same thing with the cell for row at index path method, changing the array that the cellValues come from according to what you need. Then call [tableView reload]; which will run through cellForRowAtIndexPath with the contents of the new array.