2017-07-10 1 views
0

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.

+0

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

+0

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 –

+0

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

Antwort

0

also wenn ich verstanden, Sie wollen nur Daten vom Server bekommen, so verwenden Sie die Methode URLSession(). DataTask Sie verwenden InputStream OutputStream das ist Java Weg oder nicht? wenn Sie Benachrichtigungen verwenden wollen UNUserNotificationCenter ist der richtige Weg, Benutzer und Server in schnellen

+0

Der Server ist ein Python-Server, also muss ich die Methode verwenden, die ich gerade verwende. –

0

zu kommunizieren Wie Paulw11 wies darauf hin, wenn getPiIn() genannt wird, hat inStream! einen Wert von nil wie der Code jetzt steht und wie die Funktionen werden genannt. Durch Hinzufügen von static let shared = Network() zum Anfang der Netzwerkklasse und Aufruf aller Funktionen aus dieser Klasse als Network.shared.function über alle Dateien verhindert es den Wert nil

Verwandte Themen