) {
145 | XCTFail("WebSocket should not attempt to migrate to a better path during testing.")
146 | }
147 |
148 | func webSocketDidReceiveError(connection: WebSocketConnection, error: NWError) {
149 | Self.errorExpectation?.fulfill()
150 | }
151 |
152 | func webSocketDidReceivePong(connection: WebSocketConnection) {
153 | Self.pongExpectation?.fulfill()
154 |
155 | guard Self.pingsWithIntervalExpectation != nil else {
156 | return
157 | }
158 |
159 | if Self.receivedPongTimestamps.count == Self.expectedReceivedPongsCount {
160 | Self.pingsWithIntervalExpectation?.fulfill()
161 | }
162 | Self.receivedPongTimestamps.append(Date())
163 | }
164 |
165 | func webSocketDidReceiveMessage(connection: WebSocketConnection, string: String) {
166 | XCTAssertEqual(string, Self.stringMessage)
167 | Self.stringMessageExpectation.fulfill()
168 | }
169 |
170 | func webSocketDidReceiveMessage(connection: WebSocketConnection, data: Data) {
171 | XCTAssertEqual(data, Self.dataMessage)
172 | Self.dataMessageExpectation.fulfill()
173 | }
174 | }
175 |
176 |
--------------------------------------------------------------------------------
/Tests/NWWebSocketTests/Server/NWServerConnection.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import Network
3 |
4 | internal class NWServerConnection {
5 |
6 | // MARK: - Public properties
7 |
8 | let id: Int
9 |
10 | var didStopHandler: ((Error?) -> Void)? = nil
11 | var didReceiveStringHandler: ((String) -> ())? = nil
12 | var didReceiveDataHandler: ((Data) -> ())? = nil
13 |
14 | // MARK: - Private properties
15 |
16 | private static var nextID: Int = 0
17 | private let connection: NWConnection
18 |
19 | // MARK: - Lifecycle
20 |
21 | init(nwConnection: NWConnection) {
22 | connection = nwConnection
23 | id = Self.nextID
24 | Self.nextID += 1
25 | }
26 |
27 | deinit {
28 | print("deinit")
29 | }
30 |
31 | // MARK: - Public methods
32 |
33 | func start() {
34 | print("connection \(id) will start")
35 | connection.stateUpdateHandler = self.stateDidChange(to:)
36 | listen()
37 | connection.start(queue: .main)
38 | }
39 |
40 | func receiveMessage(data: Data, context: NWConnection.ContentContext) {
41 | guard let metadata = context.protocolMetadata.first as? NWProtocolWebSocket.Metadata else {
42 | return
43 | }
44 |
45 | switch metadata.opcode {
46 | case .binary:
47 | didReceiveDataHandler?(data)
48 | case .cont:
49 | //
50 | break
51 | case .text:
52 | guard let string = String(data: data, encoding: .utf8) else {
53 | return
54 | }
55 | didReceiveStringHandler?(string)
56 | case .close:
57 | //
58 | break
59 | case .ping:
60 | pong()
61 | break
62 | case .pong:
63 | //
64 | break
65 | @unknown default:
66 | fatalError()
67 | }
68 | }
69 |
70 | func send(string: String) {
71 | let metaData = NWProtocolWebSocket.Metadata(opcode: .text)
72 | let context = NWConnection.ContentContext(identifier: "textContext",
73 | metadata: [metaData])
74 | self.send(data: string.data(using: .utf8), context: context)
75 | }
76 |
77 | func send(data: Data) {
78 | let metaData = NWProtocolWebSocket.Metadata(opcode: .binary)
79 | let context = NWConnection.ContentContext(identifier: "binaryContext",
80 | metadata: [metaData])
81 | self.send(data: data, context: context)
82 | }
83 |
84 | func stop() {
85 | print("connection \(id) will stop")
86 | }
87 |
88 | // MARK: - Private methods
89 |
90 | private func stateDidChange(to state: NWConnection.State) {
91 | switch state {
92 | case .setup:
93 | print("connection is setup.")
94 | case .waiting(let error):
95 | connectionDidReceiveError(error)
96 | case .preparing:
97 | print("connection is being establised.")
98 | case .ready:
99 | print("connection \(id) ready")
100 | case .cancelled:
101 | stopConnection(error: nil)
102 | case .failed(let error):
103 | stopConnection(error: error)
104 | @unknown default:
105 | fatalError()
106 | }
107 | }
108 |
109 | private func listen() {
110 | connection.receiveMessage() { (data, context, isComplete, error) in
111 | if let data = data, let context = context, !data.isEmpty {
112 | self.receiveMessage(data: data, context: context)
113 | }
114 | if let error = error {
115 | self.connectionDidReceiveError(error)
116 | } else {
117 | self.listen()
118 | }
119 | }
120 | }
121 |
122 | private func pong() {
123 | let metaData = NWProtocolWebSocket.Metadata(opcode: .pong)
124 | let context = NWConnection.ContentContext(identifier: "pongContext",
125 | metadata: [metaData])
126 | self.send(data: Data(), context: context)
127 | }
128 |
129 | private func send(data: Data?, context: NWConnection.ContentContext) {
130 | self.connection.send(content: data,
131 | contentContext: context,
132 | isComplete: true,
133 | completion: .contentProcessed( { error in
134 | if let error = error {
135 | self.connectionDidReceiveError(error)
136 | return
137 | }
138 | print("connection \(self.id) did send, data: \(String(describing: data))")
139 | }))
140 | }
141 |
142 | private func connectionDidReceiveError(_ error: NWError) {
143 | print("connection did receive error: \(error.debugDescription)")
144 | }
145 |
146 | private func stopConnection(error: Error?) {
147 | connection.stateUpdateHandler = nil
148 | if let didStopHandler = didStopHandler {
149 | self.didStopHandler = nil
150 | didStopHandler(error)
151 | }
152 | if let error = error {
153 | print("connection \(id) did fail, error: \(error)")
154 | } else {
155 | print("connection \(id) did end")
156 | }
157 | }
158 | }
159 |
160 |
--------------------------------------------------------------------------------
/Tests/NWWebSocketTests/Server/NWWebSocketServer.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import Network
3 |
4 | internal class NWSwiftWebSocketServer {
5 |
6 | // MARK: - Private properties
7 |
8 | private let port: NWEndpoint.Port
9 | private var listener: NWListener?
10 | private let parameters: NWParameters
11 | private var connectionsByID: [Int: NWServerConnection] = [:]
12 |
13 | // MARK: - Lifecycle
14 |
15 | init(port: UInt16) {
16 | self.port = NWEndpoint.Port(rawValue: port)!
17 | parameters = NWParameters(tls: nil)
18 | parameters.allowLocalEndpointReuse = true
19 | parameters.includePeerToPeer = true
20 | let wsOptions = NWProtocolWebSocket.Options()
21 | wsOptions.autoReplyPing = true
22 | parameters.defaultProtocolStack.applicationProtocols.insert(wsOptions, at: 0)
23 | }
24 |
25 | // MARK: - Public methods
26 |
27 | func start() throws {
28 | print("Server starting...")
29 | if listener == nil {
30 | listener = try! NWListener(using: parameters, on: self.port)
31 | }
32 | listener?.stateUpdateHandler = self.stateDidChange(to:)
33 | listener?.newConnectionHandler = self.didAccept(nwConnection:)
34 | listener?.start(queue: .main)
35 | }
36 |
37 | func stop() {
38 | listener?.cancel()
39 | }
40 |
41 | // MARK: - Private methods
42 |
43 | private func didAccept(nwConnection: NWConnection) {
44 | let connection = NWServerConnection(nwConnection: nwConnection)
45 | connectionsByID[connection.id] = connection
46 |
47 | connection.start()
48 |
49 | connection.didStopHandler = { err in
50 | if let err = err {
51 | print(err)
52 | }
53 | self.connectionDidStop(connection)
54 | }
55 | connection.didReceiveStringHandler = { string in
56 | self.connectionsByID.values.forEach { connection in
57 | print("sent \(string) to open connection \(connection.id)")
58 | connection.send(string: string)
59 | }
60 | }
61 | connection.didReceiveDataHandler = { data in
62 | self.connectionsByID.values.forEach { connection in
63 | print("sent \(String(data: data, encoding: .utf8) ?? "NOTHING") to open connection \(connection.id)")
64 | connection.send(data: data)
65 | }
66 | }
67 |
68 | print("server did open connection \(connection.id)")
69 | }
70 |
71 | private func stateDidChange(to newState: NWListener.State) {
72 | switch newState {
73 | case .setup:
74 | print("Server is setup.")
75 | case .waiting(let error):
76 | print("Server is waiting to start, non-fatal error: \(error.debugDescription)")
77 | case .ready:
78 | print("Server ready.")
79 | case .cancelled:
80 | self.stopSever(error: nil)
81 | case .failed(let error):
82 | self.stopSever(error: error)
83 | @unknown default:
84 | fatalError()
85 | }
86 | }
87 |
88 | private func connectionDidStop(_ connection: NWServerConnection) {
89 | self.connectionsByID.removeValue(forKey: connection.id)
90 | print("server did close connection \(connection.id)")
91 | }
92 |
93 | private func stopSever(error: NWError?) {
94 | self.listener = nil
95 | for connection in self.connectionsByID.values {
96 | connection.didStopHandler = nil
97 | connection.stop()
98 | }
99 | self.connectionsByID.removeAll()
100 | if let error = error {
101 | print("Server failure, error: \(error.debugDescription)")
102 | } else {
103 | print("Server stopped normally.")
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/Tests/NWWebSocketTests/XCTestManifests.swift:
--------------------------------------------------------------------------------
1 | #if !canImport(ObjectiveC)
2 | import XCTest
3 |
4 | extension NWWebSocketTests {
5 | // DO NOT MODIFY: This is autogenerated, use:
6 | // `swift test --generate-linuxmain`
7 | // to regenerate.
8 | static let __allTests__NWWebSocketTests = [
9 | ("testConnect", testConnect),
10 | ("testDisconnect", testDisconnect),
11 | ("testPingsWithInterval", testPingsWithInterval),
12 | ("testReceiveDataMessage", testReceiveDataMessage),
13 | ("testReceiveError", testReceiveError),
14 | ("testReceivePong", testReceivePong),
15 | ("testReceiveStringMessage", testReceiveStringMessage),
16 | ]
17 | }
18 |
19 | public func __allTests() -> [XCTestCaseEntry] {
20 | return [
21 | testCase(NWWebSocketTests.__allTests__NWWebSocketTests),
22 | ]
23 | }
24 | #endif
25 |
--------------------------------------------------------------------------------
/docs/Classes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Classes Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
29 |
30 |
31 | NWWebSocket Reference
32 |
33 | Classes Reference
34 |
35 |
36 |
37 |
60 |
61 |
62 |
63 | Classes
64 | The following classes are available globally.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
A WebSocket client that manages a socket connection.
84 |
85 |
See more
86 |
87 |
88 |
Declaration
89 |
94 |
95 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/docs/Protocols.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Protocols Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
29 |
30 |
31 | NWWebSocket Reference
32 |
33 | Protocols Reference
34 |
35 |
36 |
37 |
60 |
61 |
62 |
63 | Protocols
64 | The following protocols are available globally.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
Defines a WebSocket connection.
84 |
85 |
See more
86 |
87 |
88 |
Declaration
89 |
90 |
Swift
91 |
public protocol WebSocketConnection
92 |
93 |
94 |
95 |
98 |
99 |
100 |
101 |
102 |
109 |
110 |
111 |
112 |
113 |
114 |
Defines a delegate for a WebSocket connection.
115 |
116 |
See more
117 |
118 |
119 |
Declaration
120 |
121 |
Swift
122 |
public protocol WebSocketConnectionDelegate : AnyObject
123 |
124 |
125 |
126 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
140 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/docs/Protocols/WebSocketConnection.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WebSocketConnection Protocol Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
29 |
30 |
31 | NWWebSocket Reference
32 |
33 | WebSocketConnection Protocol Reference
34 |
35 |
36 |
37 |
60 |
61 |
62 |
63 | WebSocketConnection
64 |
65 |
66 |
67 |
public protocol WebSocketConnection
68 |
69 |
70 |
71 | Defines a WebSocket connection.
72 |
73 |
76 |
77 |
78 |
79 |
80 |
81 |
88 |
89 |
90 |
91 |
92 |
93 |
Connect to the WebSocket.
94 |
95 |
96 |
97 |
Declaration
98 |
99 |
Swift
100 |
func connect ()
101 |
102 |
103 |
104 |
107 |
108 |
109 |
110 |
111 |
118 |
119 |
120 |
121 |
122 |
123 |
Send a UTF-8 formatted String
over the WebSocket.
124 |
125 |
126 |
127 |
Declaration
128 |
129 |
Swift
130 |
func send ( string : String )
131 |
132 |
133 |
134 |
135 |
Parameters
136 |
137 |
138 |
139 |
140 |
141 | string
142 |
143 |
144 |
145 |
146 |
The String
that will be sent.
147 |
148 |
149 |
150 |
151 |
152 |
153 |
156 |
157 |
158 |
159 |
160 |
167 |
168 |
169 |
170 |
171 |
172 |
Send some Data
over the WebSocket.
173 |
174 |
175 |
176 |
Declaration
177 |
178 |
Swift
179 |
func send ( data : Data )
180 |
181 |
182 |
183 |
184 |
Parameters
185 |
186 |
187 |
188 |
189 |
190 | data
191 |
192 |
193 |
194 |
195 |
The Data
that will be sent.
196 |
197 |
198 |
199 |
200 |
201 |
202 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 | listen()
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
Start listening for messages over the WebSocket.
222 |
223 |
224 |
225 |
Declaration
226 |
227 |
Swift
228 |
func listen ()
229 |
230 |
231 |
232 |
235 |
236 |
237 |
238 |
239 |
246 |
247 |
248 |
249 |
250 |
251 |
Ping the WebSocket periodically.
252 |
253 |
254 |
255 |
Declaration
256 |
257 |
Swift
258 |
func ping ( interval : TimeInterval )
259 |
260 |
261 |
262 |
263 |
Parameters
264 |
265 |
266 |
267 |
268 |
269 | interval
270 |
271 |
272 |
273 |
274 |
The TimeInterval
(in seconds) with which to ping the server.
275 |
276 |
277 |
278 |
279 |
280 |
281 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 | ping()
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
Ping the WebSocket once.
301 |
302 |
303 |
304 |
Declaration
305 |
306 |
Swift
307 |
func ping ()
308 |
309 |
310 |
311 |
314 |
315 |
316 |
317 |
318 |
325 |
326 |
327 |
328 |
329 |
330 |
Disconnect from the WebSocket.
331 |
332 |
333 |
334 |
Declaration
335 |
336 |
Swift
337 |
func disconnect ( closeCode : NWProtocolWebSocket . CloseCode )
338 |
339 |
340 |
341 |
342 |
Parameters
343 |
344 |
345 |
346 |
347 |
348 | closeCode
349 |
350 |
351 |
352 |
353 |
The code to use when closing the WebSocket connection.
354 |
355 |
356 |
357 |
358 |
359 |
360 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 | delegate
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
The WebSocket connection delegate.
380 |
381 |
382 |
383 |
Declaration
384 |
389 |
390 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
404 |
405 |
406 |
407 |
408 |
409 |
--------------------------------------------------------------------------------
/docs/badge.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | documentation
17 |
18 |
19 | documentation
20 |
21 |
22 | 100%
23 |
24 |
25 | 100%
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/docs/css/highlight.css:
--------------------------------------------------------------------------------
1 | /* Credit to https://gist.github.com/wataru420/2048287 */
2 | .highlight {
3 | /* Comment */
4 | /* Error */
5 | /* Keyword */
6 | /* Operator */
7 | /* Comment.Multiline */
8 | /* Comment.Preproc */
9 | /* Comment.Single */
10 | /* Comment.Special */
11 | /* Generic.Deleted */
12 | /* Generic.Deleted.Specific */
13 | /* Generic.Emph */
14 | /* Generic.Error */
15 | /* Generic.Heading */
16 | /* Generic.Inserted */
17 | /* Generic.Inserted.Specific */
18 | /* Generic.Output */
19 | /* Generic.Prompt */
20 | /* Generic.Strong */
21 | /* Generic.Subheading */
22 | /* Generic.Traceback */
23 | /* Keyword.Constant */
24 | /* Keyword.Declaration */
25 | /* Keyword.Pseudo */
26 | /* Keyword.Reserved */
27 | /* Keyword.Type */
28 | /* Literal.Number */
29 | /* Literal.String */
30 | /* Name.Attribute */
31 | /* Name.Builtin */
32 | /* Name.Class */
33 | /* Name.Constant */
34 | /* Name.Entity */
35 | /* Name.Exception */
36 | /* Name.Function */
37 | /* Name.Namespace */
38 | /* Name.Tag */
39 | /* Name.Variable */
40 | /* Operator.Word */
41 | /* Text.Whitespace */
42 | /* Literal.Number.Float */
43 | /* Literal.Number.Hex */
44 | /* Literal.Number.Integer */
45 | /* Literal.Number.Oct */
46 | /* Literal.String.Backtick */
47 | /* Literal.String.Char */
48 | /* Literal.String.Doc */
49 | /* Literal.String.Double */
50 | /* Literal.String.Escape */
51 | /* Literal.String.Heredoc */
52 | /* Literal.String.Interpol */
53 | /* Literal.String.Other */
54 | /* Literal.String.Regex */
55 | /* Literal.String.Single */
56 | /* Literal.String.Symbol */
57 | /* Name.Builtin.Pseudo */
58 | /* Name.Variable.Class */
59 | /* Name.Variable.Global */
60 | /* Name.Variable.Instance */
61 | /* Literal.Number.Integer.Long */ }
62 | .highlight .c {
63 | color: #999988;
64 | font-style: italic; }
65 | .highlight .err {
66 | color: #a61717;
67 | background-color: #e3d2d2; }
68 | .highlight .k {
69 | color: #000000;
70 | font-weight: bold; }
71 | .highlight .o {
72 | color: #000000;
73 | font-weight: bold; }
74 | .highlight .cm {
75 | color: #999988;
76 | font-style: italic; }
77 | .highlight .cp {
78 | color: #999999;
79 | font-weight: bold; }
80 | .highlight .c1 {
81 | color: #999988;
82 | font-style: italic; }
83 | .highlight .cs {
84 | color: #999999;
85 | font-weight: bold;
86 | font-style: italic; }
87 | .highlight .gd {
88 | color: #000000;
89 | background-color: #ffdddd; }
90 | .highlight .gd .x {
91 | color: #000000;
92 | background-color: #ffaaaa; }
93 | .highlight .ge {
94 | color: #000000;
95 | font-style: italic; }
96 | .highlight .gr {
97 | color: #aa0000; }
98 | .highlight .gh {
99 | color: #999999; }
100 | .highlight .gi {
101 | color: #000000;
102 | background-color: #ddffdd; }
103 | .highlight .gi .x {
104 | color: #000000;
105 | background-color: #aaffaa; }
106 | .highlight .go {
107 | color: #888888; }
108 | .highlight .gp {
109 | color: #555555; }
110 | .highlight .gs {
111 | font-weight: bold; }
112 | .highlight .gu {
113 | color: #aaaaaa; }
114 | .highlight .gt {
115 | color: #aa0000; }
116 | .highlight .kc {
117 | color: #000000;
118 | font-weight: bold; }
119 | .highlight .kd {
120 | color: #000000;
121 | font-weight: bold; }
122 | .highlight .kp {
123 | color: #000000;
124 | font-weight: bold; }
125 | .highlight .kr {
126 | color: #000000;
127 | font-weight: bold; }
128 | .highlight .kt {
129 | color: #445588; }
130 | .highlight .m {
131 | color: #009999; }
132 | .highlight .s {
133 | color: #d14; }
134 | .highlight .na {
135 | color: #008080; }
136 | .highlight .nb {
137 | color: #0086B3; }
138 | .highlight .nc {
139 | color: #445588;
140 | font-weight: bold; }
141 | .highlight .no {
142 | color: #008080; }
143 | .highlight .ni {
144 | color: #800080; }
145 | .highlight .ne {
146 | color: #990000;
147 | font-weight: bold; }
148 | .highlight .nf {
149 | color: #990000; }
150 | .highlight .nn {
151 | color: #555555; }
152 | .highlight .nt {
153 | color: #000080; }
154 | .highlight .nv {
155 | color: #008080; }
156 | .highlight .ow {
157 | color: #000000;
158 | font-weight: bold; }
159 | .highlight .w {
160 | color: #bbbbbb; }
161 | .highlight .mf {
162 | color: #009999; }
163 | .highlight .mh {
164 | color: #009999; }
165 | .highlight .mi {
166 | color: #009999; }
167 | .highlight .mo {
168 | color: #009999; }
169 | .highlight .sb {
170 | color: #d14; }
171 | .highlight .sc {
172 | color: #d14; }
173 | .highlight .sd {
174 | color: #d14; }
175 | .highlight .s2 {
176 | color: #d14; }
177 | .highlight .se {
178 | color: #d14; }
179 | .highlight .sh {
180 | color: #d14; }
181 | .highlight .si {
182 | color: #d14; }
183 | .highlight .sx {
184 | color: #d14; }
185 | .highlight .sr {
186 | color: #009926; }
187 | .highlight .s1 {
188 | color: #d14; }
189 | .highlight .ss {
190 | color: #990073; }
191 | .highlight .bp {
192 | color: #999999; }
193 | .highlight .vc {
194 | color: #008080; }
195 | .highlight .vg {
196 | color: #008080; }
197 | .highlight .vi {
198 | color: #008080; }
199 | .highlight .il {
200 | color: #009999; }
201 |
--------------------------------------------------------------------------------
/docs/css/jazzy.css:
--------------------------------------------------------------------------------
1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td {
2 | background: transparent;
3 | border: 0;
4 | margin: 0;
5 | outline: 0;
6 | padding: 0;
7 | vertical-align: baseline; }
8 |
9 | body {
10 | background-color: #f2f2f2;
11 | font-family: Helvetica, freesans, Arial, sans-serif;
12 | font-size: 14px;
13 | -webkit-font-smoothing: subpixel-antialiased;
14 | word-wrap: break-word; }
15 |
16 | h1, h2, h3 {
17 | margin-top: 0.8em;
18 | margin-bottom: 0.3em;
19 | font-weight: 100;
20 | color: black; }
21 |
22 | h1 {
23 | font-size: 2.5em; }
24 |
25 | h2 {
26 | font-size: 2em;
27 | border-bottom: 1px solid #e2e2e2; }
28 |
29 | h4 {
30 | font-size: 13px;
31 | line-height: 1.5;
32 | margin-top: 21px; }
33 |
34 | h5 {
35 | font-size: 1.1em; }
36 |
37 | h6 {
38 | font-size: 1.1em;
39 | color: #777; }
40 |
41 | .section-name {
42 | color: gray;
43 | display: block;
44 | font-family: Helvetica;
45 | font-size: 22px;
46 | font-weight: 100;
47 | margin-bottom: 15px; }
48 |
49 | pre, code {
50 | font: 0.95em Menlo, monospace;
51 | color: #777;
52 | word-wrap: normal; }
53 |
54 | p code, li code {
55 | background-color: #eee;
56 | padding: 2px 4px;
57 | border-radius: 4px; }
58 |
59 | pre > code {
60 | padding: 0; }
61 |
62 | a {
63 | color: #0088cc;
64 | text-decoration: none; }
65 | a code {
66 | color: inherit; }
67 |
68 | ul {
69 | padding-left: 15px; }
70 |
71 | li {
72 | line-height: 1.8em; }
73 |
74 | img {
75 | max-width: 100%; }
76 |
77 | blockquote {
78 | margin-left: 0;
79 | padding: 0 10px;
80 | border-left: 4px solid #ccc; }
81 |
82 | .content-wrapper {
83 | margin: 0 auto;
84 | width: 980px; }
85 |
86 | header {
87 | font-size: 0.85em;
88 | line-height: 32px;
89 | background-color: #414141;
90 | position: fixed;
91 | width: 100%;
92 | z-index: 3; }
93 | header img {
94 | padding-right: 6px;
95 | vertical-align: -4px;
96 | height: 16px; }
97 | header a {
98 | color: #fff; }
99 | header p {
100 | float: left;
101 | color: #999; }
102 | header .header-right {
103 | float: right;
104 | margin-left: 16px; }
105 |
106 | #breadcrumbs {
107 | background-color: #f2f2f2;
108 | height: 21px;
109 | padding-top: 17px;
110 | position: fixed;
111 | width: 100%;
112 | z-index: 2;
113 | margin-top: 32px; }
114 | #breadcrumbs #carat {
115 | height: 10px;
116 | margin: 0 5px; }
117 |
118 | .sidebar {
119 | background-color: #f9f9f9;
120 | border: 1px solid #e2e2e2;
121 | overflow-y: auto;
122 | overflow-x: hidden;
123 | position: fixed;
124 | top: 70px;
125 | bottom: 0;
126 | width: 230px;
127 | word-wrap: normal; }
128 |
129 | .nav-groups {
130 | list-style-type: none;
131 | background: #fff;
132 | padding-left: 0; }
133 |
134 | .nav-group-name {
135 | border-bottom: 1px solid #e2e2e2;
136 | font-size: 1.1em;
137 | font-weight: 100;
138 | padding: 15px 0 15px 20px; }
139 | .nav-group-name > a {
140 | color: #333; }
141 |
142 | .nav-group-tasks {
143 | margin-top: 5px; }
144 |
145 | .nav-group-task {
146 | font-size: 0.9em;
147 | list-style-type: none;
148 | white-space: nowrap; }
149 | .nav-group-task a {
150 | color: #888; }
151 |
152 | .main-content {
153 | background-color: #fff;
154 | border: 1px solid #e2e2e2;
155 | margin-left: 246px;
156 | position: absolute;
157 | overflow: hidden;
158 | padding-bottom: 20px;
159 | top: 70px;
160 | width: 734px; }
161 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote {
162 | margin-bottom: 1em; }
163 | .main-content p {
164 | line-height: 1.8em; }
165 | .main-content section .section:first-child {
166 | margin-top: 0;
167 | padding-top: 0; }
168 | .main-content section .task-group-section .task-group:first-of-type {
169 | padding-top: 10px; }
170 | .main-content section .task-group-section .task-group:first-of-type .section-name {
171 | padding-top: 15px; }
172 | .main-content section .heading:before {
173 | content: "";
174 | display: block;
175 | padding-top: 70px;
176 | margin: -70px 0 0; }
177 | .main-content .section-name p {
178 | margin-bottom: inherit;
179 | line-height: inherit; }
180 | .main-content .section-name code {
181 | background-color: inherit;
182 | padding: inherit;
183 | color: inherit; }
184 |
185 | .section {
186 | padding: 0 25px; }
187 |
188 | .highlight {
189 | background-color: #eee;
190 | padding: 10px 12px;
191 | border: 1px solid #e2e2e2;
192 | border-radius: 4px;
193 | overflow-x: auto; }
194 |
195 | .declaration .highlight {
196 | overflow-x: initial;
197 | padding: 0 40px 40px 0;
198 | margin-bottom: -25px;
199 | background-color: transparent;
200 | border: none; }
201 |
202 | .section-name {
203 | margin: 0;
204 | margin-left: 18px; }
205 |
206 | .task-group-section {
207 | margin-top: 10px;
208 | padding-left: 6px;
209 | border-top: 1px solid #e2e2e2; }
210 |
211 | .task-group {
212 | padding-top: 0px; }
213 |
214 | .task-name-container a[name]:before {
215 | content: "";
216 | display: block;
217 | padding-top: 70px;
218 | margin: -70px 0 0; }
219 |
220 | .section-name-container {
221 | position: relative;
222 | display: inline-block; }
223 | .section-name-container .section-name-link {
224 | position: absolute;
225 | top: 0;
226 | left: 0;
227 | bottom: 0;
228 | right: 0;
229 | margin-bottom: 0; }
230 | .section-name-container .section-name {
231 | position: relative;
232 | pointer-events: none;
233 | z-index: 1; }
234 | .section-name-container .section-name a {
235 | pointer-events: auto; }
236 |
237 | .item {
238 | padding-top: 8px;
239 | width: 100%;
240 | list-style-type: none; }
241 | .item a[name]:before {
242 | content: "";
243 | display: block;
244 | padding-top: 70px;
245 | margin: -70px 0 0; }
246 | .item code {
247 | background-color: transparent;
248 | padding: 0; }
249 | .item .token, .item .direct-link {
250 | display: inline-block;
251 | text-indent: -20px;
252 | padding-left: 3px;
253 | margin-left: 35px;
254 | font-size: 11.9px;
255 | transition: all 300ms; }
256 | .item .token-open {
257 | margin-left: 20px; }
258 | .item .discouraged {
259 | text-decoration: line-through; }
260 | .item .declaration-note {
261 | font-size: .85em;
262 | color: gray;
263 | font-style: italic; }
264 |
265 | .pointer-container {
266 | border-bottom: 1px solid #e2e2e2;
267 | left: -23px;
268 | padding-bottom: 13px;
269 | position: relative;
270 | width: 110%; }
271 |
272 | .pointer {
273 | background: #f9f9f9;
274 | border-left: 1px solid #e2e2e2;
275 | border-top: 1px solid #e2e2e2;
276 | height: 12px;
277 | left: 21px;
278 | top: -7px;
279 | -webkit-transform: rotate(45deg);
280 | -moz-transform: rotate(45deg);
281 | -o-transform: rotate(45deg);
282 | transform: rotate(45deg);
283 | position: absolute;
284 | width: 12px; }
285 |
286 | .height-container {
287 | display: none;
288 | left: -25px;
289 | padding: 0 25px;
290 | position: relative;
291 | width: 100%;
292 | overflow: hidden; }
293 | .height-container .section {
294 | background: #f9f9f9;
295 | border-bottom: 1px solid #e2e2e2;
296 | left: -25px;
297 | position: relative;
298 | width: 100%;
299 | padding-top: 10px;
300 | padding-bottom: 5px; }
301 |
302 | .aside, .language {
303 | padding: 6px 12px;
304 | margin: 12px 0;
305 | border-left: 5px solid #dddddd;
306 | overflow-y: hidden; }
307 | .aside .aside-title, .language .aside-title {
308 | font-size: 9px;
309 | letter-spacing: 2px;
310 | text-transform: uppercase;
311 | padding-bottom: 0;
312 | margin: 0;
313 | color: #aaa;
314 | -webkit-user-select: none; }
315 | .aside p:last-child, .language p:last-child {
316 | margin-bottom: 0; }
317 |
318 | .language {
319 | border-left: 5px solid #cde9f4; }
320 | .language .aside-title {
321 | color: #4b8afb; }
322 |
323 | .aside-warning, .aside-deprecated, .aside-unavailable {
324 | border-left: 5px solid #ff6666; }
325 | .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title {
326 | color: #ff0000; }
327 |
328 | .graybox {
329 | border-collapse: collapse;
330 | width: 100%; }
331 | .graybox p {
332 | margin: 0;
333 | word-break: break-word;
334 | min-width: 50px; }
335 | .graybox td {
336 | border: 1px solid #e2e2e2;
337 | padding: 5px 25px 5px 10px;
338 | vertical-align: middle; }
339 | .graybox tr td:first-of-type {
340 | text-align: right;
341 | padding: 7px;
342 | vertical-align: top;
343 | word-break: normal;
344 | width: 40px; }
345 |
346 | .slightly-smaller {
347 | font-size: 0.9em; }
348 |
349 | #footer {
350 | position: relative;
351 | top: 10px;
352 | bottom: 0px;
353 | margin-left: 25px; }
354 | #footer p {
355 | margin: 0;
356 | color: #aaa;
357 | font-size: 0.8em; }
358 |
359 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar {
360 | display: none; }
361 |
362 | html.dash .main-content {
363 | width: 980px;
364 | margin-left: 0;
365 | border: none;
366 | width: 100%;
367 | top: 0;
368 | padding-bottom: 0; }
369 |
370 | html.dash .height-container {
371 | display: block; }
372 |
373 | html.dash .item .token {
374 | margin-left: 0; }
375 |
376 | html.dash .content-wrapper {
377 | width: auto; }
378 |
379 | html.dash #footer {
380 | position: static; }
381 |
382 | form[role=search] {
383 | float: right; }
384 | form[role=search] input {
385 | font: Helvetica, freesans, Arial, sans-serif;
386 | margin-top: 6px;
387 | font-size: 13px;
388 | line-height: 20px;
389 | padding: 0px 10px;
390 | border: none;
391 | border-radius: 1em; }
392 | .loading form[role=search] input {
393 | background: white url(../img/spinner.gif) center right 4px no-repeat; }
394 | form[role=search] .tt-menu {
395 | margin: 0;
396 | min-width: 300px;
397 | background: #fff;
398 | color: #333;
399 | border: 1px solid #e2e2e2;
400 | z-index: 4; }
401 | form[role=search] .tt-highlight {
402 | font-weight: bold; }
403 | form[role=search] .tt-suggestion {
404 | font: Helvetica, freesans, Arial, sans-serif;
405 | font-size: 14px;
406 | padding: 0 8px; }
407 | form[role=search] .tt-suggestion span {
408 | display: table-cell;
409 | white-space: nowrap; }
410 | form[role=search] .tt-suggestion .doc-parent-name {
411 | width: 100%;
412 | text-align: right;
413 | font-weight: normal;
414 | font-size: 0.9em;
415 | padding-left: 16px; }
416 | form[role=search] .tt-suggestion:hover,
417 | form[role=search] .tt-suggestion.tt-cursor {
418 | cursor: pointer;
419 | background-color: #4183c4;
420 | color: #fff; }
421 | form[role=search] .tt-suggestion:hover .doc-parent-name,
422 | form[role=search] .tt-suggestion.tt-cursor .doc-parent-name {
423 | color: #fff; }
424 |
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleIdentifier
6 | com.jazzy.nwwebsocket
7 | CFBundleName
8 | NWWebSocket
9 | DocSetPlatformFamily
10 | nwwebsocket
11 | isDashDocset
12 |
13 | dashIndexFilePath
14 | index.html
15 | isJavaScriptEnabled
16 |
17 | DashDocSetFamily
18 | dashtoc
19 |
20 |
21 |
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/Classes.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Classes Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
29 |
30 |
31 | NWWebSocket Reference
32 |
33 | Classes Reference
34 |
35 |
36 |
37 |
60 |
61 |
62 |
63 | Classes
64 | The following classes are available globally.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
A WebSocket client that manages a socket connection.
84 |
85 |
See more
86 |
87 |
88 |
Declaration
89 |
94 |
95 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/Protocols.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Protocols Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
29 |
30 |
31 | NWWebSocket Reference
32 |
33 | Protocols Reference
34 |
35 |
36 |
37 |
60 |
61 |
62 |
63 | Protocols
64 | The following protocols are available globally.
65 |
66 |
67 |
68 |
69 |
70 |
71 |
78 |
79 |
80 |
81 |
82 |
83 |
Defines a WebSocket connection.
84 |
85 |
See more
86 |
87 |
88 |
Declaration
89 |
90 |
Swift
91 |
public protocol WebSocketConnection
92 |
93 |
94 |
95 |
98 |
99 |
100 |
101 |
102 |
109 |
110 |
111 |
112 |
113 |
114 |
Defines a delegate for a WebSocket connection.
115 |
116 |
See more
117 |
118 |
119 |
Declaration
120 |
121 |
Swift
122 |
public protocol WebSocketConnectionDelegate : AnyObject
123 |
124 |
125 |
126 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
140 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/badge.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | documentation
17 |
18 |
19 | documentation
20 |
21 |
22 | 100%
23 |
24 |
25 | 100%
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/css/highlight.css:
--------------------------------------------------------------------------------
1 | /* Credit to https://gist.github.com/wataru420/2048287 */
2 | .highlight {
3 | /* Comment */
4 | /* Error */
5 | /* Keyword */
6 | /* Operator */
7 | /* Comment.Multiline */
8 | /* Comment.Preproc */
9 | /* Comment.Single */
10 | /* Comment.Special */
11 | /* Generic.Deleted */
12 | /* Generic.Deleted.Specific */
13 | /* Generic.Emph */
14 | /* Generic.Error */
15 | /* Generic.Heading */
16 | /* Generic.Inserted */
17 | /* Generic.Inserted.Specific */
18 | /* Generic.Output */
19 | /* Generic.Prompt */
20 | /* Generic.Strong */
21 | /* Generic.Subheading */
22 | /* Generic.Traceback */
23 | /* Keyword.Constant */
24 | /* Keyword.Declaration */
25 | /* Keyword.Pseudo */
26 | /* Keyword.Reserved */
27 | /* Keyword.Type */
28 | /* Literal.Number */
29 | /* Literal.String */
30 | /* Name.Attribute */
31 | /* Name.Builtin */
32 | /* Name.Class */
33 | /* Name.Constant */
34 | /* Name.Entity */
35 | /* Name.Exception */
36 | /* Name.Function */
37 | /* Name.Namespace */
38 | /* Name.Tag */
39 | /* Name.Variable */
40 | /* Operator.Word */
41 | /* Text.Whitespace */
42 | /* Literal.Number.Float */
43 | /* Literal.Number.Hex */
44 | /* Literal.Number.Integer */
45 | /* Literal.Number.Oct */
46 | /* Literal.String.Backtick */
47 | /* Literal.String.Char */
48 | /* Literal.String.Doc */
49 | /* Literal.String.Double */
50 | /* Literal.String.Escape */
51 | /* Literal.String.Heredoc */
52 | /* Literal.String.Interpol */
53 | /* Literal.String.Other */
54 | /* Literal.String.Regex */
55 | /* Literal.String.Single */
56 | /* Literal.String.Symbol */
57 | /* Name.Builtin.Pseudo */
58 | /* Name.Variable.Class */
59 | /* Name.Variable.Global */
60 | /* Name.Variable.Instance */
61 | /* Literal.Number.Integer.Long */ }
62 | .highlight .c {
63 | color: #999988;
64 | font-style: italic; }
65 | .highlight .err {
66 | color: #a61717;
67 | background-color: #e3d2d2; }
68 | .highlight .k {
69 | color: #000000;
70 | font-weight: bold; }
71 | .highlight .o {
72 | color: #000000;
73 | font-weight: bold; }
74 | .highlight .cm {
75 | color: #999988;
76 | font-style: italic; }
77 | .highlight .cp {
78 | color: #999999;
79 | font-weight: bold; }
80 | .highlight .c1 {
81 | color: #999988;
82 | font-style: italic; }
83 | .highlight .cs {
84 | color: #999999;
85 | font-weight: bold;
86 | font-style: italic; }
87 | .highlight .gd {
88 | color: #000000;
89 | background-color: #ffdddd; }
90 | .highlight .gd .x {
91 | color: #000000;
92 | background-color: #ffaaaa; }
93 | .highlight .ge {
94 | color: #000000;
95 | font-style: italic; }
96 | .highlight .gr {
97 | color: #aa0000; }
98 | .highlight .gh {
99 | color: #999999; }
100 | .highlight .gi {
101 | color: #000000;
102 | background-color: #ddffdd; }
103 | .highlight .gi .x {
104 | color: #000000;
105 | background-color: #aaffaa; }
106 | .highlight .go {
107 | color: #888888; }
108 | .highlight .gp {
109 | color: #555555; }
110 | .highlight .gs {
111 | font-weight: bold; }
112 | .highlight .gu {
113 | color: #aaaaaa; }
114 | .highlight .gt {
115 | color: #aa0000; }
116 | .highlight .kc {
117 | color: #000000;
118 | font-weight: bold; }
119 | .highlight .kd {
120 | color: #000000;
121 | font-weight: bold; }
122 | .highlight .kp {
123 | color: #000000;
124 | font-weight: bold; }
125 | .highlight .kr {
126 | color: #000000;
127 | font-weight: bold; }
128 | .highlight .kt {
129 | color: #445588; }
130 | .highlight .m {
131 | color: #009999; }
132 | .highlight .s {
133 | color: #d14; }
134 | .highlight .na {
135 | color: #008080; }
136 | .highlight .nb {
137 | color: #0086B3; }
138 | .highlight .nc {
139 | color: #445588;
140 | font-weight: bold; }
141 | .highlight .no {
142 | color: #008080; }
143 | .highlight .ni {
144 | color: #800080; }
145 | .highlight .ne {
146 | color: #990000;
147 | font-weight: bold; }
148 | .highlight .nf {
149 | color: #990000; }
150 | .highlight .nn {
151 | color: #555555; }
152 | .highlight .nt {
153 | color: #000080; }
154 | .highlight .nv {
155 | color: #008080; }
156 | .highlight .ow {
157 | color: #000000;
158 | font-weight: bold; }
159 | .highlight .w {
160 | color: #bbbbbb; }
161 | .highlight .mf {
162 | color: #009999; }
163 | .highlight .mh {
164 | color: #009999; }
165 | .highlight .mi {
166 | color: #009999; }
167 | .highlight .mo {
168 | color: #009999; }
169 | .highlight .sb {
170 | color: #d14; }
171 | .highlight .sc {
172 | color: #d14; }
173 | .highlight .sd {
174 | color: #d14; }
175 | .highlight .s2 {
176 | color: #d14; }
177 | .highlight .se {
178 | color: #d14; }
179 | .highlight .sh {
180 | color: #d14; }
181 | .highlight .si {
182 | color: #d14; }
183 | .highlight .sx {
184 | color: #d14; }
185 | .highlight .sr {
186 | color: #009926; }
187 | .highlight .s1 {
188 | color: #d14; }
189 | .highlight .ss {
190 | color: #990073; }
191 | .highlight .bp {
192 | color: #999999; }
193 | .highlight .vc {
194 | color: #008080; }
195 | .highlight .vg {
196 | color: #008080; }
197 | .highlight .vi {
198 | color: #008080; }
199 | .highlight .il {
200 | color: #009999; }
201 |
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/css/jazzy.css:
--------------------------------------------------------------------------------
1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td {
2 | background: transparent;
3 | border: 0;
4 | margin: 0;
5 | outline: 0;
6 | padding: 0;
7 | vertical-align: baseline; }
8 |
9 | body {
10 | background-color: #f2f2f2;
11 | font-family: Helvetica, freesans, Arial, sans-serif;
12 | font-size: 14px;
13 | -webkit-font-smoothing: subpixel-antialiased;
14 | word-wrap: break-word; }
15 |
16 | h1, h2, h3 {
17 | margin-top: 0.8em;
18 | margin-bottom: 0.3em;
19 | font-weight: 100;
20 | color: black; }
21 |
22 | h1 {
23 | font-size: 2.5em; }
24 |
25 | h2 {
26 | font-size: 2em;
27 | border-bottom: 1px solid #e2e2e2; }
28 |
29 | h4 {
30 | font-size: 13px;
31 | line-height: 1.5;
32 | margin-top: 21px; }
33 |
34 | h5 {
35 | font-size: 1.1em; }
36 |
37 | h6 {
38 | font-size: 1.1em;
39 | color: #777; }
40 |
41 | .section-name {
42 | color: gray;
43 | display: block;
44 | font-family: Helvetica;
45 | font-size: 22px;
46 | font-weight: 100;
47 | margin-bottom: 15px; }
48 |
49 | pre, code {
50 | font: 0.95em Menlo, monospace;
51 | color: #777;
52 | word-wrap: normal; }
53 |
54 | p code, li code {
55 | background-color: #eee;
56 | padding: 2px 4px;
57 | border-radius: 4px; }
58 |
59 | pre > code {
60 | padding: 0; }
61 |
62 | a {
63 | color: #0088cc;
64 | text-decoration: none; }
65 | a code {
66 | color: inherit; }
67 |
68 | ul {
69 | padding-left: 15px; }
70 |
71 | li {
72 | line-height: 1.8em; }
73 |
74 | img {
75 | max-width: 100%; }
76 |
77 | blockquote {
78 | margin-left: 0;
79 | padding: 0 10px;
80 | border-left: 4px solid #ccc; }
81 |
82 | .content-wrapper {
83 | margin: 0 auto;
84 | width: 980px; }
85 |
86 | header {
87 | font-size: 0.85em;
88 | line-height: 32px;
89 | background-color: #414141;
90 | position: fixed;
91 | width: 100%;
92 | z-index: 3; }
93 | header img {
94 | padding-right: 6px;
95 | vertical-align: -4px;
96 | height: 16px; }
97 | header a {
98 | color: #fff; }
99 | header p {
100 | float: left;
101 | color: #999; }
102 | header .header-right {
103 | float: right;
104 | margin-left: 16px; }
105 |
106 | #breadcrumbs {
107 | background-color: #f2f2f2;
108 | height: 21px;
109 | padding-top: 17px;
110 | position: fixed;
111 | width: 100%;
112 | z-index: 2;
113 | margin-top: 32px; }
114 | #breadcrumbs #carat {
115 | height: 10px;
116 | margin: 0 5px; }
117 |
118 | .sidebar {
119 | background-color: #f9f9f9;
120 | border: 1px solid #e2e2e2;
121 | overflow-y: auto;
122 | overflow-x: hidden;
123 | position: fixed;
124 | top: 70px;
125 | bottom: 0;
126 | width: 230px;
127 | word-wrap: normal; }
128 |
129 | .nav-groups {
130 | list-style-type: none;
131 | background: #fff;
132 | padding-left: 0; }
133 |
134 | .nav-group-name {
135 | border-bottom: 1px solid #e2e2e2;
136 | font-size: 1.1em;
137 | font-weight: 100;
138 | padding: 15px 0 15px 20px; }
139 | .nav-group-name > a {
140 | color: #333; }
141 |
142 | .nav-group-tasks {
143 | margin-top: 5px; }
144 |
145 | .nav-group-task {
146 | font-size: 0.9em;
147 | list-style-type: none;
148 | white-space: nowrap; }
149 | .nav-group-task a {
150 | color: #888; }
151 |
152 | .main-content {
153 | background-color: #fff;
154 | border: 1px solid #e2e2e2;
155 | margin-left: 246px;
156 | position: absolute;
157 | overflow: hidden;
158 | padding-bottom: 20px;
159 | top: 70px;
160 | width: 734px; }
161 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote {
162 | margin-bottom: 1em; }
163 | .main-content p {
164 | line-height: 1.8em; }
165 | .main-content section .section:first-child {
166 | margin-top: 0;
167 | padding-top: 0; }
168 | .main-content section .task-group-section .task-group:first-of-type {
169 | padding-top: 10px; }
170 | .main-content section .task-group-section .task-group:first-of-type .section-name {
171 | padding-top: 15px; }
172 | .main-content section .heading:before {
173 | content: "";
174 | display: block;
175 | padding-top: 70px;
176 | margin: -70px 0 0; }
177 | .main-content .section-name p {
178 | margin-bottom: inherit;
179 | line-height: inherit; }
180 | .main-content .section-name code {
181 | background-color: inherit;
182 | padding: inherit;
183 | color: inherit; }
184 |
185 | .section {
186 | padding: 0 25px; }
187 |
188 | .highlight {
189 | background-color: #eee;
190 | padding: 10px 12px;
191 | border: 1px solid #e2e2e2;
192 | border-radius: 4px;
193 | overflow-x: auto; }
194 |
195 | .declaration .highlight {
196 | overflow-x: initial;
197 | padding: 0 40px 40px 0;
198 | margin-bottom: -25px;
199 | background-color: transparent;
200 | border: none; }
201 |
202 | .section-name {
203 | margin: 0;
204 | margin-left: 18px; }
205 |
206 | .task-group-section {
207 | margin-top: 10px;
208 | padding-left: 6px;
209 | border-top: 1px solid #e2e2e2; }
210 |
211 | .task-group {
212 | padding-top: 0px; }
213 |
214 | .task-name-container a[name]:before {
215 | content: "";
216 | display: block;
217 | padding-top: 70px;
218 | margin: -70px 0 0; }
219 |
220 | .section-name-container {
221 | position: relative;
222 | display: inline-block; }
223 | .section-name-container .section-name-link {
224 | position: absolute;
225 | top: 0;
226 | left: 0;
227 | bottom: 0;
228 | right: 0;
229 | margin-bottom: 0; }
230 | .section-name-container .section-name {
231 | position: relative;
232 | pointer-events: none;
233 | z-index: 1; }
234 | .section-name-container .section-name a {
235 | pointer-events: auto; }
236 |
237 | .item {
238 | padding-top: 8px;
239 | width: 100%;
240 | list-style-type: none; }
241 | .item a[name]:before {
242 | content: "";
243 | display: block;
244 | padding-top: 70px;
245 | margin: -70px 0 0; }
246 | .item code {
247 | background-color: transparent;
248 | padding: 0; }
249 | .item .token, .item .direct-link {
250 | display: inline-block;
251 | text-indent: -20px;
252 | padding-left: 3px;
253 | margin-left: 35px;
254 | font-size: 11.9px;
255 | transition: all 300ms; }
256 | .item .token-open {
257 | margin-left: 20px; }
258 | .item .discouraged {
259 | text-decoration: line-through; }
260 | .item .declaration-note {
261 | font-size: .85em;
262 | color: gray;
263 | font-style: italic; }
264 |
265 | .pointer-container {
266 | border-bottom: 1px solid #e2e2e2;
267 | left: -23px;
268 | padding-bottom: 13px;
269 | position: relative;
270 | width: 110%; }
271 |
272 | .pointer {
273 | background: #f9f9f9;
274 | border-left: 1px solid #e2e2e2;
275 | border-top: 1px solid #e2e2e2;
276 | height: 12px;
277 | left: 21px;
278 | top: -7px;
279 | -webkit-transform: rotate(45deg);
280 | -moz-transform: rotate(45deg);
281 | -o-transform: rotate(45deg);
282 | transform: rotate(45deg);
283 | position: absolute;
284 | width: 12px; }
285 |
286 | .height-container {
287 | display: none;
288 | left: -25px;
289 | padding: 0 25px;
290 | position: relative;
291 | width: 100%;
292 | overflow: hidden; }
293 | .height-container .section {
294 | background: #f9f9f9;
295 | border-bottom: 1px solid #e2e2e2;
296 | left: -25px;
297 | position: relative;
298 | width: 100%;
299 | padding-top: 10px;
300 | padding-bottom: 5px; }
301 |
302 | .aside, .language {
303 | padding: 6px 12px;
304 | margin: 12px 0;
305 | border-left: 5px solid #dddddd;
306 | overflow-y: hidden; }
307 | .aside .aside-title, .language .aside-title {
308 | font-size: 9px;
309 | letter-spacing: 2px;
310 | text-transform: uppercase;
311 | padding-bottom: 0;
312 | margin: 0;
313 | color: #aaa;
314 | -webkit-user-select: none; }
315 | .aside p:last-child, .language p:last-child {
316 | margin-bottom: 0; }
317 |
318 | .language {
319 | border-left: 5px solid #cde9f4; }
320 | .language .aside-title {
321 | color: #4b8afb; }
322 |
323 | .aside-warning, .aside-deprecated, .aside-unavailable {
324 | border-left: 5px solid #ff6666; }
325 | .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title {
326 | color: #ff0000; }
327 |
328 | .graybox {
329 | border-collapse: collapse;
330 | width: 100%; }
331 | .graybox p {
332 | margin: 0;
333 | word-break: break-word;
334 | min-width: 50px; }
335 | .graybox td {
336 | border: 1px solid #e2e2e2;
337 | padding: 5px 25px 5px 10px;
338 | vertical-align: middle; }
339 | .graybox tr td:first-of-type {
340 | text-align: right;
341 | padding: 7px;
342 | vertical-align: top;
343 | word-break: normal;
344 | width: 40px; }
345 |
346 | .slightly-smaller {
347 | font-size: 0.9em; }
348 |
349 | #footer {
350 | position: relative;
351 | top: 10px;
352 | bottom: 0px;
353 | margin-left: 25px; }
354 | #footer p {
355 | margin: 0;
356 | color: #aaa;
357 | font-size: 0.8em; }
358 |
359 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar {
360 | display: none; }
361 |
362 | html.dash .main-content {
363 | width: 980px;
364 | margin-left: 0;
365 | border: none;
366 | width: 100%;
367 | top: 0;
368 | padding-bottom: 0; }
369 |
370 | html.dash .height-container {
371 | display: block; }
372 |
373 | html.dash .item .token {
374 | margin-left: 0; }
375 |
376 | html.dash .content-wrapper {
377 | width: auto; }
378 |
379 | html.dash #footer {
380 | position: static; }
381 |
382 | form[role=search] {
383 | float: right; }
384 | form[role=search] input {
385 | font: Helvetica, freesans, Arial, sans-serif;
386 | margin-top: 6px;
387 | font-size: 13px;
388 | line-height: 20px;
389 | padding: 0px 10px;
390 | border: none;
391 | border-radius: 1em; }
392 | .loading form[role=search] input {
393 | background: white url(../img/spinner.gif) center right 4px no-repeat; }
394 | form[role=search] .tt-menu {
395 | margin: 0;
396 | min-width: 300px;
397 | background: #fff;
398 | color: #333;
399 | border: 1px solid #e2e2e2;
400 | z-index: 4; }
401 | form[role=search] .tt-highlight {
402 | font-weight: bold; }
403 | form[role=search] .tt-suggestion {
404 | font: Helvetica, freesans, Arial, sans-serif;
405 | font-size: 14px;
406 | padding: 0 8px; }
407 | form[role=search] .tt-suggestion span {
408 | display: table-cell;
409 | white-space: nowrap; }
410 | form[role=search] .tt-suggestion .doc-parent-name {
411 | width: 100%;
412 | text-align: right;
413 | font-weight: normal;
414 | font-size: 0.9em;
415 | padding-left: 16px; }
416 | form[role=search] .tt-suggestion:hover,
417 | form[role=search] .tt-suggestion.tt-cursor {
418 | cursor: pointer;
419 | background-color: #4183c4;
420 | color: #fff; }
421 | form[role=search] .tt-suggestion:hover .doc-parent-name,
422 | form[role=search] .tt-suggestion.tt-cursor .doc-parent-name {
423 | color: #fff; }
424 |
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/img/carat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher/NWWebSocket/1e545fcb53966272fc042aa17ae932f11239e00f/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/img/carat.png
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/img/dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher/NWWebSocket/1e545fcb53966272fc042aa17ae932f11239e00f/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/img/dash.png
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/img/gh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher/NWWebSocket/1e545fcb53966272fc042aa17ae932f11239e00f/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/img/gh.png
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/img/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher/NWWebSocket/1e545fcb53966272fc042aa17ae932f11239e00f/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/img/spinner.gif
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | NWWebSocket Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
28 |
29 |
30 | NWWebSocket Reference
31 |
32 | NWWebSocket Reference
33 |
34 |
35 |
36 |
59 |
60 |
61 |
62 |
63 | NWWebSocket
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | A WebSocket client written in Swift, using the Network framework from Apple.
76 |
77 |
86 |
87 |
88 |
89 | Swift 5.1 and above
90 | Xcode 11.0 and above
91 |
92 | Deployment targets
93 |
94 |
95 | iOS 13.0 and above
96 | macOS 10.15 and above
97 | tvOS 13.0 and above
98 | watchOS 6.0 and above
99 |
100 | Installation
101 | CocoaPods
102 |
103 | CocoaPods is a dependency manager for Cocoa projects.
104 |
105 | If you don’t already have the Cocoapods gem installed, run the following command:
106 | $ gem install cocoapods
107 |
108 |
109 | To integrate NWWebSocket into your Xcode project using CocoaPods, specify it in your Podfile
:
110 | source 'https://github.com/CocoaPods/Specs.git'
111 | platform :ios , '14.0'
112 | use_frameworks!
113 |
114 | pod 'NWWebSocket' , '~> 0.5.2'
115 |
116 |
117 | Then, run the following command:
118 | $ pod install
119 |
120 |
121 | If you find that you’re not having the most recent version installed when you run pod install
then try running:
122 | $ pod cache clean
123 | $ pod repo update NWWebSocket
124 | $ pod install
125 |
126 |
127 | Also you’ll need to make sure that you’ve not got the version of NWWebSocket locked to an old version in your Podfile.lock
file.
128 | Swift Package Manager
129 |
130 | To integrate the library into your project using Swift Package Manager , you can add the library as a dependency in Xcode – see the docs . The package repository URL is:
131 | https://github.com/pusher/NWWebSocket.git
132 |
133 |
134 | Alternatively, you can add the library as a dependency in your Package.swift
file. For example:
135 | // swift-tools-version:5.1
136 | import PackageDescription
137 |
138 | let package = Package (
139 | name : "YourPackage" ,
140 | products : [
141 | . library (
142 | name : "YourPackage" ,
143 | targets : [ "YourPackage" ]),
144 | ],
145 | dependencies : [
146 | . package ( url : "https://github.com/pusher/NWWebSocket.git" ,
147 | . upToNextMajor ( from : "0.5.2" )),
148 | ],
149 | targets : [
150 | . target (
151 | name : "YourPackage" ,
152 | dependencies : [ "NWWebSocket" ]),
153 | ]
154 | )
155 |
156 |
157 | You will then need to include both import Network
and import NWWebSocket
statements in any source files where you wish to use the library.
158 | Usage
159 |
160 | This section describes how to configure and use NWWebSocket to manage a WebSocket connection.
161 | Connection and disconnection
162 |
163 | Connection and disconnection is straightforward. Connecting to a WebSocket is manual by default, setting connectAutomatically
to true
makes connection automatic.
164 | Manual connection
165 | let socketURL = URL ( string : "wss://somewebsockethost.com" )
166 | let socket = NWWebSocket ( url : socketURL )
167 | socket . delegate = self
168 | socket . connect ()
169 |
170 | // Use the WebSocket…
171 |
172 | socket . disconnect ()
173 |
174 | Automatic connection
175 | let socketURL = URL ( string : "wss://somewebsockethost.com" )
176 | let socket = NWWebSocket ( url : socketURL , connectAutomatically : true )
177 | socket . delegate = self
178 |
179 | // Use the WebSocket…
180 |
181 | socket . disconnect ()
182 |
183 |
184 | NOTES:
185 |
186 |
189 | Sending data
190 |
191 | UTF-8 encoded strings or binary data can be sent over the WebSocket connection.
192 | // Sending a `String`
193 | let message = "Hello, world!"
194 | socket . send ( string : message )
195 |
196 | // Sending some binary data
197 | let data : [ UInt8 ] = [ 123 , 234 ]
198 | let messageData = Data ( data )
199 | socket . send ( data : messageData )
200 |
201 | Receiving messages and connection updates
202 |
203 | String or data messages (as well as connection state updates) can be received by making a type you define conform to WebSocketConnectionDelegate
. You can then respond to received messages or connection events accordingly.
204 | extension MyWebSocketConnectionManager : WebSocketConnectionDelegate {
205 |
206 | func webSocketDidConnect ( connection : WebSocketConnection ) {
207 | // Respond to a WebSocket connection event
208 | }
209 |
210 | func webSocketDidDisconnect ( connection : WebSocketConnection ,
211 | closeCode : NWProtocolWebSocket . CloseCode , reason : Data ?) {
212 | // Respond to a WebSocket disconnection event
213 | }
214 |
215 | func webSocketViabilityDidChange ( connection : WebSocketConnection , isViable : Bool ) {
216 | // Respond to a WebSocket connection viability change event
217 | }
218 |
219 | func webSocketDidAttemptBetterPathMigration ( result : Result < WebSocketConnection , NWError > ) {
220 | // Respond to when a WebSocket connection migrates to a better network path
221 | // (e.g. A device moves from a cellular connection to a Wi-Fi connection)
222 | }
223 |
224 | func webSocketDidReceiveError ( connection : WebSocketConnection , error : NWError ) {
225 | // Respond to a WebSocket error event
226 | }
227 |
228 | func webSocketDidReceivePong ( connection : WebSocketConnection ) {
229 | // Respond to a WebSocket connection receiving a Pong from the peer
230 | }
231 |
232 | func webSocketDidReceiveMessage ( connection : WebSocketConnection , string : String ) {
233 | // Respond to a WebSocket connection receiving a `String` message
234 | }
235 |
236 | func webSocketDidReceiveMessage ( connection : WebSocketConnection , data : Data ) {
237 | // Respond to a WebSocket connection receiving a binary `Data` message
238 | }
239 | }
240 |
241 | Ping and pong
242 |
243 | Triggering a Ping on an active WebSocket connection is a best practice method of telling the connected peer that the connection should be maintained. Pings can be triggered on-demand or periodically.
244 |
245 | // Trigger a Ping on demand
246 | socket . ping ()
247 |
248 | // Trigger a Ping periodically
249 | // (This is useful when messages are infrequently sent across the connection to prevent a connection closure)
250 | socket . ping ( interval : 30.0 )
251 |
252 | Documentation
253 |
254 | Full documentation of the library can be found in the API docs .
255 | Reporting bugs and requesting features
256 |
257 |
258 | If you have found a bug or have a feature request, please open an issue
259 | If you want to contribute, please submit a pull request (preferably with some tests 🙂 )
260 |
261 | Credits
262 |
263 | NWWebSocket is owned and maintained by Pusher . It was originally created by Daniel Browne .
264 |
265 | It uses code from the following repositories:
266 |
267 |
270 | License
271 |
272 | NWWebSocket is released under the MIT license. See LICENSE for details.
273 |
274 |
275 |
276 |
280 |
281 |
282 |
283 |
284 |
285 |
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/js/jazzy.js:
--------------------------------------------------------------------------------
1 | window.jazzy = {'docset': false}
2 | if (typeof window.dash != 'undefined') {
3 | document.documentElement.className += ' dash'
4 | window.jazzy.docset = true
5 | }
6 | if (navigator.userAgent.match(/xcode/i)) {
7 | document.documentElement.className += ' xcode'
8 | window.jazzy.docset = true
9 | }
10 |
11 | function toggleItem($link, $content) {
12 | var animationDuration = 300;
13 | $link.toggleClass('token-open');
14 | $content.slideToggle(animationDuration);
15 | }
16 |
17 | function itemLinkToContent($link) {
18 | return $link.parent().parent().next();
19 | }
20 |
21 | // On doc load + hash-change, open any targetted item
22 | function openCurrentItemIfClosed() {
23 | if (window.jazzy.docset) {
24 | return;
25 | }
26 | var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token');
27 | $content = itemLinkToContent($link);
28 | if ($content.is(':hidden')) {
29 | toggleItem($link, $content);
30 | }
31 | }
32 |
33 | $(openCurrentItemIfClosed);
34 | $(window).on('hashchange', openCurrentItemIfClosed);
35 |
36 | // On item link ('token') click, toggle its discussion
37 | $('.token').on('click', function(event) {
38 | if (window.jazzy.docset) {
39 | return;
40 | }
41 | var $link = $(this);
42 | toggleItem($link, itemLinkToContent($link));
43 |
44 | // Keeps the document from jumping to the hash.
45 | var href = $link.attr('href');
46 | if (history.pushState) {
47 | history.pushState({}, '', href);
48 | } else {
49 | location.hash = href;
50 | }
51 | event.preventDefault();
52 | });
53 |
54 | // Clicks on links to the current, closed, item need to open the item
55 | $("a:not('.token')").on('click', function() {
56 | if (location == this.href) {
57 | openCurrentItemIfClosed();
58 | }
59 | });
60 |
61 | // KaTeX rendering
62 | if ("katex" in window) {
63 | $($('.math').each( (_, element) => {
64 | katex.render(element.textContent, element, {
65 | displayMode: $(element).hasClass('m-block'),
66 | throwOnError: false,
67 | trust: true
68 | });
69 | }))
70 | }
71 |
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/js/jazzy.search.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 | var $typeahead = $('[data-typeahead]');
3 | var $form = $typeahead.parents('form');
4 | var searchURL = $form.attr('action');
5 |
6 | function displayTemplate(result) {
7 | return result.name;
8 | }
9 |
10 | function suggestionTemplate(result) {
11 | var t = '';
12 | t += '' + result.name + ' ';
13 | if (result.parent_name) {
14 | t += '' + result.parent_name + ' ';
15 | }
16 | t += '
';
17 | return t;
18 | }
19 |
20 | $typeahead.one('focus', function() {
21 | $form.addClass('loading');
22 |
23 | $.getJSON(searchURL).then(function(searchData) {
24 | const searchIndex = lunr(function() {
25 | this.ref('url');
26 | this.field('name');
27 | this.field('abstract');
28 | for (const [url, doc] of Object.entries(searchData)) {
29 | this.add({url: url, name: doc.name, abstract: doc.abstract});
30 | }
31 | });
32 |
33 | $typeahead.typeahead(
34 | {
35 | highlight: true,
36 | minLength: 3,
37 | autoselect: true
38 | },
39 | {
40 | limit: 10,
41 | display: displayTemplate,
42 | templates: { suggestion: suggestionTemplate },
43 | source: function(query, sync) {
44 | const lcSearch = query.toLowerCase();
45 | const results = searchIndex.query(function(q) {
46 | q.term(lcSearch, { boost: 100 });
47 | q.term(lcSearch, {
48 | boost: 10,
49 | wildcard: lunr.Query.wildcard.TRAILING
50 | });
51 | }).map(function(result) {
52 | var doc = searchData[result.ref];
53 | doc.url = result.ref;
54 | return doc;
55 | });
56 | sync(results);
57 | }
58 | }
59 | );
60 | $form.removeClass('loading');
61 | $typeahead.trigger('focus');
62 | });
63 | });
64 |
65 | var baseURL = searchURL.slice(0, -"search.json".length);
66 |
67 | $typeahead.on('typeahead:select', function(e, result) {
68 | window.location = baseURL + result.url;
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/search.json:
--------------------------------------------------------------------------------
1 | {"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB10DidConnect10connectionyAA0cbD0_p_tF":{"name":"webSocketDidConnect(connection:)","abstract":"Tells the delegate that the WebSocket did connect successfully.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB13DidDisconnect10connection9closeCode6reasonyAA0cbD0_p_7Network010NWProtocolcB0C05CloseK0O10Foundation4DataVSgtF":{"name":"webSocketDidDisconnect(connection:closeCode:reason:)","abstract":"Tells the delegate that the WebSocket did disconnect.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB18ViabilityDidChange10connection8isViableyAA0cbD0_p_SbtF":{"name":"webSocketViabilityDidChange(connection:isViable:)","abstract":"Tells the delegate that the WebSocket connection viability has changed.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB29DidAttemptBetterPathMigration6resultys6ResultOyAA0cbD0_p7Network7NWErrorOG_tF":{"name":"webSocketDidAttemptBetterPathMigration(result:)","abstract":"Tells the delegate that the WebSocket has attempted a migration based on a better network path becoming available.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB15DidReceiveError10connection5erroryAA0cbD0_p_7Network7NWErrorOtF":{"name":"webSocketDidReceiveError(connection:error:)","abstract":"Tells the delegate that the WebSocket received an error.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB14DidReceivePong10connectionyAA0cbD0_p_tF":{"name":"webSocketDidReceivePong(connection:)","abstract":"Tells the delegate that the WebSocket received a ‘pong’ from the server.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB17DidReceiveMessage10connection6stringyAA0cbD0_p_SStF":{"name":"webSocketDidReceiveMessage(connection:string:)","abstract":"Tells the delegate that the WebSocket received a String
message.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB17DidReceiveMessage10connection4datayAA0cbD0_p_10Foundation4DataVtF":{"name":"webSocketDidReceiveMessage(connection:data:)","abstract":"Tells the delegate that the WebSocket received a binary Data
message.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP7connectyyF":{"name":"connect()","abstract":"Connect to the WebSocket.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP4send6stringySS_tF":{"name":"send(string:)","abstract":"Send a UTF-8 formatted String
over the WebSocket.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP4send4datay10Foundation4DataV_tF":{"name":"send(data:)","abstract":"Send some Data
over the WebSocket.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP6listenyyF":{"name":"listen()","abstract":"Start listening for messages over the WebSocket.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP4ping8intervalySd_tF":{"name":"ping(interval:)","abstract":"Ping the WebSocket periodically.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP4pingyyF":{"name":"ping()","abstract":"Ping the WebSocket once.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP10disconnect9closeCodey7Network010NWProtocolcB0C05CloseG0O_tF":{"name":"disconnect(closeCode:)","abstract":"Disconnect from the WebSocket.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP8delegateAA0cbD8Delegate_pSgvp":{"name":"delegate","abstract":"The WebSocket connection delegate.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html":{"name":"WebSocketConnection","abstract":"Defines a WebSocket connection.
"},"Protocols/WebSocketConnectionDelegate.html":{"name":"WebSocketConnectionDelegate","abstract":"Defines a delegate for a WebSocket connection.
"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC8delegateAA03WebB18ConnectionDelegate_pSgvp":{"name":"delegate","abstract":"The WebSocket connection delegate.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC14defaultOptions7Network013NWProtocolWebB0C0D0CvpZ":{"name":"defaultOptions","abstract":"The default NWProtocolWebSocket.Options
for a WebSocket connection.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC7request20connectAutomatically7options15connectionQueueAB10Foundation10URLRequestV_Sb7Network013NWProtocolWebB0C7OptionsCSo17OS_dispatch_queueCtcfc":{"name":"init(request:connectAutomatically:options:connectionQueue:)","abstract":"Creates a NWWebSocket
instance which connects to a socket url
with some configuration options
.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC3url20connectAutomatically7options15connectionQueueAB10Foundation3URLV_Sb7Network013NWProtocolWebB0C7OptionsCSo17OS_dispatch_queueCtcfc":{"name":"init(url:connectAutomatically:options:connectionQueue:)","abstract":"Creates a NWWebSocket
instance which connects a socket url
with some configuration options
.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC7connectyyF":{"name":"connect()","abstract":"Connect to the WebSocket.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC4send6stringySS_tF":{"name":"send(string:)","abstract":"Send a UTF-8 formatted String
over the WebSocket.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC4send4datay10Foundation4DataV_tF":{"name":"send(data:)","abstract":"Send some Data
over the WebSocket.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC6listenyyF":{"name":"listen()","abstract":"Start listening for messages over the WebSocket.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC4ping8intervalySd_tF":{"name":"ping(interval:)","abstract":"Ping the WebSocket periodically.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC4pingyyF":{"name":"ping()","abstract":"Ping the WebSocket once.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC10disconnect9closeCodey7Network013NWProtocolWebB0C05CloseE0O_tF":{"name":"disconnect(closeCode:)","abstract":"Disconnect from the WebSocket.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html":{"name":"NWWebSocket","abstract":"A WebSocket client that manages a socket connection.
"},"Classes.html":{"name":"Classes","abstract":"The following classes are available globally.
"},"Protocols.html":{"name":"Protocols","abstract":"The following protocols are available globally.
"}}
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/Documents/undocumented.json:
--------------------------------------------------------------------------------
1 | {
2 | "warnings": [
3 |
4 | ],
5 | "source_directory": "/Users/danielbrowne/Documents/Work/NWWebSocket"
6 | }
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.docset/Contents/Resources/docSet.dsidx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher/NWWebSocket/1e545fcb53966272fc042aa17ae932f11239e00f/docs/docsets/NWWebSocket.docset/Contents/Resources/docSet.dsidx
--------------------------------------------------------------------------------
/docs/docsets/NWWebSocket.tgz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher/NWWebSocket/1e545fcb53966272fc042aa17ae932f11239e00f/docs/docsets/NWWebSocket.tgz
--------------------------------------------------------------------------------
/docs/img/carat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher/NWWebSocket/1e545fcb53966272fc042aa17ae932f11239e00f/docs/img/carat.png
--------------------------------------------------------------------------------
/docs/img/dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher/NWWebSocket/1e545fcb53966272fc042aa17ae932f11239e00f/docs/img/dash.png
--------------------------------------------------------------------------------
/docs/img/gh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher/NWWebSocket/1e545fcb53966272fc042aa17ae932f11239e00f/docs/img/gh.png
--------------------------------------------------------------------------------
/docs/img/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pusher/NWWebSocket/1e545fcb53966272fc042aa17ae932f11239e00f/docs/img/spinner.gif
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | NWWebSocket Reference
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
28 |
29 |
30 | NWWebSocket Reference
31 |
32 | NWWebSocket Reference
33 |
34 |
35 |
36 |
59 |
60 |
61 |
62 |
63 | NWWebSocket
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | A WebSocket client written in Swift, using the Network framework from Apple.
76 |
77 |
86 |
87 |
88 |
89 | Swift 5.1 and above
90 | Xcode 11.0 and above
91 |
92 | Deployment targets
93 |
94 |
95 | iOS 13.0 and above
96 | macOS 10.15 and above
97 | tvOS 13.0 and above
98 | watchOS 6.0 and above
99 |
100 | Installation
101 | CocoaPods
102 |
103 | CocoaPods is a dependency manager for Cocoa projects.
104 |
105 | If you don’t already have the Cocoapods gem installed, run the following command:
106 | $ gem install cocoapods
107 |
108 |
109 | To integrate NWWebSocket into your Xcode project using CocoaPods, specify it in your Podfile
:
110 | source 'https://github.com/CocoaPods/Specs.git'
111 | platform :ios , '14.0'
112 | use_frameworks!
113 |
114 | pod 'NWWebSocket' , '~> 0.5.2'
115 |
116 |
117 | Then, run the following command:
118 | $ pod install
119 |
120 |
121 | If you find that you’re not having the most recent version installed when you run pod install
then try running:
122 | $ pod cache clean
123 | $ pod repo update NWWebSocket
124 | $ pod install
125 |
126 |
127 | Also you’ll need to make sure that you’ve not got the version of NWWebSocket locked to an old version in your Podfile.lock
file.
128 | Swift Package Manager
129 |
130 | To integrate the library into your project using Swift Package Manager , you can add the library as a dependency in Xcode – see the docs . The package repository URL is:
131 | https://github.com/pusher/NWWebSocket.git
132 |
133 |
134 | Alternatively, you can add the library as a dependency in your Package.swift
file. For example:
135 | // swift-tools-version:5.1
136 | import PackageDescription
137 |
138 | let package = Package (
139 | name : "YourPackage" ,
140 | products : [
141 | . library (
142 | name : "YourPackage" ,
143 | targets : [ "YourPackage" ]),
144 | ],
145 | dependencies : [
146 | . package ( url : "https://github.com/pusher/NWWebSocket.git" ,
147 | . upToNextMajor ( from : "0.5.2" )),
148 | ],
149 | targets : [
150 | . target (
151 | name : "YourPackage" ,
152 | dependencies : [ "NWWebSocket" ]),
153 | ]
154 | )
155 |
156 |
157 | You will then need to include both import Network
and import NWWebSocket
statements in any source files where you wish to use the library.
158 | Usage
159 |
160 | This section describes how to configure and use NWWebSocket to manage a WebSocket connection.
161 | Connection and disconnection
162 |
163 | Connection and disconnection is straightforward. Connecting to a WebSocket is manual by default, setting connectAutomatically
to true
makes connection automatic.
164 | Manual connection
165 | let socketURL = URL ( string : "wss://somewebsockethost.com" )
166 | let socket = NWWebSocket ( url : socketURL )
167 | socket . delegate = self
168 | socket . connect ()
169 |
170 | // Use the WebSocket…
171 |
172 | socket . disconnect ()
173 |
174 | Automatic connection
175 | let socketURL = URL ( string : "wss://somewebsockethost.com" )
176 | let socket = NWWebSocket ( url : socketURL , connectAutomatically : true )
177 | socket . delegate = self
178 |
179 | // Use the WebSocket…
180 |
181 | socket . disconnect ()
182 |
183 |
184 | NOTES:
185 |
186 |
189 | Sending data
190 |
191 | UTF-8 encoded strings or binary data can be sent over the WebSocket connection.
192 | // Sending a `String`
193 | let message = "Hello, world!"
194 | socket . send ( string : message )
195 |
196 | // Sending some binary data
197 | let data : [ UInt8 ] = [ 123 , 234 ]
198 | let messageData = Data ( data )
199 | socket . send ( data : messageData )
200 |
201 | Receiving messages and connection updates
202 |
203 | String or data messages (as well as connection state updates) can be received by making a type you define conform to WebSocketConnectionDelegate
. You can then respond to received messages or connection events accordingly.
204 | extension MyWebSocketConnectionManager : WebSocketConnectionDelegate {
205 |
206 | func webSocketDidConnect ( connection : WebSocketConnection ) {
207 | // Respond to a WebSocket connection event
208 | }
209 |
210 | func webSocketDidDisconnect ( connection : WebSocketConnection ,
211 | closeCode : NWProtocolWebSocket . CloseCode , reason : Data ?) {
212 | // Respond to a WebSocket disconnection event
213 | }
214 |
215 | func webSocketViabilityDidChange ( connection : WebSocketConnection , isViable : Bool ) {
216 | // Respond to a WebSocket connection viability change event
217 | }
218 |
219 | func webSocketDidAttemptBetterPathMigration ( result : Result < WebSocketConnection , NWError > ) {
220 | // Respond to when a WebSocket connection migrates to a better network path
221 | // (e.g. A device moves from a cellular connection to a Wi-Fi connection)
222 | }
223 |
224 | func webSocketDidReceiveError ( connection : WebSocketConnection , error : NWError ) {
225 | // Respond to a WebSocket error event
226 | }
227 |
228 | func webSocketDidReceivePong ( connection : WebSocketConnection ) {
229 | // Respond to a WebSocket connection receiving a Pong from the peer
230 | }
231 |
232 | func webSocketDidReceiveMessage ( connection : WebSocketConnection , string : String ) {
233 | // Respond to a WebSocket connection receiving a `String` message
234 | }
235 |
236 | func webSocketDidReceiveMessage ( connection : WebSocketConnection , data : Data ) {
237 | // Respond to a WebSocket connection receiving a binary `Data` message
238 | }
239 | }
240 |
241 | Ping and pong
242 |
243 | Triggering a Ping on an active WebSocket connection is a best practice method of telling the connected peer that the connection should be maintained. Pings can be triggered on-demand or periodically.
244 |
245 | // Trigger a Ping on demand
246 | socket . ping ()
247 |
248 | // Trigger a Ping periodically
249 | // (This is useful when messages are infrequently sent across the connection to prevent a connection closure)
250 | socket . ping ( interval : 30.0 )
251 |
252 | Documentation
253 |
254 | Full documentation of the library can be found in the API docs .
255 | Reporting bugs and requesting features
256 |
257 |
258 | If you have found a bug or have a feature request, please open an issue
259 | If you want to contribute, please submit a pull request (preferably with some tests 🙂 )
260 |
261 | Credits
262 |
263 | NWWebSocket is owned and maintained by Pusher . It was originally created by Daniel Browne .
264 |
265 | It uses code from the following repositories:
266 |
267 |
270 | License
271 |
272 | NWWebSocket is released under the MIT license. See LICENSE for details.
273 |
274 |
275 |
276 |
280 |
281 |
282 |
283 |
284 |
285 |
--------------------------------------------------------------------------------
/docs/js/jazzy.js:
--------------------------------------------------------------------------------
1 | window.jazzy = {'docset': false}
2 | if (typeof window.dash != 'undefined') {
3 | document.documentElement.className += ' dash'
4 | window.jazzy.docset = true
5 | }
6 | if (navigator.userAgent.match(/xcode/i)) {
7 | document.documentElement.className += ' xcode'
8 | window.jazzy.docset = true
9 | }
10 |
11 | function toggleItem($link, $content) {
12 | var animationDuration = 300;
13 | $link.toggleClass('token-open');
14 | $content.slideToggle(animationDuration);
15 | }
16 |
17 | function itemLinkToContent($link) {
18 | return $link.parent().parent().next();
19 | }
20 |
21 | // On doc load + hash-change, open any targetted item
22 | function openCurrentItemIfClosed() {
23 | if (window.jazzy.docset) {
24 | return;
25 | }
26 | var $link = $(`a[name="${location.hash.substring(1)}"]`).nextAll('.token');
27 | $content = itemLinkToContent($link);
28 | if ($content.is(':hidden')) {
29 | toggleItem($link, $content);
30 | }
31 | }
32 |
33 | $(openCurrentItemIfClosed);
34 | $(window).on('hashchange', openCurrentItemIfClosed);
35 |
36 | // On item link ('token') click, toggle its discussion
37 | $('.token').on('click', function(event) {
38 | if (window.jazzy.docset) {
39 | return;
40 | }
41 | var $link = $(this);
42 | toggleItem($link, itemLinkToContent($link));
43 |
44 | // Keeps the document from jumping to the hash.
45 | var href = $link.attr('href');
46 | if (history.pushState) {
47 | history.pushState({}, '', href);
48 | } else {
49 | location.hash = href;
50 | }
51 | event.preventDefault();
52 | });
53 |
54 | // Clicks on links to the current, closed, item need to open the item
55 | $("a:not('.token')").on('click', function() {
56 | if (location == this.href) {
57 | openCurrentItemIfClosed();
58 | }
59 | });
60 |
61 | // KaTeX rendering
62 | if ("katex" in window) {
63 | $($('.math').each( (_, element) => {
64 | katex.render(element.textContent, element, {
65 | displayMode: $(element).hasClass('m-block'),
66 | throwOnError: false,
67 | trust: true
68 | });
69 | }))
70 | }
71 |
--------------------------------------------------------------------------------
/docs/js/jazzy.search.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 | var $typeahead = $('[data-typeahead]');
3 | var $form = $typeahead.parents('form');
4 | var searchURL = $form.attr('action');
5 |
6 | function displayTemplate(result) {
7 | return result.name;
8 | }
9 |
10 | function suggestionTemplate(result) {
11 | var t = '';
12 | t += '' + result.name + ' ';
13 | if (result.parent_name) {
14 | t += '' + result.parent_name + ' ';
15 | }
16 | t += '
';
17 | return t;
18 | }
19 |
20 | $typeahead.one('focus', function() {
21 | $form.addClass('loading');
22 |
23 | $.getJSON(searchURL).then(function(searchData) {
24 | const searchIndex = lunr(function() {
25 | this.ref('url');
26 | this.field('name');
27 | this.field('abstract');
28 | for (const [url, doc] of Object.entries(searchData)) {
29 | this.add({url: url, name: doc.name, abstract: doc.abstract});
30 | }
31 | });
32 |
33 | $typeahead.typeahead(
34 | {
35 | highlight: true,
36 | minLength: 3,
37 | autoselect: true
38 | },
39 | {
40 | limit: 10,
41 | display: displayTemplate,
42 | templates: { suggestion: suggestionTemplate },
43 | source: function(query, sync) {
44 | const lcSearch = query.toLowerCase();
45 | const results = searchIndex.query(function(q) {
46 | q.term(lcSearch, { boost: 100 });
47 | q.term(lcSearch, {
48 | boost: 10,
49 | wildcard: lunr.Query.wildcard.TRAILING
50 | });
51 | }).map(function(result) {
52 | var doc = searchData[result.ref];
53 | doc.url = result.ref;
54 | return doc;
55 | });
56 | sync(results);
57 | }
58 | }
59 | );
60 | $form.removeClass('loading');
61 | $typeahead.trigger('focus');
62 | });
63 | });
64 |
65 | var baseURL = searchURL.slice(0, -"search.json".length);
66 |
67 | $typeahead.on('typeahead:select', function(e, result) {
68 | window.location = baseURL + result.url;
69 | });
70 | });
71 |
--------------------------------------------------------------------------------
/docs/search.json:
--------------------------------------------------------------------------------
1 | {"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB10DidConnect10connectionyAA0cbD0_p_tF":{"name":"webSocketDidConnect(connection:)","abstract":"Tells the delegate that the WebSocket did connect successfully.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB13DidDisconnect10connection9closeCode6reasonyAA0cbD0_p_7Network010NWProtocolcB0C05CloseK0O10Foundation4DataVSgtF":{"name":"webSocketDidDisconnect(connection:closeCode:reason:)","abstract":"Tells the delegate that the WebSocket did disconnect.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB18ViabilityDidChange10connection8isViableyAA0cbD0_p_SbtF":{"name":"webSocketViabilityDidChange(connection:isViable:)","abstract":"Tells the delegate that the WebSocket connection viability has changed.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB29DidAttemptBetterPathMigration6resultys6ResultOyAA0cbD0_p7Network7NWErrorOG_tF":{"name":"webSocketDidAttemptBetterPathMigration(result:)","abstract":"Tells the delegate that the WebSocket has attempted a migration based on a better network path becoming available.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB15DidReceiveError10connection5erroryAA0cbD0_p_7Network7NWErrorOtF":{"name":"webSocketDidReceiveError(connection:error:)","abstract":"Tells the delegate that the WebSocket received an error.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB14DidReceivePong10connectionyAA0cbD0_p_tF":{"name":"webSocketDidReceivePong(connection:)","abstract":"Tells the delegate that the WebSocket received a ‘pong’ from the server.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB17DidReceiveMessage10connection6stringyAA0cbD0_p_SStF":{"name":"webSocketDidReceiveMessage(connection:string:)","abstract":"Tells the delegate that the WebSocket received a String
message.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnectionDelegate.html#/s:11NWWebSocket03WebB18ConnectionDelegateP03webB17DidReceiveMessage10connection4datayAA0cbD0_p_10Foundation4DataVtF":{"name":"webSocketDidReceiveMessage(connection:data:)","abstract":"Tells the delegate that the WebSocket received a binary Data
message.
","parent_name":"WebSocketConnectionDelegate"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP7connectyyF":{"name":"connect()","abstract":"Connect to the WebSocket.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP4send6stringySS_tF":{"name":"send(string:)","abstract":"Send a UTF-8 formatted String
over the WebSocket.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP4send4datay10Foundation4DataV_tF":{"name":"send(data:)","abstract":"Send some Data
over the WebSocket.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP6listenyyF":{"name":"listen()","abstract":"Start listening for messages over the WebSocket.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP4ping8intervalySd_tF":{"name":"ping(interval:)","abstract":"Ping the WebSocket periodically.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP4pingyyF":{"name":"ping()","abstract":"Ping the WebSocket once.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP10disconnect9closeCodey7Network010NWProtocolcB0C05CloseG0O_tF":{"name":"disconnect(closeCode:)","abstract":"Disconnect from the WebSocket.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html#/s:11NWWebSocket03WebB10ConnectionP8delegateAA0cbD8Delegate_pSgvp":{"name":"delegate","abstract":"The WebSocket connection delegate.
","parent_name":"WebSocketConnection"},"Protocols/WebSocketConnection.html":{"name":"WebSocketConnection","abstract":"Defines a WebSocket connection.
"},"Protocols/WebSocketConnectionDelegate.html":{"name":"WebSocketConnectionDelegate","abstract":"Defines a delegate for a WebSocket connection.
"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC8delegateAA03WebB18ConnectionDelegate_pSgvp":{"name":"delegate","abstract":"The WebSocket connection delegate.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC14defaultOptions7Network013NWProtocolWebB0C0D0CvpZ":{"name":"defaultOptions","abstract":"The default NWProtocolWebSocket.Options
for a WebSocket connection.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC7request20connectAutomatically7options15connectionQueueAB10Foundation10URLRequestV_Sb7Network013NWProtocolWebB0C7OptionsCSo17OS_dispatch_queueCtcfc":{"name":"init(request:connectAutomatically:options:connectionQueue:)","abstract":"Creates a NWWebSocket
instance which connects to a socket url
with some configuration options
.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC3url20connectAutomatically7options15connectionQueueAB10Foundation3URLV_Sb7Network013NWProtocolWebB0C7OptionsCSo17OS_dispatch_queueCtcfc":{"name":"init(url:connectAutomatically:options:connectionQueue:)","abstract":"Creates a NWWebSocket
instance which connects a socket url
with some configuration options
.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC7connectyyF":{"name":"connect()","abstract":"Connect to the WebSocket.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC4send6stringySS_tF":{"name":"send(string:)","abstract":"Send a UTF-8 formatted String
over the WebSocket.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC4send4datay10Foundation4DataV_tF":{"name":"send(data:)","abstract":"Send some Data
over the WebSocket.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC6listenyyF":{"name":"listen()","abstract":"Start listening for messages over the WebSocket.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC4ping8intervalySd_tF":{"name":"ping(interval:)","abstract":"Ping the WebSocket periodically.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC4pingyyF":{"name":"ping()","abstract":"Ping the WebSocket once.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html#/s:11NWWebSocketAAC10disconnect9closeCodey7Network013NWProtocolWebB0C05CloseE0O_tF":{"name":"disconnect(closeCode:)","abstract":"Disconnect from the WebSocket.
","parent_name":"NWWebSocket"},"Classes/NWWebSocket.html":{"name":"NWWebSocket","abstract":"A WebSocket client that manages a socket connection.
"},"Classes.html":{"name":"Classes","abstract":"The following classes are available globally.
"},"Protocols.html":{"name":"Protocols","abstract":"The following protocols are available globally.
"}}
--------------------------------------------------------------------------------
/docs/undocumented.json:
--------------------------------------------------------------------------------
1 | {
2 | "warnings": [
3 |
4 | ],
5 | "source_directory": "/Users/danielbrowne/Documents/Work/NWWebSocket"
6 | }
--------------------------------------------------------------------------------