Send image to printer using sockets on port 9100 - swift

I'm currently able to send text to a printer (like EPSON TM20-II) using Swift. The printer receives the data and prints it without any problems. (For that, I'm encoding my string in UTF-8)
My custom class for the socket :
class OutSocket {
var addr: String
var port: Int
var task: NSURLSessionStreamTask!
init(host: String, port: Int){
print("init")
self.addr = host
self.port = port
setupConnection()
}
func setupConnection() {
print("setup")
let session = NSURLSession(configuration: .defaultSessionConfiguration())
task = session.streamTaskWithHostName(addr, port: port)
self.task.resume()
}
func send(data: NSData) {
self.task.writeData(data, timeout: 5.0) { (error) in
if error == nil {
print("Data sent")
} else {
print("Nope")
}
}
}
}
And I'm using it like this :
let socket = OutSocket(host: "192.168.1.42", port: 9100)
socket.send((itemText + "\n").dataUsingEncoding(NSUTF8StringEncoding)!)
I can send an image to the printer, but it only prints me the data characters.
How can I print an image, and not the data characters ?
I saw the Epson SDK but I want it to works with any printer that support TCP/IP printing. I tried to encode my image in base64 but still not print the image.
here the code :
let socket = OutSocket(host: "192.168.1.42", port: 9100)
let image = UIImage(named: "name-logo")
let imgData = UIImagePNGRepresentation(image!)
let imgEncoded = imgData!.base64EncodedDataWithOptions(.Encoding64CharacterLineLength)
socket.send(imgEncoded)
Thanks in advance,

Related

How to write a NWProtocolFramer for Network.framework that splits streams into frames using a delimiter?

