I'm trying to build a function that will check if a retrieved JSON value have changed (messagecount in a given conversation). I'm populating a TableView with my JSON data and I would like to store the value in a dictionary and compare them later when I do a data update.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ConversationsModel* conversation = _feed.conversations[indexPath.row];
static NSString *identifier = #"ConversationCell";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:identifier];
}
[self getMessageCountToDictionary:conversation.messagecount id:conversation.conversationid];
cell.textLabel.text = conversation.title;
return cell;
}
And my method to store the values in a NSMutableDictionary:
- (void)getMessageCountToDictionary:(NSNumber*)messagecount id:(NSString *)conversationid
{
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
if (conversationid != NULL) {
[dictionary setValue:conversationid forKey:[NSString stringWithFormat:#"%#", conversationid]];
[dictionary setValue:messagecount forKey:#"messageCount"];
dictionaryCopy = [dictionary mutableCopy];
}
NSLog(#"Stored in dictionary %lu", (unsigned long)dictionary.count);
}
NSLog returns 2
Well, I'm not sure if I'm on the right track here for what I intend to do. All inputs are highly appreciated.
I would recommend to use key-value observer to watch your objects changing values.
You can read more about it here:
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html
Related
Hi I am trying to display two dimensional array like in this image but not work my code please help me and my json respone is in image which i want to display in UITableView
-(void)getCategories
{
Service *srv=[[Service alloc]init];
NSString *str=#"http://streamtvbox.com/site/api/matrix/";//?country_code=91&phone=9173140993&fingerprint=2222222222";
NSString *method=#"channels";
NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
[srv postToURL:str withMethod:method andParams:dict completion:^(BOOL success, NSDictionary *responseObj)
{
NSLog(#"%#",responseObj);
arrayCategories = [responseObj valueForKey:#"categories"];
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrayCategories.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ChannelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [[arrayCategories objectAtIndex:indexPath.row]valueForKey:#"categories"];
return cell;
}
Hope it will help you,
You are doing some minor mistake, do something as below,
arrayCategories = [responseObj valueForKey:#"categories"]; //Which is already there in your code....
And while fetching value in your textLabel, write as below
cell.textLabel.text = [[[arrayCategories objectAtIndex:indexPath.row] componentsSeparatedByString:#"="] objectAtIndex:1];
Do not write here valueForKey "categories".
Let me know if you still face any issue.
I got it the issue is in your response.In categories key you are not getting array , you are getting object.Paste exact log NSLog(#"%#",responseObj); that you get in your success block so that i can help you to sort it out.
I've got the code below to fill up an array of notifications. This array is needed to fill up a menu in my iOS app with notifications.
// extract specific value...
NSArray *switchValues = [res objectForKey:#"data"];
NSLog(#"%#", switchValues);
for (NSDictionary *switchValue in switchValues) {
NSString *text = [switchValue objectForKey:#"text"];
NSLog(#"%#", text);
[self.notificationsArray addObject:text];
}
Further down the line I then do this:
- (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];
}
NSMutableArray *titles = self.notificationsArray;
cell.textLabel.text = titles[indexPath.row];
return cell;
}
However, I keep getting an empty array. What am I doing wrong?
Why don't you do
[notificationsArray objectAtIndex:indexPath.row]
instead of
NSMutableArray *titles = self.notificationsArray;
cell.textLabel.text = titles[indexPath.row];
?
If you really dont want, at least do
NSMutableArray *titles = [NSMutableArray arrayWithArray:self.notificationsArray];
And in the first piece of code, what are the Console Logs? Are you sure you enter in the for loop?
I am trying to get my NSdictionary values into a UITableViewCell. Here is my dictionary format:
{
date = "3/4/14, 3:33:01 PM Pacific Standard Time";
weight = 244;
}
Here is the code I'm using to populate my uitableview (which is not working).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"WeightCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
NSArray* allKeys = [weights allKeys];
NSDictionary *obj = [allKeys objectAtIndex: indexPath.row];
cell.textLabel.text = [obj objectForKey: #"date"];
cell.detailTextLabel.text = [obj objectForKey:#"weight"];
return cell;
}
You should try initialising the array for the tableView outside of the tableView itself... something along the lines of
- (void)viewDidLoad
{
[super viewDidLoad];
_allKeys = [[NSMutableArray alloc] initWithArray:[weights allKeys]];
}
Once you have initialised that data you can access it throughout the process. Also to find out how many rows your tableview needs.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_allKeys count];
}
Then when you access the array into a dictionary it has retained the row count and can access it properly.
NSDictionary *obj = [_allKeys objectAtIndex: indexPath.row];
cell.textLabel.text = [obj objectForKey: #"date"];
cell.detailTextLabel.text = [obj objectForKey:#"weight"];
From what I can see the dictionary cant access the array at your indexPath.row because you haven't initialised the array anywhere before you use it in your tableView.
Hope that helps, T
Some of the other posters have good suggestions. However, this line:
NSDictionary *obj = [allKeys objectAtIndex: indexPath.row];
Is wrong. allKeys is an array of your dictionary keys, which are presumably strings.
So, you want code like this instead:
NSString *thisKey = allKeys[indexPath.row];
NSDictionary *obj = weights[thisKey];
Note that I am using the new Objective C literal syntax. The expression weights[thisKey] is equivalent to [weights objectForKey: thisKey]
I don't see the definition of the weights object. If you want to keep adding NSDictionary's to an array, you need to use an NSMutableArray, and you'll probably want to do that by setting it as a #property on your class. Let's say you added it like this:
#property (strong, nonatomic) NSMutableArray *weights;
Then in your tableView:cellForRowAtIndexPath: method you'll want to get the NSDictionary corresponding to that line by using self.weights[indexPath.row]. Also don't forget to instantiate weights before using it, otherwise it will return nil and no objects are going to be added to it.
P.S.: the user provided some context here and what he probably needs is Core Data.
Im parsing JSON data in an external class (NSObject) class that then put organizes the parsed data into an array. That array is then placed into my Table View. Because it takes longer to parse the info then to finish viewDidLoad the array is always set to nil.
Code:
- (void)viewDidLoad
{
//Fetching Data
[super viewDidLoad];
myClass = [[MyClass alloc] init];
[myClass fetchDataWithTarget:self];
//Initialize the dataArray
dataArray = [[NSMutableArray alloc] init];
//First section data
NSArray *firstItemsArray = myClass.fechedDataArray;
NSDictionary *firstItemsArrayDict = [NSDictionary dictionaryWithObject:firstItemsArray forKey:#"data"];
[dataArray addObject:firstItemsArrayDict];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSDictionary *dictionary = [dataArray objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:#"data"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
How can I insure that firstItemsArray is set after the data is fetched.
Note: There is obviously more to the table view then this, I did all the dictionary stuff to separate sections and what not.
You'll have to load the JSON data into the array BEFORE
- (void) viewDidLoad
or use some type threading (asynchronous method) such as:
performSelectorInBackground:withObject
NSOperation or Grand Central Dispatch
I have an array of EventObject(s). Each object has title and city and many others attributes. I want to show title of cell as event title, and subtitle of cell as event city. I tried doing that in the following, but I only get the last object displayed 4 times (that is the number of objects in the array).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
// NSDate *object = _objects[indexPath.row];
// cell.textLabel.text = [object description];
EventObject *eventInstance = [[EventObject alloc] init];
int row = [indexPath row];
eventInstance = eventObjectsArray[row];
cell.textLabel.text = eventInstance.eventTitle;
NSLog(#"Event Title: %#", eventInstance.eventTitle);
cell.detailTextLabel.text = eventInstance.eventCity;
return cell;
}
What did I do wrong? I am learning objective-c so beginners errors surely. Thanks
EDIT: This is how I am inserting objects:
//get events from database
eventsDictionary = [eventInstance getEventsObjects];
//process each key in dictionary and assign to eventInstance
for(id key in eventsDictionary)
{
eventInstance.eventId = [NSString stringWithFormat:#"%#", key[#"id"]];
eventInstance.eventTitle = [NSString stringWithFormat:#"%#", key[#"title"]];
eventInstance.eventDescription = [NSString stringWithFormat:#"%#", key[#"description"]];
eventInstance.eventCity = [NSString stringWithFormat:#"%#", key[#"city"]];
[eventObjectsArray addObject:eventInstance];
}
Suggestions
[This can be issue]
While adding objects in your eventObjectsArray make sure to have new insatnce of EventObject everytime before you add object
EventObject *eventInstance = [[EventObject alloc] init];
eventInstance.eventTitle = #"your title";
eventInstance.eventCity = #"your city";
[eventObjectsArray addObject:eventInstance];
[This is suggestion as you should know this to improve your coding standard and memory management]
While retriving objects back from array you really don't need to have instance of custom object rather have refrence to it like
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
//EventObject *eventInstance = [[EventObject alloc] init]; //you don't need this
int row = [indexPath row];
EventObject *eventInstance = eventObjectsArray[row]; // make reference like this
cell.textLabel.text = eventInstance.eventTitle;
NSLog(#"Event Title: %#", eventInstance.eventTitle);
cell.detailTextLabel.text = eventInstance.eventCity;
return cell;
}