So I have this method in which I query some Singleton class to get data, I add it to my mutable array called profile details, but It doesn't get added, if i add it to a temp array first and then use that to assign it to my profile details array it works? What's happening here?
//Property declaration
#property (nonatomic, strong) NSMutableArray *profileDetails;
//Method definition
- (void) getAllProfiles : (NSArray *) profiles
{
if (_myHealthDetailService == nil) {
self.myHealthDetailService = [[MyHealthDetailService alloc] init];
}
if (profiles) {
if (self.currentProfileCounter < [profiles count]) {
MyHealth *profile = [profiles objectAtIndex:self.currentProfileCounter];
[self.myHealthDetailService requestForMyHealthDetailWithHealth:profile completion:^(NSArray *healths) {
self.currentProfileCounter = self.currentProfileCounter + 1;
if (healths) {
NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:healths.count];
for (MyHealth *profile in healths) {
NSLog(#"Adding Proile: %#",profile);
[self.profileDetails addObject:profile];
[tempArray addObject:profile];
NSLog(#"Proile details array after adding %# profile is: %#",profile, self.profileDetails);
NSLog(#"Temp Proile details array after adding %# profile is: %#",profile, tempArray);
}
self.profileDetails = tempArray;
NSLog(#"Proile details array after copying is: %#",self.profileDetails);
}
DashboardHealthCell_iPad *cell = (DashboardHealthCell_iPad *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForItem:DashboardRow_iPadTypeHealth inSection:0]];
NSLog(#"Proile details array is: %#",self.profileDetails);
[cell populateMyHealthProfiles:self.profileDetails];
} failureBlock:^(NSError *error) {
}];
}
}
}
Relevant NSLog output:
2014-03-12 12:45:58.144 CHM[9768:70b] Proile details array after adding <MyHealth: 0xd562ce0> profile is: (null)
2014-03-12 12:45:58.144 CHM[9768:70b] Temp Proile details array after adding <MyHealth: 0xd562ce0> profile is: (
"<MyHealth: 0xd562270>",
"<MyHealth: 0xd5629e0>",
"<MyHealth: 0xd562ce0>"
)
2014-03-12 12:45:58.144 CHM[9768:70b] Proile details array after copying is: (
"<MyHealth: 0xd562270>",
"<MyHealth: 0xd5629e0>",
"<MyHealth: 0xd562ce0>"
)
The problem seems to be that self.profileDetails is nil by the time you invoke
[self.profileDetails addObject:profile];
There's no place where you alloc / init that Array, so nothing gets added. You can probably get rid of your tempArray by doing
// this
profileDetails = [NSMutableArray arrayWithCapacity:healths.count];
// instead of this
NSMutableArray *tempArray = [NSMutableArray arrayWithCapacity:healths.count];
Related
How can I pass the event to the toDoArray? I'm not sure what I'm missing. Any help appreciated.
SDEventModel.h
#interface SDEventModel : AWSDynamoDBObjectModel <AWSDynamoDBModeling>
ViewController.h
#property (nonatomic, strong) NSArray *toDoArray;
ViewController.m
if (task.result) {
AWSDynamoDBPaginatedOutput *paginatedOutput = task.result;
for (SDEventModel *event in paginatedOutput.items) {
//Do something with event.
NSLog(#"Task results: %#", event);
[self.toDoArray arrayByAddingObject:event];
NSLog(#"To do array results: %#", self.toDoArray);
[self.tableview reloadData];
}
}
Here is the output of the NSLog.
Task results: <SDEventModel: 0x7faa88d81430> {
city = "New York";
image = "photo-22.jpg";
title = "Hang with friends";
}
To do array results: (null)
The arrayByAddingObject method returns another array with the added object, and does not append the same.
This is how the method is intended to be used:
self.toDoArray = [self.toDoArray arrayByAddingObject:event];
However, in your case, it seems that the array is not even initialized. So you need to do something like this as well:
-(void) viewDidLoad {
[super viewDidLoad];
self.toDoArray = #[];
}
Define toDoArray as NSMutableArray like this in ViewController.h
#property (nonatomic, strong) NSMutableArray *toDoArray;
Now in ViewController.m initialise that array and add objects of event into it
if (task.result) {
self.toDoArray = [NSMutableArray new];
AWSDynamoDBPaginatedOutput *paginatedOutput = task.result;
for (SDEventModel *event in paginatedOutput.items) {
//Do something with event.
NSLog(#"Task results: %#", event);
[self.toDoArray addObject:event];
}
NSLog(#"To do array results: %#", self.toDoArray);
[self.tableview reloadData];
}
Please check Whether the Array in which you are adding object is Mutable or not?
if it is not mutable, you can create a new array or convert existing array to Mutable Array using mutableCopy
Im trying to filter through an array and get rid of all the duplicate strings.
NSMutableArray *initialWomensCategoryArray = [NSMutableArray new];
for(NSArray *womensCategoryInnner in [objects valueForKey:#"womensCategory"])
{
for(id object in womensCategoryInnner)
{
[initialWomensCategoryArray addObject:object];
womensDataArray = [[NSMutableArray alloc]init];
for (id obj in initialWomensCategoryArray)
{
if (![womensDataArray containsObject:obj])
{
[womensDataArray addObject: obj];
}
}
}
}
Above Error want to say "You have getting NULL value" when you have add Object into array. So you have two possibility for this error
1) [initialWomensCategoryArray addObject:object]
2) [womensDataArray addObject: obj]
I think you have to check for the first one([initialWomensCategoryArray addObject:object])
I have two array, called array1 and array2. I would like to remove every object from array1 that's value of the "nameId" key can be find in both array. Actually I'm trying it in a for loop, but it doesn't make sense. It doesn not crash, it just simply calls the log in the else statement, that I don't understand why happens. Maybe somebody could show me the right solution.
NSMutableArray *newArray = [self.array1 mutableCopy];
for (PFObject * object in newArray) {
PFObject *placeholderObject = object;
for (PFObject *object2 in self.array2) {
if ([placeholderObject[#"nameId"] isEqualToString:object2[#"nameId"]]) {
[self.array1 removeObject:object];
NSLog (#"EXISTING OBJECT FOUND %#", object);
} else {
NSLog(#"UNIQUE OBJECT FOUND %#", idO[#"hirCime"]);
}
}
}
When creating a mutableCopy of an array you create a new array with a copy of every object in it but they aren't the same ones, so object is a member of newArray but is not a member of self.array1 so you can't remove it from that array.
This should work:
// Creates a new empty mutable array
NSMutableArray *newArray = [#[] mutableCopy];
for (PFObject *object in self.array) {
BOOL found = NO;
for (PFObject *object2 in self.array2) {
if ([object[#"nameId"] isEqualToString:object2[#"nameId"]]) {
found = YES;
NSLog (#"EXISTING OBJECT FOUND %#", object);
break;
} else {
NSLog(#"UNIQUE OBJECT FOUND %#", idO[#"hirCime"]);
}
}
if (!found) {
[newArray addObject:[object copy]];
}
}
// And maybe you want this
self.array = newArray;
I have an app that I need to support till the original developer comes back.
Basically it has a method that groups the data into sections of UITableView.
It all works very nicely and shows the Sections by DogLocation.
This is the code I have :
-(void)loadSortedData:(NSString*)breedToLoad fieldToSort:(NSString*)sortField
{
self.items = [DbUtilities getDogsByBreed:breedToLoad SortField:sortField];
NSMutableDictionary * theDictionary = [NSMutableDictionary dictionary];
for ( Dog * object in self.items )
{
NSMutableArray * theMutableArray = [theDictionary objectForKey:object.DogLocation];
if ( theMutableArray == nil )
{
theMutableArray = [NSMutableArray array];
[theDictionary setObject:theMutableArray forKey:object.DogLocation];
}
[theMutableArray addObject:object];
}
self.sortedMediaItems = [[theDictionary allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
/* Save `theDictionary` in an instance variable */
self.theSource = theDictionary;
[self.tableView reloadData];
}
I call this method in my ViewDidLoad by using following syntax:
[self loadSortedData:#"Cattle" fieldToSort:#"DogLocation"];
What I am trying to achieve is to be able to call this method by passing a value in the method e.g so that I can sort it by other fields and not just the DogLocation e.g DogAge,DogPrice .
Could anyone kindly direct me or show me a better way to achieve this instead of writing big if else statement?
Thank you in advance.
You can try using the M13OrderedDictionary, it's based on NSObject not NSDictionary but it does the job required: https://github.com/Marxon13/M13OrderedDictionary
As long as sortField is always a valid property of Dog, you can use Key-Value Coding.
for ( Dog * object in self.items )
{
id key = [object valueForKey:sortField];
NSMutableArray * theMutableArray = [theDictionary objectForKey:key];
if ( theMutableArray == nil )
{
theMutableArray = [NSMutableArray array];
[theDictionary setObject:theMutableArray forKey:key];
}
[theMutableArray addObject:object];
}
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.