macOS Networking Swift Samples

macOS Swift networking examples including HTTP requests, HTTP server, and TCP socket programming

Key Facts

Category
Swift
Items
3
Format Families
sample

Sample Overview

macOS Swift networking examples including HTTP requests, HTTP server, and TCP socket programming This sample set belongs to Swift and can be used to test related workflows inside Elysia Tools.

💻 HTTP Request swift

🟡 intermediate ⭐⭐⭐

Send GET and POST requests using URLSession with proper error handling and response processing

⏱️ 25 min 🏷️ swift, macos, networking, http
Prerequisites: Basic Swift knowledge, Foundation framework, Networking concepts
// macOS Swift HTTP Request Examples
// Using Foundation framework

import Foundation

// 1. Simple GET Request
class SimpleGETRequest {

    static func fetch(url: String) {
        print("\n--- Simple GET Request ---")

        guard let url = URL(string: url) else {
            print("Invalid URL")
            return
        }

        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
                return
            }

            guard let httpResponse = response as? HTTPURLResponse else {
                print("Invalid response")
                return
            }

            print("Status Code: \(httpResponse.statusCode)")

            if let data = data, let content = String(data: data, encoding: .utf8) {
                print("Response (first 200 chars): \(String(content.prefix(200)))")
            }
        }

        task.resume()
    }
}

// 2. GET Request with Parameters
class GETWithParameters {

    static func fetchWithParams(baseUrl: String, params: [String: String]) {
        print("\n--- GET with Parameters ---")

        guard var urlComponents = URLComponents(string: baseUrl) else {
            print("Invalid URL")
            return
        }

        urlComponents.queryItems = params.map { key, value in
            URLQueryItem(name: key, value: value)
        }

        guard let url = urlComponents.url else {
            print("Invalid URL with parameters")
            return
        }

        print("Request URL: \(url.absoluteString)")

        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
                return
            }

            if let httpResponse = response as? HTTPURLResponse {
                print("Status Code: \(httpResponse.statusCode)")
            }
        }

        task.resume()
    }
}

// 3. POST Request with JSON Body
class POSTRequest {

    static func postJSON(url: String, body: [String: Any]) {
        print("\n--- POST JSON Request ---")

        guard let url = URL(string: url) else {
            print("Invalid URL")
            return
        }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        do {
            let jsonData = try JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
            request.httpBody = jsonData

            if let jsonString = String(data: jsonData, encoding: .utf8) {
                print("Request Body: \(jsonString)")
            }

            let task = URLSession.shared.dataTask(with: request) { data, response, error in
                if let error = error {
                    print("Error: \(error.localizedDescription)")
                    return
                }

                if let httpResponse = response as? HTTPURLResponse {
                    print("Status Code: \(httpResponse.statusCode)")
                }

                if let data = data, let responseString = String(data: data, encoding: .utf8) {
                    print("Response: \(responseString)")
                }
            }

            task.resume()

        } catch {
            print("JSON serialization error: \(error)")
        }
    }
}

// 4. POST Request with Form Data
class POSTFormData {

    static func postForm(url: String, params: [String: String]) {
        print("\n--- POST Form Data ---")

        guard let url = URL(string: url) else {
            print("Invalid URL")
            return
        }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"

        let formString = params.map { key, value in
            "\(key)=\(value.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? value)"
        }.joined(separator: "&")

        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
        request.httpBody = formString.data(using: .utf8)

        print("Form Data: \(formString)")

        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
                return
            }

            if let httpResponse = response as? HTTPURLResponse {
                print("Status Code: \(httpResponse.statusCode)")
            }
        }

        task.resume()
    }
}

// 5. Request with Custom Headers
class RequestWithHeaders {

    static func fetchWithHeaders(url: String, headers: [String: String]) {
        print("\n--- Request with Custom Headers ---")

        guard let url = URL(string: url) else {
            print("Invalid URL")
            return
        }

        var request = URLRequest(url: url)

        for (key, value) in headers {
            request.setValue(value, forHTTPHeaderField: key)
            print("\(key): \(value)")
        }

        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
                return
            }

            if let httpResponse = response as? HTTPURLResponse {
                print("Status Code: \(httpResponse.statusCode)")
                print("Response Headers:")
                if let allHeaders = httpResponse.allHeaderFields as? [String: String] {
                    for (key, value) in allHeaders {
                        print("  \(key): \(value)")
                    }
                }
            }
        }

        task.resume()
    }
}

// 6. Download File
class DownloadFile {

