Possible to use Socket Programming for file transfer to devices on other platforms(OS) via wi-fi network?

I have two Apps, App A and App B.App A is installed in iOS device and App B is installed in a device running on another platform.The devices are connected via Wi-fi.Is it possible to transfer file from App A to B using Socket Programming?

Is it possible to transfer file from App A to B using Socket Programming?

Yes. On iOS I generally recommend that you use NSStream rather than the BSD Sockets API directly (this is particularly true with Swift, where it’s not particularly pleasant to call BSD Sockets directly). A good starting point in the WiTap sample code.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Is there a swift version of the Witap?

Is there a swift version of the [WiTap]?

No.

Well, I have one sitting on my hard disk but I’m reluctant to publish it because the rearchitecting I did (both for Swift and to support other platforms) made it more complex than I’d like for a sample with a wide audience.

OTOH, using NSStream from Swift is pretty straightforward. I’ve included a simple example below.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
import UIKit

extension Stream {
    static func streamsToHost(name hostname: String, port: Int) -> (inputStream: InputStream, outputStream: OutputStream) {
        var inStream: InputStream? = nil
        var outStream: OutputStream? = nil
        Stream.getStreamsToHost(withName: hostname, port: port, inputStream: &inStream, outputStream: &outStream)
        return (inStream!, outStream!)
    }
}

class StreamViewer : UITableViewController, StreamDelegate {

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        switch (indexPath.section, indexPath.row) {
            case (0, 0):
                self.streamTest()
            case (0, 1):
                self.pingTest()
            default:
                fatalError()
        }
        self.tableView.deselectRow(at: indexPath, animated: true)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if let streams = self.streams {
            self.stop(streams: streams)
        }
    }

    var streams: (inputStream: InputStream, outputStream: OutputStream)? = nil
    var ping = Data()

    func streamTest() {
        if let streams = self.streams {
            NSLog("stream stop")
            self.stop(streams: streams)
        } else {
            NSLog("stream start")
            self.start(name: "imap.mail.me.com", port: 993, tls: true, ping: "a001 NOOP\r\n")
            // self.start(name: "localhost", port: 12345, tls: false, ping: "Hello Cruel World!\r\n")
        }
    }

    func pingTest() {
        if let streams = self.streams {
            NSLog("stream ping")
            self.ping(streams: streams)
        } else {
            NSLog("stream ping while not connected")
        }
    }

    func start(name: String, port: Int, tls: Bool, ping: String) {
        self.ping = ping.data(using: .utf8)!
        let streams = Stream.streamsToHost(name: name, port: port)
        self.streams = streams

        if tls {
            let success = streams.inputStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
            precondition(success)
        }

        for s in [streams.inputStream, streams.outputStream] {
            s.schedule(in: .current, forMode: .defaultRunLoopMode)
            s.delegate = self
            s.open()
        }
    }

    func ping(streams: (inputStream: InputStream, outputStream: OutputStream)) {
        let data = self.ping
        let dataCount = data.count
        let bytesWritten = data.withUnsafeBytes { (p: UnsafePointer<UInt8>) -> Int in
            return streams.outputStream.write(p, maxLength: dataCount)
        }
        if bytesWritten < 0 {
            NSLog("stream write error")
        } else if bytesWritten < data.count {
            NSLog("stream write short %d / %d", bytesWritten, data.count)
        } else {
            NSLog("stream task write %@", data as NSData)
        }
    }

    func stop(streams: (inputStream: InputStream, outputStream: OutputStream)) {
        for s in [streams.inputStream, streams.outputStream] {
            s.delegate  = nil
            s.close()
        }
        self.streams = nil
    }

    func stream(_ thisStream: Stream, handle eventCode: Stream.Event) {
        guard let streams = self.streams else { fatalError() }
        let streamName = thisStream == streams.inputStream ? " input" : "output"
        switch eventCode {
            case [.openCompleted]:
                NSLog("%@ stream did open", streamName as NSString)
                break
            case [.hasBytesAvailable]:
                NSLog("%@ stream has bytes", streamName as NSString)

                var buffer = [UInt8](repeating: 0, count: 2048)
                let bytesRead = streams.inputStream.read(&buffer, maxLength: buffer.count)
                if bytesRead > 0 {
                    NSLog("%@ stream read %@", streamName, NSData(bytes: &buffer, length: bytesRead))
                }
            case [.hasSpaceAvailable]:
                NSLog("%@ stream has space", streamName as NSString)
            case [.endEncountered]:
                NSLog("%@ stream end", streamName)
                self.stop(streams: streams)
            case [.errorOccurred]:
                let error = thisStream.streamError! as NSError
                NSLog("%@ stream error %@ / %d", streamName, error.domain, error.code)
                self.stop(streams: streams)
            default:
                fatalError()
        }
    }
}
Possible to use Socket Programming for file transfer to devices on other platforms(OS) via wi-fi network?
 
 
Q