I tried the following code to create a framer that splits a stream of ASCII bytes into frames separated by the pipe ascii character: "|".
import Network
fileprivate let pipe = Character("|").asciiValue!
class PipeFramer: NWProtocolFramerImplementation {
static let label = "Pipe framer"
static let definition = NWProtocolFramer.Definition(implementation: PipeFramer.self)
var minLengthUntilNextMessage = 1 {
didSet { print("client: minLength set to", minLengthUntilNextMessage) }
}
required init(framer: NWProtocolFramer.Instance) {}
func start(framer: NWProtocolFramer.Instance) -> NWProtocolFramer.StartResult { .ready }
func handleInput(framer: NWProtocolFramer.Instance) -> Int {
while true {
var delimiterPosition: Int?
_ = framer.parseInput(minimumIncompleteLength: minLengthUntilNextMessage, maximumLength: 65535) { buffer, endOfMessage in
if let buffer = buffer {
print("client: parsing buffer: \"\(String(bytes: buffer, encoding: .utf8) ?? buffer.debugDescription)\"")
if let indexOfDelimiter = buffer.firstIndex(of: pipe) {
minLengthUntilNextMessage = 1
delimiterPosition = indexOfDelimiter
} else {
minLengthUntilNextMessage = buffer.count + 1
}
} else {
print("client: no buffer")
}
return 0
}
if let length = delimiterPosition {
guard framer.deliverInputNoCopy(length: length, message: .init(instance: framer), isComplete: true) else {
return 0
}
_ = framer.parseInput(minimumIncompleteLength: 1, maximumLength: 65535) { _,_ in 1 }
} else {
return minLengthUntilNextMessage
}
}
}
func handleOutput(framer: NWProtocolFramer.Instance, message: NWProtocolFramer.Message, messageLength: Int, isComplete: Bool) {
try! framer.writeOutputNoCopy(length: messageLength)
framer.writeOutput(data: [pipe])
}
func wakeup(framer: NWProtocolFramer.Instance) {}
func stop(framer: NWProtocolFramer.Instance) -> Bool { return true }
func cleanup(framer: NWProtocolFramer.Instance) { }
}
The problem is that from the moment I get a chunk that does not end with "|", the framer gets stuck on that chunk. So the other chunks that come after this incomplete chunk never fully arrive in the framer.parseInput(...) call. Because it always parses chunks of minimumIncompleteLength and hence never arrives to the point where the next "|" is.
Here is a simple reproduction of this problem:
Create a TCP server
Setup the server so that it sends chunks of messages when a client connects.
Connect to the server (created in 1.) using the framer from above.
Start receiving messages.
Swift Code:
import Network
let client = DispatchQueue(label: "Server")
let server = DispatchQueue(label: "Client")
let networkParameters = NWParameters.tcp
networkParameters.defaultProtocolStack.applicationProtocols.insert(NWProtocolFramer.Options(definition: PipeFramer.definition), at: 0)
let server = try! NWListener(using: .tcp)
server.newConnectionHandler = { connection in
print("server: new connection from", connection.endpoint)
print("server (client \(connection.endpoint)): state", connection.state)
connection.viabilityUpdateHandler = { viable in
print("server (client \(connection.endpoint)): state", connection.state)
if viable {
print("server: sending")
connection.send(content: "A|Be||Sea".data(using: .utf8)!, isComplete: false, completion: .idempotent)
serverQueue.asyncAfter(deadline: .now() + 5) {
print("server: sending second part")
connection.send(content: " is longer than expected|0|".data(using: .utf8)!, isComplete: true, completion: .idempotent)
}
serverQueue.asyncAfter(deadline: .now() + 8) {
print("server: sending last part")
connection.send(content: "Done|".data(using: .utf8)!, isComplete: true, completion: .idempotent)
}
}
}
connection.start(queue: serverQueue)
}
server.stateUpdateHandler = { state in
print("server:", state)
if state == .ready, let port = server.port {
print("server: listening on", port)
}
}
server.start(queue: serverQueue)
let client = NWConnection(to: .hostPort(host: "localhost", port: server.port!), using: networkParameters)
func receiveNext() {
client.receiveMessage { (data, context, complete, error) in
let content: String
if let data = data {
content = String(data: data, encoding: .utf8) ?? data.description
} else {
content = data?.debugDescription ?? "<no data>"
}
print("client: received \"\(content)\"", context.debugDescription, complete, error?.localizedDescription ?? "No error")
receiveNext()
}
}
client.stateUpdateHandler = { state in
print("client:", state)
if state == .ready {
print("client: receiving")
receiveNext()
}
}
client.start(queue: clientQueue)
Results in:
server: waiting(POSIXErrorCode: Network is down)
server: ready
server: listening on 54894
client: preparing
client: ready
client: receiving
server: new connection from ::1.53179
server (client ::1.53179): state setup
server (client ::1.53179): state ready
server: sending
client: parsing buffer: "A|Be||Sea"
client: minLength set to 1
client: parsing buffer: "Be||Sea"
client: minLength set to 1
client: parsing buffer: "|Sea"
client: minLength set to 1
client: parsing buffer: "Sea"
client: minLength set to 4
client: parsing buffer: ""
client: minLength set to 1
client: received "A" Optional(Network.NWConnection.ContentContext) true No error
client: received "Be" Optional(Network.NWConnection.ContentContext) true No error
client: received "<no data>" Optional(Network.NWConnection.ContentContext) true No error
client: parsing buffer: "Sea"
client: minLength set to 4
server: sending second part
client: parsing buffer: "Sea "
client: minLength set to 5
client: parsing buffer: "Sea i"
client: minLength set to 6
server: sending last part
client: parsing buffer: "Sea is"
client: minLength set to 7
client: parsing buffer: "Sea is "
client: minLength set to 8
Notice that the fourth and fifth message are never received by the client. How should I write the Framer so that it receives messages after an incoming incomplete chunk?
References
A swift package containing the above code
Corresponding discussion on  Developer Forums
I had exactly the same problem... The network protocol that I was working with also had a simple delimiter that separated each 'message' and the protocol had no header that told me what to expect. Often at the end of the buffer, there was only a partial message with no delimiter and needed to read more bytes to get the remainder of the message. Something like this:
| PACKET A | PACKET B |
|<message>|<message>|<message><mess...age>|<message><message><message><m...essage>
1 2 4 5a 5b 6 7 8 9a 9b
Note:
delimiter = | - single character
lhsMessage = message 5a
rhsMessage = message 5b
Even after watching WWDC and looking at the other examples from Apple, I still do not completely understand how handleInput and parseInput are supposed to function.
I assumed I could simply return from handleInput with the (lhsMessage.count + 1) and it would keep the partial message in the current buffer AND add additional bytes into the buffer (ie from PACKET B) that parseInput could inspect.
However, it does appear to work that way. Instead I ended up storing the value of lhsMessage in a class var and then returned lhsMessage.count from parseInput, which I believe moves the ‘cursor’ in the buffer to end and forces handleInput to get the new packet (ie packet B).
As part of parseInput, I then check if I have a lhsMessage and then assume if I find a delimiter that it is in fact rhsMessage. I then join LHS and RHS to create a completeMessage. At this point, I also return from parseInput the value of (rhsMessage.count + 1) to move the cursor along again.
Now to send this completeMessage I could not use deliverInputNoCopy as the bytes that make up completeMessage were no longer in the buffer :-)
Instead handleInput sent the message back using deliverInput.

