I am trying to use the NSCalendar initializer but i’m having trouble understanding the documentation. what I have so far is
struct SwiftUIView: View {
var body: some View {
let Date = NSCalendar.init(calendarIdentifier: .coptic)
Text("(Date)")
}
}
struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView()
}
}
its giving me an error saying
"Value of optional type ‘NSCalendar?’ must be unwrapped to a value of type ‘NSCalendar’"
if someone could help me figure this out, that would be great. Thank you
2
Answers
The interface you want for Swift is Calendar rather than NSCalendar:
The NSCalendar interface is from ObjC and is documented to return nil if the name of the calendar is unknown (you can pass arbitrary strings in ObjC for this parameter).
The Swift Calendar interface cannot fail because it will not allow you to create an unknown identifier.
There are many types that begin "NS" that are bridged from Objective-C. It is very common for there to be a Swift version that drops the "NS" prefix. When you see this, you should generally use the Swift version. It will generally behave in a more Swift-like way.
If your goal is to display the current date on the Coptic calendar, however, you will need more than this. A calendar represents the whole calendar, not a particular date. You will need a DateFormatter in order to create a localized string.
For example:
(I believe there is a bug in Calendar such that the Coptic calendar has era symbols "ERA0" and "ERA1". I believe the correct symbols for this calendar are "BC" and "AM". You can force this by assigning them directly to the date formatter. If I’m correct that this is a bug and it impacts you, I recommend opening an Apple Feedback. See also the DateFormatter documentation for how to customize this string.)
To xTwisteDx’s point, to put this in SwiftUI you want something along these lines:
Ok so this is an issue with Optionals. Anytime you see
?
or!
then you can assume that it is an optional. Essentially the reason that it is aType?
, notice the?
is because it’s possible that it has returned anil
value. For example the following snippets are possible in SwiftThe way that you handle these is to check using
if let
orguard
statements. Alternatively you can also force unwrap after checking fornil
.If Let
In this example, if
optionalString
is nil, the print statement WILL NOT happen. However if optionalString contains a value, it will. It’s essentially a way of telling the compiler to check for nil values and only run code if it’s safe.Guard
In this example, it works the same as an
If Let
with a notable difference being that the safeString is accessible at a bigger scope than theIf Let
also it returns if the value is not "unwrapped" so any code below it will not be called if it’s not safely unwrapped.Force Unwrapping
Force unwrapping is something you should avoid however there are instances when it’s acceptable. This is an example of force unwrapping. Notice that I used the
!
which basically says "I know this value is not nil, use it." That is the only time you should ever use it, when you can guarantee there isn’t anil
value.Your Problem
In the context of your issue,
NSCalendar.init(calendarIdentifier: .coptic)
returns an optional type or,someType?
meaning it has the possibility to benil
The solution is below.