在AppDelegate

时间:2017-07-10 23:47:20

标签: ios swift sockets

我正在尝试从我的应用程序(iOS)上读取从我的套接字的服务器端进入的数据。我设置了一个包含connect和get输入函数的网络类。当我将NetworkEnable()函数放入AppDelegate文件中的func application...时,套接字连接并且服务器按预期进行操作。但是当我的视图控制器中的代码到达getPiIn()函数时,函数的第一行会出现EXC_BAD_INSTRUCTIONS错误。

网络类文件:

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
}

继承人在ViewController.Swift中调用getPi

func changeTemp() {

    let tempString = String(network.getPiIn())

    currentTemp.text = tempString

}

我的猜测是,由于流代理在另一个类中被声明为self,因此无法在ViewController.swift中访问它们,但是当我将.self更改为ViewController时视图从不加载。

值得一提的是,当我将network.NetworkEnable()放在ViewDidLoad()中时,它会正常工作,直到我离开该视图并返回。

2 个答案:

答案 0 :(得分:0)

所以,如果我理解你只想从服务器获取数据,那么使用方法URLSession()。dataTask 你使用InputStream OutputStream这是java方式还是没有? 如果您想获得通知,请使用UNUserNotificationCenter 是快速通信用户和服务器的正确方法

答案 1 :(得分:0)

正如Paulw11所指出的那样,当调用getPiIn()时,inStream!的值为nil,因为代码现在代表,以及如何调用函数。通过将static let shared = Network()添加到网络类的开头并在所有文件中将该类中的所有函数调用为Network.shared.function,可以防止值返回nil