UDP Listener on iOS 14

I have a question regarding how to set up a UDP listener on iOS 14. I have a UDP listener which has worked in the past, but after updating to iOS 14 it works sporadically/not at all.
This lives in an NSObject, and listens for a UDP broadcast across the local network on port 15000 (no specific IP address). It uses the CocoaAsyncSocket library. When I call setUpSocket() local network permissions are not triggered, but the app is able to sporadically pick up UDP packets.
var socket: GCDAsyncUdpSocket?
var broadcastPort: UInt16 = 15000
var broadcastAddress: String = ""
var connectAddress = ""
var connectPort = 0
func setUpSocket() {
    findUDP()
    let socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.main)
     
    socket.setIPv4Enabled(true)
    socket.setIPv6Enabled(false)
     
    do {
      try socket.bind(toPort: broadcastPort) /*15000*/
      try socket.enableBroadcast(false)
      try socket.beginReceiving()
       
    } catch let error as NSError {
       
      print("Issue with setting up listener \(error)")
       
    }
     
  }
/*Called when UDP packets are received.*/
func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress: Data, withFilterContext filterContext: Any?) {
     
    do {
      let jsonDictionary = try JSONSerialization.jsonObject(with: data, options: []) as! [String : Any]
       
      if (connected == false) {
        if (jsonDictionary["Addresses"] != nil) {
          if (jsonDictionary["Addresses"] is NSArray) {
            let addresses = jsonDictionary["Addresses"] as! NSArray
             
            for i in addresses {
              let ipAddress:String = i as! String
              if (ipAddress.range(of: "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\\/([0-9]|[1-2][0-9]|3[0-2]))?$", options: .regularExpression) != nil) {
                connectAddress = ipAddress
              }
            }
            connectPort = jsonDictionary["Port"] as! Int
          }
           
/*Sets up a TCP connection on the IP and Port provided in the UDP broadcast.*/
setupNetworkCommunication(ip: connectAddress, port: connectPort)
          
          closeSocket()
        }
      }
       
    } catch let error {
      return print(error)
    }
  }
How can I update this to comply with iOS 14? If I need to update to use Bonjour services, how can I listen on a port without specifying an address (and without having to look for a specific Bonjour service broadcast, because the broadcast I'm looking for doesn't use Bonjour).
Is it acceptable to quickly open and close a Bonjour NWBrowser in order to trigger the network permissions, and then use my code as-is? This seems to work but seems hacky at best.
Thanks in advance.
Here are the steps that we had to go through in order to use CocoaAsyncSocket with UDP in our app:
Request the multicast entitlement from Apple (requestor must be the Account Holder of the team): com.apple.developer.networking.multicast
In the target's Info.plist, set a string for the following key:
Privacy - Local Network Usage Description
After getting permission for the entitlement from Apple, add a true(1) Boolean value for the following key in the *.entitlements file for your app (this last step is what kept us from receiving UDP broadcast packets):
com.apple.developer.networking.multicast
I was able to explore this some more and got some help via the apple developer forums, posting an answer here as well for those who are interested.
I ended up using an NWListener to listen for UDP packets, then set up an NWConnection once once I'd received something. I use this NWConnection to read data from the UDP broadcast.
From Quinn "The Eskimo:"
Listening for UDP broadcasts via an NWListener and then using the NWConnection objects it vends (via the new connection handler) to communicate over unicast with the broadcast’s sender is an expected use case.
I encourage anyone reading this to check out our discussion on the Apple Developer Forum as well.
Here is my implementation:
var udpListener: NWListener?
var udpConnection: NWConnection?
var backgroundQueueUdpListener = DispatchQueue.main
func findUDP() {
let params = NWParameters.udp
udpListener = try? NWListener(using: params, on: 15000)
udpListener?.service = NWListener.Service.init(type: "_appname._udp")
self.udpListener?.stateUpdateHandler = { update in
print("update")
print(update)
switch update {
case .failed:
print("failed")
default:
print("default update")
}
}
self.udpListener?.newConnectionHandler = { connection in
print("connection")
print(connection)
self.createConnection(connection: connection)
self.udpListener?.cancel()
}
udpListener?.start(queue: self.backgroundQueueUdpListener)
}
func createConnection(connection: NWConnection) {
self.udpConnection = connection
self.udpConnection?.stateUpdateHandler = { (newState) in
switch (newState) {
case .ready:
print("ready")
self.send()
self.receive()
case .setup:
print("setup")
case .cancelled:
print("cancelled")
case .preparing:
print("Preparing")
default:
print("waiting or failed")
}
}
self.udpConnection?.start(queue: .global())
}
func endConnection() {
self.udpConnection?.cancel()
}

