Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ECO-4915] Add documentation comments #165

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,59 @@ jobs:
- name: Build example app
run: swift run BuildTool build-example-app --platform ${{ matrix.platform }}

check-documentation:
runs-on: macos-15
umair-ably marked this conversation as resolved.
Show resolved Hide resolved

permissions:
deployments: write
id-token: write
contents: read

steps:
- uses: actions/checkout@v4
with:
submodules: true

# This step can be removed once the runners’ default version of Xcode is 16 or above
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16

# Dry run upload-action to get base-path url
- name: Dry-Run Upload (to get url)
id: preupload
uses: ably/sdk-upload-action@v2
with:
mode: preempt
sourcePath: .build/plugins/Swift-DocC/outputs/AblyChat.doccarchive # Path to the Swift DocC output folder
githubToken: ${{ secrets.GITHUB_TOKEN }}
artifactName: AblyChat

# Build the documentation using Swift DocC
- name: Build documentation
run: |
swift package generate-documentation --target AblyChat --disable-indexing \
--hosting-base-path "${{ steps.preupload.outputs.base-path }}" \
--transform-for-static-hosting
working-directory: ${{ github.workspace }}

# Configure AWS credentials for uploading documentation
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: eu-west-2
role-to-assume: arn:aws:iam::${{ secrets.ABLY_AWS_ACCOUNT_ID_SDK }}:role/ably-sdk-builds-ably-chat-swift
role-session-name: "${{ github.run_id }}-${{ github.run_number }}"

# Upload the generated documentation
- name: Upload Documentation
uses: ably/sdk-upload-action@v2
with:
sourcePath: .build/plugins/Swift-DocC/outputs/AblyChat.doccarchive # Path to the Swift DocC output folder
githubToken: ${{ secrets.GITHUB_TOKEN }}
artifactName: AblyChat # Optional root-level directory name
landingPagePath: documentation/ablychat

# We use this job as a marker that all of the required checks have completed.
# This allows us to configure a single required status check in our branch
# protection rules instead of having to type loads of different check names
Expand All @@ -193,6 +246,7 @@ jobs:
- build-and-test-xcode
- build-release-configuration-xcode
- check-example-app
- check-documentation

steps:
- name: No-op
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
docs-coverage-report
# End of .gitignore created by Swift Package Manager

