1. Setup a socket server on a Raspberry Pi:
See Connect Mac/iPhone to a Simple Python Socket Server (Raspberry Pi Part)
The above link also shows how to connect to the socket server from a Mac using telnet and local client python file.
2. Edit ViewController.swift as:
import UIKit
class ViewController: UIViewController, NSStreamDelegate {
//Button
var buttonConnect : UIButton!
//Label
var label : UILabel!
var labelConnection : UILabel!
//Socket server
let addr = "192.168.xx.xx"
let port = 9876
//Network variables
var inStream : NSInputStream?
var outStream: NSOutputStream?
//Data received
var buffer = [UInt8](count: 200, repeatedValue: 0)
override func viewDidLoad() {
super.viewDidLoad()
ButtonSetup()
LabelSetup()
}
//Button Functions
func ButtonSetup() {
buttonConnect = UIButton(frame: CGRectMake(20, 50, 300, 30))
buttonConnect.setTitle("Connect to server", forState: UIControlState.Normal)
buttonConnect.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
buttonConnect.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
buttonConnect.addTarget(self, action: "btnConnectPressed:", forControlEvents: UIControlEvents.TouchUpInside)
view.addSubview(buttonConnect)
let buttoniPhone = UIButton(frame: CGRectMake(20, 100, 300, 30))
buttoniPhone.setTitle("Send \"This is iPhone\"", forState: UIControlState.Normal)
buttoniPhone.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
buttoniPhone.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
buttoniPhone.addTarget(self, action: "btniPhonePressed:", forControlEvents: UIControlEvents.TouchUpInside)
view.addSubview(buttoniPhone)
let buttonQuit = UIButton(frame: CGRectMake(20, 150, 300, 30))
buttonQuit.setTitle("Send \"Quit\"", forState: UIControlState.Normal)
buttonQuit.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
buttonQuit.setTitleColor(UIColor.cyanColor(), forState: UIControlState.Highlighted)
buttonQuit.addTarget(self, action: "btnQuitPressed:", forControlEvents: UIControlEvents.TouchUpInside)
view.addSubview(buttonQuit)
}
func btnConnectPressed(sender: UIButton) {
NetworkEnable()
buttonConnect.alpha = 0.3
buttonConnect.enabled = false
buttonConnect.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
}
func btniPhonePressed(sender: UIButton) {
let data : NSData = "This is iPhone".dataUsingEncoding(NSUTF8StringEncoding)!
outStream?.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length)
}
func btnQuitPressed(sender: UIButton) {
let data : NSData = "Quit".dataUsingEncoding(NSUTF8StringEncoding)!
outStream?.write(UnsafePointer<UInt8>(data.bytes), maxLength: data.length)
}
//Label setup function
func LabelSetup() {
label = UILabel(frame: CGRectMake(0,0,300,150))
label.center = CGPointMake(view.center.x, view.center.y+100)
label.textAlignment = NSTextAlignment.Center
label.numberOfLines = 0 //Multi-lines
label.font = UIFont(name: "Helvetica-Bold", size: 20)
view.addSubview(label)
labelConnection = UILabel(frame: CGRectMake(0,0,300,30))
labelConnection.center = view.center
labelConnection.textAlignment = NSTextAlignment.Center
labelConnection.text = "Please connect to server"
view.addSubview(labelConnection)
}
//Network functions
func NetworkEnable() {
print("NetworkEnable")
NSStream.getStreamsToHostWithName(addr, port: port, inputStream: &inStream, outputStream: &outStream)
inStream?.delegate = self
outStream?.delegate = self
inStream?.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
outStream?.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
inStream?.open()
outStream?.open()
buffer = [UInt8](count: 200, repeatedValue: 0)
}
func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) {
switch eventCode {
case NSStreamEvent.EndEncountered:
print("EndEncountered")
labelConnection.text = "Connection stopped by server"
inStream?.close()
inStream?.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
outStream?.close()
print("Stop outStream currentRunLoop")
outStream?.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
buttonConnect.alpha = 1
buttonConnect.enabled = true
case NSStreamEvent.ErrorOccurred:
print("ErrorOccurred")
inStream?.close()
inStream?.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
outStream?.close()
outStream?.removeFromRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
labelConnection.text = "Failed to connect to server"
buttonConnect.alpha = 1
buttonConnect.enabled = true
label.text = ""
case NSStreamEvent.HasBytesAvailable:
print("HasBytesAvailable")
if aStream == inStream {
inStream!.read(&buffer, maxLength: buffer.count)
let bufferStr = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding)
label.text = bufferStr! as String
print(bufferStr!)
}
case NSStreamEvent.HasSpaceAvailable:
print("HasSpaceAvailable")
case NSStreamEvent.None:
print("None")
case NSStreamEvent.OpenCompleted:
print("OpenCompleted")
labelConnection.text = "Connected to server"
default:
print("Unknown")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
3. Enable the socket server on Raspberry Pi and run the iOS simulator on Mac.
Result:
Reference:
Stream Programming Guide
Connect iOS device to HTTP GET/POST PHP service (Raspberry Pi Part) (iOS Part)
Connect iOS device to MySQL database on a server (Raspberry Pi Part) (iOS Part)
Connect Mac/iPhone to a Simple Python Socket Server (Raspberry Pi Part)
Go back to Communication between iOS device (Client) and Raspberry Pi (Server)
3. Enable the socket server on Raspberry Pi and run the iOS simulator on Mac.
Result:
Reference:
Stream Programming Guide
Connect iOS device to HTTP GET/POST PHP service (Raspberry Pi Part) (iOS Part)
Connect iOS device to MySQL database on a server (Raspberry Pi Part) (iOS Part)
Connect Mac/iPhone to a Simple Python Socket Server (Raspberry Pi Part)
Go back to Communication between iOS device (Client) and Raspberry Pi (Server)
Would you know how to implement this using Swift 3? You would be my hero!
ReplyDeleteAgree - Swift 3 would be ace!
ReplyDeleteGreat Tutorial!!
ReplyDeleteIs there code on Swift 3 for this project?
Excuse me, can we have the xcode project?
ReplyDeleteI used the basis of this post to create a similar app using SWIFT 3. I don't want to hijack Enoch's blog but XCODE project is published here:
Deletehttps://bitbucket.org/alansommerville/ios-tcp-io-client
Also some basic notes on this created here:
Published “TCP IO Client for IOS Demo” https://medium.com/@alan.sommerville/tcp-io-client-for-ios-demo-684dae1ed638