    static func downloadFile(url: String, destination: String) {
        print("\n--- Download File ---")

        guard let url = URL(string: url) else {
            print("Invalid URL")
            return
        }

        let task = URLSession.shared.downloadTask(with: url) { tempURL, response, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
                return
            }

            guard let tempURL = tempURL else {
                print("Invalid temp URL")
                return
            }

            do {
                let fileManager = FileManager.default
                let destURL = URL(fileURLWithPath: destination)

                // Create directory if needed
                let destDir = destURL.deletingLastPathComponent()
                if !fileManager.fileExists(atPath: destDir.path) {
                    try fileManager.createDirectory(atPath: destDir.path, withIntermediateDirectories: true, attributes: nil)
                }

                // Remove existing file
                if fileManager.fileExists(atPath: destination) {
                    try fileManager.removeItem(atPath: destination)
                }

                // Move file
                try fileManager.moveItem(at: tempURL, to: destURL)

                let attributes = try fileManager.attributesOfItem(atPath: destination)
                if let fileSize = attributes[.size] as? UInt64 {
                    print("Downloaded: \(destination)")
                    print("File size: \(fileSize) bytes")
                }

            } catch {
                print("File save error: \(error)")
            }
        }

        task.resume()
    }
}

// 7. Upload File with Progress
class UploadFile {

    static func uploadFile(url: String, filePath: String) {
        print("\n--- Upload File ---")

        guard let url = URL(string: url) else {
            print("Invalid URL")
            return
        }

        guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else {
            print("Cannot read file")
            return
        }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"

        let boundary = "Boundary-\(UUID().uuidString)"
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

        var body = Data()

        // Add file data
        body.append("--\(boundary)\r\n".data(using: .utf8)!)
        body.append("Content-Disposition: form-data; name=\"file\"; filename=\"\((filePath as NSString).lastPathComponent)\"\r\n".data(using: .utf8)!)
        body.append("Content-Type: application/octet-stream\r\n\r\n".data(using: .utf8)!)
        body.append(fileData)
        body.append("\r\n".data(using: .utf8)!)
        body.append("--\(boundary)--\r\n".data(using: .utf8)!)

        request.httpBody = body

        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
                return
            }

            if let httpResponse = response as? HTTPURLResponse {
                print("Status Code: \(httpResponse.statusCode)")
            }

            print("Upload completed")
        }

        task.resume()
    }
}

// 8. Request with Timeout
class RequestWithTimeout {

    static func fetchWithTimeout(url: String, timeout: TimeInterval) {
        print("\n--- Request with Timeout ---")

        guard let url = URL(string: url) else {
            print("Invalid URL")
            return
        }

        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = timeout

        let session = URLSession(configuration: configuration)

        let task = session.dataTask(with: url) { data, response, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
                return
            }

            if let httpResponse = response as? HTTPURLResponse {
                print("Status Code: \(httpResponse.statusCode)")
            }
        }

        task.resume()
    }
}

// 9. Async/Await HTTP Request (Swift 5.5+)
@available(macOS 12.0, *)
class ModernHTTPRequest {

    static func fetchAsync(url: String) async {
        print("\n--- Async/Await Request ---")

        guard let url = URL(string: url) else {
            print("Invalid URL")
            return
        }

        do {
            let (data, response) = try await URLSession.shared.data(from: url)

            if let httpResponse = response as? HTTPURLResponse {
                print("Status Code: \(httpResponse.statusCode)")
            }

            if let content = String(data: data, encoding: .utf8) {
                print("Response (first 200 chars): \(String(content.prefix(200)))")
            }

        } catch {
            print("Error: \(error.localizedDescription)")
        }
    }
}

// 10. Request with Response Decoding
struct User: Codable {
    let id: Int
    let name: String
    let email: String
}

class RequestWithDecoding {

    static func fetchAndDecode<T: Decodable>(url: String, type: T.Type) {
        print("\n--- Request with Decoding ---")

        guard let url = URL(string: url) else {
            print("Invalid URL")
            return
        }

        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else {
                if let error = error {
                    print("Error: \(error.localizedDescription)")
                }
                return
            }

            do {
                let decoder = JSONDecoder()
                let result = try decoder.decode(type, from: data)
                print("Decoded result: \(result)")
            } catch {
                print("Decoding error: \(error)")
            }
        }

        task.resume()
    }
}

