sjrmanning / Birdsong

:bird::musical_score: Swift WebSockets client for Phoenix Channels.
MIT License
127 stars 37 forks source link

Support Default, URL string, Component Based Socket Initialisation #1

Closed davidkuhta closed 8 years ago

davidkuhta commented 8 years ago

Wanted to get your thoughts on some variations on init, that would allow you to init based on:

  1. Nothing (Default to http://localhost:4000/socket/websocket
  2. String
  3. URLComponents

    [2] Init based on string (casting to NSURL handled in buildURL):

let socket = Socket(url: "http://localhost:3000/user_socket/websocket")

    public init(url: **String**, params: [String: String]? = nil, selfSignedSSL: Bool = false) {
        heartbeatQueue = dispatch_queue_create("com.ecksd.birdsong.hbqueue", nil)
        socket = WebSocket(url: buildURL(url, params: params))
        socket.delegate = self
        socket.selfSignedSSL = selfSignedSSL
    }

// MARK: - Private URL helpers

private func buildURL(url_string: **String**, params: [String: String]?) -> NSURL {
    **let url = NSURL(string: url_string)!**
    guard let components = NSURLComponents(URL: url, resolvingAgainstBaseURL: false),
        params = params else {
            return url
    }

    var queryItems = [NSURLQueryItem]()
    params.forEach({
        queryItems.append(NSURLQueryItem(name: $0, value: $1))
    })

    components.queryItems = queryItems
    return components.URL!
}

[1&3] URL component based (with default to: "http://localhost:4000/socket/websocket"):

let socket = Socket(port: 4001) // http://localhost:4001/socket/websocket let socket = Socket()

Add component based initialiser

    // MARK: - Component based Initialisation

    public init(protocol: String = "http", host: String = "localhost", port: Int = 4000,
               path: String = "socket", transport: String = "websocket",
               params: [String: String]? = nil, selfSignedSSL: Bool = false) {
        string_port = String(port)
        url = "\(protocol)://\(host):\(port)/\(path)/\(transport)"
        heartbeatQueue = dispatch_queue_create("com.ecksd.birdsong.hbqueue", nil)
        socket = WebSocket(url: buildURL(protocol, host, port, path, transport, params: params))
        socket.delegate = self
        socket.selfSignedSSL = selfSignedSSL
    }

And overload buildURL:

func buildURL(protocol: String, host: String, port: Int, path: String,
        transport: String, params: [String: String]? = nil) -> NSURL {
  full_path = "/\(path)/\(transport)"
  let components = NSURLComponents()
  components.scheme = "protocol";
  components.host = host;
  components.path = full_path;
  components.port = port;

guard let params = params else {
            return components.URL!
    }

    var queryItems = [NSURLQueryItem]()
    params.forEach({
        queryItems.append(NSURLQueryItem(name: $0, value: $1))
    })

    components.queryItems = queryItems
    return components.URL!
}

Note: I haven't tried these out, but if it sounds like a good fit for Birdsong, I'd be happy to work through it and pull a PR.

Cheers

sjrmanning commented 8 years ago

Looks good to me! I'm happy to look at a PR if you want to take a shot at it, otherwise I can spend some time on it soon. String init especially would be convenient :) 👍