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

Update Sample integration project with 2.8.0 SDK version #1049

Merged
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
14 changes: 1 addition & 13 deletions Example/Glia Sample Integration.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
C03A802F292B7AFA00DDECA6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C03A802E292B7AFA00DDECA6 /* AppDelegate.swift */; };
C03A8035292B7D0E00DDECA6 /* EngagementButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = C03A8034292B7D0E00DDECA6 /* EngagementButtonStyle.swift */; };
C03A8037292B7DFA00DDECA6 /* ContentViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C03A8036292B7DFA00DDECA6 /* ContentViewPresenter.swift */; };
C03A803F292B7EFB00DDECA6 /* GliaEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = C03A803E292B7EFB00DDECA6 /* GliaEnvironment.swift */; };
C03A8041292B812B00DDECA6 /* AvailabilityModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C03A8040292B812B00DDECA6 /* AvailabilityModifier.swift */; };
C03A804C292CE2FE00DDECA6 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = C03A804B292CE2FE00DDECA6 /* Colors.swift */; };
/* End PBXBuildFile section */
Expand All @@ -31,7 +30,6 @@
C03A802E292B7AFA00DDECA6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C03A8034292B7D0E00DDECA6 /* EngagementButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EngagementButtonStyle.swift; sourceTree = "<group>"; };
C03A8036292B7DFA00DDECA6 /* ContentViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentViewPresenter.swift; sourceTree = "<group>"; };
C03A803E292B7EFB00DDECA6 /* GliaEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GliaEnvironment.swift; sourceTree = "<group>"; };
C03A8040292B812B00DDECA6 /* AvailabilityModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvailabilityModifier.swift; sourceTree = "<group>"; };
C03A804B292CE2FE00DDECA6 /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -71,7 +69,6 @@
C03A8039292B7E5200DDECA6 /* Presenters */,
C03A8038292B7E4200DDECA6 /* Views */,
C03A8033292B7CEC00DDECA6 /* ViewModifiers */,
C03A803D292B7EE100DDECA6 /* Extensions */,
C03A804A292CE2DD00DDECA6 /* Appearance */,
C03A8024292B7A6700DDECA6 /* Assets.xcassets */,
C03A8026292B7A6700DDECA6 /* Preview Content */,
Expand Down Expand Up @@ -114,14 +111,6 @@
path = Presenters;
sourceTree = "<group>";
};
C03A803D292B7EE100DDECA6 /* Extensions */ = {
isa = PBXGroup;
children = (
C03A803E292B7EFB00DDECA6 /* GliaEnvironment.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
C03A8045292B9FAE00DDECA6 /* Delegate */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -214,7 +203,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C03A803F292B7EFB00DDECA6 /* GliaEnvironment.swift in Sources */,
C03A804C292CE2FE00DDECA6 /* Colors.swift in Sources */,
C03A802F292B7AFA00DDECA6 /* AppDelegate.swift in Sources */,
75BC62532A852855004763C8 /* Configuration.swift in Sources */,
Expand Down Expand Up @@ -438,7 +426,7 @@
repositoryURL = "https://github.com/salemove/ios-sdk-widgets.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.10.4;
minimumVersion = 2.8.0;
};
};
/* End XCRemoteSwiftPackageReference section */
Expand Down
6 changes: 5 additions & 1 deletion Example/Glia Sample Integration/Configuration.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import GliaWidgets
import SalemoveSDK