// Main demonstration
func demonstrateHTTPRequests() {
    print("=== macOS Swift HTTP Request Examples ===")

    // Note: Using example.com for demonstration
    // In real usage, replace with actual API endpoints

    // 1. Simple GET
    SimpleGETRequest.fetch(url: "https://example.com")
    Thread.sleep(forTimeInterval: 1)

    // 2. GET with parameters
    GETWithParameters.fetchWithParams(
        baseUrl: "https://httpbin.org/get",
        params: ["param1": "value1", "param2": "value2"]
    )
    Thread.sleep(forTimeInterval: 1)

    // 3. POST JSON
    POSTRequest.postJSON(
        url: "https://httpbin.org/post",
        body: ["name": "John Doe", "email": "[email protected]", "age": 30]
    )
    Thread.sleep(forTimeInterval: 1)

    // 4. POST Form Data
    POSTFormData.postForm(
        url: "https://httpbin.org/post",
        params: ["username": "testuser", "password": "testpass"]
    )
    Thread.sleep(forTimeInterval: 1)

    // 5. Custom Headers
    RequestWithHeaders.fetchWithHeaders(
        url: "https://httpbin.org/headers",
        headers: [
            "User-Agent": "SwiftNetworking/1.0",
            "Accept": "application/json",
            "Authorization": "Bearer token123"
        ]
    )
    Thread.sleep(forTimeInterval: 1)

    // 6. Download File
    DownloadFile.downloadFile(
        url: "https://example.com",
        destination: "/tmp/downloaded_file.html"
    )
    Thread.sleep(forTimeInterval: 1)

    // 7. Request with Timeout
    RequestWithTimeout.fetchWithTimeout(url: "https://example.com", timeout: 5)
    Thread.sleep(forTimeInterval: 1)

    // 8. Async Request (if available)
    if #available(macOS 12.0, *) {
        Task {
            await ModernHTTPRequest.fetchAsync(url: "https://example.com")
        }
        Thread.sleep(forTimeInterval: 1)
    }

    // 9. Request with Decoding
    RequestWithDecoding.fetchAndDecode(
        url: "https://jsonplaceholder.typicode.com/users/1",
        type: User.self
    )
    Thread.sleep(forTimeInterval: 2)

    print("\n=== All HTTP Request Examples Completed ===")
}

// Run demonstration
demonstrateHTTPRequests()

💻 TCP Socket swift

🟡 intermediate ⭐⭐⭐⭐

Create TCP client and server sockets for bidirectional communication

⏱️ 40 min 🏷️ swift, macos, networking, tcp
Prerequisites: Intermediate Swift, Socket programming, Networking concepts
// macOS Swift TCP Socket Examples
// Using Foundation and Network framework

import Foundation

// 1. TCP Server
class TCPServer {

    private var serverSocket: Int32 = -1
    private var isRunning = false
    private var clientHandlers: [Thread] = []

    func start(port: UInt16) {
        print("\n--- Starting TCP Server on port \(port) ---")

        // Create socket
        serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
        guard serverSocket != -1 else {
            print("Failed to create socket")
            return
        }

        // Set socket options
        var yes: Int32 = 1
        setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, &yes, socklen_t(MemoryLayout<Int32>.size))

        // Bind to address
        var address = sockaddr_in()
        address.sin_family = sa_family_t(AF_INET)
        address.sin_port = port.bigEndian
        address.sin_addr.s_addr = INADDR_ANY

        let bindResult = withUnsafePointer(to: &address) {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                bind(serverSocket, $0, socklen_t(MemoryLayout<sockaddr_in>.size))
            }
        }

        guard bindResult == 0 else {
            print("Failed to bind to port: \(errno)")
            close(serverSocket)
            return
        }

        // Listen
        guard listen(serverSocket, 5) == 0 else {
            print("Failed to listen")
            close(serverSocket)
            return
        }

        isRunning = true
        print("Server listening on port \(port)")

        // Accept connections
        DispatchQueue.global(qos: .background).async { [weak self] in
            self?.acceptConnections()
        }
    }

    private func acceptConnections() {
        while isRunning {
            var clientAddress = sockaddr_in()
            var addressLength = socklen_t(MemoryLayout<sockaddr_in>.size)

            let clientSocket = withUnsafeMutablePointer(to: &clientAddress) {
                $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                    accept(serverSocket, $0, &addressLength)
                }
            }

            guard clientSocket != -1 else {
                continue
            }

            // Get client info
            let clientIP = getIPAddress(from: &clientAddress)
            print("Client connected from \(clientIP)")

            // Handle client
            handleClient(socket: clientSocket)
        }
    }

    private func handleClient(socket: Int32) {
        DispatchQueue.global(qos: .background).async {
            var buffer = [UInt8](repeating: 0, count: 1024)

            while true {
                let bytesRead = read(socket, &buffer, buffer.count)

                if bytesRead <= 0 {
                    close(socket)
                    print("Client disconnected")
                    return
                }

                if let message = String(bytes: buffer.prefix(bytesRead), encoding: .utf8) {
                    print("Received: \(message)")

                    // Echo back
                    let response = "Echo: \(message)"
                    response.withCString { ptr in
                        write(socket, ptr, response.count)
                    }
                }
            }
        }
    }

    private func getIPAddress(from address: inout sockaddr_in) -> String {
        var ipAddress = [CChar](repeating: 0, count: Int(INET_ADDRSTRLEN))
        withUnsafePointer(to: &address.sin_addr) {
            inet_ntop(AF_INET, $0, &ipAddress, socklen_t(INET_ADDRSTRLEN))
        }
        return String(cString: ipAddress)
    }

    func broadcast(_ message: String) {
        // Broadcast to all connected clients
        // Implementation depends on how you track clients
    }

    func stop() {
        isRunning = false
        if serverSocket != -1 {
            close(serverSocket)
        }
        print("Server stopped")
    }
}

