Skip to content

Commit

Permalink
v0.2.0 (#59)
Browse files Browse the repository at this point in the history
* feat: add decoding capability in case of failure caused due to HTTP status code

Resolves: none.

* feat: override User-Agent HTTP header in session configuration (#26)

Resolves: none.

* Add macOS example (#27)

* feat: move iOS example project into new sub folder

Resolves: none.

* fix: update framework search paths

Resolves: none.

* feat: add empt macOS example project to workspace

Resolves: none.

* fix: update framework scheme name

Resolves: none.

* feat: add files to macOS example directory

Resolves: none.

* fix: apply public access modifier to DefaultHTTPErrorBody and DefaultNetworkAPIError

Resolves: none.

* refactor: add description comment for ProcessInfo extension

Resolves: none.

* fix: add RxNetworkKit bridging header reference

Resolves: none.

* refactor: apply project recommended settings

Resolves: none.

* feat: connect viewModel to tableview UI

Resolves: none.

* feat: complete ViewController class in macOS Example

Resolves: none.

* refactor: remove old un-needed file

Resolves: none.

* fix: apply correct image scale for error view

Resolves: none.

* Apply new version (0.0.2) (#28)

* fix: remove tinted button warning

Resolves: none.

* version: 0.0.2

Resolves: none.

* fix: update version for podSpec file

Resolves: none.

* fix: remove RxDataSources import statement (#31)

Resolves: none.

* Add CI Workflows For Repository (#33)

* feat: add iOS workflow

Resolves: none.

* fix: update build-ios.yml

Resolves: none.

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Create build-macos.yml

* Update build-ios.yml + build-macos.yml

* fix error 65

* Update build-ios.yml

* update build-ios.yml + build-macos.yml

* Update build-macos.yml

* Update project.pbxproj

* add publish-podspec.yml

* add workflow files outside of folders

* Update publish-podspec.yml

* Update publish-podspec.yml

* Update publish-podspec.yml

* Create pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* test container workflow

* Update build.yml

* Update build.yml

* add some changes

* Update build.yml

* add some changes

* Update build.yml

* refactor: update names + remove comments

Resolves: none.

* add trigger for trunk push workflow

* add dummy project to test SPM integration

* add spm-lint.yml

* Update spm-lint.yml

* Update spm-lint.yml

* Update spm-lint.yml

* Update spm-lint.yml

* update dummy project

* update workspace dependencies versions

* Update CI Workflows

* update CI workflows

* Update CI Workflow

* Update Dependency Version Rules (#45)

* fix: update version rules for SPM to upToNextMajor

Resolves: none.

* fix: update version rule for SPM in iOS Example project

Resolves: none.

* fix: update version rules for cocoapods in podspec file

Resolves: none.

* feat: add WebSocket capability to NetworkManager (#46)

Resolves: none.

* fix a typo

* update dependencies versions

Resolves: none.

* update Package.swift + podspec file

* change xcode version used in CI/CD to 14.3.1

Resolves: none.

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update build.yml

* Update build.yml

* update workflow files

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-trunk-push.yml

* Update spm-lint.yml

* Update build-macos.yml

* update Xcode version to 15.0.0 for CI workflows

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* Update pod-lib-lint.yml

* break: drop support for Cocoapods (cannot work with Xcode 15)

Resolves: none.

* [49][DocC][Update Documentation] (#50)

* feat: update overview for classes, structs, enums, typaliases and protocols

Resolves: none.

* feat: add docs catalog

Resolves: none.

* update CI workflows to build docs

Resolves: none.

* update CI workflows

Resolves: none.

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* Update build-ios.yml

* fix: update corrupt ci workflow file

Resolves: none.

* Delete build-deploy-docs1.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* update CI workflows

* Update build.yml

* Update build-ios.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update build-deploy-docs.yml

* Update websocket error handling (#58)

* feature: bind send and ping errors to the error relay in WebSocket object

Resolves: none.

* fix: capture weak reference to self to avoid retain cycle in example viewModel

Resolves: none.

* feat: add WebSocketError

Resolves: none.

* Update NetworkManager.md
  • Loading branch information
loay-ashraf committed Oct 10, 2023
1 parent 37c4812 commit b09471f
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 20 deletions.
29 changes: 25 additions & 4 deletions .github/workflows/build-deploy-docs.yml
Expand Up @@ -10,8 +10,8 @@ permissions:
id-token: write

jobs:
build-deploy-docs:
name: Build and Deploy Docs
build-docs:
name: Build Docs
runs-on: macos-13

steps:
Expand All @@ -27,11 +27,32 @@ jobs:
scheme: RxNetworkKit
run: |
xcodebuild docbuild -workspace "${workspace}" -scheme "${scheme}" -derivedDataPath derivedData | xcpretty
- name: Perpare Docs for Deployment
run: |
mkdir docArchives
cp -R `find derivedData -type d -name "*.doccarchive"` docArchives
zip -r RxNetworkKitDocCArchive.zip docArchives/RxNetworkKit.doccarchive
- name: Upload Docs Archive
uses: actions/upload-artifact@v3
with:
name: doc-archive-zip
path: RxNetworkKitDocCArchive.zip

deploy-docs:
name: Deploy Docs
runs-on: macos-13
needs: build-docs

steps:
- name: Checkout
uses: actions/checkout@v3
- name: Download Docs Archive
uses: actions/download-artifact@v3
with:
name: doc-archive-zip
- name: Perpare Docs for Deployment
run: |
unzip RxNetworkKitDocCArchive.zip
$(xcrun --find docc) process-archive transform-for-static-hosting docArchives/RxNetworkKit.doccarchive --hosting-base-path RxNetworkKit --output-path docs
echo "<script>window.location.href += \"/documentation/rxnetworkkit\"</script>" > docs/index.html;
- name: Upload Docs artifact
uses: actions/upload-pages-artifact@v1
with:
Expand Down
1 change: 1 addition & 0 deletions Docs.docc/Pages/NetworkManager.md
Expand Up @@ -34,4 +34,5 @@
- ``WebSocketMessage``
- ``WebSocketCloseCode``
- ``WebSocketCloseHandler``
- ``WebSocketError``
- ``NetworkManager/webSocket(_:_:_:)``
3 changes: 2 additions & 1 deletion Examples/iOS/iOS Example/View Model/ViewModel.swift
Expand Up @@ -40,7 +40,8 @@ class ViewModel {
// Create default sequence with default API call request.
let loadObservable = viewState
.filter( { ![.idle, .loading(loadType: .paginate), .error].contains($0) })
.flatMapLatest{ _ in
.flatMapLatest{ [weak self] _ in
guard let self = self else { return Observable<[Model]>.empty().materialize() }
let single: Single<[Model]> = self.networkManager.request(Router.default)
return single
.asObservable()
Expand Down
3 changes: 2 additions & 1 deletion Examples/macOS/macOS Example/View Model/ViewModel.swift
Expand Up @@ -40,7 +40,8 @@ class ViewModel {
// Create default sequence with default API call request.
let loadObservable = viewState
.filter( { ![.idle, .loading(loadType: .paginate), .error].contains($0) })
.flatMapLatest{ _ in
.flatMapLatest{ [weak self] _ in
guard let self = self else { return Observable<[Model]>.empty().materialize() }
let single: Single<[Model]> = self.networkManager.request(Router.default)
return single
.asObservable()
Expand Down
4 changes: 4 additions & 0 deletions RxNetworkKit.xcodeproj/project.pbxproj
Expand Up @@ -63,6 +63,7 @@
C6A9BEFA2A93F16200459E32 /* URLSessionConfiguration+setAdditionalHTTPHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A9BEF92A93F16200459E32 /* URLSessionConfiguration+setAdditionalHTTPHeader.swift */; };
C6A9BEFD2A93FAF100459E32 /* URLSessionConfiguration+setUserAgentHTTPHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A9BEFC2A93FAF100459E32 /* URLSessionConfiguration+setUserAgentHTTPHeader.swift */; };
C6A9BEFF2A93FB1D00459E32 /* ProcessInfo+operatingSystemName.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A9BEFE2A93FB1D00459E32 /* ProcessInfo+operatingSystemName.swift */; };
C6B4B4C42AD47A2F009073ED /* WebSocketError.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B4B4C32AD47A2F009073ED /* WebSocketError.swift */; };
C6BDFFE82ACDF3830022F675 /* Reactive+receive.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6BDFFE72ACDF3830022F675 /* Reactive+receive.swift */; };
C6BDFFEA2ACDF3D90022F675 /* Reactive+send.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6BDFFE92ACDF3D90022F675 /* Reactive+send.swift */; };
C6BDFFEC2ACDF4100022F675 /* Reactive+ping.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6BDFFEB2ACDF4100022F675 /* Reactive+ping.swift */; };
Expand Down Expand Up @@ -127,6 +128,7 @@
C6A9BEF92A93F16200459E32 /* URLSessionConfiguration+setAdditionalHTTPHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLSessionConfiguration+setAdditionalHTTPHeader.swift"; sourceTree = "<group>"; };
C6A9BEFC2A93FAF100459E32 /* URLSessionConfiguration+setUserAgentHTTPHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URLSessionConfiguration+setUserAgentHTTPHeader.swift"; sourceTree = "<group>"; };
C6A9BEFE2A93FB1D00459E32 /* ProcessInfo+operatingSystemName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProcessInfo+operatingSystemName.swift"; sourceTree = "<group>"; };
C6B4B4C32AD47A2F009073ED /* WebSocketError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSocketError.swift; sourceTree = "<group>"; };
C6BDFFE72ACDF3830022F675 /* Reactive+receive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Reactive+receive.swift"; sourceTree = "<group>"; };
C6BDFFE92ACDF3D90022F675 /* Reactive+send.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Reactive+send.swift"; sourceTree = "<group>"; };
C6BDFFEB2ACDF4100022F675 /* Reactive+ping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Reactive+ping.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -364,6 +366,7 @@
C6BDFFEF2ACDF4AB0022F675 /* WebSocketCloseHandler.swift */,
C6BDFFF22ACDF50F0022F675 /* WebSocketMessage.swift */,
C6BDFFF42ACDF5250022F675 /* WebSocketCloseCode.swift */,
C6B4B4C32AD47A2F009073ED /* WebSocketError.swift */,
);
path = "Web Socket";
sourceTree = "<group>";
Expand Down Expand Up @@ -498,6 +501,7 @@
0B77E09129D965D30077FBC0 /* Reactive+URLSessionAdaptedUploadResponse.swift in Sources */,
C6A9BEFA2A93F16200459E32 /* URLSessionConfiguration+setAdditionalHTTPHeader.swift in Sources */,
C6BDFFF32ACDF5100022F675 /* WebSocketMessage.swift in Sources */,
C6B4B4C42AD47A2F009073ED /* WebSocketError.swift in Sources */,
0B77E0A629D965D30077FBC0 /* DefaultNetworkAPIError.swift in Sources */,
0B77E0A429D965D30077FBC0 /* NetworkReachability.swift in Sources */,
0B77E0B229D965D30077FBC0 /* Completable+Retry.swift in Sources */,
Expand Down
4 changes: 3 additions & 1 deletion Source/Web Socket/Extensions/Reactive+ping.swift
Expand Up @@ -9,6 +9,7 @@ import Foundation
import RxSwift

extension Reactive where Base: URLSessionWebSocketTask {

/// Sends a ping to the websocket server.
///
/// - Returns: `Completable` observable encapsulating send ping operation.
Expand All @@ -19,9 +20,10 @@ extension Reactive where Base: URLSessionWebSocketTask {
subscription(.completed)
return
}
subscription(.error(error))
subscription(.error(WebSocketError.ping(error: error)))
}
return Disposables.create()
}
}

}
7 changes: 2 additions & 5 deletions Source/Web Socket/Extensions/Reactive+receive.swift
Expand Up @@ -23,16 +23,13 @@ extension Reactive where Base: URLSessionWebSocketTask {
subscription.onNext(message)
receive(subscription: subscription)
case .failure(let error):
subscription.onError(error)
subscription.onError(WebSocketError.receive(error: error))
}
}
}
return Observable<WebSocketMessage>.create { subscription in
receive(subscription: subscription)
return Disposables.create {
let request = base.currentRequest
base.cancel(with: closeHandler.code(for: request), reason: closeHandler.reason(for: request))
}
return Disposables.create()
}
.share()
}
Expand Down
4 changes: 3 additions & 1 deletion Source/Web Socket/Extensions/Reactive+send.swift
Expand Up @@ -9,6 +9,7 @@ import Foundation
import RxSwift

extension Reactive where Base: URLSessionWebSocketTask {

/// Sends message to the websocket server.
///
/// - Parameter message: `WebSocketMessage` to be sent to websocket server.
Expand All @@ -21,9 +22,10 @@ extension Reactive where Base: URLSessionWebSocketTask {
subscription(.completed)
return
}
subscription(.error(error))
subscription(.error(WebSocketError.send(error: error)))
}
return Disposables.create()
}
}

}
26 changes: 19 additions & 7 deletions Source/Web Socket/WebSocket.swift
Expand Up @@ -17,7 +17,7 @@ public class WebSocket<T: Decodable> {
/// a generic `PublishRelay` object for data messages received from websocket server.
public let data: PublishRelay<T> = .init()
/// a `PublishRelay` object for errors encountered while receiving/sending from/to websocket server.
public let error: PublishRelay<Error> = .init()
public let error: PublishRelay<WebSocketError> = .init()
private let task: URLSessionWebSocketTask
private let closeHandler: WebSocketCloseHandler
private let receiveObservable: Observable<WebSocketMessage>
Expand All @@ -35,6 +35,11 @@ public class WebSocket<T: Decodable> {
setupBindings()
}

/// Destroys current `WebSocket` instance and cancels current task.
deinit {
disconnect()
}

/// Resumes current task to establish the connection.
public func connect() {
task.resume()
Expand All @@ -49,17 +54,23 @@ public class WebSocket<T: Decodable> {
/// Sends message to the websocket server.
///
/// - Parameter message: `WebSocketMessage` to be sent to websocket server.
///
/// - Returns: `Completable` observable encapsulating send message operation.
public func send(_ message: WebSocketMessage) -> Completable {
public func send(_ message: WebSocketMessage) {
task.rx.send(message: message)
.subscribe(onError: { error in
guard let error = error as? WebSocketError else { return }
self.error.accept(error)
})
.disposed(by: disposeBag)
}

/// Sends a ping to the websocket server.
///
/// - Returns: `Completable` observable encapsulating send ping operation.
public func ping() -> Completable {
public func ping() {
task.rx.ping()
.subscribe(onError: { error in
guard let error = error as? WebSocketError else { return }
self.error.accept(error)
})
.disposed(by: disposeBag)
}

/// Sets up internal observable bindings.
Expand Down Expand Up @@ -92,6 +103,7 @@ public class WebSocket<T: Decodable> {
.materialize()
.compactMap({
guard case .error(let error) = $0 else { return nil }
guard let error = error as? WebSocketError else { return nil }
return error
})
.bind(to: error)
Expand Down
15 changes: 15 additions & 0 deletions Source/Web Socket/WebSocketError.swift
@@ -0,0 +1,15 @@
//
// WebSocketError.swift
// RxNetworkKit
//
// Created by Loay Ashraf on 09/10/2023.
//

import Foundation

/// An enumeration that contains cases where error is received from websocket.
public enum WebSocketError: Error {
case receive(error: Error)
case send(error: Error)
case ping(error: Error)
}

0 comments on commit b09471f

Please sign in to comment.