0

I got more and more crash-reports from apple (all on iPhone 5, iOS 10.3.3) on the following lines of code:

    let date = NSDate()
    var dateComponents = DateComponents()
    dateComponents.hour = -6
    let calculatedDate = NSCalendar.current.date(byAdding: dateComponents, to: date as Date)

    let selectStatement = "SELECT nr from info where date > \(UInt((calculatedDate!.timeIntervalSince1970)) * 1000);"

The crash-report states the last line as the problem-line. So it seems, that calculatedDate is not instantiated.

In a former version a crash even occured in the first line (iPhone 5, iOS 10.3.2)

I by myself can't reproduce these crashes on an iPhone 6s.

Any suggestions what could go wrong in these statements?

tartsigam
  • 71
  • 1
  • 5
  • And don't use Foundation types when they have native Swift equivalents. Use `Date` and `Calendar`. – Dávid Pásztor Sep 01 '17 at 08:53
  • First: You seems to be mixing NSStuff (`NSDate` and `Date`, which leads to casts that could be avoided) and Swift Types. That's not recommended for a Swift 3 Code. – Larme Sep 01 '17 at 08:53
  • “I ... can't reproduce these crashes on an iPhone 6s.” ... Do it on iPhone 5 simulator and it’s easily reproduced. See [David’s answer](https://stackoverflow.com/a/45996612/1271826) below. – Rob Sep 01 '17 at 10:09
  • Will try to get rid of all the NSxxx things. They where just relics from copy/paste. – tartsigam Sep 01 '17 at 11:33
  • Why *1000? I get these timestamps from a server sending me in timeinmillis. – tartsigam Sep 01 '17 at 11:34
  • subtracting 6 hours: no, no timezone adjustment. has to do with begintimes of events. – tartsigam Sep 01 '17 at 11:36

2 Answers2

2

The problem is that the iPhone 5 is a 32bit device and you are getting an Integer overflow. See the error here when explicitly casting the result into Int32.

Use UInt64 instead of UInt to tackle the overflow issue on 32bit devices if you definitely need an integer value for your select statement.

Unrelated to the issue, but mixing Foundation types with native Swift types is discouraged when you can just use native Swift types (Date and Calendar).

Code showing the issue explicitly:

import Foundation

let date = Date()
var dateComponents = DateComponents()
dateComponents.hour = -6
let calculatedDate = Calendar.current.date(byAdding: dateComponents, to: date)
let selectStatement = "SELECT nr from info where date > \(UInt((calculatedDate!.timeIntervalSince1970)) * 1000);"
print(selectStatement) //prints 1504234558000
print(Int32(1504234558000))

ERROR at line 9, col 7: integer overflows when converted from 'Int' to 'Int32' print(Int32(1504234558000))

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • 2
    Solved Problem while u where writing. Updated the whole project to (U)Int64 where needed in the last 2 hours. thx – tartsigam Sep 01 '17 at 11:30
0

Use Date() instead of NSDate() & Calendar instead of NSCalendar.

let date = Date()
var dateComponents = DateComponents()
dateComponents.hour = -6
if let calculatedDate = Calendar.current.date(byAdding: dateComponents, to: date) {
   let selectStatement = "SELECT nr from info where date > \(UInt((calculatedDate.timeIntervalSince1970)) * 1000);"
}
Prince Agrawal
  • 3,619
  • 3
  • 26
  • 41