Fatal Error

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Servus Zusammen,
    ich habe heute folgendes Problem:
    Und zwar möchte ich verschiedene Daten abspeichern und anschließend vergleichen.
    Das Problem ist jetzt nur, dass eines dieser Daten einen Fatal Error beim starten der App auswirft, da dafür ja noch kein Wert festgelegt wurde...
    "Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value"

    Weiß jemand von euch wie ich dieses Problem lösen kann?

    Um diese Zeile geht es:
    //Datum letzes Essen
    let date = UserDefaults.standard.object(forKey: "DatumLetzesEssen") as! Date


    Schon einmal vielen Dank! :)

    Liebe Grüße,

    Ferdi
  • Was sagt dir denn die Fehlermeldung?
    "Unexpectedly found nil while unwrapping an Optional value"


    Spoiler anzeigen
    Wie du richtig geschrieben hast, hast du dafür ja noch keinen Wert festgelegt und deshalb sagt er dir er hat "nil" (nichts) gefunden.

    Also musst du jetzt dem Compiler verklickern, dass er doch bitte weiter macht, sollte der Wert nicht existent sein.
    Zum Beispiel über eine If-Anweisung oder du probierst mal ...
    let date = UserDefaults.standard.object(forKey: ""DatumLetztesEssen" as! Date ?? Date() Was dir quasi ein Datum setzt, sollte er für UserDefaults nichts finden.



    Sollte das auch nicht klappen bin ich mit nur einer Zeile Code die ich daraus erkennen kann überfragt :D
  • Die Idee mit der If abfrage war tatsächlich auch mein erster Lösungsansatz, jedoch wird des einfach ignoriert und die gleiche Fehlermeldung erneut rausgefeuert...

    Ich habe meinen Code jetzt mal so wie von dir oben beschrieben abgeändert, leider wirft mir des nur noch mehr Fehlermeldungen um die Ohren :/


    Hier wird das Datum abgespeichert (funktioniert):

    Quellcode

    1. if UserDefaults.standard.object(forKey: "letzesEssen") as? Date != nil {
    2. let date = UserDefaults.standard.object(forKey: "letztesEssen") as! Date
    3. let df = DateFormatter()
    4. df.dateFormat = "dd.MM.yyyy"
    5. let str = df.string(from: date)
    6. l2.text = str
    7. }
    8. else{}


    Hier soll jetzt der unterschied der Tage gezählt werden (oben genannter Fehler):

    Quellcode

    1. //Flammen
    2. //Datum letzes Essen
    3. let date = UserDefaults.standard.object(forKey: "letztesEssen") as! Date
    4. //Datum erstes Essen
    5. let lastDate = UserDefaults.standard.object(forKey: "erstesEssen") as! Date
    6. //Aktuelles Datum zum Vergleich
    7. let today = Date()
    8. let dateFormatter = DateFormatter()
    9. dateFormatter.locale = Locale(identifier: "en_US_POSIX")
    10. dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
    11. let flammenAbfrageDay = Calendar.current.dateComponents([.day], from: date, to: today).day
    12. let flammenAbfrage = Int(flammenAbfrageDay!)
    13. if flammenAbfrage == 1
    14. {
    15. let flammenanzahl = Calendar.current.dateComponents([.day], from: lastDate, to: today).day
    16. let flammenanzahlint = Int(flammenanzahl!)
    17. labelflamme2.text = String(flammenanzahlint)
    18. UserDefaults.standard.set(1, forKey: "flammenStatus2209")
    19. UserDefaults.standard.synchronize()
    20. }
    21. else
    22. {
    23. labelflamme2.text = "0"
    24. UserDefaults.standard.set(0, forKey: "flammenStatus2209")
    25. UserDefaults.standard.synchronize()
    26. }
    Alles anzeigen
  • … und warum nimmst Du den Rat von @ashtari nicht an und nutzt weiterhin

    Quellcode

    1. let date = UserDefaults.standard.object(forKey: "letztesEssen") as! Date
    Der Tipp war doch, mittels ?? dafür zu sorgen, dass das Unwrapping bei einem nil-Wert des Optionals einen Standardwert hat (und nicht abraucht).

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Wenn etwas erwartet nil sein kann, dann niemals as! verwenden! - Bzw. wieso erwartest Du, dass "letztesEssen" immer da ist?

    Dein zweiter Ansatz könnte schon funktionieren. Vielleicht musst Du das Projekt noch mal löschen oder so. Aber wieso zwei mal das Objekt rausholen. Du hast es doch schon in der Hand???

    Das mit dem default Datum gefällt mir eigentlich auch nicht, da "letztesEssen" doch ruhig nil sein kann. Es gab halt noch kein "letztesEssen".

    Ich würde es so in der Art lösen

    Quellcode

    1. import Foundation
    2. // UserDefaults.standard.set(Date(), forKey: "DatumLetzesEssen")
    3. if let date = UserDefaults.standard.object(forKey: "DatumLetzesEssen") as? Date {
    4. let formatter = DateFormatter()
    5. formatter.dateFormat = "dd.MM.yyyy"
    6. let str = formatter.string(from: date)
    7. print("Date: \(str)")
    8. } else {
    9. print("NO DATE")
    10. }
    Alles anzeigen
  • manoh schrieb:

    Wenn etwas erwartet nil sein kann, dann niemals as! verwenden! - Bzw. wieso erwartest Du, dass "letztesEssen" immer da ist?
    Wenn etwas erwartet nil sein kann, dann kann man durchaus as! verwenden, muss es dann aber eben nur beim Unwrapping mit nem Default Wert versehen, sonst reitest du deine App in die Scheiße, wie Ferdinand hier ja selber gelernt hat... :D

    manoh schrieb:

    Das mit dem default Datum gefällt mir eigentlich auch nicht, da "letztesEssen" doch ruhig nil sein kann. Es gab halt noch kein "letztesEssen".
    Das is auch ne Glaubensfrage.
    Ich persönlich verwende kein "nil" in meinem code. Wenn der Wert nicht gesetzt ist, setze ich ihn.


    manoh schrieb:

    Ich würde es so in der Art lösen
    Jau, die Lösung sieht gut aus.
  • ashtari schrieb:

    Wenn etwas erwartet nil sein kann, dann kann man durchaus as! verwenden, muss es dann aber eben nur beim Unwrapping mit nem Default Wert versehen, sonst reitest du deine App in die Scheiße, wie Ferdinand hier ja selber gelernt hat...
    Nee. as! erwartet, dass etwas nicht nil ist. Wenn es doch nil ist, dann bekommst Du eine Exception.

    Quellcode

    1. let date = UserDefaults.standard.object(forKey: "DatumLetztesEssen") as! Date ?? Date()
    2. // Fatal error: Unexpectedly found nil while unwrapping an Optional value
    Wenn Du allerdings as? Date ?? Date() schreibst, dann geht das wieder. as! wird nur verwendet, wenn man sich sicher ist bzw. wenn man as! sieht, dann fragt man sich automatisch, ob das sein kann, da man diese Operation selten verwenden soll.
  • manoh schrieb:

    ashtari schrieb:

    Wenn etwas erwartet nil sein kann, dann kann man durchaus as! verwenden, muss es dann aber eben nur beim Unwrapping mit nem Default Wert versehen, sonst reitest du deine App in die Scheiße, wie Ferdinand hier ja selber gelernt hat...
    Nee. as! erwartet, dass etwas nicht nil ist. Wenn es doch nil ist, dann bekommst Du eine Exception.

    Quellcode

    1. let date = UserDefaults.standard.object(forKey: "DatumLetztesEssen") as! Date ?? Date()
    2. // Fatal error: Unexpectedly found nil while unwrapping an Optional value
    Wenn Du allerdings as? Date ?? Date() schreibst, dann geht das wieder. as! wird nur verwendet, wenn man sich sicher ist bzw. wenn man as! sieht, dann fragt man sich automatisch, ob das sein kann, da man diese Operation selten verwenden soll.


    Super genau, so hab ich es jetzt gelöst und es funktioniert einwandfrei! :)
    Das ist so wie ich finde, die einfachste der oben genannten Möglichkeiten.
    Ich bin immer wieder erstaunt was so ein kleiner Fehler doch für ne riesige Wirkung haben kann.. statt ? ein ! und alles ist verloren :whistling:

    Vielen Dank euch allen :thumbup:
  • Ferdinand schrieb:

    Ich bin immer wieder erstaunt was so ein kleiner Fehler doch für ne riesige Wirkung haben kann.. statt ? ein ! und alles ist verloren :whistling:
    Da geht es mir immer wieder ähnlich, wenn ich auf tausende LoC schaue und denke, dass jedes kleine Vertippen oder „Verdenken“ das ganze Konstrukt zum Einsturz bringen könnte. Klar, dass selbst bei ausgiebigstem Testen nie alle Fehler gefunden werden, aber dennoch finde ich Programmieren auch nach über 35 Jahren noch extrem cool:

    Ein Problem formulieren, abstrahieren, in Teilschritte zerlegen und in eine (künstliche) Sprache übersetzen … und „schon“ macht der Computer, was ich will - manchmal :D

    Faszinierend!

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Manchmal, du sagst es! :thumbsup:

    Um meinen Programmabschnitt weiter zu teste, muss ich das Datum des Simulators umstellen.
    Im Internet habe ich hierzu leider nur gefunden, dass man dies in den Einstellungen des iPhones unter Region&Sprache vornehmen kann.
    Hier finde ich aber den beschriebenen "Datum und Uhrzeit" Button nicht...
    Wurde das in einem Update verlegt?

    Grüße

    Ferdi
  • Ferdinand schrieb:

    Um meinen Programmabschnitt weiter zu teste, muss ich das Datum des Simulators umstellen.
    Ein neuer Thread für ein neues Problem wäre cool gewesen - die Dinger kosten hier nix und es würde das Auffinden einer Lösung für andere erleichtern.

    Zur Frage: Seit Xcode 11 kannst Du das Datum des Simulators angeblich per Kommandozeile setzen (habe keinen Mac zur Hand). Zumindest wird es in dessen Release Notes erwähnt:

    Quellcode

    1. xcrun simctl status_bar <device> override --time "9:41" --batteryState charged --batteryLevel 100
    Du müsstest auch eine Zeitangabe wie 2022-08-18T13:12:00+02:00 angeben können.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.