// 2. TCP Client
class TCPClient {

    private var clientSocket: Int32 = -1

    func connect(host: String, port: UInt16) -> Bool {
        print("\n--- Connecting to \(host):\(port) ---")

        // Create socket
        clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
        guard clientSocket != -1 else {
            print("Failed to create socket")
            return false
        }

        // Resolve host
        var hints = addrinfo()
        hints.ai_family = AF_INET
        hints.ai_socktype = SOCK_STREAM

        var result: UnsafeMutablePointer<addrinfo>?
        let status = getaddrinfo(host, String(port), &hints, &result)

        guard status == 0, let info = result else {
            print("Failed to resolve host")
            close(clientSocket)
            return false
        }

        defer { freeaddrinfo(info) }

        // Connect
        guard connect(clientSocket, info.pointee.ai_addr, info.pointee.ai_addrlen) == 0 else {
            print("Failed to connect: \(errno)")
            close(clientSocket)
            return false
        }

        print("Connected to server")
        return true
    }

    func send(_ message: String) -> Bool {
        guard clientSocket != -1 else {
            print("Not connected")
            return false
        }

        let bytesSent = message.withCString { ptr in
            write(clientSocket, ptr, message.count)
        }

        if bytesSent > 0 {
            print("Sent: \(message)")
            return true
        }

        print("Failed to send")
        return false
    }

    func receive() -> String? {
        guard clientSocket != -1 else {
            return nil
        }

        var buffer = [UInt8](repeating: 0, count: 1024)
        let bytesRead = read(clientSocket, &buffer, buffer.count)

        guard bytesRead > 0 else {
            return nil
        }

        return String(bytes: buffer.prefix(bytesRead), encoding: .utf8)
    }

    func disconnect() {
        if clientSocket != -1 {
            close(clientSocket)
            clientSocket = -1
        }
        print("Disconnected")
    }
}

// 3. Chat Server
class ChatServer {

    private var server = TCPServer()
    private var clients: [Int32] = []
    private let clientsLock = NSLock()

    func start(port: UInt16) {
        print("\n--- Starting Chat Server on port \(port) ---")

        // Start TCP server
        server.start(port: port)

        print("Chat server running. Connect clients to chat!")
    }

    func broadcast(_ message: String, from socket: Int32) {
        clientsLock.lock()
        let clientList = clients
        clientsLock.unlock()

        for client in clientList {
            if client != socket {
                message.withCString { ptr in
                    write(client, ptr, message.count)
                }
            }
        }
    }

    func addClient(_ socket: Int32) {
        clientsLock.lock()
        clients.append(socket)
        clientsLock.unlock()

        broadcast("User joined", from: socket)
    }

    func removeClient(_ socket: Int32) {
        clientsLock.lock()
        clients.removeAll { $0 == socket }
        clientsLock.unlock()

        close(socket)
    }
}

// 4. TCP Client with Reconnect
class TCPClientWithReconnect {

    private var client = TCPClient()
    private var isConnected = false
    private var reconnectAttempts = 0
    private let maxAttempts = 5

    func connect(host: String, port: UInt16) {
        while reconnectAttempts < maxAttempts && !isConnected {
            if client.connect(host: host, port: port) {
                isConnected = true
                reconnectAttempts = 0
                return
            }

            reconnectAttempts += 1
            print("Reconnect attempt \(reconnectAttempts) in 2 seconds...")
            Thread.sleep(forTimeInterval: 2)
        }

        print("Failed to connect after \(maxAttempts) attempts")
    }

    func sendWithRetry(_ message: String) -> Bool {
        if isConnected {
            return client.send(message)
        } else {
            print("Not connected, attempting to reconnect...")
            return false
        }
    }

    func disconnect() {
        isConnected = false
        client.disconnect()
    }
}

// 5. Non-blocking Socket
class NonBlockingSocket {

    private var socket: Int32 = -1

    func connect(host: String, port: UInt16) {
        socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
        guard socket != -1 else { return }

        // Set non-blocking
        var flags = fcntl(socket, F_GETFL, 0)
        fcntl(socket, F_SETFL, flags | O_NONBLOCK)

        // Connect (non-blocking)
        var address = sockaddr_in()
        address.sin_family = sa_family_t(AF_INET)
        address.sin_port = port.bigEndian

        let result = connect(socket, nil, 0)
        if result == -1 && errno != EINPROGRESS {
            print("Connection error")
            close(socket)
            return
        }

        print("Non-blocking connection initiated")
    }

    func sendNonBlocking(_ data: Data) {
        var buffer = [UInt8](data)
        let sent = write(socket, &buffer, buffer.count)
        print("Sent \(sent) bytes")
    }

