Sort UITableView into sections by date from Array of events

I’ve retrieved data from 2 different shared Google Calendars, and stored the data in an array. I need to sort the data into a sectioned UITableView, sorted by date.

Heres my code:

  • Xcode 8 recommend me to change the min iOS Deployment Target from 7.1 to 8.0
  • How to dismiss the current ViewController and go to another View in Swift
  • Using app access token in IOS
  • How can i add two uiimageview and save it to iphone photo gallery in iphone application development?
  • prepareForSegue not called from custom uitableviewcell
  • How to log into web site using uiwebview with swift?
  • CalendarModel.h

    #import "JSONModel.h"
    #import "Time.h"
    
    @interface CalendarModel : JSONModel
    
    @property (strong, nonatomic) NSString* title;
    @property (strong, nonatomic) NSArray<Time>* time;
    
    @end
    

    CalendarModel.m

    #import "CalendarModel.h"
    
    @implementation CalendarModel
    
    
    +(JSONKeyMapper*)keyMapper
    {
        return [[JSONKeyMapper alloc] initWithDictionary:@{
                @"gd$when": @"time",
                @"title.$t": @"title",
                }];
    }
    
    @end
    

    Time.h

    #import "JSONModel.h"
    
    @protocol Time @end
    
    @interface Time : JSONModel
    
    @property (strong, nonatomic) NSString* startTime;
    @property (strong, nonatomic) NSString* endTime;
    
    @end
    

    Time.m does nothing, as it’s handled by JSONModel

    SportsViewController.m

    #import "SportsViewController.h"
    #import "JSONModelLib.h"
    #import "CalendarModel.h"
    #import "Time.h"
    #import "JSONValueTransformer.h"
    
    @interface SportsViewController () 
    
    @property (strong, nonatomic) NSMutableArray *events;
    @property (strong, nonatomic) NSArray *music;
    
    - (NSDate *)dateAtBeginningOfDayForDate:(NSDate *)inputDate;
    - (NSDate *)dateByAddingYears:(NSInteger)numberOfYears toDate:(NSDate *)inputDate;
    
    @end
    
    @implementation SportsViewController
    
    - (id)initWithStyle:(UITableViewStyle)style
    {
        self = [super initWithStyle:style];
        if (self) {
            // Custom initialization
        }
        return self;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        //make HTTP call
        NSString* searchCall = [NSString stringWithFormat:@"http://www.google.com/calendar/feeds/kao1d80fd2u5kh7268caop11o4%%40group.calendar.google.com/public/full?alt=json"];
        NSString* searchCall2 = [NSString stringWithFormat:@"http://www.google.com/calendar/feeds/3qag5m8iad46mtvsnnqbtrcjjg%%40group.calendar.google.com/public/full?alt=json"];
    
        [JSONHTTPClient getJSONFromURLWithString: searchCall
                                      completion:^(NSDictionary *json, JSONModelError *err) {
    
                                          //got JSON back
                                          NSLog(@"Got Sports JSON from web: %@", json);
    
                                          if (err) {
                                              [[[UIAlertView alloc] initWithTitle:@"Error"
                                                                          message:[err localizedDescription]
                                                                         delegate:nil
                                                                cancelButtonTitle:@"Close"
                                                                otherButtonTitles: nil] show];
                                              return;
                                          }
    
                                          //initialize the models
                                          _events = [CalendarModel arrayOfModelsFromDictionaries:
                                                    json[@"feed"][@"entry"]
                                                    ];
    
                                          if (_events) NSLog(@"Loaded successfully sports models");
    
                                          //show the Events
                                          [_events addObjectsFromArray:_music];
                                          NSLog(@"%@", _events);
                                          [self.tableView reloadData];
    
                                      }];
    
        [JSONHTTPClient getJSONFromURLWithString: searchCall2
                                      completion:^(NSDictionary *json2, JSONModelError *err2) {
    
                                          //got JSON back
                                          NSLog(@"Got Music JSON from web: %@", json2);
    
                                          if (err2) {
                                              [[[UIAlertView alloc] initWithTitle:@"Error"
                                                                          message:[err2 localizedDescription]
                                                                         delegate:nil
                                                                cancelButtonTitle:@"Close"
                                                                otherButtonTitles: nil] show];
                                              return;
                                          }
    
                                          //initialize the models
                                          _music = [CalendarModel arrayOfModelsFromDictionaries:
                                                    json2[@"feed"][@"entry"]
                                                    ];
    
                                          if (_music) NSLog(@"Loaded successfully music models");
                                          [_events addObjectsFromArray:_music];
                                          //show the Events
                                          [self.tableView reloadData];
    
                                      }];
        //[events addObjectsFromArray:music];
        [self.tableView reloadData];
    
    }
    ;
    
    -(void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
        }
    
    
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    #pragma mark - table methods
    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return _events.count;
    }
    
    -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    
        CalendarModel* event = _events[indexPath.row];
    
    
        NSString *dato = [[event.time objectAtIndex:0] startTime];
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSzzz";
        NSDate *gmtDate = [formatter dateFromString: dato];
        formatter.dateFormat = @"dd-MM-yyyy HH:mm";
        dato = [formatter stringFromDate:gmtDate];
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SportCell" forIndexPath:indexPath];
        cell.textLabel.text = [NSString stringWithFormat:@"%@",
                               event.title
                               ];
        cell.detailTextLabel.text = dato;
    
        return cell;
    }
    @end
    

    So basically all the data i need sorted resides in the _events array. I just do not get how i sort it by date into sections. The reason why startTime and endTime are NSStrings is that, that’s what i am returned by the call to the shared calendar on Google

    Solutions Collect From Internet About “Sort UITableView into sections by date from Array of events”

    First group all your events – you’ll have to take care of variable scoping (I’m using days and groupedEvents locally but you’ll have to declare those as ivars/properties)

        NSMutableArray *days = [NSMutableArray array];
        NSMutableDictionary *groupedEvents = [NSMutableDictionary dictionary];
    
    - (void)groupEventsIntoDays
    {
        for (CalendarModel *event in _events)
        {
            NSString *dato = [[event.time objectAtIndex:0] startTime];
            NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
            formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSzzz";
            NSDate *gmtDate = [formatter dateFromString: dato];
    
            if (![days containsObject:gmtDate])
            {
                [days addObject:gmtDate];
                [groupedEvents setObject:[NSMutableArray arrayWithObject:event] forKey:gmtDate];
            }
            else
            {
                [((NSMutableArray*)[groupedEvents objectForKey:gmtDate]) addObject:event];
            }
        }
    
        days = [[days sortedArrayUsingSelector:@selector(compare:)] mutableCopy];
    }
    

    Section headers:

    -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0,0,tableView.frame.size.width, 30)];
        UILabel *headerLabel = [[UILabel alloc] initWithFrame:header.bounds];
        [header addSubview:headerLabel];
    
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"dd-MM-yyyy HH:mm";
        NSString *dateAsString = [formatter stringFromDate:[days objectAtIndex:section]];
    
        [headerLabel setText:dateAsString];
    
        return header;
    }
    

    I only touched the first two lines in your cellForRow – you can modify the rest as needed for display/formatting:

    -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    
        NSDate *date = [days objectAtIndex:indexPath.section];
        CalendarModel *event = [((NSMutableArray*)[groupedEvents objectForKey:date]) objectAtIndex:indexPath.row];
    
        NSString *dato = [[event.time objectAtIndex:0] startTime];
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSzzz";
        NSDate *gmtDate = [formatter dateFromString: dato];
        formatter.dateFormat = @"dd-MM-yyyy HH:mm";
        dato = [formatter stringFromDate:gmtDate];
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SportCell" forIndexPath:indexPath];
        cell.textLabel.text = [NSString stringWithFormat:@"%@",
                               event.title
                               ];
        cell.detailTextLabel.text = dato;
    
        return cell;
    }