Skip to content

Commit

Permalink
feat: add web socket article
Browse files Browse the repository at this point in the history
Resolves: none.
  • Loading branch information
loay-ashraf committed Jan 27, 2024
1 parent 06242ae commit b42bdec
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 61 deletions.
106 changes: 106 additions & 0 deletions Docs.docc/Articles/ConnectingToWebSocket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Connecting To WebSocket Server

Connect to a web socket server with **RxNetworkKit**

## Overview

In this article we will walk you through on how to connect to a web socket server and how to send/receive messages and data.

### Creating a http client

In this section, you will create a ``HTTPClient`` using a ``Session``.

- First, go to *ViewController.swift* file.

- Second, create a ``HTTPClient`` using a ``Session`` in the `viewDidLoad` method as done below:

```swift
import UIKit
import RxSwift
import RxNetworkKit

class ViewController: UIViewController {

let disposeBag: DisposeBag = .init()

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let sessionConfiguration = SessionConfiguration.default
let session = Session(configuration: sessionConfiguration)
let requestInterceptor = RequestInterceptor()
let httpClient = HTTPClient(session: session, requestInterceptor: requestInterceptor)
}

}
```

- Now, you are ready to connect to a web socket server.

### Connecting to a websocket server

In this section, you will create a ``WebSocket`` and send/receive messages and data to/from the server.

- First, call the `HTTPClient.websocket` method and pass the server url, protocols and close handler as arguments.

- Second, Subscribe to the output `Observable`s and call `WebSocket.connect` method as done below:


```swift
import UIKit
import RxSwift
import RxNetworkKit

class ViewController: UIViewController {

let disposeBag: DisposeBag = .init()

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let sessionConfiguration = SessionConfiguration.default
let session = Session(configuration: sessionConfiguration)
let requestInterceptor = RequestInterceptor()
let httpClient = HTTPClient(session: session, requestInterceptor: requestInterceptor)
// Replace with your web socket server url
let webSocket: WebSocket<Model> = httpClient.webSocket(URL(string: "wss://example")!,
["ts1"],
.init(code: { _ in .normalClosure },
reason: { _ in nil }))
webSocket.text
.subscribe(onNext: { text in
// print incoming text message
print(text)
})
.disposed(by: disposeBag)
webSocket.data
.subscribe(onNext: { model in
// dump incoming data
dump(model)
})
.disposed(by: disposeBag)
webSocket.error
.subscribe(onNext: { error in
// print error description (if any)
print(error.localizedDescription)
})
.disposed(by: disposeBag)
webSocket.connect()
}

}
```

- Optionally, you can send messages and data via the `WebSocket.send(_:)` method.

- That's it, you are connected to a web socket server and ready to send/receive messages and data.

- Tip: You can disconnect from the web socket server at any time by calling the `WebSocket.disconnect` method.

- Note: Connection to the web socket server is terminated when the ``WebSocket`` instance is deallocated.

- Warning: If you intend to make updates to the UI, you must use the `observe(on: MainScheduler.instance)` operator to avoid updating the UI on a background thread (which may lead to unexpected behavior or crashes).

## Conclusion

Now, you can use **RxNetworkKit** to connect to a web socket server.
7 changes: 3 additions & 4 deletions Docs.docc/Articles/MakingDownloadRequest.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Make download requests with **RxNetworkKit**

## Overview

In this article, we will walk you through on how to add a ``HTTPDownloadRequestRouter`` and use it with ``HTTPClient`` to make download requests.
In this article, we will walk you through on how to make download requests.

### Adding a download request router