    func receiveNonBlocking() -> Data? {
        var buffer = [UInt8](repeating: 0, count: 1024)
        let received = read(socket, &buffer, buffer.count)

        if received > 0 {
            return Data(bytes: buffer, count: received)
        }

        return nil
    }
}

// 6. Socket with Timeout
class SocketWithTimeout {

    private var socket: Int32 = -1

    func connectWithTimeout(host: String, port: UInt16, timeout: TimeInterval) -> Bool {
        socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
        guard socket != -1 else { return false }

        // Set timeout
        var tv = timeval(tv_sec: Int(timeout), tv_usec: 0)
        setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, socklen_t(MemoryLayout<timeval>.size))
        setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, socklen_t(MemoryLayout<timeval>.size))

        // Connect and read with timeout
        // ... connection logic ...

        return true
    }
}

// 7. Data Stream over TCP
class TCPDataStream {

    private var client = TCPClient()

    func sendStream(host: String, port: UInt16, data: [Data]) {
        guard client.connect(host: host, port: port) else {
            return
        }

        defer { client.disconnect() }

        for (index, chunk) in data.enumerated() {
            // Send header with chunk size
            let header = "\(chunk.count);"
            _ = header.withCString { ptr in
                write(client.clientSocket, ptr, header.count)
            }

            // Send data
            chunk.withUnsafeBytes { ptr in
                write(client.clientSocket, ptr.baseAddress, chunk.count)
            }

            print("Sent chunk \(index + 1)/\(data.count): \(chunk.count) bytes")
            Thread.sleep(forTimeInterval: 0.1)
        }

        // Send end marker
        let endMarker = "0;"
        _ = endMarker.withCString { ptr in
            write(client.clientSocket, ptr, endMarker.count)
        }

        print("Stream completed")
    }

    func receiveStream() -> [Data] {
        var receivedData: [Data] = []
        var buffer = [UInt8](repeating: 0, count: 1024)

        while true {
            // Read chunk size
            var sizeBuffer = [UInt8]()
            while true {
                let count = read(client.clientSocket, &buffer, 1)
                guard count > 0 else { return receivedData }

                if buffer[0] == UInt8(ascii: ";") {
                    break
                }
                sizeBuffer.append(buffer[0])
            }

            guard let sizeString = String(bytes: sizeBuffer, encoding: .utf8),
                  let size = Int(sizeString) else {
                continue
            }

            if size == 0 {
                print("End of stream")
                break
            }

            // Read data
            var chunk = [UInt8](repeating: 0, count: size)
            var totalReceived = 0

            while totalReceived < size {
                let count = read(client.clientSocket, &chunk[totalReceived], size - totalReceived)
                guard count > 0 else { break }
                totalReceived += count
            }

            receivedData.append(Data(chunk))
            print("Received chunk: \(totalReceived) bytes")
        }

        return receivedData
    }
}

// 8. Protocol Buffer over TCP
class ProtocolBufferSocket {

    func sendProtobufMessage<T: Encodable>(_ message: T, socket: Int32) {
        // Encode message
        // Send length prefix followed by message data
        // Implementation depends on protobuf library
    }
}

// 9. Heartbeat Connection
class HeartbeatConnection {

    private var client = TCPClient()
    private var heartbeatTimer: Timer?
    private var isRunning = false

    func connectWithHeartbeat(host: String, port: UInt16, interval: TimeInterval = 5) {
        guard client.connect(host: host, port: port) else {
            return
        }

        isRunning = true

        // Start heartbeat
        heartbeatTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] _ in
            self?.sendHeartbeat()
        }

        // Listen for responses
        DispatchQueue.global(qos: .background).async { [weak self] in
            self?.listen()
        }
    }

    private func sendHeartbeat() {
        guard isRunning else { return }
        _ = client.send("HEARTBEAT")
    }

    private func listen() {
        while isRunning {
            if let response = client.receive() {
                print("Received: \(response)")
            }
            Thread.sleep(forTimeInterval: 0.1)
        }
    }

    func disconnect() {
        isRunning = false
        heartbeatTimer?.invalidate()
        client.disconnect()
    }
}

// Main demonstration
func demonstrateTCPSockets() {
    print("=== macOS Swift TCP Socket Examples ===")

    // 1. Start server in background
    let serverThread = Thread {
        let server = TCPServer()
        server.start(port: 9999)

        // Keep running
        RunLoop.current.run()
    }
    serverThread.start()

    Thread.sleep(forTimeInterval: 1)

    // 2. Connect client
    print("\n--- Client Connection ---")
    let client = TCPClient()

    if client.connect(host: "localhost", port: 9999) {
        // Send messages
        _ = client.send("Hello, Server!")
        Thread.sleep(forTimeInterval: 0.5)

        // Receive response
        if let response = client.receive() {
            print("Server response: \(response)")
        }

        // Send more messages
        _ = client.send("Message 2")
        Thread.sleep(forTimeInterval: 0.5)

        _ = client.send("Message 3")
        Thread.sleep(forTimeInterval: 0.5)

        client.disconnect()
    }

    Thread.sleep(forTimeInterval: 1)

    print("\n=== TCP Socket Examples Completed ===")
    print("Note: In production, implement proper signal handling for cleanup")
}

