Fatal error: unexpectedly found nil while unwrapping an Optional value

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

  • Fatal error: unexpectedly found nil while unwrapping an Optional value

    Bitte nicht verschlagen... :/ Ich weiß das Thema ist schon lange durch...

    Das WebView baut erfolgreich in der viewWillAppear Funktion über die u.g. Funktion connectToServer(request: Global.urlRequest) eine Verbindung auf und zeigt die Webseite im WebView an.

    Möchte ich jetzt aber nachträglich über den Code die Funktion connectToServer(request: Global.urlRequest) aufrufen um beispielsweise eine andere Webseite zu öffnen, bekomme ich folgenden Fehler:
    Bildschirmfoto 2018-10-20 um 11.43.49.png
    Folgende Dinge habe ich recherchiert und mich an ihnen orientiert beim Coden:

    docs.swift.org/swift-book/LanguageGuide/TheBasics.html#ID330
    stackoverflow.com/questions/32…wrapping-an-optional-valu


    Die Fehlermeldung ist trotzdem da.

    Wäre dankbar für jeden Tipp!




    Definitionen:

    Quellcode

    1. @IBOutlet weak var webView: WKWebView!
    2. var request: URLRequest!



    Aufbau der Verbindung:

    Quellcode

    1. func connectToServer(request: URLRequest) {
    2. print("Connect to server...")
    3. self.webView.load(request)
    4. let currentURL = "\(request)"
    5. print("Current URL: \(currentURL)")
    6. defaults.set(currentURL, forKey: "currentURL")
    7. }
  • Ich vermute mal, Du rufst im späteren Verlauf Deine connectToServer()-Funktion mit dieser Property auf?

    Scotch schrieb:

    Quellcode

    1. var request: URLRequest!

    Warum ist das als implicitly unwrapped optional (IUO), aka ! definiert? IUO sind ein selten gebrauchter Sonderfall und nicht für den regulären Hausgebrauch gedacht. Wenn Du diesen urlrequest wirklich als Property haben mußt und willst, dann mach das zu einem normalen Optional und behandle die Optionalität an entsprechender Stelle!
    Das iPhone sagt: "Zum Antworten streichen". Wie? Echt Jetzt? Muß ich erst die Wohnung streichen!?
  • Scotch schrieb:

    Das webView ist nil. Wie kann das überhaupt nil sein?
    Ich kenne Deinen Code ja nicht, aber die Wahrscheinlichkeit, dass du mit mehreren Instanzen deines Controllers hantierst, ist sehr hoch. Eine Instanz kommt aus dem Storyboard und zeigt den WebView an. Dort ist die webView Property nicht nil. Irgendwo in deinem Code erzeugst du sicherlich eine weitere Instanz, die dann mit dem angezeigtem WebView nichts zu tun hat. Da ist dann die webView Property nil und es knallt.
  • Danke Michael für den Hinweis. Packe ich alles in einen Controller, funktioniert es, aber wenn die connectToServer(request: URLRequest) Funktion aus einer anderen Klasse ansteuere, knallt es. --> WebView ist nil... Warum??
    Zur Veranschaulichung habe ich ein Demo Projekt erstellt.
    Dateien
    • Test.zip

      (71,93 kB, 454 mal heruntergeladen, zuletzt: )
  • Es ist wie ich sagte. Du erzeugst in deiner Klasse SecondVC eine neue Instanz von ViewController:

    Zeile 19:
    ViewController().connectToServer(request: url)

    Diese Instanz hat mit der Instanz aus dem Storyboard nichts zu tun. Deshalb ist da das Outlet webView auch nil. Du musst dem SecondVC eine Referenz auf die ViewController-Instanz aus dem Storyboard übergeben. Das kannst du zum Beispiel in der Methode prepare(for:sender:) machen.
  • Scotch schrieb:

    Definitionen:

    Quellcode

    1. @IBOutlet weak var webView: WKWebView!
    2. var request: URLRequest!
    @Scotch Auch wenn das überall im Internet oft so zu sehen ist, kann ich von beiden Ausrufezeichen nur abraten. Das Webview ist bspw. auch nil, wäre das Outlet nicht verknüpft, kann aber auch im ViewController LifeCycle bspw. mal 'verloren' gehen oder erst später initialisiert werden. Besonders hängt es dann auch davon ab, wann du auf das Webview zugreifst. Ich kann dir nur ans Herz legen, das Ausrufezeichen zu meiden und stattdessen ordentlich und sauber mit Optionals zu arbeiten.

    Ist dann im Programmverlauf sichergestellt (`guard let` / `if let`), dass dein property gesetzt ist, kannst du in diesem Scope ruhig mit den Ausrufezeichen hantieren, wobei es auch da eher selten bis nie Sinn macht.
    Man kann alles schaffen. Man muss es nur wollen ;)
    www.regetskcob.github.io
  • So generell solltest du das Ausrufezeichen nicht verteufeln. Gerade für Outlets generiert ja Xcode den Code mit Ausrufe- anstatt mit Fragezeichen. Das ergibt in der Regel auch Sinn, da eine nicht initialisierte Outlet-Referenz einen schweren Fehler darstellt. Hier darf bei einem Zugriff das Programm ruhig abstürzen, weil der Fehler in der Regel woanders liegt.

    Bei sonstigen Variablen, die auch auf nil zeigen dürfen, hast du aber Recht.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    So generell solltest du das Ausrufezeichen nicht verteufeln. Gerade für Outlets generiert ja Xcode den Code mit Ausrufe- anstatt mit Fragezeichen. Das ergibt in der Regel auch Sinn, da eine nicht initialisierte Outlet-Referenz einen schweren Fehler darstellt. Hier darf bei einem Zugriff das Programm ruhig abstürzen, weil der Fehler in der Regel woanders liegt.

    Bei sonstigen Variablen, die auch auf nil zeigen dürfen, hast du aber Recht.
    Okay stimmt, bei den Outlets kann man es ruhig so machen, um auch ordentlich einen auf'n Deckel zu kriegen... Siehe aktueller Fall hier :)
    Man kann alles schaffen. Man muss es nur wollen ;)
    www.regetskcob.github.io