Simple TCP listener on swift

I send messages to applications running on remote computers.
I send messages this ways.
c#:
void web_data_work()
{
try
{
TcpClient client = new TcpClient(address, port);
Byte[] data = Encoding.UTF8.GetBytes(string.Format("{0}", message));
NetworkStream stream = client.GetStream();
try
{
if (message != "")
{
stream.Write(data, 0, data.Length);
Byte[] readingData = new Byte[256];
String responseData = String.Empty;
StringBuilder completeMessage = new StringBuilder();
int numberOfBytesRead = 0;
do
{
numberOfBytesRead = stream.Read(readingData, 0, readingData.Length);
completeMessage.AppendFormat("{0}", Encoding.UTF8.GetString(readingData, 0, numberOfBytesRead));
}
while (stream.DataAvailable);
responseData = completeMessage.ToString();
this.Invoke((MethodInvoker)delegate ()
{
output_list.Items.Add(string.Format("Sended – {0}", responseData));
message = "";
});
}
}
finally
{
stream.Close();
client.Close();
}
}
catch
{
this.Invoke((MethodInvoker)delegate ()
{
output_list.Items.Add("Not sended");
message = "";
});
}
}
swift:
func web_data_work()
{
let address = address_box.stringValue
let port = port_box.intValue
let task = URLSession.shared.streamTask(withHostName: address, port: Int(port))
let data = message.data(using: .utf8)!
task.write(data as Data, timeout: 0)
{
error in
//om = "Not sended"
//self.output_message()
}
task.resume()
}
In c# i can read messages using TcpListener, how do i do it in swift?
Only two parameters are used:
"address" – ip address of the computer to which messages are sent and which is listened to by the TcpListener of that computer.
"port" – port of the sending and receiving between computers.
P.S. Preferably without additional libraries.
You can achieve this with just two classes: SocketPort & FileHandle.
Before you copy & paste the example below, please, read my comments at the end.
import Cocoa
class TcpEchoClient {
var readToEndOfFileCompletionHandler: (() -> Void)?
let fileHandle: FileHandle
var observer: NSObjectProtocol?
init(fileHandle: FileHandle) {
self.fileHandle = fileHandle
// Register observer for the data & EOF
self.observer = NotificationCenter.default.addObserver(forName: .NSFileHandleReadToEndOfFileCompletion,
object: fileHandle,
queue: OperationQueue.main) { [weak self] note in
self?.handleReadToEndOfFileCompletion(notification: note)
}
// Instruct the handle to read till the EOF & notify
fileHandle.readToEndOfFileInBackgroundAndNotify()
}
func handleReadToEndOfFileCompletion(notification note: Notification) {
defer {
// No matter what happens, call the completion handle by the end
readToEndOfFileCompletionHandler?()
}
// Is there an error?
if let errorCode = note.userInfo?["NSFileHandleError"] as? NSNumber {
print("Client \(fileHandle.fileDescriptor) error: File handle error \(errorCode.intValue)")
return
}
// No error, we should have data available
guard let data = note.userInfo?[NSFileHandleNotificationDataItem] as? Data else {
print("Client \(fileHandle.fileDescriptor) error: Unable to get data")
return
}
// Convert them to UTF-8 string
guard let text = String(data: data, encoding: .utf8) else {
print("Client \(fileHandle.fileDescriptor) error: Unable to convert data to UTF-8 string")
return
}
// Print the text
print("Client \(fileHandle.fileDescriptor) received: \(text)")
}
deinit {
// Remove observer for the data & EOF
if let observer = observer {
NotificationCenter.default.removeObserver(observer)
}
// Close the handle
try? fileHandle.close()
}
}
class TcpServer {
let port: SocketPort
let fileHandle: FileHandle
var clients: Dictionary<Int32, TcpEchoClient>
var observer: NSObjectProtocol?
init?(tcpPort: UInt16) {
guard let socketPort = SocketPort(tcpPort: tcpPort) else {
return nil
}
// Keep the socket port around otherwise you'll get error 38
port = socketPort
// No clients for now
clients = [:]
// Create handle from the socket
fileHandle = FileHandle(fileDescriptor: port.socket)
// Register observer for the connection accepted
observer = NotificationCenter.default.addObserver(forName: .NSFileHandleConnectionAccepted,
object: fileHandle,
queue: OperationQueue.main) { [weak self] note in
if let handle = note.object as? FileHandle {
// Ask immediately for another accepted connection notification
handle.acceptConnectionInBackgroundAndNotify()
}
self?.handleConnectionAccepted(notification: note)
}
// Instruct the handle to accept connection & notify
fileHandle.acceptConnectionInBackgroundAndNotify()
}
func handleConnectionAccepted(notification note: Notification) {
// Is there an error?
if let errorCode = note.userInfo?["NSFileHandleError"] as? NSNumber {
print("Server error: File handle error \(errorCode.intValue)")
return
}
// No, we should have received the client file handle
guard let clientFileHandle = note.userInfo?[NSFileHandleNotificationFileHandleItem] as? FileHandle else {
print("Server error: Unable to get accepted connection file handle")
return
}
let fileDescriptor = clientFileHandle.fileDescriptor
// Create new client from the file handle
let client = TcpEchoClient(fileHandle: clientFileHandle)
// Once it finishes, remove it from the clients dictionary
client.readToEndOfFileCompletionHandler = { [weak self] in
guard let self = self else { return }
self.clients.removeValue(forKey: fileDescriptor)
print("Server: Client removed \(fileDescriptor) (total \(self.clients.count))")
}
// Store the client in the clients dictionary
clients[fileDescriptor] = client
print("Server: New client \(fileDescriptor) added (total \(self.clients.count))")
}
deinit {
// Remove all clients
clients.removeAll()
// Close the file handle
try? fileHandle.close()
// Invalidate the socket port
port.invalidate()
// Remove connection accepted observer
if let observer = observer {
NotificationCenter.default.removeObserver(observer)
}
}
}
Then create a property (var server: TcpServer?) and initialize it (server = TcpServer(tcpPort: 8080)).
Test:
parallel -j 1 echo -n Foo '|' nc 127.0.0.1 8080 ::: {1..4}
Console output:
Server: New client 7 added (total 1)
Client 7 received: Foo
Server: Client removed 7 (total 0)
Server: New client 7 added (total 1)
Client 7 received: Foo
Server: Client removed 7 (total 0)
Server: New client 7 added (total 1)
Client 7 received: Foo
Server: Client removed 7 (total 0)
Server: New client 7 added (total 1)
Client 7 received: Foo
Server: Client removed 7 (total 0)
Comments:
This example is only a basic skeleton you can start with.
Don't be misleaded with the parallel test command.
I'm using it if I want to run multiple commands at once (same commands).
Everything in this example operates on the main queue.
Read documentation of all these classes, methods and notifications I do use. There're gotchas, you have to be familiar with run loops, etc.

