SwiftUI return type Error: Cannot convert return expression of type 'Foundation.Date' to return type 'BarCharts.Date' - swift

I am doing a bar chart in my SwiftUI app, however I encountered a problem...
struct ViewMonth: Identifiable {
let id = UUID()
let date: Date
let viewCount: Int
}
I defined several variable types in the above code.
struct Date {
static func from(year: Int, month: Int, day: Int) -> Date {
let components = DateComponents(year: year, month: month, day: day)
return Calendar.current.date(from: components)!
}
}
It seems like I can't convert the expression type 'Foundation.Date' to 'BarCharts.Date'. I don't understand the error message. Please help!
I expect the code will yield no errors.

The error complains about a terminology conflict of your type Date with existing Date in Foundation.
Basically there are three options:
Replace struct Date with extension Date.
Rename your struct Date as something which does not interfere with any type in the Foundation framework.
Declare all instances of your custom type as BarCharts.Date.
I recommend the first option.

There are two types: Foundation.Date is the date type that everyone uses. And I suppose you defined your struct Date inside a class Barcharts, so it is a Barcharts.Date.
The “from” function is declared to return Date - which is a shortcut for Barcharts.Date. Now the error message should make sense. It’s up to you to decide what you wanted it to return.

Related

How can we send Date object to Rest Api in swiftui?

Currently in my DTO class, I am declaring a type like this.
var transferDate : Date?
private enum CodingKeys: String, CodingKey {
case transferDate = "TransferDate"
}
override func encode(to encoder: Encoder) throws{
try super.encode(to:encode)
try container.encode(transferDate, forKey: .transferDate)
}
In my view, I am assigning Date like this
Dto.transferDate = self.Date
while debugging I see this in debug window
(Date) <unavailable; try printing with "vo" or "po"
Any help would be appreciated.
Thanks
You shouldn't have to do anything custom for Dates. As I recall, by default the system encodes dates as a Double like the one returned by Date.timeIntervalSinceReferenceDate().
If you're writing the RESTFUL API, you should be able to write it to handle that date format.
If you need "internet dates" (date strings in the standard format that includes an offset from UTC) you would need to specify that when setting up your encoder.

Convert date format from json data in the model and then pass to controller

Here in my model I have a few struct to handle the data from server
struct Articles: Decodable {
var content : [ArticleData]
}
struct ArticleData: Decodable {
var title: String
var date_time: Date
var image: String
}
From the jason, I get a date, it's like that:
"date_time": 1524842056.035,
First question:
I set the type of this type in model Date as you see in ArticleData, it that correct?
Then I read this json in the model something like that:
guard let json = try? JSONDecoder().decode(Articles.self, from: data!) else {
completion(.failure(loginError.networkError))
return
}
completion(.success(json.content))
As you can see, I get an array from server json.content that contain title, date_time and image. I want to convert it here in the model and pass everything in completion to the controller.
could you help me on that?
Thanks :)
you can use type 'String' for your date and then convert it using dateFormatter or, use 'dateDecodingStrategy' function in your decoder.
for passing the data you are already doing the correct thing. where ever you call the method you can get the model.

How to fix the warning of type casting in 'if let' statement in Xcode 8.3?

Consider the following code:
let nsdate: NSDate? = NSDate()
if let date = nsdate as? Date { // a warning occurs here
print(date)
}
The compiler complains like this: Conditional downcast from 'NSDate?' to 'Date' is a bridging conversion; did you mean to use 'as'?
A cast from NSData to Data has the same problem. How to fix the it?
Try to cast to an optional Date:
if let date = nsdate as Date?
You're trying to optional cast of optional NSDate to NON optional Date. As long as NSDate is bridged from obj-c to Date, so this cast always success, so no optional cast required here, just basic cast as is enough. Then you need to cast optional value, so the resulting value has to be optional too, therefore Date? is appropriate here.
Swift 3.1 distinguishes
An optional down cast as? Foo
It casts a more unspecific to a more specific type for example
let dict : [String:Any] = ["Foo" : 12]
let number = dict["Foo"] as? Int
A bridge cast of an optional type as Foo?
It bridges a (Core)Foundation type to a toll free Swift type and vice versa.
It's the optional equivalent of the usual non-optional syntax
let string : NSString = "Foo"
let swiftString = string as String
The difference is subtle for the developer but very useful for the compiler.
Basically don't use the NS... Foundation classes in Swift 3 if there is a native Swift counterpart.
Try this:
let nsdate: NSDate? = NSDate()
if let date = nsdate {
print(date)
}
The compiler knows it´s an NSDate if unwrapped, so what you are doing is actually casting an NSDate to a Date