/node_modules
Expand Down
20 changes: 19 additions & 1 deletion AblyChat.xcworkspace/xcshareddata/swiftpm/Package.resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "1d806168af5c6dfac34494fc5941d89fb9d4f96e4803f3a16742053db45c2b49",
"originHash" : "7cf5aad170e2009b8ed30136589be3e449ac79a630487eb65f95143b02db577f",
"pins" : [
{
"identity" : "ably-cocoa",
Expand Down Expand Up @@ -55,6 +55,24 @@
"version" : "1.1.2"
}
},
{
"identity" : "swift-docc-plugin",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-plugin",
"state" : {
"revision" : "85e4bb4e1cd62cec64a4b8e769dcefdf0c5b9d64",
"version" : "1.4.3"
}
},
{
"identity" : "swift-docc-symbolkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftlang/swift-docc-symbolkit",
"state" : {
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
"version" : "1.0.0"
}
},
{
"identity" : "table",
"kind" : "remoteSourceControl",
Expand Down
20 changes: 19 additions & 1 deletion Package.resolved
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "87bdf964454a6a566cd3557b1ae36935d1d19b6a8a8073b9fce67464d6593572",
"originHash" : "f5dd87027f1300f852cf86019686409a47c851bc11433a4138c8956b8a09ad6f",
"pins" : [
{
"identity" : "ably-cocoa",
Expand Down Expand Up @@ -55,6 +55,24 @@
"version" : "1.1.2"
}
},
{
"identity" : "swift-docc-plugin",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-docc-plugin",
"state" : {
"revision" : "85e4bb4e1cd62cec64a4b8e769dcefdf0c5b9d64",
"version" : "1.4.3"
}
},
{
"identity" : "swift-docc-symbolkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swiftlang/swift-docc-symbolkit",
"state" : {
"revision" : "b45d1f2ed151d057b54504d653e0da5552844e34",
"version" : "1.0.0"
}
},
{
"identity" : "table",
"kind" : "remoteSourceControl",
Expand Down
4 changes: 4 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ let package = Package(
url: "https://github.com/JanGorman/Table.git",
from: "1.1.1"
),
.package(
url: "https://github.com/apple/swift-docc-plugin",
from: "1.0.0"
),
],
targets: [
.target(
Expand Down
6 changes: 4 additions & 2 deletions Sources/AblyChat/BufferingPolicy.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Describes what to do with realtime events that come in faster than the consumer of an `AsyncSequence` can handle them.
// (This is the same as `AsyncStream<T>.Continuation.BufferingPolicy` but with the generic type parameter `T` removed.)
/**
* Describes what to do with realtime events that come in faster than the consumer of an `AsyncSequence` can handle them.
* (This is the same as `AsyncStream<T>.Continuation.BufferingPolicy` but with the generic type parameter `T` removed.)
*/
public enum BufferingPolicy: Sendable {
case unbounded
case bufferingOldest(Int)
Expand Down
54 changes: 54 additions & 0 deletions Sources/AblyChat/ChatClient.swift
Original file line number Diff line number Diff line change
@@ -1,15 +1,48 @@
import Ably

public protocol ChatClient: AnyObject, Sendable {
/**
* Returns the rooms object, which provides access to chat rooms.
*
* - Returns: The rooms object.
*/
var rooms: any Rooms { get }

/**
* Returns the underlying connection to Ably, which can be used to monitor the clients
* connection to Ably servers.
*
* - Returns: The connection object.
*/
var connection: any Connection { get }

/**
* Returns the clientId of the current client.
*
* - Returns: The clientId.
*/
var clientID: String { get }

/**
* Returns the underlying Ably Realtime client.
*
* - Returns: The Ably Realtime client.
*/
var realtime: RealtimeClient { get }

/**
* Returns the resolved client options for the client, including any defaults that have been set.
*
* - Returns: The client options.
*/
var clientOptions: ClientOptions { get }
}

public typealias RealtimeClient = any RealtimeClientProtocol

/**
* This is the core client for Ably chat. It provides access to chat rooms.
*/
public actor DefaultChatClient: ChatClient {
public let realtime: RealtimeClient
public nonisolated let clientOptions: ClientOptions
Expand All @@ -20,6 +53,13 @@ public actor DefaultChatClient: ChatClient {
// (CHA-CS4) The chat client must allow its connection status to be observed by clients.
public nonisolated let connection: any Connection

/**
* Constructor for Chat
*
* - Parameters:
* - realtime: The Ably Realtime client.
* - clientOptions: The client options.
*/
public init(realtime: RealtimeClient, clientOptions: ClientOptions?) {
self.realtime = realtime
self.clientOptions = clientOptions ?? .init()
Expand All @@ -34,8 +74,22 @@ public actor DefaultChatClient: ChatClient {
}
}

/**
* Configuration options for the chat client.
*/
public struct ClientOptions: Sendable {
/**
* A custom log handler that will be used to log messages from the client.
*
* By default, the client will log messages to the console.
*/
public var logHandler: LogHandler?

/**
* The minimum log level at which messages will be logged.
*
* By default, ``LogLevel/error`` will be used.
umair-ably marked this conversation as resolved.
Show resolved Hide resolved
*/
public var logLevel: LogLevel?

public init(logHandler: (any LogHandler)? = nil, logLevel: LogLevel? = nil) {
Expand Down
73 changes: 72 additions & 1 deletion Sources/AblyChat/Connection.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
import Ably

/**
* Represents a connection to Ably.
*/
public protocol Connection: AnyObject, Sendable {
/**
* The current status of the connection.
*/
var status: ConnectionStatus { get async }

// TODO: (https://github.com/ably-labs/ably-chat-swift/issues/12): consider how to avoid the need for an unwrap
/**
* The current error, if any, that caused the connection to enter the current status.
*/
var error: ARTErrorInfo? { get async }
maratal marked this conversation as resolved.
Show resolved Hide resolved

/**
* Subscribes a given listener to a connection status changes.
*
* - Parameters:
* - bufferingPolicy: The ``BufferingPolicy`` for the created subscription.
*
* - Returns: A subscription `AsyncSequence` that can be used to iterate through ``ConnectionStatusChange`` events.
*/
func onStatusChange(bufferingPolicy: BufferingPolicy) -> Subscription<ConnectionStatusChange>
/// Same as calling ``onStatusChange(bufferingPolicy:)`` with ``BufferingPolicy.unbounded``.

/// Same as calling ``onStatusChange(bufferingPolicy:)`` with ``BufferingPolicy/unbounded``.
///
/// The `Connection` protocol provides a default implementation of this method.
func onStatusChange() -> Subscription<ConnectionStatusChange>
Expand All @@ -17,18 +37,50 @@ public extension Connection {
}
}

/**
* The different states that the connection can be in through its lifecycle.
*/
public enum ConnectionStatus: Sendable {
// (CHA-CS1a) The INITIALIZED status is a default status when the realtime client is first initialized. This value will only (likely) be seen if the realtime client doesn’t have autoconnect turned on.

/**
* A temporary state for when the library is first initialized.
*/
case initialized

// (CHA-CS1b) The CONNECTING status is used when the client is in the process of connecting to Ably servers.

/**
* The library is currently connecting to Ably.
*/
case connecting

// (CHA-CS1c) The CONNECTED status is used when the client connected to Ably servers.

/**
* The library is currently connected to Ably.
*/
case connected

// (CHA-CS1d) The DISCONNECTED status is used when the client is not currently connected to Ably servers. This state may be temporary as the underlying Realtime SDK seeks to reconnect.

/**
* The library is currently disconnected from Ably, but will attempt to reconnect.
*/
case disconnected

// (CHA-CS1e) The SUSPENDED status is used when the client is in an extended state of disconnection, but will attempt to reconnect.

/**
* The library is in an extended state of disconnection, but will attempt to reconnect.
*/
case suspended

// (CHA-CS1f) The FAILED status is used when the client is disconnected from the Ably servers due to some non-retriable failure such as authentication failure. It will not attempt to reconnect.

/**
* The library is currently disconnected from Ably and will not attempt to reconnect.
*/
case failed

internal init(from realtimeConnectionState: ARTRealtimeConnectionState) {
Expand All @@ -51,11 +103,30 @@ public enum ConnectionStatus: Sendable {
}
}

/**
* Represents a change in the status of the connection.
*/
public struct ConnectionStatusChange: Sendable {
/**
* The new status of the connection.
*/
public var current: ConnectionStatus

/**
* The previous status of the connection.
*/
public var previous: ConnectionStatus

// TODO: (https://github.com/ably-labs/ably-chat-swift/issues/12): consider how to avoid the need for an unwrap
/**
* An error that provides a reason why the connection has
* entered the new status, if applicable.
*/
public var error: ARTErrorInfo?

/**
* The time in milliseconds that the client will wait before attempting to reconnect.
*/
public var retryIn: TimeInterval

public init(current: ConnectionStatus, previous: ConnectionStatus, error: ARTErrorInfo? = nil, retryIn: TimeInterval) {
Expand Down
4 changes: 2 additions & 2 deletions Sources/AblyChat/Dependencies.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ public protocol RealtimeClientProtocol: ARTRealtimeProtocol, Sendable {
var connection: Connection { get }
}

/// Expresses the requirements of the object returned by ``RealtimeClientProtocol.channels``.
/// Expresses the requirements of the object returned by ``RealtimeClientProtocol/channels``.
public protocol RealtimeChannelsProtocol: ARTRealtimeChannelsProtocol, Sendable {
associatedtype Channel: RealtimeChannelProtocol

// It’s not clear to me why ARTRealtimeChannelsProtocol doesn’t include this function (https://github.com/ably/ably-cocoa/issues/1968).
func get(_ name: String, options: ARTRealtimeChannelOptions) -> Channel
}

/// Expresses the requirements of the object returned by ``RealtimeChannelsProtocol.get(_:)``.
/// Expresses the requirements of the object returned by ``RealtimeChannelsProtocol/get(_:options:)``.
public protocol RealtimeChannelProtocol: ARTRealtimeChannelProtocol, Sendable {}

public protocol ConnectionProtocol: ARTConnectionProtocol, Sendable {}
Expand Down
Loading
Loading