writeDataUnsupported in ChannelInboundHandler (Swift-NIO)

I am trying to make a simple echo UDP server that sends back all incoming datagrams prefixed with a UTF8 string.
In my attempts to reach this goal, I succeeded in sending back the incoming data, but when I try to prefix this data with the string: "You sent: ", I get an error writeDataUnsupported
This is my code:
I made a ChannelInboundHandler called Echo all it does is: For each incoming datagram, it sends the string "You sent: " and then the data of the incoming datagram.
final class Echo: ChannelInboundHandler {
typealias InboundIn = ByteBuffer
typealias OutboundOut = ByteBuffer
var wroteResponse = false
static let response = "You sent: ".data(using: .utf8)!
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
if !wroteResponse {
var buffer = ctx.channel.allocator.buffer(capacity: Echo.response.count)
buffer.write(bytes: Echo.response)
ctx.write(self.wrapOutboundOut(buffer), promise: nil)
wroteResponse = true
}
ctx.write(data, promise: nil)
}
func channelReadComplete(ctx: ChannelHandlerContext) {
ctx.flush()
wroteResponse = false
}
}
Then I made a single threaded event loop group and assigned a datagram bootsrap to it. Then I bound the bootstrap to port 4065.
let 🔂 = MultiThreadedEventLoopGroup(numThreads: 1)
let bootstrap = DatagramBootstrap(group: 🔂)
.channelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
.channelInitializer { $0.pipeline.add(handler: Echo()) }
defer {
try! 🔂.syncShutdownGracefully()
}
try bootstrap
.bind(host: "127.0.0.1", port: 4065)
.wait()
.closeFuture
.wait()
Why do I always get this writeDataUnsupported while trying to send the string: "You sent: "?
For DatagramChannel you need to wrap your ByteBuffer into an AddressEnvelope. Which also means your ChannelInboundHandler should operate on AddressedEnvelope<ByteBuffer>.
To make the ChannelInboundHandler operate on AddressedEnvelope<ByteBuffer>, as Norman Maurer suggests, you can rewrite Echo so it looks more like:
final class Echo: ChannelInboundHandler {
typealias InboundIn = AddressedEnvelope<ByteBuffer>
typealias OutboundOut = AddressedEnvelope<ByteBuffer>
static let response = "You sent: ".data(using: .utf8)!
func channelRead(ctx: ChannelHandlerContext, data: NIOAny) {
var incomingEnvelope = unwrapInboundIn(data)
var buffer = ctx.channel.allocator.buffer(capacity: Echo.response.count + incomingEnvelope.data.readableBytes)
buffer.write(bytes: Echo.response)
buffer.write(buffer: &incomingEnvelope.data)
let envelope = AddressedEnvelope(remoteAddress: incomingEnvelope.remoteAddress, data: buffer)
ctx.write(wrapOutboundOut(envelope), promise: nil)
}
func channelReadComplete(ctx: ChannelHandlerContext) {
ctx.flush()
}
}