NSCalendar.startOfDayForDate(date:) equivalent for iOS 7 with non-optional return type

Is it possible to change an NSDate object so that the result is equivalent to NSCalendar.startOfDayForDate(date:)? That method is only available to iOS 8 and newer, but I am looking for something that works on iOS 7.
I have looked at two methods:
NSCalendar.dateFromComponents(comps:) as described here: NSDate beginning of day and end of day. For instance, like this:
class func startOfDay(date: NSDate, calendar: NSCalendar) -> NSDate {
if #available(iOS 8, *) {
return calendar.startOfDayForDate(date)
} else {
let dateComponents = calendar.components([.Year, .Month, .Day], fromDate: date)
return calendar.dateFromComponents(dateComponents)!
}
}
NSDateFormatter.dateFromString(string:) by way of
stringFromDate(date:), i.e. converting the NSDate object into a string without the time, then converting it back into an NSDate object.
The problem with both methods is that they return an optional NSDate. I am reluctant to unwrap this implicitly and I’d rather avoid changing the return type of the method within which these methods are called.
I think the calendar.components() method returns an optional, because you can theoretically enter components that do not create valid date, like 2000-02-30. If, as in your case, the components already come from a valid date, I would not be reluctant to implicitly unwrap the optional.

NSNull into a Struct with a property of type NSDate

I have an object from the server that is recognized by Swift 2.1 as either NSDate or NSNull. I want to put it into a struct with a property of type NSDate.
Is that possible? If not, how should I handle this to be type safe later when I use it?
struct Data {
var completedAt: [NSDate]
var name: [String]
var gender: [Bool]
}
but sometimes completedAt comes from the server as NSNull:
completedAt = "<null>";
Any help is very much appreciated, thank you.
Based on my interpretation of the text in the question you didn't mean to declare the variables as arrays.
This is how I handle my parson and I think it works pretty neatly.
The date formatter should probable not be initiated in every iteration of the constructor. If you won't use the date regularly you might want to keep the detesting until you need to parse the date or you can have a static date formatter utility that you only instantiate once.
struct Data {
var completedAt: NSDate?
var name: String
var gender: Bool
init?(dictionary: [String:AnyObject]) {
//Guessing that you want some of the values non optional...
guard let name = dictionary["name"] as? String,
let gender = dictionary["gender"] as? String
else {
return nil
}
self.name = name
self.gender = gender
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
//safe handle of optional values
if let completedAtString = dictionary["completedAt"] as? String, completedAt = dateFormater.dateFromString(completedAtString) {
self.completedAt = completedAt
}
}
}
Take a step back. For each item that the server might provide, there is no guarantee whatsoever that you receive what you expect, since you cannot control the server. So you need to decide how to react to which input.
In the case of expecting a date for example (if your data comes in JSON, that means you likely expect a string formatted in a certain way), the actual data that you receive might be an array, dictionary, string, number, bool, null, or nothing. You might then for example decide that you want to interpret nothing or null or an empty string as nil, that you want to interpret a string containing a well-formatted date as an NSDate, and anything else a fatal error in a debug version, and as either nothing or a fatal error in a release version. On the other hand, if an NSDate is absolutely required then you might interpret anything that doesn't give an NSDate as an error.
Then you write a function that delivers exactly what you want and use it. That way you can parse complex data, with your code warning you when something isn't as it should be, and with your code either surviving any possible input, or deliberately crashing on wrong input, as you want it.