BUG in Swift NSDataDetector detected :)```

 var parseDATE: String {
        let detector   = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)
        let matches    = detector?.matches(in: self, options: [], range: NSMakeRange(0, self.utf16.count))
        let dt         = matches?.first?.date
        if dt         == nil { return parseERROR }
        let fmt        = DateFormatter()
        fmt.dateFormat = "yyyy-MM-dd HH:mm:ssZZZZZ"
        let s = String(fmt.string(from: dt!))
        return s.Left(19)

I have used the above code to validate Strings as Dates in Swift for some time. It will extract any valid date from a phrase and return an SQLDate formatted string

However, today I found there is an :lady_beetle: in NSDataDetector. it crashes if the date is in the year 2100 or beyond or the year < 1700

So it is fine for MOST things… but not everything

Gonna have to forgive me as I’ve only been really looking it Swift for 3 days, have you tried wrapping it in a do-catch block?

It is not a matter of catching the error, that I can do… its the fact that I think a date range of 1700 to 2100 is rather short sighted… Genealogy for example would have to use something else

1 Like

I would agree with you that it does appear very short sighted, but it sadly isn’t surprising.

I was just reading that it appears Swift will crash an app on error/exception, which is the opposite behavior of Objective-C. A change Apple made with 10.14, before that Obj-C would crash on error/exception.

I’m still going over in my head the differences between structs and classes. It feels like the main differences are classes can be subclassed and in Xojo terms when passed to a function operate as “ByRef”, while structs operate like “ByVal”. Both can be mutable or immutable, but even if you make an immutable object, you can make it mutable via functions.

The way Swift handles Classes, Structure and even Enums is WAY WAY more flexible.

for example

  public enum linePattern : Int {
        case none
        case solid
        case dotted
        case dashed
        func pattern() -> [CGFloat] {
            switch self {
                case .none  : return []
                case .solid  : return [1,0]
                case .dotted : return [2,2] // 1100
                case .dashed : return [4,4] // 11110000

let pattern = linePattern..dotted.pattern()
1 Like