Expand Down Expand Up @@ -83,7 +83,6 @@ class ViewController: UIViewController {
let sessionConfiguration = SessionConfiguration.default
let session = Session(configuration: sessionConfiguration)
let requestInterceptor = RequestInterceptor()
let restClient = RESTClient(session: session, requestInterceptor: requestInterceptor)
let httpClient = HTTPClient(session: session, requestInterceptor: requestInterceptor)
// Replace with your download url
let downloadRequestRouter = DownloadRequestRouter.default(url: URL(string: "https://example.com/image/2435454.png")!)
Expand All @@ -103,7 +102,7 @@ class ViewController: UIViewController {
print(error.localizedDescription)
})
.disposed(by: disposeBag)
}
}

}
```
Expand All @@ -114,7 +113,7 @@ class ViewController: UIViewController {

- Note: If you choose to save the downloaded file to the disk, you will receive the `completed` download event instead of the `completedWithData` download event.

- Warning: If you intend to make updates to the UI, you must use the `observe(on: MainScheduler.instance)` operator to avoid updating the UI on a background thread (which may lead to an unexpected behavior or a crash).
- Warning: If you intend to make updates to the UI, you must use the `observe(on: MainScheduler.instance)` operator to avoid updating the UI on a background thread (which may lead to unexpected behavior or crashes).

## Conclusion

Expand Down
4 changes: 2 additions & 2 deletions Docs.docc/Articles/MakingFirstRequest.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Make your first request with **RxNetworkKit**

## Overview

In this article, we will walk you through on how to add a ``HTTPRequestRouter`` and use it with ``RESTClient`` to make a request.
In this article, we will walk you through on how to make a request.

### Adding a request router

Expand Down Expand Up @@ -138,7 +138,7 @@ class ViewController: UIViewController {

- Note: It is best to apply an architectural pattern (like MVVM, MVP, VIPER, etc.) rather than making requests in the `ViewController` directly, but that is not done in the above example for the sake of simplicity.

- Warning: If you intend to make updates to the UI, you must use the `observe(on: MainScheduler.instance)` operator to avoid updating the UI on a background thread (which may lead to an unexpected behavior or a crash).
- Warning: If you intend to make updates to the UI, you must use the `observe(on: MainScheduler.instance)` operator to avoid updating the UI on a background thread (which may lead to unexpected behavior or crashes).

## Conclusion

Expand Down
9 changes: 4 additions & 5 deletions Docs.docc/Articles/MakingMultipartFormUploadRequest.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Make multipart form upload requests with **RxNetworkKit**

## Overview

In this article, we will walk you through on how to add a ``HTTPUploadRequestRouter`` and use it with ``HTTPClient`` to make multipart form upload requests.
In this article, we will walk you through on how to make multipart form upload requests.

### Adding an upload request router

Expand Down Expand Up @@ -60,7 +60,7 @@ enum UploadRequestRouter: HTTPUploadRequestRouter {

In this section, you will create a ``HTTPClient`` and use the ``HTTPUploadRequestRouter`` you created in the previous section with it to make a upload request.

- First, go to *ViewController.swift* file and create a ``HTTPClient`` using a ``Session`` in the `viewDidLoad` method
- First, go to *ViewController.swift* file and create a ``HTTPClient`` using a ``Session`` in the `viewDidLoad` method.

- Second, Create an `UploadRequestRouter`, a one ore more file `Data`, a one or more ``HTTPUploadRequestFile`` and a ``HTTPUploadRequestFormData``.

Expand All @@ -83,7 +83,6 @@ class ViewController: UIViewController {
let sessionConfiguration = SessionConfiguration.default
let session = Session(configuration: sessionConfiguration)
let requestInterceptor = RequestInterceptor()
let restClient = RESTClient(session: session, requestInterceptor: requestInterceptor)
let httpClient = HTTPClient(session: session, requestInterceptor: requestInterceptor)
// Replace with your upload url
let uploadRequestRouter = UploadRequestRouter.default(url: URL(string: "https://example.com/upload/multi")!)
Expand All @@ -107,7 +106,7 @@ class ViewController: UIViewController {
print(error.localizedDescription)
})
.disposed(by: disposeBag)
}
}

}
```
Expand All @@ -120,7 +119,7 @@ class ViewController: UIViewController {

- Note: You can specify additional text fields for the multipart from data through the `parameters` parameter.

- Warning: If you intend to make updates to the UI, you must use the `observe(on: MainScheduler.instance)` operator to avoid updating the UI on a background thread (which may lead to an unexpected behavior or a crash).
- Warning: If you intend to make updates to the UI, you must use the `observe(on: MainScheduler.instance)` operator to avoid updating the UI on a background thread (which may lead to unexpected behavior or crashes).

## Conclusion

Expand Down
7 changes: 3 additions & 4 deletions Docs.docc/Articles/MakingUploadRequest.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Make upload requests with **RxNetworkKit**

## Overview

In this article, we will walk you through on how to add a ``HTTPUploadRequestRouter`` and use it with ``HTTPClient`` to make upload requests.
In this article, we will walk you through on how to make upload requests.

### Adding an upload request router

Expand Down Expand Up @@ -83,7 +83,6 @@ class ViewController: UIViewController {
let sessionConfiguration = SessionConfiguration.default
let session = Session(configuration: sessionConfiguration)
let requestInterceptor = RequestInterceptor()
let restClient = RESTClient(session: session, requestInterceptor: requestInterceptor)
let httpClient = HTTPClient(session: session, requestInterceptor: requestInterceptor)
// Replace with your upload url
let uploadRequestRouter = UploadRequestRouter.default(url: URL(string: "https://example.com/upload")!)
Expand All @@ -104,7 +103,7 @@ class ViewController: UIViewController {
print(error.localizedDescription)
})
.disposed(by: disposeBag)
}
}

}
```
Expand All @@ -115,7 +114,7 @@ class ViewController: UIViewController {

- Note: If you choose to upload a file from the disk, you don't have to specify the file name as it will be extracted from the provided file url.

- Warning: If you intend to make updates to the UI, you must use the `observe(on: MainScheduler.instance)` operator to avoid updating the UI on a background thread (which may lead to an unexpected behavior or a crash).
- Warning: If you intend to make updates to the UI, you must use the `observe(on: MainScheduler.instance)` operator to avoid updating the UI on a background thread (which may lead to unexpected behavior or crashes).

## Conclusion

Expand Down
1 change: 1 addition & 0 deletions Docs.docc/Pages/RxNetworkKit.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ RxNetworkKit is a generic reactive networking framework that leverages the stabi
- <doc:MakingDownloadRequest>
- <doc:MakingUploadRequest>
- <doc:MakingMultipartFormUploadRequest>
- <doc:ConnectingToWebSocket>

### Foundation

Expand Down
21 changes: 0 additions & 21 deletions Examples/iOS/iOS Example/Controller/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,6 @@ class ViewController: UIViewController {
let restClient = RESTClient(session: session, requestInterceptor: requestInterceptor)
let httpClient = HTTPClient(session: session, requestInterceptor: requestInterceptor)
viewModel = .init(restClient: restClient, httpClient: httpClient)
let uploadRequestRouter = UploadRequestRouter.default(url: URL(string: "https://example.com/upload/multi")!)
let file1Data = "Example file 1".data(using: .utf8)!
let file2Data = "Example file 2".data(using: .utf8)!
let file1 = HTTPUploadRequestFile(forKey: "file1", withName: "example1.txt", withData: file1Data)!
let file2 = HTTPUploadRequestFile(forKey: "file2", withName: "example2.txt", withData: file1Data)!
let formData = HTTPUploadRequestFormData(parameters: [:], files: [file1, file2])
httpClient.upload(uploadRequestRouter, formData)
.subscribe(onNext: { (event: HTTPUploadRequestEvent<Model>) in
switch event {
case .progress(let progress):
// print upload progress
print("Uploading: \(progress.fractionCompleted)%")
case .completed(let model):
// dump the received response body
dump(model)
}
}, onError: { error in
// print the error description (if any)
print(error.localizedDescription)
})
.disposed(by: disposeBag)
}
/// Sets up views.
private func setupUI() {
Expand Down
25 changes: 0 additions & 25 deletions Shared/CoreExample/Source/Network/DownloadRequestRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,3 @@ public enum DownloadRequestRouter: HTTPDownloadRequestRouter {
}
}
}

public enum UploadRequestRouter: HTTPUploadRequestRouter {
case `default`(url: URL)
public var scheme: HTTPScheme {
.https
}
public var domain: String {
""
}
public var path: String {
""
}
public var headers: [String : String] {
[:]
}
public var parameters: [String : String]? {
nil
}
public var url: URL? {
switch self {
case .default(let url):
return url
}
}
}

0 comments on commit b42bdec

Please sign in to comment.