Latest 0.1.2
Homepage https://github.com/chouheiwa/SwiftAsnycSocket
License MIT
Platforms ios 9.0, osx 10.10
Authors

Version Status Platform Carthage compatible GitHub license

SwiftAsyncSocket is a socket connnection tool based on GCD with full implement by Swift.

I translated it from CocoaAsyncSocket.

In other words, if you have experience to use CocoaAsyncSocket, you will feel familar to this.

SwiftAsyncSocket can support both TCP/IP and UDP/IP socket.

SwiftAsyncSocket is heavier then CocoaAsyncSocket. Because there is more then 8,000 line in one file of CocoaAsyncSocket. I scattered these logic across multiple files.

SwiftAsyncSocket has already passed SwiftLint check.

Installation

1. Mannual install

SwiftAsyncSocket now support Cocoapods

So now you can only use this by those steps.

# Download the source of the code 
git clone https://github.com/chouheiwa/SwiftAsnycSocket.git

cd SwiftAsnycSocket

open ./SwiftAsyncSocket.xcodeproj

Then open xcodeproj file. And use cmd + b to build a framework. Finally copy it to your work.

2. CocoaPods

Install using CocoaPods by adding this line to your Podfile:

use_frameworks! # Add this if you are targeting iOS 8+ or using Swift
pod 'SwiftAsyncSocket'  

3.Carthage

SwiftAsyncSocket is Carthage compatible. To include it add the following line to your Cartfile

github "chouheiwa/SwiftAsyncSocket"

Usage

TCP/IP

1. Use as client.

If there has a socket server start at localhost:8080

import SwiftAsyncSocket

class Client {
    var socket: SwiftAsyncSocket

    init() {
        // you can not set delegate here because in this line that init function has not complete.So set delegate next line
        socket = SwiftAsyncSocket(delegate: nil, delegateQueue: DispatchQueue.global(), socketQueue: nil)
        // All the delagate function is optional. If you want to use. You can implement it.
        socket.delgate = self

        do {
            // Connected 
            try socket.connect(toHost: "localhost", onPort: 8080)
        } catch {
            // Here to print error
            print("(error)")
        }
    }
}
/// If you want to use as client, 
/// at least you need to implement these three method
extension Client: SwiftAsyncSocketDelgate {
    func socket(_ socket: SwiftAsyncSocket, didConnect toHost: String, port: UInt16) {
        // If you use socket.connect(toHost: , onPort: )
        // When the socket connected, this method will be called
        // Then you can call 
        // socket.write(data:, timeOut:, tag:) 
        // to send the data to server or 
        // socket.readData(timeOut:, tag:)
        // to read data from server

    }

    func socket(_ socket: SwiftAsyncSocket, didWriteDataWith tag: Int) {
        // When send data complete, this method will be called
    }

    func socket(_ socket: SwiftAsyncSocket, didRead data: Data, with tag: Int) {
        // When read data complete, this method will return the data from server
    }
}
2. Use as server.
import Foundation
import SwiftAsyncSocket
class Server: SwiftAsyncSocketDelegate {
    var baseSocket: SwiftAsyncSocket
    /// Here we use map to help we locate which socket has already been disconnected
    var acceptSockets: [String:SwiftAsyncSocket] = [:]

    var port: UInt16

    var canAccept: Bool = false

    var canSendData: ((SwiftAsyncSocket) -> Void)?

    var didReadData: ((Data) -> Void)?

    init() {
        baseSocket = SwiftAsyncSocket(delegate: nil, delegateQueue: DispatchQueue.global(), socketQueue: nil)

        port = UInt16.random(in: 1024..<50000)

        baseSocket.delegate = self

        do {
            canAccept = try baseSocket.accept(port: port)

            canAccept = true
        } catch let error as SwiftAsyncSocketError {
            print("(error)")
        } catch {
            fatalError("(error)")
        }
    }

