Objective c simple sorting using NSSortDescriptor - xcode

I want to simple sorting in nslog , this is my viewcontroller.
- (void)viewDidLoad {
[super viewDidLoad];
sobj=[[SortObjects alloc]init];
sobj.description; //this doesn't work
[sobj description];//this doesn't work either
NSLog(#"sobj = %#", sobj);
}`
& here is my Object Class SortObjects.h
enter code here- (NSString *)description {
return [NSString stringWithFormat:#"%# %#", self.firstName, self.lastName];
NSArray *firstNames = #[ #"Alice", #"Bob", #"Charlie", #"Quentin" ];
NSArray *lastNames = #[ #"Smith", #"Jones", #"Smith", #"Alberts" ];
NSArray *ages = #[ #24, #27, #33, #31 ];
NSMutableArray *people = [NSMutableArray array];
[firstNames enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
SortObjects *sObjects = [[SortObjects alloc] init];
sObjects.firstName = [firstNames objectAtIndex:idx];
sObjects.lastName = [lastNames objectAtIndex:idx];
sObjects.age = [ages objectAtIndex:idx];
[people addObject:sObjects];
}];
NSSortDescriptor *firstNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"firstName"
ascending:YES
selector:#selector(localizedStandardCompare:)];
NSSortDescriptor *lastNameSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"lastName"
ascending:YES
selector:#selector(localizedStandardCompare:)];
NSSortDescriptor *ageSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"age"
ascending:NO];
NSLog(#"By age: %#", [people sortedArrayUsingDescriptors:#[ageSortDescriptor]]);
value of sobj is coming null in nslog??

Related

issue loading core data into uitableview

I have been trying to figure this issue out for days now with no luck, any advice would be greatly appreciated.
I have a uitableviewcontroller that loads data from core data. When the tableview loads, the first 6 (no matter how many objects are actually saved) are loaded. When I begin to scroll down, all of the following cells are labeled "(null)". When I go back up to the top, the data in the original 6 cells are replaced with "(null)". When I logged the contents of the array from the fetch, all of the objects from core data get logged, but when I log the contents of the cell, the first 6 contents get logged, the a long list of rows with (null) get logged.
I've tried a lot of differnet things to debug this, but nothing has worked so far.
Here is the tableviewcontroller file
-(void)viewWillAppear:(BOOL)animated
{
[self setTitle:#"My Safe"];
self.dictionaryWithContent = [[NSMutableDictionary alloc] init];
self.search = #0;
[self fetchDataFromCoreData];
[self.tableView setFrame:CGRectMake(0, 88, self.tableView.bounds.size.width, self.tableView.bounds.size.height)];
self.searchResults = [[NSMutableArray alloc] init];
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 44.0f)];
UIBarButtonItem *changeViewsButton = [[UIBarButtonItem alloc] initWithTitle:#"Tweets By User"
style:UIBarButtonItemStylePlain
target:self
action:#selector(switchViewControllers)];
self.navigationItem.rightBarButtonItem = changeViewsButton;
self.tableView.delegate = self;
self.tableView.dataSource = self;
// CGRect searchView = CGRectMake(0, 44, self.tableView.bounds.size.width, 44);
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
[self.searchController loadViewIfNeeded];
self.tableView.tableHeaderView = self.searchController.searchBar;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.barTintColor = twitter_blue;
self.searchController.delegate = self;
self.searchController.searchBar.delegate = self;
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
self.navigationController.navigationBar.barTintColor = twitter_blue;
self.navigationController.navigationBar.translucent = NO;
self.navigationController.navigationBar.tintColor = [UIColor whiteColor];
[self.navigationController.navigationBar setTitleTextAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]}];
}
-(void)fetchDataFromCoreData
{
AppDelegate *del = [[AppDelegate alloc] init];
NSManagedObjectContext *context = del.managedObjectContext;
NSString *entity;
entity = [NSString stringWithFormat:#"Tweet"];
NSFetchRequest *fet = [NSFetchRequest fetchRequestWithEntityName:entity];
NSError *e;
NSArray *array = [context executeFetchRequest:fet error:&e];
self.arrayWithContent = [[NSArray alloc] initWithArray:array];
for (Tweet *t in self.arrayWithContent) {
NSLog(#"array %#", t.messageOfTweet);
}
}
-(void)switchViewControllers
{
PCRSavedTweetByUserTableViewController *vc = [[PCRSavedTweetByUserTableViewController alloc] init];
PCRNavigationBarController *navBarControllerOfSafeSide = [[PCRNavigationBarController alloc] initWithRootViewController:vc];
[self.navigationController presentViewController:navBarControllerOfSafeSide animated:YES completion:nil];
}
#pragma mark Status bar
- (void)willPresentSearchController:(UISearchController *)searchController {
// do something before the search controller is presented
self.navigationController.navigationBar.translucent = YES;
}
-(void)willDismissSearchController:(UISearchController *)searchController
{
self.navigationController.navigationBar.translucent = NO;
searchController = self.searchController;
}
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
searchController = self.searchController;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
self.search = #1;
[self.searchResults removeAllObjects];
NSString *searchBarString = self.searchController.searchBar.text;
for (Tweet *tweet in self.arrayWithContent){
if ([tweet.messageOfTweet containsString:searchBarString] || [tweet.userNameOfTweetUser containsString:searchBarString] || [tweet.whoPosted.name containsString:searchBarString]) {
[self.searchResults addObject:tweet];
}
}
[self.tableView reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[self.searchController.searchBar resignFirstResponder];
self.search = #0;
[self.tableView reloadData];
}
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
self.searchController.searchBar.text = #"";
}
#pragma mark Table
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
return [self.arrayWithContent count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 120.0f;
}
- (PCRTweetFeedCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
PCRTweetFeedCell *cell = [tableView dequeueReusableCellWithIdentifier:#"PCRSavedTweetFeedCell"];
PCRTweet *tweetLocal = [[PCRTweet alloc] init];
if (cell == nil) {
cell = [[PCRTweetFeedCell alloc] initWithTweet:tweetLocal reuseIdentifier:#"PCRSavedTweetFeedCell"];
}
Tweet *tweetForIndex;
NSArray *arrayForCell = [[self.arrayWithContent reverseObjectEnumerator] allObjects];
NSArray *searchArrayForCell = [[self.searchResults reverseObjectEnumerator] allObjects];
if ([self.search isEqual:#0]){
tweetForIndex = [arrayForCell objectAtIndex:indexPath.row];
} else if ([self.search isEqual:#1]){
tweetForIndex = [searchArrayForCell objectAtIndex:indexPath.row];
}
NSString *date = [NSString stringWithFormat:#"%#", tweetForIndex.dateOfTweet];
TweetUser *tweetUser = tweetForIndex.whoPosted;
cell.t = tweetForIndex;
UIImage *imageOfTweetUser;
if (tweetUser.profilePicture) {
imageOfTweetUser = [UIImage imageWithData:tweetUser.profilePicture];
} else {
NSURL *urlWithProfilePicture = [NSURL URLWithString:tweetUser.profilePictureURL];
NSData *dataWithPic = [NSData dataWithContentsOfURL:urlWithProfilePicture];
imageOfTweetUser = [UIImage imageWithData:dataWithPic];
}
self.imageOfTweetUserGlobal = imageOfTweetUser;
cell.tweetMessage.text = tweetForIndex.messageOfTweet;
cell.tweetDate.text = date;
cell.tweetUserNameLabel.text = tweetForIndex.userNameOfTweetUser;
cell.profilePictureOfTwitterUserImageView.image = imageOfTweetUser;
cell.nameForPassing = [NSString stringWithFormat:#"%#'s Tweet", tweetUser.name];
return cell;
}
Well maybe this is your problem.
if ([self.search isEqual:#0]){
I think you are initially fetching the data but than once you init the searchController it starts looking for the searchResults.
The code you are looking is:
if ([self.search isActive]){
I found the solution. I changed
AppDelegate *del = [[AppDelegate alloc] init];
NSManagedObjectContext *context = del.managedObjectContext;
to
AppDelegate *del = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context =[del managedObjectContext];
and it works perfectly.

Different table view cell row heights for different size classes?

How can I change this UITableViewController custom class to dynamically change the height of the Table View Cells? I have specified different font sizes for the iPad and iPhone size classes.
(This is a continuation of a previous discussion with #rdelmar)
#import "CREWFoodWaterList.h"
#interface CREWFoodWaterList ()
#end
#implementation CREWFoodWaterList
#define VIEW_NAME #"FoodWaterList" // add to database for this view and notes view
#define VIEW_DESCRIPTION #"Food Water - items to keep available" // to add to the database
#define RETURN_NC #"NCSuggestedContentsMenu" // where to return to when complete processing should be specified there
#define NOTES_TITLE #"Food and Water Notes" // pass to notes VC
#define THIS_NC #"NCFoodWaterList" // pass to next VC (so returns to the NC for this view)
- (IBAction)changedSwitch:(UISwitch *)sender {
if (sender.tag == 0) {
[self saveSwitch: #"switchWater" toValue:[NSNumber numberWithBool:sender.on]];
} else if (sender.tag == 1) {
[self saveSwitch: #"switchCanned" toValue:[NSNumber numberWithBool:sender.on]];
} else if (sender.tag == 2) {
[self saveSwitch: #"switchComfort" toValue:[NSNumber numberWithBool:sender.on]];
} else if (sender.tag == 3) {
[self saveSwitch: #"switchSpecial" toValue:[NSNumber numberWithBool:sender.on]];
}
} // end of changedSwitch
-(void)loadSavedSwitches {
// now set the switches to previously stored values
NSNumber *switchValue;
switchValue = [self getSwitch: #"switchWater"];
if ([switchValue intValue] == 0) {
self.switchWater.on = NO;
} else {
self.switchWater.on = YES;
}
self.textWater.text = [self getDescription:#"switchWater"];
switchValue = [self getSwitch: #"switchCanned"];
if ([switchValue intValue] == 0) {
self.switchCanned.on = NO;
} else {
self.switchCanned.on = YES;
}
self.textCanned.text = [self getDescription:#"switchCanned"];
switchValue = [self getSwitch: #"switchComfort"];
if ([switchValue intValue] == 0) {
self.switchComfort.on = NO;
} else {
self.switchComfort.on = YES;
}
self.textComfort.text = [self getDescription:#"switchComfort"];
// self.textComfort.textColor = [UIColor whiteColor];
switchValue = [self getSwitch: #"switchSpecial"];
if ([switchValue intValue] == 0) {
self.switchSpecial.on = NO;
} else {
self.switchSpecial.on = YES;
}
self.textSpecial.text = [self getDescription:#"switchSpecial"];
}
- (void) createNewSwitches {
// set create all switches and set to off
[self newSwitch: #"switchWater" toValue:#"At least three litres of bottle water per person per day"];
[self newSwitch: #"switchCanned" toValue:#"Canned foods, dried goods and staples"];
[self newSwitch: #"switchComfort" toValue:#"Comfort foods"];
[self newSwitch: #"switchSpecial" toValue:#"Food for infants, seniors and special diets"];
}
// COMMON Methods
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 50;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// set font size for table headers
[[UIDevice currentDevice] model];
NSString *myModel = [[UIDevice currentDevice] model];
NSInteger nWords = 1;
NSRange wordRange = NSMakeRange(0, nWords);
NSArray *firstWord = [[myModel componentsSeparatedByString:#" "] subarrayWithRange:wordRange];
NSString *obj = [firstWord objectAtIndex:0];
if ([obj isEqualToString:#"iPad"]) {
[[UILabel appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setFont:[UIFont boldSystemFontOfSize:26]];}
else if ([obj isEqualToString:#"iPhone"]) {
[[UILabel appearanceWhenContainedIn:[UITableViewHeaderFooterView class], nil] setFont:[UIFont boldSystemFontOfSize:16]];
};
[defaults setObject:NOTES_TITLE forKey: #"VCtitle"]; // pass to notes VC
[defaults setObject:VIEW_NAME forKey: #"VCname"]; // pass to notes VC to use to store notes
[defaults setObject:THIS_NC forKey: #"CallingNC"]; // get previous CallingNC and save it for use to return to in doneAction
[self initializeView];
} // end of viewDidLoad
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.tableView reloadData]; // this was necessary to have the cells size correctly when the table view first appeared
}
- (void) initializeView {
CREWAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"View" inManagedObjectContext:context];
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(viewName = %#)", VIEW_NAME];
[request setPredicate:pred];
NSError *error = nil;
NSArray * objects = [context executeFetchRequest:request error:&error];
if ([objects count] == 0) { // create new view instance
NSManagedObject * newView;
newView = [NSEntityDescription insertNewObjectForEntityForName:#"View" inManagedObjectContext:context];
[newView setValue:VIEW_NAME forKey:#"viewName"];
[newView setValue:VIEW_DESCRIPTION forKey:#"viewDescription"];
// create all switches and set to off
[self createNewSwitches];
}
// load all switches
[self loadSavedSwitches];
} // end of initializeView
// create a new switch
- (void) newSwitch:(NSString*)switchName toValue:(NSString*)switchDescription {
NSError *error = nil;
CREWAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSManagedObject * newSwitch;
newSwitch = [NSEntityDescription insertNewObjectForEntityForName:#"Switch" inManagedObjectContext:context];
[newSwitch setValue:VIEW_NAME forKey:#"viewName"];
[newSwitch setValue:switchName forKey:#"switchName"];
[newSwitch setValue:switchDescription forKey:#"switchDescription"];
[newSwitch setValue:[NSNumber numberWithInt:0] forKey:#"switchValue"];
if (! [context save:&error])
// NSLog(#"**** START entering %#",VIEW_NAME);
NSLog(#"newSwitch Couldn't save new data! Error:%#", [error description]);
} // end of newSwitch
// read existing switch settings
- (NSNumber *) getSwitch:(NSString*)switchName {
CREWAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"Switch" inManagedObjectContext:context];
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(viewName = %#) AND (switchName = %#)", VIEW_NAME, switchName];
[request setPredicate:pred];
// Execute Fetch Request
NSManagedObjectContext * matches = nil;
NSError *fetchError = nil;
NSArray *objects = [appDelegate.managedObjectContext executeFetchRequest:request error:&fetchError];
if (fetchError) {
};
NSNumber *switchValue;
if (! [objects count] == 0) {
matches = objects [0];
switchValue = [matches valueForKey : #"switchValue"];
}
return switchValue;
} // end of getSwitch
- (NSString *) getDescription:(NSString*)switchName {
CREWAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"Switch" inManagedObjectContext:context];
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(viewName = %#) AND (switchName = %#)", VIEW_NAME, switchName];
[request setPredicate:pred];
// Execute Fetch Request
NSManagedObjectContext * matches = nil;
NSError *fetchError = nil;
NSArray *objects = [appDelegate.managedObjectContext executeFetchRequest:request error:&fetchError];
if (fetchError) {
// NSLog(#"**** START entering %#",VIEW_NAME);(#"getSwitch Fetch error:%#", fetchError); // no
};
NSString *switchDescription;
if (! [objects count] == 0) {
matches = objects [0];
switchDescription = [matches valueForKey : #"switchDescription"];
}
return switchDescription;
} // end of getDescription
- (void)saveSwitch:(NSString*)switchName toValue:(NSNumber*)newSwitchValue {
CREWAppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:#"Switch" inManagedObjectContext:context]; // get switch entity
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(viewName = %#) AND (switchName = %#)", VIEW_NAME, switchName ];
[request setPredicate:pred];
NSManagedObject *matches = nil;
NSError *fetchError = nil;
NSArray * objects = [context executeFetchRequest:request error:&fetchError];
if (![objects count] == 0) {
matches = objects[0];
}
[matches setValue:newSwitchValue forKey:#"switchValue"];
if (! [context save:&fetchError])
// NSLog(#"**** START entering %#",VIEW_NAME);
NSLog(#"saveSwitch Couldn't save data! Error:%#", [fetchError description]); // perhaps this can be Done later
} // end of saveSwitch
// set alternate cells to different colors
- (UIColor *)getUIColorObjectFromHexString:(NSString *)hexStr alpha:(CGFloat)alpha
{
// Convert hex string to an integer
unsigned int hexint = [self intFromHexString:hexStr];
// Create color object, specifying alpha as well
UIColor *color =
[UIColor colorWithRed:((CGFloat) ((hexint & 0xFF0000) >> 16))/255
green:((CGFloat) ((hexint & 0xFF00) >> 8))/255
blue:((CGFloat) (hexint & 0xFF))/255
alpha:alpha];
return color;
}
// Helper method..
- (unsigned int)intFromHexString:(NSString *)hexStr
{
unsigned int hexInt = 0;
// Create scanner
NSScanner *scanner = [NSScanner scannerWithString:hexStr];
// Tell scanner to skip the # character
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:#"#"]];
// Scan hex value
[scanner scanHexInt:&hexInt];
return hexInt;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *grayishCyan = #"#a3c9ca";
NSString *grayishRed = #"#caa4a3";
UIColor *colorCyan = [self getUIColorObjectFromHexString:grayishCyan alpha:.9];
UIColor *colorPink = [self getUIColorObjectFromHexString:grayishRed alpha:.9];
// // NSLog(#"**** START entering %#",VIEW_NAME);(#"UIColor: %#", colorPink);
if (indexPath.row == 0 || indexPath.row%2 == 0) {
cell.backgroundColor = colorCyan;
}
else {
cell.backgroundColor = colorPink;
}
}
- (IBAction)doneAction:(id)sender {
// NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
UIViewController *viewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:RETURN_NC]; // previous Navigation controller
[self presentViewController:viewController animated:YES completion:nil];
};
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#end

How can I sort all index of objects in array

I am using this line of code; my array contains name, email and phone no. This code only sorts namewise, but I want email and phone no with name. How can I do this that my array separeNamesByLetters contains email and phone with name?
NSMutableSet *firstCharacters = [NSMutableSet setWithCapacity:0];
for( NSString*string in [ tableDataArray valueForKey:#"name"] ){
[firstCharacters addObject:[[string substringToIndex:1] uppercaseString]];
}
NSArray *allLetters = [[firstCharacters allObjects] sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
int indexLetter = 0;
separeNamesByLetters = [NSMutableArray new];
for (NSString *letter in allLetters) {
NSMutableDictionary*userBegeinsWith = [NSMutableDictionary new];
[userBegeinsWith setObject:letter forKey:#"letter" ];
NSMutableArray *groupNameByLetters = [NSMutableArray new];
NSString *compareLetter1 = [NSString stringWithFormat:#"%#", allLetters[indexLetter]];
for (NSString*friendName in[ tableDataArray valueForKey:#"name"]) {
NSString *compareLetter2 = [[friendName substringToIndex:1] uppercaseString];
if ( [compareLetter1 isEqualToString:compareLetter2] ) {
[groupNameByLetters addObject:friendName];
}
}
indexLetter++;
[userBegeinsWith setObject:groupNameByLetters forKey:#"list"];
[separeNamesByLetters addObject: userBegeinsWith];
}
NSLog(#"%#", separeNamesByLetters);
}
Have you considered using NSSortDescriptors? See the following example:
NSMutableArray *array = [NSMutableArray new];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"Doe, John", #"name", #"3361231234", #"phone", #"johndoe#email.com", #"email", nil];
[array addObject:dict];
dict = [NSDictionary dictionaryWithObjectsAndKeys:#"Doe, Jane", #"name", #"9191234532", #"phone", #"janedoe#email.com", #"email", nil];
[array addObject:dict];
NSSortDescriptor *nameDescriptor =
[[NSSortDescriptor alloc]
initWithKey:#"name"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)];
NSSortDescriptor *phoneDescriptor =
[[NSSortDescriptor alloc]
initWithKey:#"phone"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)];
NSSortDescriptor *emailDescriptor =
[[NSSortDescriptor alloc]
initWithKey:#"email"
ascending:YES
selector:#selector(localizedCaseInsensitiveCompare:)];
NSArray * descriptors = [NSArray arrayWithObjects:nameDescriptor, phoneDescriptor, emailDescriptor, nil];
NSArray * sortedArray = [array sortedArrayUsingDescriptors:descriptors];
Let me know if this helps.
When I do this, I create a new NSArray of NSDictionaries. The NSDictionary has two properties: sectionTitle and records. The sectionTitle holds the first-letter of the field you are searching on. The records contain the actual objects that begin with that sectionTitle.
Add this sectionTitle method to your model class. I usually do this in an Extension to the actual model class.
- (NSString *)sectionTitle:(NSString*)sortByProperty {
NSString *propertyValue;
if ([sortByProperty isEqualToString:#"name"]) {
if (self.name == nil) return #"";
propertyValue = self.name;
} else if ([sortByProperty isEqualToString:#"email"]) {
if (self.email == nil) return #"";
propertyValue = self.phone;
} else if ([sortByProperty isEqualToString:#"phone"]) {
if (self.phone == nil) return #"";
propertyValue = phone
}
NSString *tmp;
if ([propertyValue length] > 0) {
tmp = [propertyValue substringToIndex:1];
} else {
return #"";
}
return tmp;
}
This should be quicker than iterating through your array each time you refresh your tableView.
Next, iterate through these sectionTitles, filter your array, and add the filtered results to the records attribute of the dictionary:
- (NSMutableArray*)sortedArrayForUITableView:(NSMutableArray *)tableDataArray sortBy:(NSString*)sortByProperty {
NSArray *tmp = [tableDataArray valueForKeyPath:#"#distinctUnionOfObjects.sectionTitle"];
NSArray *allLetters = [NSMutableArray arrayWithArray:[tmp sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:#"self" ascending:YES]]]];
NSMutableArray *tree = [NSMutableArray new];
for (NSString *sectionTitle in allLetters) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.sectionTitle == %#", sectionTitle];
NSMutableArray *tmpArray = [NSMutableArray arrayWithArray:[tableDataArray filteredArrayUsingPredicate:predicate]];
NSArray *sortedArray = [tmpArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:sortByProperty ascending:YES]]];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:sectionTitle, #"sectionTitle", sortedArray, #"records", nil];
[tree addObject:dict];
}
return tree;
}
You will need to implement several UITableViewDataSource and UITableViewDelegate methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.tree count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *dict = [NSDictionary dictionaryWithDictionary:[self.tree objectAtIndex:section]];
NSArray *tmp = [NSArray arrayWithArray:[dict objectForKey:#"records"]];
return [tmp count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSDictionary *dict = [NSDictionary dictionaryWithDictionary:[self.tree objectAtIndex:section]];
return [dict objectForKey:#"sectionTitle"];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return self.allLetters;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return index;
}
Lastly, you will build your cell in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath. Hope that helps.

Save Array to plist

I'm trying to store some items into a pList. Here is the array loop:
for (id obj in items)
NSLog(#"obj: %#", obj);
Output NSLog:
2013-03-27 13:00:40.072 mycode[47436:c07] obj: Red
2013-03-27 13:00:40.073 mycode[47436:c07] obj: Blue
2013-03-27 13:00:40.073 mycode[47436:c07] obj: Green
// The arrayWithObjects works. But I don't know how to (loop?) through my items for saving into the plist file...
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"data.plist"];
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: path]) {
NSLog(#"%#", path);
NSMutableDictionary *plist = [[NSDictionary dictionaryWithContentsOfFile:path] mutableCopy];
NSMutableArray *newArray = [[[NSMutableArray alloc] init] autorelease];
newArray = [NSArray arrayWithObjects:#"Red", #"Green", #"Blue" nil]; // <--- WORKS!
newArray = [NSArray arrayWithObjects:items, nil]; // <-- ?
[plist setObject:newArray forKey:#"Hi"];
[plist writeToFile:path atomically:YES];
[plist release];
} else {
NSLog(#"File not found");
}
[filemgr release];
Maybe this piece of code helps you.
NSMutableArray *newArray = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *targetArray = [[[NSMutableArray alloc] init] autorelease];
newArray = [NSArray arrayWithObjects:#"Red", #"Green", #"Blue" nil];
for(int i=0;i<newArray.count;i++)
{
[targetArray addObject:[newArray objectAtIndex:i]];
}
[plist setObject:targetArray forKey:#"Hi"];
[plist writeToFile:path atomically:YES];
or another method
NSMutableArray *targetArray = [[[NSMutableArray alloc] init] autorelease];
for (id obj in items)
{
[targetArray addObject:items];
}
[plist setObject:targetArray forKey:#"Hi"];
[plist writeToFile:path atomically:YES];
Hope this helps !!!

How to solve: Why is coreData(NSFetchedResultsController) sorting differently in iOS5 and iOS4

i have a tableview which is populated with NSFetchedResultsController.
On didSelectRowAtIndexPathi am updating the current row. The sorting here should not change. The difference in the selected row is, that i mark it as read. No title changes or something.
In iOS4 the row gets updated and still leave on his current place, it does not move to the end of section. Thats the right way.
in iOS5 the row gets also updated but it moves to the end of the Section. I want to prevent that. How can i do that? And why is that happening?
See my code:
- (NSFetchedResultsController *)fetchedResultsController
{
if (__fetchedResultsController != nil)
{
return __fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"EntitySetsCardsInbox" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *inboxPred = [NSPredicate predicateWithFormat:#"archived == 0 AND cardId != 0"];
[fetchRequest setPredicate:inboxPred];
if (sortString == nil) {
//sortString = [[NSString alloc] initWithString:#"sortingOrder"];
sortString = [[NSString alloc] initWithString:#"colorOrder"];
sortAsc = NO;
}
if ([sortString isEqualToString:#"cardTitle"]) {
NSSortDescriptor *sortDescriptor2 = [[[NSSortDescriptor alloc] initWithKey:sortString ascending:sortAsc selector:#selector(localizedCaseInsensitiveCompare:)] autorelease];
NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortDescriptor2, nil] autorelease];
[fetchRequest setSortDescriptors:sortDescriptors];
XLog(#"sortDescriptors: %#", sortDescriptors);
} else {
NSSortDescriptor *sortDescriptor2 = [[[NSSortDescriptor alloc] initWithKey:sortString ascending:sortAsc] autorelease];
NSArray *sortDescriptors = [[[NSArray alloc] initWithObjects:sortDescriptor2, nil] autorelease];
[fetchRequest setSortDescriptors:sortDescriptors];
XLog(#"sortDescriptors: %#", sortDescriptors);
}
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[...]
}
i think your sortdescriptor is changing when you updating your rows. add one more sortdescriptor to fix the list with it and check it again. in my case i have a very similar issue and it solved my problem. maybe yours, too.

Resources