Strings end up as nulls - ios

I have a sequence of code. In it there are custom objects: Item and ItemList. The relevant members of these are Item.code and ItemList.ItemDictionary. Item.code is simply a NSString code (Like "AVK") that uniquely identifies an Item. These Items are separated into categories. There are 4 categories (Named "CatOne", etc). The ItemDictionary is a dictionary with the category names as keys and an NSMutableArray as the object; the array is filled with Item objects that are part of the category.
The basic problem is that when I try to access the Item.code, the string comes out as (null).
The functionality is that I have an array of updated Items (updatedItems) and I want to update the ItemList.ItemDictionary with these new Items.
The following are all properties of the object, and are synthesized in the main file.
#synthesize ItemListFromFile;
#synthesize upDatedItems;
#synthesize tempPassedManifest;
And the code:
-(id) upDatedItems:(NSArray *)newItems manifest:(Manifest *)manifest {
ItemListFromFile = [[ItemList alloc] init];
ItemListFromFile.ItemDictionary = [[NSMutableDictionary alloc] init];
ItemListFromFile = [NSKeyedUnarchiver unarchiveObjectWithFile:manifest.ItemListSavePath];
updatedItems = newItems
tempPassedManifest = manifest;
[self UpdateItemList];
return self;
}
-(void)UpdateItemList {
NSMutableArray *newItemArray = [[NSMutableArray alloc] init];
NSMutableArray *oldItemArray = [[NSMutableArray alloc] init];
// Go through each category. "i" is category Number
for (int i=1; i <= [Number of Categories]; i++)
{
NSString *currentCategoryName = [Get Category Name]; //This works...
// ********* Debug statements ************
// This Loop is where NSLog shows something's not right
// These conditions work fine.
for (int j = 0; j < [[ItemListFromFile.ItemDictionary objectForKey:currentCategoryName] count]; j++)
{
// This Log outputs (null) when it should output the code from the Item
NSLog(#"Code from File: %#", [[[ItemListFromFile.ItemDictionary objectForKey:currentCategoryName] objectAtIndex:j] code]);
}
// ************** Debug ******************
if ([[ItemListFromFile.ItemDictionary allKeys] containsObject:currentCategoryName])
{
[oldItemArray setArray:[ItemListFromFile.ItemDictionary objectForKey:currentCategoryName]];
for (Item *anItem in oldItemArray)
{
NSLog(#"OldItemArray Code: %#", anItem.code);
}
}
else
{
[oldItemArray removeAllObjects];
}
[newItemArray removeAllObjects];
// Go through each Item in category i.
for (NSString *currentCode in [array of codes in category i (this works)])
{
// There's two options of where to grab each Item from: either upDatedItems or oldItemArray
BOOL inOldArray = YES;
for (Item *anItem in upDatedItems)
{
if ([anItem.code isEqualToString:currentCode])
{
[newItemArray addObject:anItem];
inOldArray = NO;
NSLog(#"%# was in updatedItems", currentCode);
break;
}
}
if (inOldArray)
{
// Checking in old Item Array
for (Item *anItem in oldItemArray)
{
NSLog(#"Checking %# against %#", anItem.code, currentCode);
// (anItem.code is null)
if ([anItem.code isEqualToString:currentCode])
{
[newItemArray addObject:anItem];
NSLog(#"%# was in oldItems", currentCode);
break;
}
}
}
}
//We've created the array, so add it to dictionary
[ItemListFromFile.ItemDictionary setObject:newItemArray forKey:currentCategoryName];
NSLog(#"New Dance Array: %#", newDanceArray);
}
[NSKeyedArchiver archiveRootObject:ItemListFromFile toFile:tempPassedManifest.ItemListSavePath];
}
I've tried to be as thorough as possible, but do not hesitate to ask for clarification.
Update
I've been trying a lot of solutions to this, but nothing seems to be working. Things I've tried:
Creating an object that takes the place of *anItem, so instead of a for loop that loops through the contents of the array, loops from i=0..[Count], and then sets the object at that index to the item I created before the loop. I thought this might help so that I could allocate and initialize the Item.code before setting it to whatever the Item has.
Using
oldItemArray = [ItemListFromFile.ItemDictionary objectForKey:currentCategoryName];
instead of
[oldItemArray setArray:[ItemListFromFile.ItemDictionary objectForKey:currentCategoryName]];
I tried updating all of the items in the ItemList.ItemDictionary so that when it archives, all of the items are fresh for the next trial run of the code.

Related

How to check If array has same object value before adding new value

I am getting data from Dictionary. It works well and stores data in NSMutableArray I want that before adding object into need to make sure that Array does not contain same object with Same Name and Type. Please see below.
Before inserting object we should check that it does not contain object with Type and Name if contains no need to insert.
NSArray *resultDic = [result1 objectForKey:#"results"];
for (int i = 0; i<[resultDic count]; i++) {
id item = [resultDic objectAtIndex:i];
NSDictionary *jsonDict = (NSDictionary *) item;
GetData *theObject =[[GetData alloc] init];
NSString*error = [jsonDict valueForKey:#"error"];
if(![error isEqualToString:#"No Record Found."])
{
[theObject setVaccineID:[jsonDict valueForKey:#"ID"]];
[theObject setVaccineName:[jsonDict valueForKey:#"Name"]];
[theObject setVaccinationType:[jsonDict valueForKey:#"Type"]];
[theObject setVaccineType:[jsonDict valueForKey:#"VType"]];
[theObject setFarmName:[jsonDict valueForKey:#"FName"]];
[theObject setDay:[jsonDict valueForKey:#"Day"]];
[theObject setAddedDateTime:[jsonDict valueForKey:#"DateTime"]];
[appDelegate.dataArray addObject:theObject];
}
}
A general purpose solution is to teach your GetData object how to compare itself to others. If they can be compared, then it will be easy to determine if a match is in any collection (and you might want to compare them in other contexts, too). Do this by implementing isEqual:. That might look something like this:
// in GetData.m
- (BOOL)isEqual:(id)object {
if ([object isKindOfClass:[GetData self]]) {
// assuming that the object is fully characterized by it's ID
return [self.vaccineId isEqual:((GetData *)object).vaccineId];
}
else {
return NO;
}
}
// have the hash value operate on the same characteristics as isEqual
- (NSUInteger)hash {
return [self.vaccineId hash];
}
With that done, you can take advantage of NSArray's containsObject:.
// ...
if(![appDelegate.dataArray containsObject:theObject] && ![error isEqualToString:#"No Record Found."])
// ...

Remove Duplicate custom objects from NSMutable Array making sure to keep newest duplicate object

I have an NSMutableArray of custom objects. Each contains an ID string that is unique, and each contains an downloadedDate property.
Objects could get added twice so I need to check the ID for duplicates, and if I find a duplicate I need to keep the one that has the newest date.
Currently I am doing the following to remove duplicates, but it doesn't take into account keeping the object with the newest date.
NSArray *originalArray = [NSArray arrayWithArray:mutableItems];
NSMutableArray *uniqueArray = [NSMutableArray array];
NSMutableSet *names = [NSMutableSet set];
for (ZSSObject *g in originalArray) {
NSString *destinationName = g.code;
if (![names containsObject:destinationName]) {
[uniqueArray addObject:g];
[names addObject:destinationName];
}
}
NSArray *uniqueObjects = uniqueArray;
Objects get created like this:
ZSSObject *obj = [ZSSObject alloc] init];
obj.code = #"12345";
obj.downloadedDate = [NSDate date];
Is there an easier way to do that I want than having a bunch of copies of my array and nested loops?
Using the suggestion to use an NSDictionary instead, I came up with this solution:
NSMutableDictionary *objDict = [[NSMutableDictionary alloc] init];
for (ZSSObject *g in mutableItems) {
ZSSObject *addedObj = objDict[g.code];
if (addedObj) {
// Compare dates
if ([addedObj respondsToSelector:#selector(dateDownloaded)]) {
if ([g.dateDownloaded compare:addedObj.dateDownloaded] == NSOrderedDescending) {
[objDict setObject:g forKey:g.code];
}
}
} else {
[objDict setObject:g forKey:g.code];
}
}
NSArray *uniqueObj = objDict.allValues;

Compare the unique index value with another array in objective C

There is an array having same objects in single array , i need to compare these array’s index with another array.. Give me a help.
Something like:
NSMutableArray *latArray =
[NSMutableArray arrayWithObjects:#“43.20,#“43.23”,#“43.24”,#“43.20”,nil];
NSMutableArray *lngArray =
[NSMutableArray arrayWithObjects:#“76.90”,#“76.94”,#“76.92”,#“76.90”,nil];
NSMutableArray *imagesArray =
[[NSMutableArray alloc] initWithObjects:#"1.jpg", #"2.jpg”,#“3.jpg”,#“4.jpg”,nil];
resultResult = #"1.jpg", #“4.jpg” // because the index 0 and index 3 same values in both array.
I would wrap your coordinates into location objects and use them as the keys in a dictionary. This would allow to check for duplicate coordinates, like this:
NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
for (int i = 0; i < [imagesArray count]; i++)
{
// Wrap coordinates into a NSValue object
// (CLLocationCoordinate2D is a C-struct that cannot be used as a dictionary key)
// (CLLocation also does not implement required methods to be usable as a dictionary key)
NSValue *loc = [NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(
((NSNumber)[latArray objectAtIndex:i]).doubleValue,
((double)[lngArray objectAtIndex:i]).doubleValue)];
// 1. If you only want the first occurrence of a specific location, use this:
if ([results objectForKey:loc] == nil)
{
[results setObject:[imagesArray objectAtIndex:i] forKey:loc];
}
// 2. Or, if you want the last occurrence of a specific location, use this:
[results setObject:[imagesArray objectAtIndex:i] forKey:loc];
}
I think you are trying the check for the same objects in an array. If so do the following.
for(int i=0;i<yourarray.count;i++)
{
NSString *yourstring=[yourarray objectatindex:i];
for(int k=0;k<yourarray.count;k++)
{
if(i!=k)
{
NSString *yourstring2=[yourarray objectatindex:k];
if([yourstring isEqualtostring yourstring2])
{
//now you got equal objects. do what ever you want here
}
}
}
}

NSMutableArray adds same object each time

I am adding object in NSMutableArray it adds but it adds the same object three time instead of different or new.
Calendar Sow Array has data Breedingdate and sow name.
for (SOWObject *object in appDelegate.calenderSowArray) {
temp = object.breedingDate;
NSLog(#"Date %#",temp);
[arrayNew removeAllObjects];
for (indxs = 0; indxs <countOfarray; indxs ++) {
SOWObject *neObject= (SOWObject *)[appDelegate.calenderSowArray objectAtIndex:indxs];
NSLog(#"Breeding Date %#",neObject.breedingDate);
if ([temp isEqualToString:neObject.breedingDate]) {
[arrayNew removeAllObjects];
[arrayNew addObject:neObject];
}
}
[testArray addObject:arrayNew];
}
Try this,
NSMutableArray *testArray = [[NSMutableArray alloc]init];
for (SOWObject *object in appDelegate.calenderSowArray)
{
[testArray addObject:object];
}
This alone should be enough if you want to add all the SOWObject's in appdelegate.calendarSowArray into the TestArray.
Check if the array contains the object before adding. By doing this a particular object will be added only once.
if(![arrayNew containsObject:neObject]) // if arrayNew does not contain neObject, add it to the array
{
add it to the array
}
or if your testArray is adding same objects, then,
if(![testArray containsObject:arrayNew]) // if testArray does not contain arrayNew, add it to the array
{
add it to the array
}
It looks like you are attempting to create an array of arrays, however the inner array always contains exactly one element. If this is what you want then:
for (SOWObject *object in appDelegate.calenderSowArray) {
temp = object.breedingDate;
NSLog(#"Date %#",temp);
for (indxs = 0; indxs <countOfarray; indxs ++) {
SOWObject *neObject= (SOWObject *)[appDelegate.calenderSowArray objectAtIndex:indxs];
NSLog(#"Breeding Date %#",neObject.breedingDate);
if ([temp isEqualToString:neObject.breedingDate]) {
[testArray addObject:#[ neObject ]]; // This creates a new inner-array each time
}
}
}
And if not (you just want an array) then:
[testArray addObject:neObject];

How can I add elements to an NSDictionary in the following format?

I have an NSArray of names and ages. Now I am trying to create a new NSDictionary with item 0 holding the first name and first age and item 1 holding the second name and second age from the corresponding NSArray? Is that possible?
In my viewDidLoad:
NSMutableArray *Names = [[NSMutableArray alloc] init];
NSMutableArray *ages = [[NSMutableArray alloc] init];
for(int i = 0; i < 4; i++) {
[Names addObject:[candidates objectAtIndex:i]];
[ages addObject:[studenAge objectAtIndex:i]];
}
But how can I make an NSDictionary from this by order?
Final result
I want to write this NSDictionary into a .plist so it look like this:
Details
{
item 0
{
name:rahul
age:25
}
item 1
{
name:ram
age:26
}
item 2
{
name:aajy
age:20
}
item 4
{
name:raj
age:25
}
}
Dictionaries do not have an order.
Probably you want to add dictionaries to the array:
NSMutableArray *persons=[[NSMutableArray alloc]init];
for(int i=0;i<4;i++)
{
[persons addObject:# { #"name" : candidate[i], #"age" : studenAge[i] }];
}
You can sort this array with the sort-Methods of NSArray, NSMutableArray.
As mentioned by #Amin, dictionaries don't maintain order and since you seem to want an indexed access here is what I suggest as the final structure: an array of dictionaries:
NSMutableArray *details = [NSMutableArray array];
for (int i=0; i<4; i++) {
[details addObject:#{#"name": canditate[i], #"age":studentAge[i]}];
}
This will give you the following structure:
[{name:rahul, age:25}, {name:ram age:26},...]

Resources