1

I have integrated crashlytics into my iOS app. And I got a crash log like this

# Issue #: 1
# Issue ID: 59940bb4be077a4dcc2837ff
# Session ID: 
e68dd53b640d4ac39f21b511a9f78b78_90910b25826211e7a25d56847afe9799_0_v2
# Date: 2017-08-16T06:30:00Z
# OS Version: 10.3.3 (14G60)
# Device: iPhone 6s
# RAM Free: 3.8%
# Disk Free: 15.2%

#0. Crashed: com.apple.main-thread
0  MY APP                         0x100086b50 specialized static Functions.retunDateStringFromDateString(dateString : String, inuputFormat : String, outPutFormat : String) -> String (Functions.swift:123)
1  MY APP                         0x1000ef820 specialized TeamAttendanceViewController.tableView(UITableView, cellForRowAt : IndexPath) -> UITableViewCell (Functions.swift)
2  MY APP                         0x1000eaa78 @objc TeamAttendanceViewController.tableView(UITableView, cellForRowAt : IndexPath) -> UITableViewCell (TeamAttendanceViewController.swift)
3  UIKit                          0x193641d90 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 688
4  UIKit                          0x193641fa8 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 80
5  UIKit                          0x19362f6ac -[UITableView _updateVisibleCellsNow:isRecursive:] + 2152
6  UIKit                          0x193646f98 -[UITableView _performWithCachedTraitCollection:] + 120
7  UIKit                          0x1933df49c -[UITableView layoutSubviews] + 176
8  UIKit                          0x1932f9cc0 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1200
9  QuartzCore                     0x1904ea274 -[CALayer layoutSublayers] + 148
10 QuartzCore                     0x1904dede8 
CA::Layer::layout_if_needed(CA::Transaction*) + 292
11 QuartzCore                     0x1904deca8 
CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 32
12 QuartzCore                     0x19045a34c 
CA::Context::commit_transaction(CA::Transaction*) + 252
13 QuartzCore                     0x1904813ac 
CA::Transaction::commit() + 504
14 QuartzCore                     0x190481e78 
CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned 
long, void*) + 120
15 CoreFoundation                 0x18d1789a8 
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
16 CoreFoundation                 0x18d176630 __CFRunLoopDoObservers 
+ 372
17 CoreFoundation                 0x18d176a7c __CFRunLoopRun + 956
18 CoreFoundation                 0x18d0a6da4 CFRunLoopRunSpecific + 
424
19 GraphicsServices               0x18eb11074 GSEventRunModal + 100
20 UIKit                          0x193361c9c UIApplicationMain + 208
21 MY APP                         0x10002f710 main 
(AppDelegate.swift:16)
22 libdyld.dylib                  0x18c0b559c start + 4

this is the first time I'm going to read a crash log file. As I understand. There is something wrong with my Functionclass's returnDateString method's 123 line. But how can I understand what is the exact issue in this line? And this is my method in the Function class.

class func retunDateStringFromDateString(dateString : String,inuputFormat: String, outPutFormat : String) -> String{
    if(dateString != ""){
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = inuputFormat//this your string date format

        let date = dateFormatter.date(from: dateString)


        dateFormatter.dateFormat = outPutFormat///this is what you want to convert format

        let timeStamp = dateFormatter.string(from: date!)


        return timeStamp
    }else{
        return ""
    }

}

And this is my 123 line. let timeStamp = dateFormatter.string(from: date!)

What would be the reason for this? Please help me. Thanks

UPDATE

var inTimeArray = inTime?.components(separatedBy: ".")
print(inTimeArray)

cell.inOneTime.text = Functions.nullToNilForString(value: Functions.retunDateStringFromDateString(dateString: (inTimeArray?[0])! ,inuputFormat: "yyyy-MM-dd'T'HH:mm:ss", outPutFormat:  "HH:mm") as AnyObject?)?.description
Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
user1960169
  • 3,533
  • 12
  • 39
  • 61
  • 1
    Possible duplicate of [DateFormatter doesn't return date for "HH:mm:ss"](https://stackoverflow.com/questions/40692378/dateformatter-doesnt-return-date-for-hhmmss) – Tamás Sengel Aug 16 '17 at 10:31
  • 1
    You most probably have `nil` in `date`. What is your `inputFormat` and what is `dateString`? Also do not use force unwrapping unless you are 100% the value won't ever be nil. As for understanding the crashlog, crash logs only show a stack trace, they cannot tell you the exact cause of the trouble, since in release mode your app is not running in debugger and hence there can be no breakpoints to catch and identify a runtime exception. However, as you did here, you can pinpoint the error to the line causing it in most cases. – Dávid Pásztor Aug 16 '17 at 10:32
  • @DávidPásztor I updated my question with the calling line – user1960169 Aug 16 '17 at 10:35
  • @user1960169 what is the value of `(inTimeArray?[0]`? when your app crashes? – Dávid Pásztor Aug 16 '17 at 10:38
  • @DávidPásztor This is where I have a trouble. Because When I run this on my device its not crashing even for same logged user. This happened in my client;s device. So I am not sure how to get this value. – user1960169 Aug 16 '17 at 10:40
  • @user1960169 the problem is most probably coming from the locale settings, check my answer – Dávid Pásztor Aug 16 '17 at 10:47
  • for future learning purpose and how to read, I suggest that you deliberately right code that would crash...at same time you could see the crash log on fabric and also on Xcode... – mfaani Aug 16 '17 at 14:17

2 Answers2

2

Based on the discussion in comments, it seems that the locale settings are different on your user's device than on your test devices and different locales can cause trouble when using explicit date formats.

As I have already stated in comments, do not force unwrap the date value, rather use optional unwrapping and show an error message to the user if dateFormatter.date(from: String) fails.

You should either change your dateFormat to a format that is locale independent, or set dateFormatter.locale = Locale(identifier: "en_US_POSIX") or any other locale that you have tested your explicit date formats with.

As for understanding the crashlog, crash logs only show a stack trace, they cannot tell you the exact cause of the trouble, since in release mode your app is not running in debugger and hence there can be no breakpoints to catch and identify a runtime exception. However, as you did here, you can pinpoint the error to the line causing it in most cases.

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • Thank you so much. If I set dateFormatter.locale = Locale(identifier: "en_US_POSIX") will it work for any other locale settings in any device? – user1960169 Aug 16 '17 at 10:56
  • 1
    It depends on where your `dateString` is coming from. If it is a value independent of the device, then yes, setting the locale to US will work on each device independent of the locale settings. – Dávid Pásztor Aug 16 '17 at 10:57
  • Is there any way that I can semulate this same issue in my device? – user1960169 Aug 16 '17 at 11:36
  • Try to change the Locale and see if you get the crash with any particular locales. – Dávid Pásztor Aug 16 '17 at 11:37
  • I changed Language and the region into few but still I didn't get the crash – user1960169 Aug 16 '17 at 11:41
  • It might be a weird edge case setup that generated the issue, but without more information it's impossible to say for sure. What you could do is change your code as suggested to not use forced unwrapping and use a logging framework, such as SwiftyBeaver using which you can send custom error messages. With this setup you should be able to get more information about the user's settings if such a problem occurs again. – Dávid Pásztor Aug 16 '17 at 12:44
1

The most likely problem here is that you are force unwrapping your optional date parameter. If it can't parse dateString into a date in the first place, date will be nil and force unwrapping will cause a crash.

Try something like this instead:

guard let date = dateFormatter.date(from: dateString) else {
    // handle the error
    return ""
}
//...
return dateFormatter.string(from: date)

See the docs on optionals to get a better understanding https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html