1

My Xcode app crashes if the user inputs a year below 1948 or for example more than the year 2086 and was wondering if anyone had this issue before and how to resolve?

The user selects their date of birth and the app displays data such as the number of seconds between today's date and their date of birth.

I am new to Xcode (Xcode 8) so still learning. Thanks in advance

@IBAction func clickScreenBtn(_ sender: Any) {


    let birthDay = UserDefaults.standard.object(forKey: "birthday") as! Date
    var component = NSCalendar.current.dateComponents([.day], from: birthDay, to: Date())



    type = type + 1

    switch type {
    case 0:
        unitLabel.text = "Days"
        timeLabel.text = ""
        timeLabel.text = timeLabel.text?.appendingFormat("%d", component.day!)
        break
    case 4:
        type = 0
        unitLabel.text = "Days"
        timeLabel.text = ""
        timeLabel.text = timeLabel.text?.appendingFormat("%d", component.day!)
        break
    case 1:
        component = NSCalendar.current.dateComponents([.hour], from: birthDay, to: Date())
        unitLabel.text = "Hours"
        timeLabel.text = ""
        timeLabel.text = timeLabel.text?.appendingFormat("%d", component.hour!)
        break
    case 2:
        component = NSCalendar.current.dateComponents([.minute], from: birthDay, to: Date())
        unitLabel.text = "Minutes"
        timeLabel.text = ""
        timeLabel.text = timeLabel.text?.appendingFormat("%d", component.minute!)
        break
    case 3:

        component = NSCalendar.current.dateComponents([.second], from: birthDay, to: Date())

        unitLabel.text = "Seconds"
        timeLabel.text = ""
        timeLabel.text = timeLabel.text?.appendingFormat("%d", component.second!)


        break
    default:
        break
    }
}

Error:

 0x108142301 <+9425>:  callq  0x1082a95c4               ; symbol stub for: Foundation.Calendar.dateComponents (Swift.Set<Foundation.Calendar.Component>, from : Foundation.Date, to : Foundation.Date) -> Foundation.DateComponents
0x108142306 <+9430>:  movq   -0x710(%rbp), %rdi
0x10814230d <+9437>:  movq   %rax, -0x730(%rbp)
0x108142314 <+9444>:  callq  0x10813d8a0               ; swift_rt_swift_release
0x108142319 <+9449>:  movq   -0x730(%rbp), %rax
0x108142320 <+9456>:  movq   %rax, -0x8(%rbp)
0x108142324 <+9460>:  movq   -0x218(%rbp), %rdi
0x10814232b <+9467>:  callq  0x10813d8a0               ; swift_rt_swift_release
0x108142330 <+9472>:  movq   0x1e3081(%rip), %rax      ; (void *)0x000000010e87f068: swift_isaMask
0x108142337 <+9479>:  movq   -0x168(%rbp), %rdx
0x10814233e <+9486>:  movq   (%rdx), %rdi
0x108142341 <+9489>:  andq   (%rax), %rdi
0x108142344 <+9492>:  movq   %rdi, -0x738(%rbp)
0x10814234b <+9499>:  movq   %rdx, %rdi
0x10814234e <+9502>:  movq   -0x738(%rbp), %rax
0x108142355 <+9509>:  callq  *0x80(%rax)
0x10814235b <+9515>:  movq   %rax, -0x70(%rbp)
0x10814235f <+9519>:  movq   -0x230(%rbp), %rax
0x108142366 <+9526>:  movsd  -0x1d8(%rbp), %xmm0       ; xmm0 = mem[0],zero 
0x10814236e <+9534>:  movd   %xmm0, %rax
0x108142373 <+9539>:  cmpq   $0x0, -0x70(%rbp)
0x108142378 <+9544>:  jne    0x108142409               ; <+9689> at MainViewController.swift
0x10814237e <+9550>:  movq   -0x230(%rbp), %rax
0x108142385 <+9557>:  movsd  -0x1d8(%rbp), %xmm0       ; xmm0 = mem[0],zero 
0x10814238d <+9565>:  movd   %xmm0, %rax
0x108142392 <+9570>:  movq   -0x230(%rbp), %rax
0x108142399 <+9577>:  movsd  -0x1d8(%rbp), %xmm0       ; xmm0 = mem[0],zero 
0x1081423a1 <+9585>:  movd   %xmm0, %rax
0x1081423a6 <+9590>:  movq   -0x230(%rbp), %rax
0x1081423ad <+9597>:  movsd  -0x1d8(%rbp), %xmm0       ; xmm0 = mem[0],zero 
0x1081423b5 <+9605>:  movd   %xmm0, %rax
0x1081423ba <+9610>:  leaq   0x1b13f9(%rip), %rdi      ; "fatal error"
0x1081423c1 <+9617>:  movl   $0xb, %eax
0x1081423c6 <+9622>:  movl   %eax, %esi
0x1081423c8 <+9624>:  movl   $0x2, %eax
0x1081423cd <+9629>:  leaq   0x1b13ac(%rip), %rcx      ; "unexpectedly found nil while unwrapping an Optional value"
0x1081423d4 <+9636>:  movl   $0x39, %edx
0x1081423d9 <+9641>:  movl   %edx, %r8d
0x1081423dc <+9644>:  xorl   %edx, %edx
0x1081423de <+9646>:  movl   %edx, -0x73c(%rbp)
0x1081423e4 <+9652>:  movl   %eax, %edx
0x1081423e6 <+9654>:  movl   %eax, %r9d
0x1081423e9 <+9657>:  movl   $0x0, (%rsp)
0x1081423f0 <+9664>:  callq  0x1082a95f4               ; symbol stub for: function signature specialization <preserving fragile attribute, Arg[2] = Dead, Arg[3] = Dead> of Swift._fatalErrorMessage (Swift.StaticString, Swift.StaticString, file : Swift.StaticString, line : Swift.UInt, flags : Swift.UInt32) -> Swift.Never
0x1081423f5 <+9669>:  movq   -0x230(%rbp), %rcx
0x1081423fc <+9676>:  movsd  -0x1d8(%rbp), %xmm0       ; xmm0 = mem[0],zero 
0x108142404 <+9684>:  movd   %xmm0, %rcx
0x108142409 <+9689>:  leaq   -0x70(%rbp), %rax
0x10814240d <+9693>:  movq   -0x70(%rbp), %rcx
0x108142411 <+9697>:  movq   %rcx, %rdi
0x108142414 <+9700>:  movq   %rax, -0x748(%rbp)
0x10814241b <+9707>:  movq   %rcx, -0x750(%rbp)
0x108142422 <+9714>:  callq  0x1082a9858               ; symbol stub for: objc_retain
0x108142427 <+9719>:  leaq   0x1b1398(%rip), %rdi      ; "Seconds"
DaE
  • 189
  • 1
  • 4
  • 14
  • `var components = DateComponents(); components.year = 1939; let birthDay = NSCalendar.current.date(from: components)!;` works fine.. It returns a date that has the year 1939 and the rest of the code runs fine. I imagine you might be crashing at `let birthDay = UserDefaults.standard.object(forKey: "birthday") as! Date` instead.. You need to post a stacktrace. – Brandon Aug 27 '17 at 21:31
  • 4
    Which line causes the crash? What's the complete and exact error message? Please put this info in your question (don't post comments). – rmaddy Aug 27 '17 at 22:09
  • 2
    Style cleanup requests -- you probably come from the world of C: Remove `break` everywhere. Then replace the two lines that manipulate `timeLabel` in every `case` with: `timeLabel.text = "\(component.day!)"` That's all you need to put a numeric value in a String property. – BaseZen Aug 28 '17 at 01:20
  • Somebody has to write a "Force Unwrapping Considered Harmful" article. – Nicolas Miari Aug 28 '17 at 02:50
  • 2
    @NicolasMiari https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu covers that. – rmaddy Aug 28 '17 at 02:55

