write date in Xcode

What is the right way to insert or write today's date in Core Data?


in .xcdatamodeld I have the Entity Contingut and the Attributes:

dateCreated of Type Date

text1 of Type String


    func today1() {
        let date = Date() 
        let calendar = Calendar.current
       
        let day = calendar.component(.day, from: date)
        let month = calendar.component(.month, from: date)
        let year = calendar.component(.year, from: date)
        let avui = "\(year)-\(month)-\(day)"
        print (avui)
    }

     // CREATE
    @IBAction func createData(_ sender: UIButton) {

        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
        let managedContext = appDelegate.persistentContainer.viewContext
        let contingutEntity = NSEntityDescription.entity(forEntityName: "Contingut", in: managedContext)!
        let contingut = NSManagedObject(entity: contingutEntity, insertInto: managedContext)
        contingut.setValue(today1(), forKey: "dateCreated")
        contingut.setValue("some text", forKey: "text1")

        do {
           try managedContext.save()
        } catch let error as NSError {
           print("Could not save. \(error), \(error.userInfo)")
        }

    }


When I create a new text1, I want to register the day. What is the right way to do that?

Replies

What is your problem ?

What do you expect ?

What do you get ?

- What is the problem:


When I click the button insert I get an error:

Thread 1: signal SIGABRT


In the console:

2020-03-02 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unacceptable type of value for attribute: property = "data"; desired type = NSDate; given type = __NSCFString; value = (Function).'

libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

The problem is in this line of code:

contingut.setValue("\(today2)", forKey: "data")


If I remove the previous line of code and I only use this, it works well. Here I insert the text from the UITextView:

contingut.setValue(textForm.text, forKey: "text1")


- What do you expect? I just want to safe the date when the user enter the text in a form (UITextView)

hi,


i think someone in the forum can help with this, but we will need more information before going forward. and we'll need more code.


some things to consider and/or answer:


(1) there is no call to (execute) the function today1 anywhere in your code. did you ever call it, and was the current date ever printed?


Note: line 23 does not call the today1 function -- it asks to print the function, not to invoke the function. for example, consider the following playground code:


import Foundation
func today1() {
  let date = Date()
  let calendar = Calendar.current
  let day = calendar.component(.day, from: date)
  let month = calendar.component(.month, from: date)
  let year = calendar.component(.year, from: date)
  let avui = "\(year)-\(month)-\(day)"
  print (avui)
}
print(today1)
today1()


the output of line 11 is (Function), while the output of line 12 is 2020-3-4.


(2) what is "today2" in line 19 of your code? is there another function somewhere in your code that you have not shown? if so, what is it, and why would you try to save a string whose content is a function (?) as an NSDate/Date?


(3) do you have a class/type definition for "contingut" in line 18? is this a generic NSManagedObject, or is it a variable of class "Contingut" that's defined in a Core Data Data Model?


hope to hear more on this and that we can help,

DMG

Thank you for your answer. I have updated my question. I think that corrects some errors in my previous code and answers your questions.


In the end, I want to know how to insert the date when the information is entered.

hi,


thanks for updating your code ... and so i'd offer these suggestions:


(1) your today1 function probably should not print the date (unless you'd like to rename it as "printTheDateRightNow()" or something), but return the date as a String. like this:


func today1() -> String {
    let date = Date()
    let calendar = Calendar.current
    let day = calendar.component(.day, from: date)
    let month = calendar.component(.month, from: date)
    let year = calendar.component(.year, from: date)
    return "\(year)-\(month)-\(day)"
}


note that this function is merely one of convenience on your part: it's not necessary to place the current date into Core Data.


(2) replace line 19 to simply put the current Date into Core Data as


contingut.setValue(Date(), forKey: "dateCreated")


(3) replace line 24 as


print (today1())


again, this has no effect on what was moved into Core Data, but it does confirm for you that the save was successful.


i think that should do it, although please understand that you are storing a "point in time" in Core Data, not simply a month-day-year combination.


hope that helps,

DMG

Thank you for your answer.


This line of code gives me error:

contingut.setValue(Date(), forKey: "dateCreated")


I tried to keep the datamodel Attribute Type to String and then change to Date. In both cases, it gives me an error


Then I tried:

contingut.setValue("\(Date())", forKey: "dateCreated")

In this case, it creates well the date but only if the Type is String


I am confused, what is the right way to do that?

hi,


you're having trouble with my suggestion of:


contingut.setValue(Date(), forKey: "dateCreated")


i'm puzzled as to why this has a problem -- but you're not showing the error message that's generated. that might help the diagnoosis.


on the other hand, i have a working app where an entity named Session has a attribute named date that's defined in the object model as a Date, which comes across in code generation for the class Session as:


@NSManaged public var date: Date?


i don't usually move values with setValue(forKey:), but instead i prefer to assign a date value to a variable "session" of type Session with (something like) this


let date = Date()
session.date = date


perhaps this alternative syntax will work, or at least provide a better error message for you.


hope that helps,

DMG

hi,


FWIW: i'm convinced that the problem you're having is with your Core Data definitions and not with any code that i've suggested.


to push this forward, i created a little project that adds entities of one type to Core data having a date attribute. it can then can show you what's been added to Core Data (so you can see how to retrieve data).


you can find it at:


bitbucket.org/delawaremathguy/narcisfromgirona


hope that helps,

DMG

After trying many things I could find where the problem is. Things go wrong when I change the Type of the Attribute in the .xcdatamodeld The only solution I could find is to create a new project.


I cannot even create a new Attribute with a different name. It seems that, I cannot change any Attribute in the .xcdatamodeld. Am I missing anything?

hi,


i would suggest two things:


(1) use the default setting of Codgen to Class Definition in the xcdatamodeld file (set for each entity, look in the right-most tab of the Inspector pane). this generates the (empty) Class definition and the extensions that define the attributes as class variables.


-- if you need to attach your own functions or computed properties to a Core Data class, just add a new file to extend the class.


(2) in XCode, use the Product menu, with the menu on-screen, hold down the Option key, and select Clean Build folder. (i think this is Option-Shift-Command K.) it would not hurt at this point to quit and then restart XCode.


it takes a little bit to get everything in-sync with the Core Data model during compiles -- for example, the Core Data class definitions have to be generated as Swift files before anything that uses them gets compiled. and i've had occasional troubles with XCode (current version 11.3.1) getting it to take changes in the model right away and "forget" other attributes or entities that have changed.


hope that helps,

DMG

Thank you for your help


I do not understand your (1) I suppose that I use the Default Configurations if I do nothing. Is that right? Or should I do something to activate it?


Thank your so much!


Narcís