Incompatible pointer types initializing 'NSDate - ios

I am setting up some constants, one being an NSDate but receiving this wanring message:
Incompatible pointer types initializing NSDate *const __strong with an expression of type NSString
Simple explanation of code (imp file):
NSDate *const kPAPUserBirthdayKey = #"fbBirthday";
Advanced explanation:
I use a constants file as a singleton holding constant variables for the API i write to. For example the above which is a Date field which will hold the facebook users birthday when connecting to Facebook.
This is then later used in the following conversion:
// Convert the DOB string into Date format
NSDateFormatter* df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"MM/dd/yyyy"];
NSDate* userDOB = [df dateFromString:user.birthday];
[[PFUser currentUser] setObject:userDOB forKey:kPAPUserBirthdayKey];
Can someone explain what the warning actually means and what should be changed here? I get the same error on the last line of the above?

NSDate *const kPAPUserBirthdayKey = #"fbBirthday";
You are assigning a string to a NSDate.
Change NSDate to NSString.
Use:
NSString const *kPAPUserBirthdayKey = #"fbBirthday";
Also check what you need ?
A constant pointer or pointer to a constant.

NSDate *const kPAPUserBirthdayKey = #"fbBirthday";
Here fbBirthday is a string not date. The warning says that.

Change your constant's type to NSString. The compiler is telling you you're making an assignment between incompatible types, as NSString is not a subclass of NSDate.

Related

Failed in convert NSString from kABBirthdayProperty to NSDate