// Uncomment to run demonstration
// demonstrateTCPSockets()

print("\nNote: TCP socket examples provided. Uncomment demonstrateTCPSockets() to run.")

💻 HTTP Server swift

🔴 complex ⭐⭐⭐⭐⭐

Create a simple HTTP server using Vapor framework or native Swift with sockets

⏱️ 45 min 🏷️ swift, macos, networking, server
Prerequisites: Advanced Swift, Networking, Socket programming
// macOS Swift HTTP Server Examples
// Using Foundation and Network framework

import Foundation

// 1. Simple HTTP Server using sockets
class SimpleHTTPServer {

    private var listenerSocket: Int32 = -1
    private var isRunning = false

    func start(port: UInt16) {
        print("\n--- Starting HTTP Server on port \(port) ---")

        // Create socket
        listenerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
        guard listenerSocket != -1 else {
            print("Failed to create socket")
            return
        }

        // Set socket options
        var yes: Int32 = 1
        setsockopt(listenerSocket, SOL_SOCKET, SO_REUSEADDR, &yes, socklen_t(MemoryLayout<Int32>.size))

        // Bind to port
        var addr = sockaddr_in()
        addr.sin_family = sa_family_t(AF_INET)
        addr.sin_port = port.bigEndian
        addr.sin_addr.s_addr = INADDR_ANY

        let bindResult = withUnsafePointer(to: &addr) {
            $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                bind(listenerSocket, $0, socklen_t(MemoryLayout<sockaddr_in>.size))
            }
        }

        guard bindResult == 0 else {
            print("Failed to bind to port")
            close(listenerSocket)
            return
        }

        // Listen
        guard listen(listenerSocket, 5) == 0 else {
            print("Failed to listen")
            close(listenerSocket)
            return
        }

        isRunning = true
        print("Server started on http://localhost:\(port)")

        // Accept connections in background thread
        DispatchQueue.global(qos: .background).async { [weak self] in
            self?.acceptConnections()
        }
    }

    private func acceptConnections() {
        while isRunning {
            var clientAddr = sockaddr_in()
            var clientLen = socklen_t(MemoryLayout<sockaddr_in>.size)

            let clientSocket = withUnsafeMutablePointer(to: &clientAddr) {
                $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
                    accept(listenerSocket, $0, &clientLen)
                }
            }

            guard clientSocket != -1 else {
                continue
            }

            // Handle client in background
            DispatchQueue.global(qos: .background).async { [weak self] in
                self?.handleClient(clientSocket: clientSocket)
            }
        }
    }

    private func handleClient(clientSocket: Int32) {
        defer { close(clientSocket) }

        // Read request
        var buffer = [UInt8](repeating: 0, count: 4096)
        let bytesRead = read(clientSocket, &buffer, buffer.count)

        guard bytesRead > 0 else {
            return
        }

        let request = String(bytes: buffer.prefix(bytesRead), encoding: .utf8) ?? ""
        print("\nRequest received:")
        print(request.prefix(500))

        // Parse request
        let lines = request.components(separatedBy: "\r\n")
        guard let requestLine = lines.first,
              let parts = requestLine.components(separatedBy: " ").split(separator: " ").map(String.init),
              parts.count >= 2,
              let method = parts.first,
              let path = parts.dropFirst().first else {
            sendResponse(clientSocket: clientSocket, statusCode: 400, body: "Bad Request")
            return
        }

        print("Method: \(method), Path: \(path)")

        // Handle different paths
        let response: String
        switch path {
        case "/":
            response = createHTMLResponse("<h1>Welcome to Swift HTTP Server</h1><p>This is a simple HTTP server built with Swift.</p>")
        case "/about":
            response = createHTMLResponse("<h1>About</h1><p>Swift HTTP Server v1.0</p>")
        case "/json":
            let json = "{\"message\": \"Hello from Swift\", \"status\": \"success\"}"
            response = createJSONResponse(json)
        case "/time":
            let time = Date().description
            response = createJSONResponse("{\"time\": \"\(time)\"}")
        default:
            response = createHTMLResponse("<h1>404 Not Found</h1><p>The page \(path) was not found.</p>", statusCode: 404)
        }

        // Send response
        _ = write(clientSocket, response, response.count)
        print("Response sent")
    }

    private func createHTMLResponse(_ body: String, statusCode: Int = 200) -> String {
        let statusText: String
        switch statusCode {
        case 200: statusText = "OK"
        case 404: statusText = "Not Found"
        default: statusText = "OK"
        }

        let html = """
        <!DOCTYPE html>
        <html>
        <head>
            <title>Swift Server</title>
            <style>
                body { font-family: Arial, sans-serif; margin: 40px; }
                h1 { color: #333; }
            </style>
        </head>
        <body>
            \(body)
        </body>
        </html>
        """

        return """
        HTTP/1.1 \(statusCode) \(statusText)\r
        Content-Type: text/html\r
        Content-Length: \(html.count)\r
        Connection: close\r
        \r
        \(html)
        """
    }

    private func createJSONResponse(_ json: String) -> String {
        return """
        HTTP/1.1 200 OK\r
        Content-Type: application/json\r
        Content-Length: \(json.count)\r
        Connection: close\r
        \r
        \(json)
        """
    }

    private func sendResponse(clientSocket: Int32, statusCode: Int, body: String) {
        let response = createHTMLResponse(body, statusCode: statusCode)
        _ = write(clientSocket, response, response.count)
    }

    func stop() {
        isRunning = false
        if listenerSocket != -1 {
            close(listenerSocket)
        }
        print("Server stopped")
    }
}

