Please help me to modify this part of code,
if let dateVaule = UserDefaults().value(forKey: SplashSeenDate){
let dateStr = dateVaule as! String
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone.ReferenceType.local
let date = dateFormatter.date(from:dateStr)
if Global.sharedInstance.Splashs != nil && Global.sharedInstance.Splashs?.count != 0{
for (i,splash) in (Global.sharedInstance.Splashs?.enumerated().reversed())!{
if !checkTimeStamp(date: splash.create_timestamp,StoredDate: date!){
Global.sharedInstance.Splashs?.remove(at: i)
}
}
print(Global.sharedInstance.Splashs?.count ?? "-1")
}
}
Honestly speaking, i am very confuse with the date formatter. when this project launch, it occured crash at
if !checkTimeStamp(date: splash.create_timestamp,StoredDate: date!){
However, I could not replicate this crash... **Only a few user with iOS10 occured this crash.**Please kindly advise, Thanks a lot!
func checkTimeStamp(date: String!,StoredDate: Date) -> Bool {
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.locale = Locale(identifier:"en_US_POSIX")
let datecomponents = dateFormatter.date(from: date)
if (datecomponents! >= StoredDate) {
return true
} else {
return false
}
}
You are converting String
to Date
in two different ways:
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone.ReferenceType.local //###Why don't you use `TimeZone.current`?
let date = dateFormatter.date(from:dateStr)
And in checkTimeStamp(date: String!,StoredDate: Date) -> Bool
:
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.locale = Locale(identifier:"en_US_POSIX")
let datecomponents = dateFormatter.date(from: date)
In your case, lacking this line is critical for your first conversion:
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
You can find many articles discussing about DateFormatter
(or NSDateFormatter
in old articles) returning nil
.
When you use DateFormatter
with fixed format like "yyyy-MM-dd HH:mm:ss"
, you must set locale
to Locale(identifier: "en_US_POSIX")
.
Maybe you'd better define one conversion method (or computed property) to convert String
to Date
which fits for your app's requirements, and use it everywhere you need String
to Date
conversion:
extension String {
var toAppDate: Date? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.timeZone = TimeZone.current
dateFormatter.locale = Locale(identifier: "en_US_POSIX") //### <- Do not miss.
return dateFormatter.date(from: self)
}
}
Generally, your code uses too much forced-unwrapping or forced-casting. You can re-write it without using any forced-something:
if
let dateStr = UserDefaults().string(forKey: SplashSeenDate),
let date = dateStr.toAppDate,
let splashes = Global.sharedInstance.Splashs, !splashes.isEmpty
{
//### In most cases, `filter` is faster than repeated `remove`.
Global.sharedInstance.Splashs = splashes.filter {
checkTimeStamp(date: $0.create_timestamp, storedDate: date)
}
print(Global.sharedInstance.Splashs?.count ?? "-1")
}
(Assuming create_timestamp
is not Optional, and renamed parameter label StoredDate:
to storedDate:
.)