1 Answers1

1

If you get rid of all the !s and replace them with some actual error checking, you should be able to find out where the error is occurring rather quickly. For example, this version will log whatever is going wrong to the console:

@IBAction func clickScreenBtn(_ sender: Any) {
    guard let birthDay = UserDefaults.standard.object(forKey: "birthday") as? Date else {
        print("Couldn't get birthday")
        return
    }

    let currentDate = Date()

    guard let day = Calendar.current.dateComponents([.day], from: birthDay, to: currentDate).day else {
        print("Couldn't get day")
        return
    }

    type = type + 1

    switch type {
    case 0:
        unitLabel.text = "Days"
        timeLabel.text = "\(day)"
    case 4:
        type = 0
        unitLabel.text = "Days"
        timeLabel.text = "\(day)"
    case 1:
        guard let hour = Calendar.current.dateComponents([.hour], from: birthDay, to: currentDate).hour else {
            print("Couldn't get hour")
            return
        }

        unitLabel.text = "Hours"
        timeLabel.text = "\(hour)"
    case 2:
        guard let minute = Calendar.current.dateComponents([.minute], from: birthDay, to: currentDate).minute else {
            print("Couldn't get minute")
            return
        }

        unitLabel.text = "Minutes"
        timeLabel.text = "\(minute)"
    case 3:
        guard let second = Calendar.current.dateComponents([.second], from: birthDay, to: currentDate).second else {
            print("Couldn't get second")
            return
        }

        unitLabel.text = "Seconds"
        timeLabel.text = "\(second)"
    default:
        break
    }
}

Once you know where the issue is actually occurring, it should be much easier to fix it.

Charles Srstka
  • 16,665
  • 3
  • 34
  • 60
  • 1
    Why use `NSCalendar` in Swift 3? Use `Calendar`. – rmaddy Aug 28 '17 at 02:42
  • Ah, you're right. I've been doing everything in Swift 4 lately, and for some reason, I was misremembering that the `NSCalendar` to `Calendar` change happened in Swift 4, rather than Swift 3. I'll edit the answer. – Charles Srstka Aug 28 '17 at 02:51