// Configure the Glia class
final class GliaConfiguration {
Expand All @@ -12,6 +11,11 @@ final class GliaConfiguration {
// This queue is later on checked for being listed on site, being open,
// and being available for visitors who want to engage via video.
let queueId = ""

// Set DirectID token to authenticate user.
// With authenticated user you will be able to start Secure Conversation
// and operators will get user data from JWT token on their side
let directIdToken = ""

func composeConfiguration() -> Configuration {
let configuration = Configuration(
Expand Down
13 changes: 9 additions & 4 deletions Example/Glia Sample Integration/Delegate/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,29 @@ import GliaCoreSDK
import SwiftUI

class AppDelegate: NSObject, UIApplicationDelegate {
private let gliaDelegate = GliaCore.AppDelegate()
private let gliaCoreAppDelegate = GliaCoreAppDelegate()

func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
) -> Bool {
gliaDelegate.application(application, didFinishLaunchingWithOptions: launchOptions)
gliaCoreAppDelegate.application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}

func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
GliaCore.sharedInstance.pushNotifications.application(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken)
GliaCore.sharedInstance.pushNotifications.application(
application,
didRegisterForRemoteNotificationsWithDeviceToken: deviceToken
)
}

func applicationDidBecomeActive(_ application: UIApplication) {
gliaDelegate.applicationDidBecomeActive(application)
gliaCoreAppDelegate.applicationDidBecomeActive(application)
// Restart any tasks that were paused (or not yet started) while the application was inactive.
// If the application was previously in the background, optionally refresh the user interface.
}
}
17 changes: 0 additions & 17 deletions Example/Glia Sample Integration/Extensions/GliaEnvironment.swift

This file was deleted.

160 changes: 114 additions & 46 deletions Example/Glia Sample Integration/Presenters/ContentViewPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,86 +5,120 @@ import SwiftUI
class ContentViewPresenter: ObservableObject {
private let gliaConfiguration: GliaConfiguration
private var theme = Theme()
private var gliaAuthentication: Glia.Authentication?
private var queue: Queue?

@Published var isSDKLoaded = false

@Published var isVideoAvailable = false
@Published var isAudioAvailable = false
@Published var isChatAvailable = false
@Published var isAsyncMessagesAvailable = false

@Published var isAuthenticated = false

init() {
gliaConfiguration = GliaConfiguration()
theme = customizeTheme()

// To use any methods from iOS Core SDK (e.g. `GliaCore.listQueues`),
// you need to initialize `CoreSDK` separately with your site's credentials.
initializeCoreSDK {
GliaCore.sharedInstance.listQueues { [weak self] queues, error in
guard error == nil else {
print("Error has happened: \(error!.reason)")
return
}
let queue = queues?.first(where: { $0.id == self?.gliaConfiguration.queueId })
self?.queue = queue
self?.isVideoAvailable = queue?.isMediaTypeSupported(.video) ?? false
self?.isAudioAvailable = queue?.isMediaTypeSupported(.audio) ?? false
self?.isChatAvailable = queue?.isMediaTypeSupported(.text) ?? false
}
}
}

// Configure listening of Glia's events
private func eventListener() {
Glia.sharedInstance.onEvent = { event in
switch event {
case .started:
break
case .engagementChanged:
break
case .ended:
break
case .minimized:
break
case .maximized:
break
// you need to initialize `CoreSDK` separately with your site's credentials.
initializeCoreSDK { [weak self] result in
switch result {
case .success:
self?.isSDKLoaded = true
self?.initializeAuthentication()
self?.checkQueueEngagementsAvailability()
case .failure(let error):
print("Error has happened: \(error.localizedDescription)")
}
}
}

// Start the engagement of a desired `EngagementKind`.
func startEngagement(_ kind: EngagementKind) {
do {
try Glia.sharedInstance.start(
kind,
configuration: gliaConfiguration.composeConfiguration(),
queueID: gliaConfiguration.queueId,
visitorContext: nil,
theme: theme
)
try Glia.sharedInstance.startEngagement(of: kind, in: [gliaConfiguration.queueId])
} catch {
print("Error starting engagement")
}
}

// Authenticate user with token to start secure conversation
// and display user data on operator side
func authenticate() {
gliaAuthentication?.authenticate(
with: gliaConfiguration.directIdToken,
accessToken: nil
) { [weak self] result in
switch result {
case .success:
self?.isAuthenticated = true
case .failure(let error):
print("Error has happened: \(error.localizedDescription)")
}
}
}

func deauthenticate() {
gliaAuthentication?.deauthenticate { [weak self] result in
switch result {
case .success:
self?.isAuthenticated = false
case .failure(let error):
print("Error has happened: \(error.localizedDescription)")
}
}
}

// Show the visitor code to display code and start engagements with live observation
func showVisitorCode() {
var topViewController: UIViewController?
for scene in UIApplication.shared.connectedScenes {
guard let windowScene = scene as? UIWindowScene else {
continue
}
for window in windowScene.windows where window.isKeyWindow {
topViewController = window.rootViewController
break
}
}

if let topViewController {
Glia.sharedInstance.callVisualizer.showVisitorCodeViewController(from: topViewController)
}
}
}

private extension ContentViewPresenter {
// Configure Glia, for Core SDK.
private func initializeCoreSDK(completion: @escaping () -> Void) {
func initializeCoreSDK(completion: @escaping (Result<Void, Error>) -> Void) {
do {
let configuration = try GliaCore.Configuration(
siteId: gliaConfiguration.siteId,
region: gliaConfiguration.environment.gliaCoreRegion,
authorizingMethod: .siteApiKey(id: gliaConfiguration.siteApiId, secret: gliaConfiguration.siteApiSecret)
let configuration = Configuration(
authorizationMethod: .siteApiKey(
id: gliaConfiguration.siteApiId,
secret: gliaConfiguration.siteApiSecret
),
environment: gliaConfiguration.environment,
site: gliaConfiguration.siteId
)

GliaCore.sharedInstance.configure(
try Glia.sharedInstance.configure(
with: configuration,
theme: theme,
completion: completion
)
} catch {
print("Error has happened: \(error.localizedDescription)")
}
}

func initializeAuthentication() {
gliaAuthentication = try? Glia.sharedInstance.authentication(with: .allowedDuringEngagement)
}

// Customize and apply Theme
private func customizeTheme() -> Theme {
func customizeTheme() -> Theme {
let themeColors = ThemeColor(
primary: .init(Colors.gliaPurple),
baseLight: .white,
Expand All @@ -98,13 +132,47 @@ class ContentViewPresenter: ObservableObject {
fontStyle: .default,
showsPoweredBy: true
)
theme.chat.backgroundColor = .white
theme.minimizedBubble.badge?.backgroundColor = .systemPink
theme.chat.backgroundColor = .fill(color: .white)
theme.minimizedBubble.badge?.backgroundColor = .fill(color: .systemPink)
theme.minimizedBubble.badge?.fontColor = .white
theme.minimizedBubble.badge?.font = .systemFont(ofSize: 14)

return theme
}

func checkQueueEngagementsAvailability() {
Glia.sharedInstance.listQueues { [weak self] result in
switch result {
case .success(let queues):
let queue = queues.first(where: { $0.id == self?.gliaConfiguration.queueId })
self?.queue = queue
self?.isVideoAvailable = queue?.isMediaTypeSupported(.video) ?? false
self?.isAudioAvailable = queue?.isMediaTypeSupported(.audio) ?? false
self?.isChatAvailable = queue?.isMediaTypeSupported(.text) ?? false
self?.isAsyncMessagesAvailable = queue?.isMediaTypeSupported(.messaging) ?? false
case .failure(let error):
print("Error has happened: \(error.localizedDescription)")
}
}
}

// This is an example of how events are handled and could be observer in Glia Widgets
func eventListener() {
Glia.sharedInstance.onEvent = { event in
switch event {
igorkravchenko marked this conversation as resolved.
Show resolved Hide resolved
case .started:
break
case .engagementChanged:
break
case .ended:
break
case .minimized:
break
case .maximized:
break
}
}
}
}

// Check if the desired queue is open and available for a certain media.
Expand Down
26 changes: 23 additions & 3 deletions Example/Glia Sample Integration/Views/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,39 @@ struct ContentView: View {
presenter.startEngagement(.chat)
}
.buttonStyle(EngagementButtonStyle())
.modifier(IsAvailable(presenter.isChatAvailable))
.modifier(IsAvailable(presenter.isChatAvailable && presenter.isSDKLoaded))

Button("Audio Call") {
presenter.startEngagement(.audioCall)
}
.buttonStyle(EngagementButtonStyle())
.modifier(IsAvailable(presenter.isAudioAvailable))
.modifier(IsAvailable(presenter.isAudioAvailable && presenter.isSDKLoaded))

Button("Video Call") {
presenter.startEngagement(.videoCall)
}
.buttonStyle(EngagementButtonStyle())
.modifier(IsAvailable(presenter.isVideoAvailable))
.modifier(IsAvailable(presenter.isVideoAvailable && presenter.isSDKLoaded))

Button("Call Visualizer") {
presenter.showVisitorCode()
}
.modifier(IsAvailable(presenter.isSDKLoaded))
.buttonStyle(EngagementButtonStyle())

Button("Secure Conversation") {
presenter.startEngagement(.messaging(.welcome))
}
.buttonStyle(EngagementButtonStyle())
.modifier(
IsAvailable(presenter.isAsyncMessagesAvailable && presenter.isAuthenticated && presenter.isSDKLoaded)
)

Button(presenter.isAuthenticated ? "Deauthenticate" : "Authenticate") {
presenter.isAuthenticated ? presenter.deauthenticate() : presenter.authenticate()
}
.buttonStyle(EngagementButtonStyle())
.modifier(IsAvailable(presenter.isAsyncMessagesAvailable && presenter.isSDKLoaded))
}
.padding(.vertical, 48)
}
Expand Down
Loading