Reading Sensor data indefinitely using TCP in Swift

I am new to Swift and i am trying to read the data from a sensor that connects to my router using Wifi. According to the sensor documentation: "In local communication mode the sensor node works as TCP/IP-server and writes output data in ASCII-format in the defined IP-address port 8080 at 1Hz rate.” So i want to read that data that the sensor is continuously emitting every second and use it to plot a chart on the iPhone. This is how the sample data looks like, the first value on each row(7255,7256.., 7259) is the time that changes every second.
7255,64,6,46,390,555,1,11137,0,0
7256,64,6,46,390,785,1,1108,0,0
7257,64,6,46,390,602,1,1135,0,0
7258,64,6,46,390,847,2,1135,0,0
7259,64,6,47,403,870,2,1669,0,0
I wrote a sample application and I am able to connect to the sensor and read the data but it doesn’t work continuously or consistently. I will receive one record then it will wait for few second and then all of a sudden i will receive the data for 5-8 seconds. Also after working for 25-30 seconds it will wait for a long time and then nothing will be read anymore. I would like to read the data continuously like the free app "WIFI TCP Test Tool" available for free on App Store. This app reads the data perfectly every second from the sensor so i know there is nothing wrong with the sensor or my router. Here is my sample code, would appreciate any help.
import UIKit
import Foundation
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
func readSensorData() {
let addr = "192.168.0.100"
let port = 8080
var buffer = [UInt8](count: 255, repeatedValue: 0)
var inp : NSInputStream?
var out : NSOutputStream?
NSStream.getStreamsToHostWithName(addr, port: port, inputStream: &inp, outputStream: &out)
if inp != nil && out != nil {
let inputStream : NSInputStream = inp!
inputStream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
inputStream.open()
if inputStream.streamError == nil {
while true {
let readChars: Int = inputStream.read(&buffer, maxLength: buffer.count)
if (readChars > 0) {
let readString: String = NSString(data: NSData(bytes:buffer, length:readChars), encoding: NSUTF8StringEncoding)! as String
print(readString)
} else {
print ("sensor closed connection")
inputStream.close()
break
}
}
} else {
print ("could not create socket")
}
} else {
print("could not initialize stream")
}
}
#IBAction func startSensorReadTapped(sender: AnyObject) {
readSensorData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}