I tried to convert NSString to NSDate as the instruction: NSString to NSdate
My snippet does not work, maybe the source NSString extracts incorrect
from ABPerson, with kABBirthdayProperty. It gets error with reason:
-[__NSTaggedDate bytes]: unrecognized selector sent to instance 0xc1c3a7619800000d
This is the snippet:
-(void) abRead: (ABPerson*) myRecord
{ if ([myRecord valueForProperty:kABBirthdayProperty] != nil)
{ NSDateFormatter* myBirthday = [[NSDateFormatter alloc] init];
[myBirthday setDateFormat:#"YYYY-DD-MM HH:MM:SS"];
NSDate* birthDay = [myBirthday dateFromString:[myRecord valueForProperty:kABBirthdayProperty]];
}
I guess that the NSString got from kABBirthdayProperty have some special format or some thing. I checked:
NSLog(#"birthday: %#", [myRecord valueForProperty:kABBirthdayProperty]);
it print out as NSString should be:
birthday :1980-02-08 05:00:00 +0000
Do I need any conversion from ABPerson:kABProperty to NSString correctly?
sorry for my bad English.
That property is already an NSDate*, it is not an NSString*. As such, you should not try and convert it from an NSString* to an NSDate* and just use it as an NSDate* directly:
-(void) abRead: (ABPerson*) myRecord {
NSDate* birthDay = [myRecord valueForProperty:kABBirthdayProperty];
if (birthday != nil) {
// Do something with birthday
}
}
The error you are getting actually tells you this:
-[__NSTaggedDate bytes]: unrecognized selector sent to instance 0xc1c3a7619800000d
This is telling you that an instance of type __NSTaggedDate is having the method bytes called on it. This implies that you're treating a type as if it is a different type.

Convert NSDate to Unix Time Stamp for use in Dictionary

While there are numerous examples on SO and the web of converting the current date to a unix timestamp, I can't seem to find one for any date.
This code produces error shown.
NSDate *date = self.datepicker.date;
time_t start = (time_t) [date timeIntervalSince1970];//collection element of time_t is not an objective-c object
Would appreciate any suggestions.
I believe that code will work and the error message relates to a different statement.
If you want to put that time_t into a dictionary then you'll need to wrap it in an NSNumber object. However you may as well keep it as an NSTimeInterval (double) and cast it when using it:
NSDate *date = self.datepicker.date;
NSTimeInterval start = [date timeIntervalSince1970]
dict[#"startTime"] = #(start);
However you can also cast it before adding it to the dictionary if you really want to.

Evernote search with date range

My objective is to display all notes created on date A, date B, date C etc.
I'm building an Evernote Query as such:
//for all notes created on 2015 May 11
ENNoteSearch *searchMayEleven = [ENNoteSearch noteSearchWithSearchString: #"created:20150511 -created:20150512"];
[[ENSession sharedSession] findNotesWithSearch:searchMayEleven
inNotebook:nil
orScope:ENSessionSearchScopeAll
sortOrder:ENSessionSortOrderRecentlyCreated
maxResults:100
completion:^(NSArray *findNotesResults, NSError *findNotesError) {
//completion block
}]];
My results, however, fetch notes that are created on 12 May as well as 11 May.
1) I deduce that I have to set a timezone in my Evernote Session. Based on your experience, is this a valid deduction?
2) If so, I haven't been able to find a way to do so after reading through the documentation. Is it even possible?
3) Would you advice an alternative approach? Perhaps using the notestore instead?
In Evernote your dates are being kept in UTC.
When you make the search you need to create an Evernote search grammar that's relative to the timezone that you're interested in. In your case the timezone of the client or of the iPhone.
To get the user timezone:
ENSession * session = [ENSession sharedSession];
EDAMUser * user = session.user;
where the EDAMUser class has this structure:
#interface EDAMUser : FATObject
#property (nonatomic, strong) NSNumber * id; // EDAMUserID
#property (nonatomic, strong) NSString * username;
...
#property (nonatomic, strong) NSString * timezone;
For example my user timezone is: America/Montreal so on EST.
In order to get all the notes created May 11th you need to construct this Evernote search grammar:
#"created:20150511T040000Z -created:20150512T040000Z"
notice the ...T040000Z at the end.
So the conclusion is that you need to include the "definition" of the date from the client's perspective otherwise the query will work on UTC.
Here is an example of how to build the Evernote grammar search for the current day:
-(NSString *)buildQueryStringForDate: (NSDate *)date {
NSDateFormatter * formatter = [NSDateFormatter new];
[formatter setDateFormat:#"yyyyMMdd'T'HHmmss'Z'"];
formatter.timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
formatter.locale = [NSLocale systemLocale];
DateRange * dateRange = [DateRange rangeForDayContainingDate:[NSDate new]];
return [NSString stringWithFormat:#"created:%# -created:%#", [formatter stringFromDate:dateRange.startDate], [formatter stringFromDate:dateRange.endDate]];
}
The code for [DateRange rangeForDayContainingDate:[NSDate new]] can be found here: How can I generate convenient date ranges based on a given NSDate?
I hope this helps.
It sounds like this might be a time zone issue. The fact that notes from the previous day are being surfaced could be explained by the fact that the search you are performing checks the time as reported by the client (usually the local time zone of the client) and not UTC or any well-defined time zone.
Your existing search grammar: created:20150511 -created:20150512 should return notes created after May 11 and before May 12th utilizing the time and date on the client that was used when the note was created. To force the search to use absolute time for when a note was created and not the created time as reported by the Evernote client you must use the Z postfix to the date-time stamp as seen in the following search grammar which will you return notes created only on May 15, 2015 UTC:
created:20150511T000000Z -created:20150512T000000Z
Sources
https://dev.evernote.com/doc/articles/search_grammar.php
https://dev.evernote.com/doc/reference/Types.html#Struct_Note
Given the time constraint on hand, I am deploying the following solution:
-(NSString *)buildQueryStringForDate: (NSDate *)date {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
NSDate *dateAfter = [date dateByAddingDays:1];
NSTimeZone *currentTimeZone = [NSTimeZone localTimeZone];
[dateFormat setDateFormat: #"'created:'YYYYMMdd'T'HHmmss"];
[dateFormat setTimeZone:currentTimeZone];
NSString *searchString = [NSString stringWithFormat: #"%# -%#", [dateFormat stringFromDate:[date dateByAddingTimeInterval: currentTimeZone.secondsFromGMT]], [dateFormat stringFromDate:[dateAfter dateByAddingTimeInterval: currentTimeZone.secondsFromGMT]]];
NSLog(#"%#",searchString);
return searchString;
}
In all, it's a hack using NSDate instance method of secondsFromGMT to offset the timezone difference. Does not really use the correct concepts. but it'd have to do for now.
Any comments will be warmly welcomed :)

Create a date from a string

I'm pretty comfortable with core data now (only been iOS Developer for 6 months) but I haven't come upon having to put a date in core data.
So here's the situation. I'm pulling data from a web service in JSON format. One of the elements that I have is a date element and I don't know the syntax for properly storing this in core data.
If that isn't clear here is an example:
Syntax for storing a string:
newDate.eventyType = NSLocalizedString([diction objectForKey:#"eventyType"], nil);
Syntax for storing a number:
newDate.id = [NSNumber numberWithInt:[NSLocalizedString([diction objectForKey:#"id"], nil) intValue]];
So I need to know the syntax for storing a date.
Try like this:-
If you are extracting and storing your date from json format into NSString Variable then try below to convert into NSDate:-
NSString *strDate2=#"19-01-2014";
NSDateFormatter *format=[[NSDateFormatter alloc]init];
[format setDateFormat:#"dd-MM-yyyy"];
NSDate *dt1=[format dateFromString:strDate1];
As already answered before me, to create an NSDate object from NSString one uses NSDateFormatter. The important thing to know about the date formatter is that it uses user’s locale (including calendar!) and time zone. But the dates you expect to receive are probably in one, fixed locale and in one time zone. This can cause date formatter to fail parsing the date string.
The solution to this is to set the locale and the time zone to the date formatter explicitly:
NSDateFormatter *rfc3339DateFormatter = [[[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX”];
rfc3339DateFormatter.locale = enUSPOSIXLocale;
rfc3339DateFormatter.dateFormat = #"yyyy'-'MM'-'dd”;
rfc3339DateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
See Technical Q&A QA1480 for more detailed explanation.

NSDecimalNumber, addition, and just not sure

I'm not sure what to do next. They're just dollar amounts from a text field. I'm trying to add them together.
NSString *checkAmount = [checkAmountInput.text substringFromIndex:1];
NSDecimalNumber *checkAmountValue = (NSDecimalNumber*)[NSString stringWithFormat:#"%#",checkAmount];
NSLog(#"%#", checkAmountValue);
NSString *bankBalance = [bankBalanceInput.text substringFromIndex:1];
NSDecimalNumber *bankBalanceValue = (NSDecimalNumber*)[NSString stringWithFormat:#"%#",bankBalance];
NSLog(#"%#", bankBalanceValue);
NSDecimalNumber *totalAmount =
NSLog(#"%#",totalAmount);
When I try using decimalNumberByAdding I get:
'-[__NSCFString decimalNumberByAdding:]: unrecognized selector sent to instance 0x8a39a10'
Maybe I'm going about this all wrong... but I'm just starting out again.
Your checkAmountValue and bankBalanceValue aren't actually NSDecimalNumber instances. Casting an NSString to an NSDecimalNumber will silence a compiler warning, but the objects are still just strings.
You can use decimalNumberWithString: to create an actual NSDecimalNumber instance from a string:
NSString *bankBalance = [bankBalanceInput.text substringFromIndex:1];
NSDecimalNumber *bankBalanceValue = [NSDecimalNumber decimalNumberWithString:bankBalance];
There's some mixed up code there. Effectively, what you want to do is grab the text from two NSTextFields, and convert them to NSDecimalNumbers and add them. You can certainly do that. Be aware that NSTextField, can also 'parse' the string value directly and return you a numeric type (int, double, float) directly:
double d = [textField doubleValue];
If you still wanted to use NSDecimalNumber, and parse it from an NSString:
NSString *s = [textField stringValue];
To convert the string to an NSDecimalNumber:
NSDecimalNumber *n1 = [NSDecimalNumber decimalNumberWithString:s]
NSDecimalNumber *n2 = // repeat as above for the second string
To add them together:
NSDecimalNumber *n3 = [n1 decimalNumberByAdding:n2];
Note that, decimalNumberWithString is a class factory method which creates an instance of NSDecimalNumber by parsing a string. In your case you were simply casting to this which really doesn't create the type that you need.

Resources