    func socket(_ socket: SwiftAsyncSocket, didAccept newSocket: SwiftAsyncSocket) {
        /// We use a time and a random number to make key unique
        let random = Int.random(in: 0..<99999)

        let date = Date()
        let key = "(date)(random)"
        acceptSockets[key] = newSocket
        newSocket.userData = key
        newSocket.delegate = self
        newSocket.delegateQueue = DispatchQueue.global()
        canSendData?(newSocket)
    }

    func socket(_ socket: SwiftAsyncSocket, didWriteDataWith tag: Int) {

    }

    func socket(_ socket: SwiftAsyncSocket, didRead data: Data, with tag: Int) {
        didReadData?(data)
    }

    func socket(_ socket: SwiftAsyncSocket?, didDisconnectWith error: SwiftAsyncSocketError?) {
        guard let key = socket?.userData as? String else { return }

        acceptSockets.removeValue(forKey: key)
    }
}

UDP

1. Use as client.
import Foundation
import SwiftAsyncSocket

class UdpClient {
    var socket: SwiftAsyncUDPSocket

    init() {
        // you can not set delegate here because in this line that init function has not complete.So set delegate next line
        serverSocket = SwiftAsyncUDPSocket(delegate: nil, delegateQueue: DispatchQueue.main)
        // All the delagate function is optional. If you want to use. You can implement it.
        socket.delgate = self

        do {
            // Connected 
            try socket.connect(toHost: "localhost", onPort: 8090)
        } catch {
            // Here to print error
            print("(error)")
        }
    }

    func sendData() {
        let data = "data".data(using: .utf8) ?? Data()

        do {
            socket.send(data: data, timeout: -1, tag: 10)
            // Use next line if you want to receive data
            try socket.receiveAlways()
        } catch {
            print("(error)")
        }
    }
}
/// You don't need implement any method to send data
extension Client: SwiftAsyncUDPSocketDelgate {
    func updSocket(_ socket: SwiftAsyncUDPSocket,
                   didReceive data: Data,
                   from address: SwiftAsyncUDPSocketAddress,
                   withFilterContext filterContext: Any?) {

    }
}
2. Use as server.
import Foundation
import SwiftAsyncSocket

class UdpServer {
    let port: UInt16
    let serverSocket: SwiftAsyncUDPSocket

    var didReceiveData: ((Data) -> Void)?

    init(port: UInt16) throws {
        self.port = port
        serverSocket = SwiftAsyncUDPSocket(delegate: nil, delegateQueue: DispatchQueue.main)

        serverSocket.delegate = self

        try serverSocket.bind(port: port)

        try serverSocket.receiveAlways()
    }
}
extension UdpServer: SwiftAsyncUDPSocketDelegate {
    func updSocket(_ socket: SwiftAsyncUDPSocket,
                   didReceive data: Data,
                   from address: SwiftAsyncUDPSocketAddress,
                   withFilterContext filterContext: Any?) {

        let string = String(data: data, encoding: .utf8) ?? ""
        print("Receive Data: (string)")
    }
}

Latest podspec

{
    "name": "SwiftAsyncSocket",
    "swift_version": "4.2",
    "version": "0.1.2",
    "summary": "A GCD base of Socket writing by Swift 4.2",
    "description": "A socket connection tool writing by Swift.nIt has has the same function with CocoaAsyncSocket",
    "homepage": "https://github.com/chouheiwa/SwiftAsnycSocket",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    },
    "authors": {
        "chouheiwa": "[email protected]"
    },
    "platforms": {
        "ios": "9.0",
        "osx": "10.10"
    },
    "source": {
        "git": "https://github.com/chouheiwa/SwiftAsnycSocket.git",
        "tag": "0.1.2"
    },
    "source_files": [
        "Sources",
        "Sources/**/*"
    ],
    "exclude_files": "Sources/**/*.plist"
}

Pin It on Pinterest

Share This