I would like to receive the date value in the api value as utc. I looked up the stackoverflow.
There was a similar case, but we couldn't solve it because it was different from me.
The server (POSTMAN(db) stores the value "b_date": 1602813891.
link >> Dateformatter issue in swift
mycode
var ViewItem: BoardView?
func DetailViewList() {
DispatchQueue.main.async {
self.txtUserName.text = String(ViewItem.userId ?? "")
self.txtCount.text = String(ViewItem.b_count ?? 0)
}
}
func utcToLocal(utcDate: String, dateFormat: String) -> String {
let dfFormat = DateFormatter()
dfFormat.dateFormat = dateFormat
dfFormat.timeZone = TimeZone(abbreviation: "UTC")
let dtUtcDate = dfFormat.date(from: utcDate)
dfFormat.timeZone = TimeZone.current
dfFormat.dateFormat = dateFormat
txtDate.text = Int(ViewItem?.b_date) // ERROR [Cannot invoke initializer for type 'Int' with an argument list of type '(Int?)'] , Overloads for 'Int' exist with these partially matching parameter lists: (CGFloat), (Double), (Float), (Float80), (Int64), (Word), (__shared NSNumber)
return dfFormat.string(from: dtUtcDate!)
}
jsonData
struct BoardView: Codable {
var b_date: Int?
var b_count: Int?
var userId: String?
}
Related
I have some decoders for different types.
In this function decoders for date are creating.
private static var __once: () = {
//possible formats
let formatters = [
"yyyy-MM-dd",
"yyyy-MM-dd'T'HH:mm:ssZZZZZ",
"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ",
"yyyy-MM-dd'T'HH:mm:ss'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SSS",
"yyyy-MM-dd HH:mm:ss"
].map { (format: String) -> DateFormatter in
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = format
formatter.timeZone = TimeZone(secondsFromGMT: 0)
return formatter
}
// Decoder for Date
Decoders.addDecoder(clazz: Date.self) { (source: AnyObject, instance: AnyObject?) -> Decoded<Date> in
if let sourceString = source as? String {
for formatter in formatters {
if let date = formatter.date(from: sourceString) {
return .success(date) //in this state date = 2022-03-26 05:45:00 +0000 (not nil)
}
}
}
...some code
}
Decoder calls here. It work right way for another types, but "date" turns to nil after returning from decoder function.
static func decodeOptional<T>(clazz: T.Type, source: AnyObject?) -> Decoded<T?> {
if let source = source, !(source is NSNull) {
switch Decoders.decode(clazz: clazz, source: source, instance: nil) { //this function call decoder for date from above.
case let .success(value): return .success(value) // but date in this statement turns no nil
case let .failure(error): return .failure(error)
}
} else {
return .success(nil)
}
}
static func decode<T>(clazz: T.Type, source: AnyObject, instance: AnyObject?) -> Decoded<T> {
initialize()
...somecode...//decoder with key "Date"
let key = "\(T.self)"
if let decoder = decoders[key], let value = decoder(source, instance) as? Decoded<T> {
return value
} else {
return .failure(.typeMismatch(expected: String(describing: clazz), actual: String(describing: source)))
}
}
Returning type:
public enum Decoded<ValueType> { ////ValueType = Date
case success(ValueType)
case failure(DecodeError)
}
Why Date object turns from real value to nil after returning from function?
I'm working on message Kit and I want to get the date from the message kit, But I'm getting an error while used it. I've chatDashboardView Controller and I've defined the computed property (getFormatter) and above the chatdashboard I've defined the Message struct.
public static var getFormatter: String{
let dformatter = DateFormatter()
dformatter.dateFormat = "dd/MM/yyy HH:mm"
let dateToString = dformatter.string(from: Date())
return dateToString
}
struct Message: MessageType{
public var sender: SenderType
public var messageId: String
public var sentDate: Date
public var kind: MessageKind
}
In networking class want to access this getFormatter property its saying me (Cannot call value of non-function type 'String') this is the error see the code and guide me thanks
func getAllMessagesForConverstion(id:String,compltion:#escaping(Result<[Message],Error>) -> Void){
checkMessageUSer(id) { (user) in
guard let users = user else {print("not getting the users sorry on getllMessage");return}
let messages : [Message] = users.compactMap({dic in
guard let content = dic["content"] as? String,
let dateString = dic["date"] as? String,
let messageId = dic["id"] as? String,
let isRead = dic["is_read"] as? String,
let senderEmail = dic["sender_email"] as? String,
let typeMessage = dic["type"] as? String,
let name = dic["name"] as? String,
let dateData = ChatDashboard.getFormatter(from: dateString) else
{return nil}
let senderData = Sender(photo: "", senderId: senderEmail, displayName: name)
return Message(sender: senderData, messageId: messageId, sentDate: "", kind: .text(content))
//return Message(sender: senderData, messageId: messageId, sentDate: , kind: .text(content))
})
}
}
Your getFormatter computed property is a string, which is a string format of today (Date())
Seeing what you are trying to do, you need to change the getFormatter like below (better if you could rename it to something like formatter since it is a property not a method)
public static var formatter: DateFormatter {
let dformatter = DateFormatter()
dformatter.dateFormat = "dd/MM/yyy HH:mm"
return dformatter
}
then you can access it and use to format your date string like below in getAllMessagesForConverstion
let dateData = ChatDashboard.formatter.date(from: dateString)
I am working on an iOS project in Swift. I used Moya framework for API handling and parsing. It works perfectly. But when I try to parse varibles other than string it shows me en error:
"Missing argument for parameter 'transformation' in call"
Here is my mapper class
import Mapper
class MyMapperClaa:Mappable {
var dateVariable: NSDate?
required init(map: Mapper) throws{
try dateVariable = map.from("date")
}
}
Created an extension for Date and its worked for me
extension Date:Convertible
{
public static func fromMap(_ value: Any) throws -> Date {
guard let rawDate = value as? String else {
throw MapperError.convertibleError(value: value, type: Date.self)
}
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
if let date = dateFormatter.date(from: rawDate) {
return date
} else {
throw MapperError.convertibleError(value: value, type: Date.self)
}
}
}
sorry, you are using this lib: https://github.com/lyft/mapper. from example there:
private func extractDate(object: Any?) throws -> Date {
guard let rawDate = object as? String else {
throw MapperError.convertibleError(value: object, type: Date.self)
}
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "your date format"
if let date = dateFormatter.date(from: rawDate) {
return date
} else {
throw MapperError.convertibleError(value: object, type: Date.self)
}
}
struct DateModel: Mappable {
let date: Date
init(map: Mapper) throws {
try date = map.from("date", transformation: extractDate)
}
}
I'm having trouble with storing a date that I got from SQLite DB into a Date Var, I'm trying to save the date coming from DB to the ResultTask.AlarmDate after converting it from String to Date.
When I tried and deleted the ? from ResultTask.AlarmDate? it stored the data fine, but when I have a task without an alarm I get an error cause I want to store nil it the var when there's no alarm, and tried multiple other ways to fix it but nothing work.
I made a break point right after the issue and used the Console to see the data and got confused, cause the data shown when I print what I'm trying to store in the var but the var is still nil, all shown below.
Notes
The code that getting data from DB works fine, I'm using the Objective-C FM-Database library, and result is seen in the Console below.
the .toDate() is an extension for String that I use and it code is in AppDelegate.swift as seen bellow, and it work just fine.
the Task Variable type is something I made in a Task.swift file to easy the work, and it work just fine & shown below.
The Function:
func GetTasks() -> [Task]{
var Tasks : [Task] = [Task]()
let dirPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)
let docsDir = dirPaths[0]
databasePath = (docsDir + "/" + "Tasks.db") as NSString
let TaskRecorderDB = FMDatabase(path: databasePath as String)
if (TaskRecorderDB?.open())! {
let querySQL = "Select * from 'Tasks' ORDER BY Priority DESC"
let results:FMResultSet? = TaskRecorderDB?.executeQuery(querySQL, withArgumentsIn: nil)
while results!.next() {
var ResultTask : Task! = Task()
ResultTask.ID = Int((results?.int(forColumn: "ID"))!)
ResultTask.FileName = results?.string(forColumn: "FileName")
ResultTask.Name = results?.string(forColumn: "Name")
ResultTask.Categorie = Int((results?.int(forColumn: "Categorie"))!)
ResultTask.Priority = Int((results?.int(forColumn: "Priority"))!)
ResultTask.AlarmDate? = (results?.string(forColumn: "Alarm").toDate())!
//Break point
ResultTask.Repeat? = (results?.string(forColumn: "Repeat"))!
ResultTask.Completed = Int((results?.int(forColumn: "Completed"))!).toBool()
if(ResultTask.Completed == false){
Tasks.append(ResultTask)
}
ResultTask = nil
}
TaskRecorderDB?.close()
} else {
print("Error #DB06: \(TaskRecorderDB?.lastErrorMessage())")
}
return Tasks
}
Console:
(lldb) print (results?.string(forColumn: "Alarm").toDate())!
(Date) $R0 = 2016-11-23 17:21:00 UTC
(lldb) print ResultTask.AlarmDate
(Date?) $R1 = nil
(lldb)
AppDelegate.swift:
extension String {
func toDate () ->Date! {
var FinalDate : Date! = nil
if (self != ""){
let DateFormatter : Foundation.DateFormatter = Foundation.DateFormatter()
DateFormatter.locale = Locale.current
DateFormatter.dateFormat = "y-MM-dd_HH-mm-ss"
FinalDate = DateFormatter.date(from: self)!
}
return FinalDate
}
}
Task.swift:
import Foundation
class Task : NSObject {
var ID : Int! = nil
var FileName : String! = nil
var Name : String! = nil
var Categorie : Int! = nil
var Priority : Int! = nil
var AlarmDate : Date! = nil
var Repeat : String! = nil
var Expired : Bool! = nil
var Completed : Bool! = nil
}
Thanks in advance.
Edit for #KaraBenNemsi :
I updates the .toDate() as you said.
& in task I used var AlarmDate : Date? instead of var AlarmDate : Date! = nil (I didn't use you're other tip in Task.swift for now cause I'll need to change a lot of other code in the app).
And used ResultTask.AlarmDate = results?.string(forColumn: "Alarm").toDate() and I get a fatal error: unexpectedly found nil while unwrapping an Optional value in it when the task doesn't have an alarm.
Try to change this line in the task class since it can be optional
from this
var AlarmDate: Date! = nil
to this
var AlarmDate: Date?
And then use this line to set the alarm
ResultTask.AlarmDate = results?.string(forColumn: "Alarm")?.toDate()
Also variable names should usually start with a lowercase letter.
I also think this line is unnecessary. You can just omit that line.
ResultTask = nil
Please also change the extension to
extension String {
func toDate() -> Date? {
guard self != "" else {
return nil
}
var finalDate: Date?
let DateFormatter : Foundation.DateFormatter = Foundation.DateFormatter()
DateFormatter.locale = Locale.current
DateFormatter.dateFormat = "y-MM-dd_HH-mm-ss"
finalDate = DateFormatter.date(from: self)
return finalDate
}
}
And maybe try to get more into how optionals work
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html
Addition:
Your class task should probably also look more like below. But then you have to change code in other places as well. It also forces you to pass all the required parameters in the constructor when initialising the task object.
class Task {
var id: Int
var fileName: String
var name: String
var category: Int
var priority: Int
var alarmDate: Date?
var repeating: String
var expired: Bool
var completed: Bool
init(id: Int, fileName: String, name: String, category: Int, priority: Int, repeating: String, expired: Bool, completed: Bool) {
self.id = id
self.fileName = fileName
self.name = name
self.category = category
self.priority = priority
self.repeating = repeating
self.expired = expired
self.completed = completed
}
}
And here is also a link to a Swift style guide:
https://github.com/raywenderlich/swift-style-guide
Change your task to have this
var AlarmDate : Date?
And then do this
if let alarm = results?.string(forColumn: "Alarm").toDate() {
ResultTask.AlarmDate = alarm
}
If any nil is found while unwrapping results, you won't set the value of ResultTask.AlarmDate.
I am trying to save a Date into a textfield and have that save into CoreData. I have the textfield set up and am able to use the date picker just fine with the NSDateFormatter but I am having trouble with getting it to save into the textfield into CoreData.
extension NSDate{
var stringValue: String{
return self.toString()
}
func toString() -> String {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let str = formatter.stringFromDate(self)
return str
}
}
extension String{
var dateValue: NSDate?{
return self.toDate()
}
func toDate() -> NSDate? {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
if let date = formatter.dateFromString(self) {
return date
}else{
// if format failed, Put some code here
return nil // an example
}
}
}
add this befor your class or another swift file,
then change textFieldDDate.NSDate = ddate to:
textFieldDDate.text = ddate.stringValue
you can only use text(String!) with UITextField,also only NSDate in your newItem.ddate.
change newItem.ddate = textFieldDDate.text to
newItem.ddate = textFieldDDate.text.dateValue
I see var ddate = data.valueForKey("ddate"), I guess it is type of NSDate? maybe you need change it to String, it can't be just use as!(?) String,if I am right, you need use my code of extension NSDate{} to change it too.
I checked your codes, just find some lines maybe it is save data to coreData:
if segue.identifier == "update" {
var selectedItem: NSManagedObject = myDivelog[self.tableView.indexPathForSelectedRow()!.row] as! NSManagedObject
let ADLVC: AddDiveLogViewController = segue.destinationViewController as! AddDiveLogViewController
ADLVC.divenumber = selectedItem.valueForKey("divenumber") as! String
ADLVC.ddate = selectedItem.valueForKey("ddate") as! NSDate
ADLVC.divelocation = selectedItem.valueForKey("divelocation") as! String
ADLVC.existingItem = selectedItem
}
am I right? I get this link of an answer of how to save a Data to CoreData for you. because maybe something wrong in there.
here it is https://stackoverflow.com/a/26025022/5113355