get single FetchedObject from FCR to write Label - ios

I have a problem with my FCR. I want to show my datas on Labels but FCR doesnt allow me.There is my codes..
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"faturaAdi == 'ADSL' "];
I have fetched only 1 data which fatura name is ADSL.. and I want to write this faturaAdi on my label but i couldn't do that.
NSArray *array = [[NSArray alloc]init];
array = self.fetchedResultsController.fetchedObjects;
_lblFaturaAdi.text = [self.fetchedResultsController.fetchedObjects valueForKey:#"faturaAdi"];
NSLog(#"%#",[array valueForKey:#"faturaAdi"]);
NSLog shows Takip[967:60b] (
ADSL
)
When i put the
_lblFaturaAdi.text = [self.fetchedResultsController.fetchedObjects valueForKey:#"faturaAdi"];
app crash with this error ;
-[__NSArrayI length]: unrecognized selector sent to instance 0xa18c740
how can i solve this ?

Your code should change to:
NSArray *array = self.fetchedResultsController.fetchedObjects;
if (array.count > 0) {
self.lblFaturaAdi.text = [[array objectAtIndex:0] valueForKey:#"faturaAdi"];
NSLog(#"%#", _lblFaturaAdi.text);
} else {
NSLog(#"no results found");
}
Because you don't need to initialise an array before replacing it and you need to index into the array before you can extract the value.

Related

How to add an index to an NSMutableArray based on value in another array?

I've looked at lots of questions about NS(Mutable)Arrays. I guess I am not grokking the concept, or the questions don't seem relevant.
What I' trying to do is the following:
Incoming Array 1:
Name
Code
Start time
End Time
etc
Incoming Array 2
Code
Ordinal
What I want:
Ordinal
Name
Code
Start time
End Time
etc
This is my code at present:
int i=0;
for (i=0; i < stationListArray.count; i++) {
NSString *slCodeString = [stationListArray[i] valueForKey:#"Code"];
NSLog(#"slCodeString: %#", slCodeString);
int j=0;
for (j=0; j< lineSequenceArray.count; j++) {
NSString *lsCodeString = [lineSequenceArray[j]valueForKey:#"StationCode"];
NSLog(#"lsCodeString: %#", lsCodeString);
if ([slCodeString isEqualToString:lsCodeString]) {
NSLog(#"match");
NSString *ordinalString = [lineSequenceArray[j] valueForKey:#"SeqNum"];
NSLog(#"ordinalString: %#", ordinalString);
[stationListArray[i] addObject:ordinalString]; <------
}
}
}
I'm logging the values and they return correctly.
The compiler doesn't like the last statement. I get this error:
[__NSCFDictionary addObject:]: unrecognized selector sent to instance 0x7f9f63e13c30
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary addObject:]: unrecognized selector sent to instance 0x7f9f63e13c30'
Here is an excerpt from the StationListArray:
(
{
Address = {
City = Greenbelt;
State = MD;
Street = ".....";
Zip = 20740;
};
Code = E10;
Lat = "39.0111458605";
Lon = "-76.9110575731";
Name = Greenbelt;
}
)
NSString *ordinalString = [lineSequenceArray[j] valueForKey:#"SeqNum"]; //Is NSString
[stationListArray[i] addObject:ordinalString];//<----- trying to call addObject method of NSMutableArray on NSDictionary -> Not GOOD
When you do [stationListArray[i] you get NSDictionary in your case
(Generally it returns an NSObject that is inside the NSArray at the given index, in your case is NSDictionary).
So in order to complete your desired operation: you should make an NSMutableDictionary instance (In this case it should be the mutableCopy from the stationListArray[i]'s NSObject which is NSDictionary, when you do mutableCopy it copies the entire NSDictionary and makes it Mutable)
make the changes on it and then assign it in to the stationListArray[i]
For example:
NSMutableDictionary * tempDict = [[stationArray objectAtIndex:i]mutableCopy];//Create a mutable copy of the `NSDictionary` that is inside the `NSArray`
[[tempDict setObject:ordinalString forKey:#"Ordinal"]; //In this line you are adding the Ordinal `NSString` in to the tempDict `NSMutableDictionary` so now you have the desired `NSMutableDictionary`. You can change the key to whatever you wish.
[stationArray replaceObjectAtIndex:i withObject:[tempDict copy]];//Swap the original(old NSDictionary) with the new updated `NSMutableDictionary` I used the copy method in order to replace it with the IMMUTABLE `NSDictionary`
[stationListArray[i] addObject:ordinalString]; <------
This is not an NSMutableArray. You must use
[stationListArray addObject:ordinalString]; <------
instead of the what you have done.
Here is the way you can write a better understandable code because for me the code is not clear.You can also try like this in loop to achieve what you want.
NSMutableArray *array = [NSMutableArray new];
NSMutableDictionary *dictMain = [NSMutableDictionary new];
NSMutableDictionary *dictAddress = [NSMutableDictionary new];
[dictAddress setValue:#"Greenbelt" forKey:#"City"];
[dictAddress setValue:#"MD" forKey:#"State"];
[dictAddress setValue:#"....." forKey:#"Street"];
[dictAddress setValue:#"20740" forKey:#"Zip"];
[dictMain setValue:dictAddress forKey:#"Address"];
[dictMain setValue:#"E10" forKey:#"Code"];
[dictMain setValue:#"39.0111458605" forKey:#"Lat"];
[dictMain setValue:#"-76.9110575731" forKey:#"Lon"];
[dictMain setValue:#"Greenbelt" forKey:#"Name"];
[array addObject:dictMain];

trouble retrieving string from array

I am working with the following function atm, but I'm banging my head against a wall.
-(double)fetchTimeUntilNextUpdateInSeconds{
NSFetchRequest *fetchReq = [[NSFetchRequest alloc]initWithEntityName:#"DataInfo"];
fetchReq.predicate = [NSPredicate predicateWithFormat:#"data_info_id == 1"];
[fetchReq setPropertiesToFetch:[NSArray arrayWithObject:#"nextupdate"]];
NSArray *array = [self.context executeFetchRequest:fetchReq error:nil];
NSString *string = [[array valueForKey:#"nextupdate"] stringValue];
NSLog(#"string: %# array count:%lu", string, (unsigned long)array.count);
NSArray *hoursAndMins = [string componentsSeparatedByString:#":"];
int hours = [hoursAndMins[0] intValue];
int mins = [hoursAndMins[1] intValue];
return (mins*60)+(hours*60*60);
}
LOG: string: (
"05:42"
) array count:1
I'm getting following error: -[__NSArrayI componentsSeparatedByString:]: unrecognized selector sent to instance 0x174224060'
fair enough, i try to invoke "stringValue" method on string (as showed in code snippet) and get the following instead:
-[__NSArrayI stringValue:]: unrecognized selector sent to instance 0x174224060'
The ladder makes me think I'm already receiving a string as stringValue is not a method of that class.... but why won't the first work then. Better yet, what am I doing wrong here?
I guess, executeFetchRequest returns an array containing always one item.
The mistake is the method valueForKey which is ambiguous. It's a key value coding method as well as a method of NSManagedObject. If you want to get the value of a key of one object, so first get the first object from the array and then call valueForKey.
NSArray *array = [self.context executeFetchRequest:fetchReq error:nil];
// get the value of the key `nextUpdate` of the first item of the array
NSString *string = [array[0] valueForKey:#"nextupdate"];
To make clear what's happening when valueForKey is sent to an array, see this code, it returns an array of the values for the key id of all members of the array.
NSArray *array = #[#{#"name" : #"John", #"id" : #"1"}, #{#"name" : #"Jane", #"id" : #"2"}];
NSLog(#"%#", [array valueForKey:#"id"]); // --> #[#"1", #"2"]
Uhh, could also be the case that ( "05:42" ) has quotation marks that you may need to escape before you write this as a string to an array. OR you just maybe need to typecast the value of string AGAIN, but instead of doing that, why not try this first and tell us what happens.
NSArray *hoursAndMins = [[[array valueForKey:#"nextupdate"] stringValue] componentsSeparatedByString:#":"];

Removing object from array doesnt remove anything

I have:
self.path = [self pathByCopyingFile:#"Notes List.plist"];
self.data = [[NSMutableDictionary alloc] initWithContentsOfFile:self.path];
self.notes = [self.data objectForKey:#"Notes"];
Then in a button (Button method definitely gets called):
NSString *title = self.navigationItem.title;
//Filter notes array by title
NSPredicate *pred = [NSPredicate predicateWithFormat:#"Title =[cd] %#", title];
NSArray * titleArray = [self.notes filteredArrayUsingPredicate:pred];
//delete all the notes with the old title name
[self.notes removeObject:titleArray];
NSLog(#"%#", self.notes);
At this point, self.notes still contains the items and i dont know why they arnt being removed
You are trying to remove an array from the array. That's not what you want. I believe your goal is to remove all of the objects in the titleArray from your notes array.
And this doesn't even consider that self.notes is probably an NSArray and not an NSMutableArray.
If self.notes is mutable you can use the removeObjectsInArray:.
[self.notes removeObjectsInArray:titleArray];

How to filter an NSArray using a NSPredicate

I am trying to filter an array of NSDictionaries that I have.
This is what my filter currently looks like:
NSDictionary *selectedItemDictionary = [sortedItemsArray objectAtIndex:indexPath.row];
NSMutableArray *sortedItemsMutableArrayCopy = [sortedItemsArray copy];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"dpc like %#", [selectedItemDictionary objectForKey:#"dpc"]];
[sortedItemsMutableArrayCopy filterUsingPredicate:predicate];
This is what my selectedItemDictionary looks like:
dc = 3;
Cmp = F;
Qty = 0;
dp = 0;
Effectively I am trying to search through sortedItemsArray and make a new array of anything that has the same dc number as the selected row in my UITableViewCell. However with the code above I am receiving this error:
-[__NSArrayI filterUsingPredicate:]: unrecognized selector sent to instance
filterUsingPredicate: is a method for NSMutable array you are looking for filteredArrayUsingPredicate:
you can tell from the console output __NSArrayI that you have an immutable array instance.
if you want a mutable array you need to change [sortedItemsArray copy] to [sortedItemsArray mutableCopy]

Optimizing query for search using nspredicates

This issue has been brought up a lot but I can't seem to optimize this piece of search code any further.
this filterSet array has about 1000 items and it's taking 8 seconds to reproduce results on a non-simulator iPad (simulator shows results in less than a second):
for(NSString *rowID in [self.filterSet array]) {
self.rowResults = [self.filteredResults filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"rowID = %#", rowID]];
self.rowResults = [self.rowResults valueForKey:#"value"];
self.duplicateValueSet = [NSOrderedSet orderedSetWithArray:self.rowResults];
filterCount = [[self.resultsArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF = %#", rowID]] count];
if([self.duplicateValueSet count] != filterCount)
filterCount -= abs([self.duplicateValueSet count] - filterCount);
if(filterCount == matchingCount)
[self.results addObject:rowID];
}
any suggestions to optimizing this query? The majority of the search is taken up in all the filters and predicate sorting. thanks.
edit: so i removed a lot of the code in the for loop and found the culprit to be the first line
self.rowResults = [self.filteredResults filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"rowID = %#", rowID]];
this is for some reason taking 7 seconds to execute. Is there a faster/more efficient way to create a predicate to match the rowID string? I've thought about using the makeobjectsperformselector NSArray method but for some reason I get the NSCFNumber unrecognized selector issue (which is saying my array has NSNumbers instead of NSStrings)
so my initial algorithm was running at O(N^2) which is pretty much as bad as it gets (realistically).
I've ended up using an NSDictionary to map keys/values so that I can easily reference them within the first for loop's first pass:
NSMutableDictionary *filteredResultsDict = [[[NSMutableDictionary alloc] init] autorelease];
for (int i = 0; i < [filteredResults count]; i++) {
NSString *key = [[filteredResults objectAtIndex:i] valueForKey:#"rowID"];
NSMutableArray *filtersArray = [NSMutableArray array];
NSMutableArray *tempArray = [filteredResultsDict objectForKey:key];
if (tempArray != nil || [tempArray count] > 0) {
[tempArray addObject:[filteredResults objectAtIndex:i]];
[filteredResultsDict setValue:tempArray forKey:key];
}
else {
[filtersArray addObject:[filteredResults objectAtIndex:i]];
[filteredResultsDict setValue:filtersArray forKey:key];
}
}
and then in my actual for loop, I can call this in place of the previous rowResults:
NSNumber *rowIDNum = [NSNumber numberWithInteger: [rowID integerValue]];
rowResults = [[filteredResultsDict objectForKey:rowIDNum] valueForKey:#"value"];

Resources