I'm calling a method passing two arrays to it as follow :
NSArray *marked_dates = [NSArray arrayWithObjects:[dateFormat dateFromString:#"19/03/2014"],[dateFormat dateFromString:#"17/04/2014"],[dateFormat dateFromString:#"12/02/2014"], nil];
NSArray *marked_colors = [NSArray arrayWithObjects:[UIColor greenColor],[UIColor greenColor],[UIColor greenColor],nil];
[calendar markDates:marked_dates withColors:marked_colors];
Below is the method receiving this :
-(void)markDates:(NSArray *)dates withColors:(NSArray *)colors {
self.markedDates = dates;
self.markedColors = colors;
NSLog(#"%#",[NSString stringWithFormat:#"%d",[dates count]]);
for (int i = 0; i<[self.markedDates count]; i++) {
NSLog(#"%#",[NSString stringWithFormat:#"%#", self.markedDates[i]]);
}
[self setNeedsDisplay];
}
The log says 0 and I obviously don't get into the for loop.
Thanks for any help.
EDIT :
I will also vote up for any information about the warning : "format string is not a string literal"
Below the declaration of the properties :
#property (nonatomic, retain) NSArray *markedDates;
#property (nonatomic, retain) NSArray *markedColors;
EDIT :
So yes, the formater gives null values.
Here is how I did it :
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MM/dd/yyyy"];
NSLog(#"%#",[NSString stringWithFormat:#"%#",[dateFormat dateFromString:#"19/03/2014"]]);
//this prints "null"
EDIT with solution :
Bad mistake, I misconfigured the formatter
using this worked for me, thank you all for your help.
[dateFormat setDateFormat:#"dd/MM/yyyy"];
The dates array is probably empty due to the date formatter only producing nil values. Fix the date formatter so it will correctly generate NSDate objects and it should work:
[dateFormat setDateFormat:#"dd/MM/yyyy"];
First of all you should not create the property name and Local instance variable as same name. Because property it's self create instance var with _Property name.And the issue is with line.
NSArray *marked_dates = [NSArray arrayWithObjects:[dateFormat dateFromString:#"19/03/2014"],[dateFormat dateFromString:#"17/04/2014"],[dateFormat dateFromString:#"12/02/2014"], nil];
Add the date format also.
check this again. let me know if you still facing the same issue.
[dateFormat setDateFormat:#"dd/MM/yyyy"]; ?
Related
I have an array with custom objects which have a NSDate property. I would like to somehow get all objects whose NSDate are on Sunday, Monday, Tuesday, and so on.
I feel like this isn't possible using predicates but hoping I am wrong and hoping there is a way without having to iterate over all objects, get the dates, convert them using date formatter and then figuring out the day.
I think block method of predicate code will be more feasible to do this task.
Here is my code
NSPredicate *pred = [NSPredicate predicateWithBlock:^BOOL(Object * _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
NSCalendar* cal = [NSCalendar currentCalendar];
NSDateComponents* comp = [cal components:NSCalendarUnitWeekday fromDate:evaluatedObject.mDate];
NSInteger weekDay = [comp weekday]; // 1 = Sunday, 2 = Monday, etc.
return weekDay == 4;
}];
NSArray *arrFilteredObject = [arrData filteredArrayUsingPredicate:pred];
Here Object is my Custom object class which hold two field i.e one NSString and one NSDate attribute.
Here is my Object class for your reference
#interface Object : NSObject
#property (nonatomic, strong) NSString *title;
#property (nonatomic, strong) NSDate *mDate;
#end
Hope it helps. Please let me know if you face any issue with this approach.
I was able to figure this out. Here's my way in Objective-C which can also be adapted for swift easily I am sure.
I actually have an array of custom objects each of which has a NSDate property which I need to be filtering on by day of week.
I achieved my solution by adding another custom getter to my custom object:
Interface:
#property (nonatomic, retain, getter = dayOfWeek) NSString *dayOfWeek;
Implementation:
-(NSString*)dayOfWeek{
return [[(AppDelegate*)[[UIApplication sharedApplication] delegate] dayOfWeekFormatter] stringFromDate:self.createdAt];
}
The dayOfWeekFormatter is a NSDateFormatter which I create in my AppDelegate which can be reused instead of recreating it each time:
#property (strong, nonatomic) NSDateFormatter *dayOfWeekFormatter;
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
self.dayOfWeekFormatter = [NSDateFormatter new];
[self.dayOfWeekFormatter setDateFormat:#"eeee"];
[self.dayOfWeekFormatter setLocale:locale];
You must set the Locale!
Now I am able to use this predicate to filter for whatever day I need. Here's an example for filtering for all objects on Wednesday:
NSArray *dayArray = [myTestArrayOfObjects filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"dayOfWeek == 'Wednesday'"]];
I am trying to build an NSDictionary from an NSManagedObject. I was under the impression that you could do this with: NSMutableDictionary *myDict;
[myDict setObject:self.title forKey:#"title"];
}
Because a dictionary cannot hold nil values, I am testing for nil first. However, when I verify using a break that properties have values, when I build the dictionary it is nil. It shows as nil using a breakpoint and logs to console as NULL. Would appreciate someone confirming that the following is a valid way to create a dictionary and, if so, why the dictionary would be nil?
NSString *title = #"Test";
NSNumber *complete = #1;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
NSString *lasttouchedstr =[dateFormatter stringFromDate:[NSDate date]];
NSMutableDictionary *myDict;
if (self.title.length>=1) {
[myDict setObject:self.title forKey:#"title"];
}
if (![self.complete isKindOfClass:[NSNull class]]) {
[myDict setObject:self.complete forKey:#"complete"];
}
if (![self.lasttouched isKindOfClass:[NSNull class]]) {
[myDict setObject:lasttouchedstr forKey:#"lasttouchedstr"];
}
NSLog(#"myDict is:%#",myDict)//Logs as NULL
return myDict;
Thanks in advance for any suggestions.
NSMutableDictionary *myDict; declares the value but does not initialize it. You need
NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init];
Secondly, managed objects will not be returning a value of NSNull for any of their attributes. You need to check for != nil instead. See here for a nice explanation of the differences between nulls and nils.
Hi i am new for ios and i am integrating my app with services and i am getting here trip creation TimeandDate values and storing that values one separate Array and also i am getting pickUpAdress values from services and storing them one separate arrayList
After storing in arrayList i am set date values at "Ascending" order in my tableList
after set "Ascending" when i display them in tableList both array-list data they are mismatching to one another please help me how can i resolve this problem how can i set my Adrress array values for matching to related DateandTimes
code:-
#import "ViewController.h"
#interface ViewController ()
{
NSSortDescriptor* sortOrder;
NSArray * ToBeReadyTimeArray1;
NSMutableArray * ToBeReadyTimeArray ,*finalToBeReadyTimeArray,*AdressArray;
UITableView * MaintableView;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
ToBeReadyTimeArray1 = [[NSArray alloc]init];
ToBeReadyTimeArray = [[NSMutableArray alloc]initWithObjects:#"02/17/2016",#"03/13/2016",#"04/18/2016",#"05/21/2016", nil];
finalToBeReadyTimeArray =[[NSMutableArray alloc]init];
AdressArray = [[NSMutableArray alloc]initWithObjects:#"Adress1",#"Adress2",#"Adress3",#"Adress4", nil];
//Arange Date formate At Assending order:-
sortOrder = [NSSortDescriptor sortDescriptorWithKey: #"self" ascending: YES];
ToBeReadyTimeArray1 = [ToBeReadyTimeArray sortedArrayUsingDescriptors: [NSArray arrayWithObject: sortOrder]];
for (NSString *dte in ToBeReadyTimeArray1){
NSDateFormatter *aDateFormatter = [[NSDateFormatter alloc] init];
[aDateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[aDateFormatter setDateFormat:#"MM/dd/yyyy"];
NSDate * parsed = [aDateFormatter dateFromString:dte];
[aDateFormatter setDateFormat:#"dd MMM yyyy"];
NSString *aFormattedElapsedTime = [aDateFormatter stringFromDate:parsed];
NSLog(#"tobe Ready time %#",aFormattedElapsedTime);
[finalToBeReadyTimeArray addObject:aFormattedElapsedTime];
}
}
I presume you are trying to list pick up times / address with some sorted order. If that's so, i would have created a NSArray of Booking or Trip models which would contain the information as Address (NSString *) and PickUpTime (NSDate *) and then would have implemented a sorting method using the property as variable key.
In my case, I implemented an array of booking models which has pickUpTime and address.
#property (nonatomic, retain) NSNumber *pickUpTime; // Timestamp instead of NSDate ...
#property (nonatomic, retain) NSString *address;
I implemented a category method for NSArray. Please note that sort order enumerations are manually implemented.
+ (NSArray *)sortArray:(NSArray *)unSortedArray byOrder:(SortOrder)sortOrder usingVariableKey:(NSString *)variableKey {
NSArray *sortedArray = [NSArray array];
BOOL isAscendingOrder = NO;
if (sortOrder == SortOrderAscending) {
isAscendingOrder = YES;
}
if (unSortedArray) {
NSSortDescriptor *valueDescriptor = [[NSSortDescriptor alloc] initWithKey:variableKey ascending:isAscendingOrder];
NSArray *descriptors = [NSArray arrayWithObject:valueDescriptor];
sortedArray = [[unSortedArray sortedArrayUsingDescriptors:descriptors] mutableCopy];
}
return sortedArray;
}
Then, i invoked the following ...
// Here, resultMutableArray is a mutable array of booking models ...
NSArray *resultArray = [NSArray sortArray:[resultMutableArray copy] byOrder:SortOrderDescending usingVariableKey:#"pickUpTime"];
I have an NSMutableArray called self.objectArray, that contains custom objects. Each object holds an NSDictionary and two other string objects. Actually I need to work only with the dictionary. Every dictionary contains a key named keyDate which holds an NSString that look like this: MM/dd/yy HH:mm:ss.
I would like to sort the array based on their keyDate. The object with the oldest date should be the first object and so on. I've found some questions, that looked helpful and I could create the code that you can see below, but I get an error everytime I run it. As I think NSSortDescriptor won't be the right tool since my keys aren't key value compliant.
PNMessage 0x125c0590> valueForUndefinedKey:]: this class is not key value coding-compliant for the key keyDate.'
NSSortDescriptor *dateDescriptor = [NSSortDescriptor
sortDescriptorWithKey:#"keyDate"
ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
NSArray *sortedEventArray = [self.objectArray
sortedArrayUsingDescriptors:sortDescriptors];
self.finallySorted = [sortedEventArray mutableCopy];
If it's possible I would do it with sort descriptor, however I think there should be some other options, but can't figure out its proper implementation.
So I can also catch every object's keyDate with a for loop, but don't know how can I sort them based on the value. I would really appreciate if somebody could show me the right way.
for(PNMessage *mg in self.objectArray)
{
NSLog(#" test log %#", mg.message[#"keyDate"]);
}
I already checked this answer:
How to sort an NSMutableArray with custom objects in it?
but the structure of my object is different.
My first code based on this question, but it doesn't worked.
How to sort an NSMutableArray with custom objects in it?
UPDATE: my try based on Kaan's answer (doesn't works yet)
static NSDateFormatter *formatter = nil;
if(!formatter) {
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MM/dd/yy HH:mm:ss"];
}
NSArray *sortedArray = [self.object sortedArrayUsingComparator:^NSComparisonResult(PNMessage *obj1, PNMessage *obj2) {
NSString *date1String = obj1.message[#"keyDate"];
NSString *date2String = obj1.message[#"keyDate"];
NSDate *date1 = [formatter dateFromString:date1String];
NSDate *date2 = [formatter dateFromString:date2String];
if ( date1 < date2 ) {
return (NSComparisonResult)NSOrderedAscending;
} else if ( date1 > date2 ) {
return (NSComparisonResult)NSOrderedDescending;
}
return (NSComparisonResult)NSOrderedSame;
}];
I would consider using the sortedArrayUsingComparator method
Assuming your custom class is called PNMessage:
static NSDateFormatter *formatter = nil;
if(!formatter) {
formatter = [[NSDateFormatter alloc] init];
[formatter setFormat:#"MM/dd/yy HH:mm:ss"];
}
NSArray *sortedArray = [self.objectArray sortedArrayUsingComparator:^NSComparisonResult(PNMessage *obj1, PNMessage *obj2) {
NSString *date1String = obj1[#"keyDate"];
NSString *date2String = obj1[#"keyDate"];
NSDate *date1 = [formatter dateFromString:date1String];
NSDate *date2 = [formatter dateFromString:date2String];
return [date1 compare:date2];
}];
Tip: If you decide on following this, make sure you declare your NSDateFormatter instance as static outside of the sorting body, since allocating Formatters in iOS can be very expensive and cause serious performance penalties.
I wrote this code to reload the UItableView with an events that has the same date as the current date when the user click on todays events UIButton in the main view controller but the problem is the below code is not reloading the right data (it just gives the initial data without comparing the date of the event with the date of the calendar in the IPhone), my data comes from a json file within the project and consists from NSArray of events, each has a different value for each key and one of these keys is the data of that event ("date"), can anyone plz clarify for me why the below code is not returning the right data ??
#implementation MainViewController {
NSArray *_events;
}
....
- (IBAction)upcomingEvents:(id)sender {
NSDate *currDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"dd-MM-YYYY"];
NSString *dateString = [dateFormatter stringFromDate:currDate];
for (Events *event in _events){
if([event.date isEqualToString:dateString]){
[self.myTableView reloadData];
}
}
}
If you're using a UITableViewDataSource you should make sure that it returns only the events that match your condition [event.date isEqualToString:dateString]
You can do
NSArray * dateEvents = [_events filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(Events * event, NSDictionary *bindings)
{
return [event.date isEqualToString:dateString];
}];
Then you can use dateEvents for your UITableViewDataSource.