// 2. Request Handler
class RequestHandler {

    struct HTTPRequest {
        let method: String
        let path: String
        let headers: [String: String]
        let body: String
    }

    struct HTTPResponse {
        let statusCode: Int
        let headers: [String: String]
        let body: String
    }

    static func parseRequest(_ data: String) -> HTTPRequest? {
        let lines = data.components(separatedBy: "\r\n")
        guard let requestLine = lines.first,
              let parts = requestLine.components(separatedBy: " ").split(separator: " ").map(String.init),
              parts.count >= 2 else {
            return nil
        }

        let method = parts[0]
        let path = parts[1]

        var headers: [String: String] = [:]
        var headerEndIndex = 1

        for (index, line) in lines.dropFirst().enumerated() {
            if line.isEmpty {
                headerEndIndex = index + 2
                break
            }
            let headerParts = line.components(separatedBy: ": ")
            if headerParts.count == 2 {
                headers[headerParts[0]] = headerParts[1]
            }
        }

        let body = lines.dropFirst(headerEndIndex).joined(separator: "\r\n")

        return HTTPRequest(method: method, path: path, headers: headers, body: body)
    }

    static func routeRequest(_ request: HTTPRequest) -> HTTPResponse {
        switch request.method {
        case "GET":
            return handleGET(request)
        case "POST":
            return handlePOST(request)
        default:
            return HTTPResponse(statusCode: 405, headers: [:], body: "Method Not Allowed")
        }
    }

    private static func handleGET(_ request: HTTPRequest) -> HTTPResponse {
        switch request.path {
        case "/":
            return HTMLResponse("<h1>Welcome</h1><p>Use /json for JSON response</p>")
        case "/json":
            return JSONResponse(["message": "Hello", "status": "success"])
        case "/users":
            let users = [
                ["id": 1, "name": "John"],
                ["id": 2, "name": "Jane"]
            ]
            return JSONResponse(users)
        default:
            return HTMLResponse("<h1>404</h1>", statusCode: 404)
        }
    }

    private static func handlePOST(_ request: HTTPRequest) -> HTTPResponse {
        switch request.path {
        case "/echo":
            return JSONResponse(["echo": request.body])
        default:
            return HTMLResponse("<h1>POST received</h1>")
        }
    }

    private static func HTMLResponse(_ body: String, statusCode: Int = 200) -> HTTPResponse {
        return HTTPResponse(
            statusCode: statusCode,
            headers: ["Content-Type": "text/html"],
            body: body
        )
    }

    private static func JSONResponse(_ data: Any) -> HTTPResponse {
        guard let jsonData = try? JSONSerialization.data(withJSONObject: data, options: []),
              let jsonString = String(data: jsonData, encoding: .utf8) else {
            return HTTPResponse(statusCode: 500, headers: [:], body: "Internal Server Error")
        }

        return HTTPResponse(
            statusCode: 200,
            headers: ["Content-Type": "application/json"],
            body: jsonString
        )
    }
}

// 3. Router with Middleware
class Router {

    typealias Middleware = (URLRequest) -> URLRequest?
    typealias Handler = (URLRequest) -> String

    struct Route {
        let method: String
        let path: String
        let handler: Handler
    }

    private var routes: [Route] = []
    private var middlewares: [Middleware] = []

    func addMiddleware(_ middleware: @escaping Middleware) {
        middlewares.append(middleware)
    }

    func addRoute(method: String, path: String, handler: @escaping Handler) {
        routes.append(Route(method: method, path: path, handler: handler))
    }

    func handle(method: String, path: String, headers: [String: String], body: String) -> (Int, [String: String], String)? {
        // Apply middlewares
        for middleware in middlewares {
            // Middleware processing (simplified)
        }

        // Find matching route
        for route in routes {
            if route.method == method && route.path == path {
                let responseBody = route.handler(
                    URLRequest(url: URL(string: "http://localhost\(path)")!)
                )
                return (200, ["Content-Type": "text/html"], responseBody)
            }
        }

        // No matching route
        return (404, [:], "<h1>404 Not Found</h1>")
    }
}

