Skip to content

Commit

Permalink
Make interface for enqueueing with multiple queue
Browse files Browse the repository at this point in the history
These changes will allow integrators fetching available
queues without the needs to configure SDK with specific
queue id.

Deprecated:
- Interface for configuration SDK with queue ID

Introduced:
- Configuration method without queue id
- Starting engagement with queue ids

MOB-2594
  • Loading branch information
yurii-glia committed Sep 13, 2023
1 parent 7f72567 commit 2ec4a2e
Show file tree
Hide file tree
Showing 24 changed files with 170 additions and 127 deletions.
62 changes: 15 additions & 47 deletions GliaWidgets/Public/Glia/Glia+StartEngagement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ extension Glia {
///
/// - Parameters:
/// - engagementKind: Engagement media type.
/// - in: Queue identifiers
/// - theme: A custom theme to use with the engagement.
/// - visitorContext: Visitor context.
/// - features: Set of features to be enabled in the SDK.
Expand All @@ -22,17 +23,29 @@ extension Glia {
///
public func startEngagement(
engagementKind: EngagementKind,
in queueIds: [String],
theme: Theme = Theme(),
features: Features = .all,
sceneProvider: SceneProvider? = nil
) throws {
// `interactor?.queueIds.isEmpty == false` statement is needed for integrators who uses old interface
// and pass queue identifier through `configuration` function.
guard !queueIds.isEmpty || interactor?.queueIds.isEmpty == false else { throw GliaError.startingEngagementWithNoQueueIdsIsNotAllowed }
guard engagement == .none else { throw GliaError.engagementExists }
guard let interactor = self.interactor else { throw GliaError.sdkIsNotConfigured }
if let engagement = environment.coreSdk.getCurrentEngagement(),
engagement.source == .callVisualizer {
throw GliaError.callVisualizerEngagementExists
}

// This check is needed for integrators who uses old interface
// and pass queue identifier through `configuration` function,
// but would not pass queue ids in this method, so SDK would not override
// existed queue id.
if !queueIds.isEmpty {
interactor.queueIds = queueIds
}

let viewFactory = ViewFactory(
with: theme,
messageRenderer: messageRenderer,
Expand All @@ -46,6 +59,7 @@ extension Glia {
uiScreen: environment.uiScreen
)
)

startRootCoordinator(
with: interactor,
viewFactory: viewFactory,
Expand All @@ -55,53 +69,7 @@ extension Glia {
)
}

/// Starts the engagement.
///
/// - Parameters:
/// - engagementKind: Engagement media type.
/// - configuration: Engagement configuration.
/// - queueID: Queue identifier.
/// - theme: A custom theme to use with the engagement.
/// - sceneProvider: Used to provide `UIWindowScene` to the framework. Defaults to the first active foreground scene.
///
/// - throws:
/// - `GliaCoreSDK.ConfigurationError.invalidSite`
/// - `GliaCoreSDK.ConfigurationError.invalidEnvironment`
/// - `GliaCoreSDK.ConfigurationError.invalidRegionEndpoint`
/// - `GliaCoreSDK.ConfigurationError.invalidSiteApiKey`
/// - `GliaError.engagementExists`
///
public func start(
_ engagementKind: EngagementKind,
configuration: Configuration,
queueID: String,
theme: Theme = Theme(),
features: Features = .all,
sceneProvider: SceneProvider? = nil
) throws {
let completion = { [weak self] in
try self?.startEngagement(
engagementKind: engagementKind,
theme: theme,
features: features,
sceneProvider: sceneProvider
)
}
do {
try configure(
with: configuration,
queueId: queueID
) {
try? completion()
}
} catch GliaError.configuringDuringEngagementIsNotAllowed {
try completion()
}
}

// MARK: - Private

private func startRootCoordinator(
func startRootCoordinator(
with interactor: Interactor,
viewFactory: ViewFactory,
sceneProvider: SceneProvider?,
Expand Down
92 changes: 92 additions & 0 deletions GliaWidgets/Public/Glia/Glia.Deprecated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,98 @@ extension Glia {
public func requestVisitorCode(completion: @escaping (Result<VisitorCode, Swift.Error>) -> Void) {
_ = environment.coreSdk.requestVisitorCode(completion)
}

/// Deprecated, use ``Glia.configure(with:uiConfig:assetsBuilder:completion)`` instead.
@available(*, deprecated, message: "Deprecated, use ``Glia.configure(with:uiConfig:assetsBuilder:completion`` instead.")
public func configure(
with configuration: Configuration,
queueId: String,
uiConfig: RemoteConfiguration? = nil,
assetsBuilder: RemoteConfiguration.AssetsBuilder = .standard,
completion: (() -> Void)? = nil
) throws {
guard environment.coreSdk.getCurrentEngagement() == nil else {
throw GliaError.configuringDuringEngagementIsNotAllowed
}
self.uiConfig = uiConfig
self.assetsBuilder = assetsBuilder

let createdInteractor = Interactor(
configuration: configuration,
queueIds: [queueId],
environment: .init(coreSdk: environment.coreSdk, gcd: environment.gcd)
)

interactor = createdInteractor

if let callback = completion {
createdInteractor.withConfiguration { [weak createdInteractor] in
guard let interactor = createdInteractor else { return }
interactor.state = GliaCore.sharedInstance
.getCurrentEngagement()?.engagedOperator
.map(InteractorState.engaged) ?? interactor.state
callback()
}
}

startObservingInteractorEvents()
}

/// Deprecated, use ``Glia.startEngagement(engagementKind:in:theme:features:sceneProvider:)`` instead.
@available(*,
deprecated,
message: "Deprecated, use ``Glia.startEngagement(engagementKind:in:theme:features:sceneProvider:)`` instead."
)
public func startEngagement(
engagementKind: EngagementKind,
theme: Theme = Theme(),
features: Features = .all,
sceneProvider: SceneProvider? = nil
) throws {
try startEngagement(
engagementKind: engagementKind,
in: [],
theme: theme,
features: features,
sceneProvider: sceneProvider
)
}

/// Deprecated, use ``Deprecated, use ``Glia.configure(with:uiConfig:assetsBuilder:completion`` and ``Glia.startEngagement(engagementKind:in:theme:features:sceneProvider:)`` instead.`` instead.
@available(*,
deprecated,
message: """
Deprecated, use ``Glia.configure(with:uiConfig:assetsBuilder:completion`` and \
``Glia.startEngagement(engagementKind:in:theme:features:sceneProvider:)`` instead.
"""
)
public func start(
_ engagementKind: EngagementKind,
configuration: Configuration,
queueID: String,
theme: Theme = Theme(),
features: Features = .all,
sceneProvider: SceneProvider? = nil
) throws {
let completion = { [weak self] in
try self?.startEngagement(
engagementKind: engagementKind,
theme: theme,
features: features,
sceneProvider: sceneProvider
)
}
do {
try configure(
with: configuration,
queueId: queueID
) {
try? completion()
}
} catch GliaError.configuringDuringEngagementIsNotAllowed {
try completion()
}
}
}

extension Glia.Authentication {
Expand Down
8 changes: 3 additions & 5 deletions GliaWidgets/Public/Glia/Glia.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,13 @@ public class Glia {
/// Setup SDK using specific engagement configuration without starting the engagement.
/// - Parameters:
/// - configuration: Engagement configuration.
/// - queueId: Queue identifier.
/// - visitorContext: Visitor context.
/// - uiConfig: Remote UI configuration.
/// - assetsBuilder: Provides assets for remote configuration.
/// - completion: Optional completion handler that will be fired once configuration is complete.
/// Passing `nil` will defer configuration. Passing closure will start configuration immediately.
public func configure(
with configuration: Configuration,
queueId: String,
uiConfig: RemoteConfiguration? = nil,
assetsBuilder: RemoteConfiguration.AssetsBuilder = .standard,
completion: (() -> Void)? = nil
Expand All @@ -119,7 +117,7 @@ public class Glia {

let createdInteractor = Interactor(
configuration: configuration,
queueID: queueId,
queueIds: [],
environment: .init(coreSdk: environment.coreSdk, gcd: environment.gcd)
)

Expand Down Expand Up @@ -266,8 +264,8 @@ public class Glia {

// MARK: - Private

private extension Glia {
func startObservingInteractorEvents() {
extension Glia {
internal func startObservingInteractorEvents() {
interactor?.addObserver(self) { [weak self] event in
guard
let engagement = self?.environment.coreSdk.getCurrentEngagement(),
Expand Down
1 change: 1 addition & 0 deletions GliaWidgets/Public/GliaError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public enum GliaError: Error {
case callVisualizerEngagementExists
case configuringDuringEngagementIsNotAllowed
case clearingVisitorSessionDuringEngagementIsNotAllowed
case startingEngagementWithNoQueueIdsIsNotAllowed
}
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ extension EngagementCoordinator {
fetchChatHistory: environment.fetchChatHistory,
createFileUploadListModel: environment.createFileUploadListModel,
sendSecureMessagePayload: environment.sendSecureMessagePayload,
queueIds: [interactor.queueID],
queueIds: interactor.queueIds,
listQueues: environment.listQueues,
secureUploadFile: environment.uploadSecureFile,
getSecureUnreadMessageCount: environment.getSecureUnreadMessageCount,
Expand Down Expand Up @@ -439,7 +439,7 @@ extension EngagementCoordinator {
viewFactory: viewFactory,
navigationPresenter: navigationPresenter,
environment: .init(
queueIds: [interactor.queueID],
queueIds: interactor.queueIds,
listQueues: environment.listQueues,
sendSecureMessagePayload: environment.sendSecureMessagePayload,
createFileUploader: environment.createFileUploader,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,8 @@ struct CoreSdkClient {
var listQueues: ListQueues

typealias QueueForEngagement = (
_ queueID: String,
_ visitorContext: Self.VisitorContext?,
_ shouldCloseAllQueues: Bool,
_ mediaType: Self.MediaType,
_ options: Self.EngagementOptions?,
_ completion: @escaping Self.QueueTicketBlock
_ options: GliaCoreSDK.QueueForEngagementOptions,
_ completion: @escaping (Result<GliaCoreSDK.QueueTicket, GliaCoreSDK.GliaCoreError>) -> Void
) -> Void
var queueForEngagement: QueueForEngagement

Expand Down
12 changes: 10 additions & 2 deletions GliaWidgets/Sources/CoreSDKClient/CoreSDKClient.Live.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,16 @@ extension CoreSdkClient {
configureWithConfiguration: GliaCore.sharedInstance.configure(with:completion:),
configureWithInteractor: GliaCore.sharedInstance.configure(interactor:),
listQueues: GliaCore.sharedInstance.listQueues(completion:),
queueForEngagement: GliaCore.sharedInstance
.queueForEngagement(queueID:visitorContext:shouldCloseAllQueues:mediaType:options:completion:),
queueForEngagement: { options, completion in
let options = QueueForEngagementOptions(
queueIds: options.queueIds,
visitorContext: options.visitorContext,
shouldCloseAllQueues: options.shouldCloseAllQueues,
mediaType: options.mediaType,
engagementOptions: options.engagementOptions
)
GliaCore.sharedInstance.queueForEngagement(using: options, completion: completion)
},
requestMediaUpgradeWithOffer: GliaCore.sharedInstance.requestMediaUpgrade(offer:completion:),
sendMessagePreview: GliaCore.sharedInstance.sendMessagePreview(message:completion:),
sendMessageWithMessagePayload: GliaCore.sharedInstance.send(messagePayload:completion:),
Expand Down
2 changes: 1 addition & 1 deletion GliaWidgets/Sources/CoreSDKClient/CoreSDKClient.Mock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extension CoreSdkClient {
configureWithConfiguration: { _, _ in },
configureWithInteractor: { _ in },
listQueues: { _ in },
queueForEngagement: { _, _, _, _, _, _ in },
queueForEngagement: { _, _ in },
requestMediaUpgradeWithOffer: { _, _ in },
sendMessagePreview: { _, _ in },
sendMessageWithMessagePayload: { _, _ in },
Expand Down
4 changes: 2 additions & 2 deletions GliaWidgets/Sources/Interactor/Interactor.Mock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import Foundation
extension Interactor {
static func mock(
configuration: Configuration = .mock(),
queueID: String = UUID.mock.uuidString,
queueId: String = UUID.mock.uuidString,
environment: Environment = .mock
) -> Interactor {
.init(
configuration: configuration,
queueID: queueID,
queueIds: [queueId],
environment: environment
)
}
Expand Down
29 changes: 16 additions & 13 deletions GliaWidgets/Sources/Interactor/Interactor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ enum InteractorEvent {
class Interactor {
typealias EventHandler = (InteractorEvent) -> Void

let queueID: String
var queueIds: [String]
var engagedOperator: CoreSdkClient.Operator? {
switch state {
case .engaged(let engagedOperator):
Expand Down Expand Up @@ -75,10 +75,10 @@ class Interactor {

init(
configuration: Configuration,
queueID: String,
queueIds: [String],
environment: Environment
) {
self.queueID = queueID
self.queueIds = queueIds
self.configuration = configuration
self.environment = environment
}
Expand Down Expand Up @@ -155,18 +155,21 @@ extension Interactor {
.map(CoreSdkClient.VisitorContext.init(_:))

self.environment.coreSdk.queueForEngagement(
self.queueID,
coreSdkVisitorContext,
// shouldCloseAllQueues is `true` by default core sdk,
// here it is passed explicitly
true,
mediaType,
options
) { [weak self] queueTicket, error in
if let error = error {
.init(
queueIds: self.queueIds,
visitorContext: coreSdkVisitorContext,
// shouldCloseAllQueues is `true` by default core sdk,
// here it is passed explicitly
shouldCloseAllQueues: true,
mediaType: mediaType,
engagementOptions: options
)
) { [weak self] result in
switch result {
case .failure(let error):
self?.state = .ended(.byError)
failure(error)
} else if let ticket = queueTicket {
case .success(let ticket):
if case .enqueueing = self?.state {
self?.state = .enqueued(ticket)
}
Expand Down
Loading

0 comments on commit 2ec4a2e

Please sign in to comment.