Ich versuche, die Daten, die von der Serverseite meines Sockets kommen, in meiner App (iOS) zu lesen. Ich habe eine Netzwerkklasse festgelegt, die eine Verbindungs- und eine Eingabefunktion enthält. Wenn ich die Funktion NetworkEnable()
in die Datei func application...
in der AppDelegate-Datei einfüge, stellt der Socket eine Verbindung her, und der Server funktioniert ordnungsgemäß. Aber wenn der Code in meinem View-Controller die getPiIn()
-Funktion erreicht, erscheint ein EXC_BAD_INSTRUCTIONS
Fehler in der ersten Zeile der Funktion.Fehler beim Abrufen der Socket-Eingabe beim Verbinden in AppDelegate
Netzwerk Klassendatei:
class Network: NSObject, StreamDelegate {
//Socket server
let addr = "x.x.x.x"
let port = 2020
var inStream : InputStream?
var outStream: OutputStream?
var buffer = [UInt8](repeating: 0, count: 200)
func NetworkEnable() {
Stream.getStreamsToHost(withName: addr, port: port, inputStream: &inStream, outputStream: &outStream)
inStream?.delegate = self
outStream?.delegate = self
inStream?.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
outStream?.schedule(in: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
inStream?.open()
outStream?.open()
buffer = [UInt8](repeating: 0, count: 200)
print("Network Connected")
}
func stream(aStream: Stream, handleEvent eventCode: Stream.Event) {
switch eventCode {
case Stream.Event.endEncountered:
print("EndEncountered")
inStream?.close()
inStream?.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
outStream?.close()
print("Stop outStream currentRunLoop")
outStream?.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
case Stream.Event.errorOccurred:
print("ErrorOccurred")
inStream?.close()
inStream?.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
outStream?.close()
outStream?.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
case Stream.Event.hasBytesAvailable:
print("HasBytesAvailable")
if aStream == inStream {
inStream!.read(&buffer, maxLength: buffer.count)
let bufferStr = NSString(bytes: &buffer, length: buffer.count, encoding: String.Encoding.utf8.rawValue)
print(bufferStr!)
}
case Stream.Event.hasSpaceAvailable:
print("HasSpaceAvailable")
case Stream.Event.openCompleted:
print("OpenCompleted")
default:
print("Unknown")
}
}
func getPiIn() -> String {
inStream!.read(&buffer, maxLength: buffer.count) //Error Shows up here
let bufferStr = NSString(bytes: &buffer, length: buffer.count, encoding: String.Encoding.utf8.rawValue)
return(bufferStr!) as String
}
Heres der Aufruf an getPi
in ViewController.Swift
func changeTemp() {
let tempString = String(network.getPiIn())
currentTemp.text = tempString
}
Meine Vermutung ist, dass seit dem Strom Delegierten in einer anderen Klasse selbst erklärt werden sie nicht in der ViewController.swift
zugegriffen werden kann, aber wenn ich zu ViewController
ändern, lädt die Ansicht nie.
Es ist auch erwähnenswert, wenn ich network.NetworkEnable()
innerhalb der ViewDidLoad()
Platz es funktioniert gut, bis ich diese Ansicht verlassen und gehe zurück.
Sie haben zwangswrapped 'inStream', aber aufgrund der asynchronen Natur der Netzwerkoperationen ist es wahrscheinlich dass Sie "getPiIn" aufrufen, bevor die Netzwerkverbindung hergestellt wurde. Ich würde vorschlagen, dass Ihr Netzwerkcode eine "Benachrichtigung" sendet, sobald das Netzwerk verbunden ist und Ihr View-Controller diese Benachrichtigung abonniert hat. – Paulw11
Ich versuchte dies vergebens. Es ist auch erwähnenswert, dass die Ansicht nicht geladen wird, bis das Netzwerk verbunden ist und wenn die Ansicht lädt das ist, wenn der Fehler –
Sie ist Force-Unwrapping etwas, das ist "nil"; Das ist ein garantierter Absturz. Beginnen Sie damit, es in eine bedingte Auspackung zu ändern; das wird den Absturz entfernen und dann müssen Sie herausfinden, warum der Wert "null" ist. – Paulw11