// 4. Static File Server
class StaticFileServer {

    func serve(file: String, from documentRoot: String) -> (Int, [String: String], String)? {
        let filePath = documentRoot + file

        guard FileManager.default.fileExists(atPath: filePath) else {
            return nil
        }

        guard let fileData = try? Data(contentsOf: URL(fileURLWithPath: filePath)),
              let content = String(data: fileData, encoding: .utf8) else {
            return (500, [:], "Internal Server Error")
        }

        let ext = (filePath as NSString).pathExtension
        let contentType = getContentType(for: ext)

        return (200, ["Content-Type": contentType], content)
    }

    private func getContentType(for extension: String) -> String {
        switch `extension`.lowercased() {
        case "html": return "text/html"
        case "css": return "text/css"
        case "js": return "application/javascript"
        case "json": return "application/json"
        case "png": return "image/png"
        case "jpg", "jpeg": return "image/jpeg"
        case "gif": return "image/gif"
        default: return "text/plain"
        }
    }
}

// 5. Server with Logging
class ServerWithLogging {

    private var server: SimpleHTTPServer

    init() {
        server = SimpleHTTPServer()
    }

    func start(port: UInt16) {
        print("Starting server with logging...")
        server.start(port: port)
    }

    private func logRequest(_ method: String, _ path: String, _ statusCode: Int) {
        let timestamp = Date()
        print("[\(timestamp)] \(method) \(path) - \(statusCode)")
    }
}

// 6. REST API Server Example
class RESTAPIServer {

    private var data: [String: Any] = [
        "users": [
            ["id": 1, "name": "John Doe", "email": "[email protected]"],
            ["id": 2, "name": "Jane Smith", "email": "[email protected]"]
        ]
    ]

    func handleRequest(method: String, path: String, body: String?) -> (Int, String)? {
        let pathComponents = path.components(separatedBy: "/").filter { !$0.isEmpty }

        guard pathComponents.count >= 2 else {
            return (400, "Invalid path")
        }

        let resource = pathComponents[1]

        switch (method, resource) {
        case ("GET", "users"):
            return handleGetUsers()
        case ("GET", "users"):
            if pathComponents.count == 3,
               let id = Int(pathComponents[2]) {
                return handleGetUser(id: id)
            }
            return (400, "Invalid user ID")
        case ("POST", "users"):
            return handleCreateUser(body: body)
        default:
            return (404, "Not Found")
        }
    }

    private func handleGetUsers() -> (Int, String) {
        if let users = data["users"] as? [[String: Any]],
           let jsonData = try? JSONSerialization.data(withJSONObject: users, options: .prettyPrinted),
           let jsonString = String(data: jsonData, encoding: .utf8) {
            return (200, jsonString)
        }
        return (500, "Internal Server Error")
    }

    private func handleGetUser(id: Int) -> (Int, String) {
        if let users = data["users"] as? [[String: Any]],
           let user = users.first(where: { ($0["id"] as? Int) == id }),
           let jsonData = try? JSONSerialization.data(withJSONObject: user, options: .prettyPrinted),
           let jsonString = String(data: jsonData, encoding: .utf8) {
            return (200, jsonString)
        }
        return (404, "User not found")
    }

    private func handleCreateUser(body: String?) -> (Int, String) {
        guard let body = body,
              let bodyData = body.data(using: .utf8),
              let user = try? JSONSerialization.jsonObject(with: bodyData) as? [String: Any] else {
            return (400, "Invalid request body")
        }

        var users = (data["users"] as? [[String: Any]]) ?? []
        let newUser = user.merging(["id": users.count + 1]) { _, new in new }
        users.append(newUser)
        data["users"] = users

        if let jsonData = try? JSONSerialization.data(withJSONObject: newUser, options: .prettyPrinted),
           let jsonString = String(data: jsonData, encoding: .utf8) {
            return (201, jsonString)
        }

        return (500, "Internal Server Error")
    }
}

// Main demonstration
func demonstrateHTTPServer() {
    print("=== macOS Swift HTTP Server Examples ===")

    let server = SimpleHTTPServer()

    // Start server on port 8080
    server.start(port: 8080)

    print("\nServer is running. Test with:")
    print("  curl http://localhost:8080/")
    print("  curl http://localhost:8080/about")
    print("  curl http://localhost:8080/json")
    print("  curl http://localhost:8080/time")

    // Keep server running
    print("\nPress Ctrl+C to stop the server")
    RunLoop.current.run()

    // Server cleanup on exit (in practice, use signal handlers)
    // server.stop()
}

// Uncomment to run server
// demonstrateHTTPServer()

print("\nNote: HTTP server examples provided. Uncomment demonstrateHTTPServer() to start server.")