Skip to content

Commit

Permalink
Merge pull request #22 from deskpro/develop
Browse files Browse the repository at this point in the history
Script changes & ObjC support
  • Loading branch information
qsd-faris authored May 15, 2024
2 parents 4531794 + e6c338e commit 9bcb8f4
Show file tree
Hide file tree
Showing 11 changed files with 201 additions and 92 deletions.
62 changes: 57 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

# messenger-sdk-ios

![Messenger SDK iOS SWIFT](https://img.shields.io/badge/Swift-5.7_5.8_5.9-Orange?style=flat-square)
![Messenger SDK iOS OS](https://img.shields.io/badge/Platforms-_iOS_-Green?style=flat-square)
![Messenger SDK iOS LANGUAGES](https://img.shields.io/badge/Languages-Swift_|_ObjC-orange?style=flat-square)
![Messenger SDK iOS SPM](https://img.shields.io/badge/Swift_Package_Manager-compatible-green?style=flat-square)
![Messenger SDK iOS CI](https://github.com/deskpro/messenger-sdk-ios/actions/workflows/main.yml/badge.svg)

Expand All @@ -26,7 +26,7 @@ DeskPro iOS Messenger is a Chat/AI/Messaging product. You can embed a “widget
## Manual installation
Although we recommend using SPM, it is also possible to clone this repository manually, and drag and drop it into the root folder of the application.

## Setup and Initialization
## Initialization (Swift)
First, import the SDK:
```
import messenger_sdk_ios
Expand All @@ -53,25 +53,77 @@ To open a Messenger, paste this line example in the desired place:
messenger?.present().show()
```


## Initialization (Objective-C)
First, import the SDK:
```
@import messenger_sdk_ios;
```

Then, in your ViewController.h:
```
@property (strong, nonatomic) MessengerConfig *messengerConfig;
@property (strong, nonatomic) DeskPro *messenger;
```

Then, in your ViewController.m:
```
- (void)viewDidLoad {
[super viewDidLoad];
self.messengerConfig = [[MessengerConfig alloc] initWithAppUrl:@"YOUR_APP_URL" appId:@"YOUR_APP_ID" appKey:@"YOUR_APP_KEY"];
self.messenger = [[DeskPro alloc] initWithMessengerConfig:self.messengerConfig containingViewController:self enableAutologging:false];
}
```

Replace `YOUR_APP_URL` and `YOUR_APP_ID` with your app's URL and ID, and `YOUR_APP_KEY` with you app's KEY, or nil.


To open a Messenger, paste this line example in the desired place:
```
[[self.messenger present] show];
```


Note: You can create multiple Messenger instances.

### Setting user info

### Setting user info (Swift)
```
messenger?.setUserInfo(user: userObject)
```

### Setting user info (Objective-C)
```
[self.messenger setUserInfoWithUser:userObject];
```

Note: User(name, firstName, lastName, email)

### Authorize user
### Authorize user (Swift)
```
messenger?.authorizeUser(jwtToken: jwtToken)
```

### Push notifications
### Authorize user (Objective-C)
```
[self.messenger authorizeUserWithUserJwt:jwtToken];
```

### Push notifications (Swift)
```
messenger?.setPushRegistrationToken(token: token)
```

### Push notifications (Objective-C)
```
[self.messenger setPushRegistrationTokenWithToken:token];
```


Prerequisite: The application should be connected to the notifications platform, enabled for receiving notifications and obtaining tokens.


## Versioning
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/deskpro/messenger-sdk-ios/tags).

2 changes: 1 addition & 1 deletion Sources/Data/PushNotificationData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ import Foundation
///Data class representing the payload of a push notification.
///
///The class encapsulates the information included in a push notification.
public class PushNotificationData {
@objc public class PushNotificationData: NSObject {

}
23 changes: 16 additions & 7 deletions Sources/Data/User.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,30 @@
import Foundation

/// - Tag: User
public class User: Codable, Equatable {
@objc public class User: NSObject, Codable {

public var name: String? = nil
public var first_name: String? = nil
public var last_name: String? = nil
public var email: String? = nil
@objc public var name: String? = nil
@objc public var first_name: String? = nil
@objc public var last_name: String? = nil
@objc public var email: String? = nil

public init(name: String? = nil, firstName: String? = nil, lastName: String? = nil, email: String? = nil) {
@objc public init(name: String? = nil, firstName: String? = nil, lastName: String? = nil, email: String? = nil) {
self.name = name
self.first_name = firstName
self.last_name = lastName
self.email = email
}

/// Objective-C compatible equality check
@objc public func isEqualToUser(_ user: User) -> Bool {
return self.name == user.name && self.first_name == user.first_name && self.last_name == user.last_name && self.email == user.email
}
}

/// Extend the Swift functionality to still support the == operator in Swift contexts
extension User {

public static func == (lhs: User, rhs: User) -> Bool {
return lhs.name == rhs.name && lhs.first_name == rhs.first_name && lhs.last_name == rhs.last_name && lhs.email == rhs.email
return lhs.isEqualToUser(rhs)
}
}
33 changes: 17 additions & 16 deletions Sources/Deskpro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,38 @@ import UIKit
/// The `DeskPro` class provides methods for initializing the Messenger, managing user information,
/// handling push notifications, and presenting the DeskPro messaging interface.
///
public final class DeskPro: Messenger {
@objc public final class DeskPro: NSObject, Messenger {

private var messengerConfig: MessengerConfig

/// Coordinator to make sure that only one instance of webView is opened.
private var coordinator: PresentCoordinator

/// User defaults manager for storing user-related information.
var appUserDefaults: AppUserDefaults
var appUserDefaults: DeskproUserDefaults

/// Each Deskpro instance is having its own eventRouter to handle events in chat.
public var eventRouter: EventRouter
@objc public var eventRouter: EventRouter

/// Initializes the functionality of the application.
///
/// This method is a constructor for creating Deskpro objects with specific configurations and prepare for the execution of other features.
///
///- Parameter messengerConfig: The configuration object containing settings for the DeskPro Messenger.
///
public init(messengerConfig: MessengerConfig, containingViewController: UIViewController, enableAutologging: Bool = false) {
@objc public init(messengerConfig: MessengerConfig, containingViewController: UIViewController, enableAutologging: Bool = false) {
self.eventRouter = .init(enableAutologging: enableAutologging)
self.messengerConfig = messengerConfig
self.coordinator = PresentCoordinator(containingViewController: containingViewController, eventRouter: eventRouter)
self.appUserDefaults = AppUserDefaults(appId: messengerConfig.appId)
self.appUserDefaults = DeskproUserDefaults(appId: messengerConfig.appId)
}

/// Performs a test operation and returns a result as a String.
///
/// The method is intended to simulate a test scenario and provide a String result based on the outcome of the test.
///
/// - Returns: A String representing the result of the test operation.
public static func test() -> String {
@objc public static func test() -> String {
return "Hello world from Messenger!"
}

Expand All @@ -53,7 +53,7 @@ public final class DeskPro: Messenger {
///
/// - Parameter user: The [User](x-source-tag://User) object containing the user information.
///
public final func setUserInfo(user: User) {
@objc public final func setUserInfo(user: User) {
appUserDefaults.setUserInfo(user)
}

Expand All @@ -73,7 +73,7 @@ public final class DeskPro: Messenger {
///
/// - Returns: `true` if the token is successfully saved, `false` otherwise.
@discardableResult
public final func authorizeUser(userJwt: String) -> Bool {
@objc public final func authorizeUser(userJwt: String) -> Bool {
appUserDefaults.setJwtToken(userJwt)
return true
}
Expand All @@ -89,7 +89,7 @@ public final class DeskPro: Messenger {
///
/// - Returns: `true` if the logout operation is successful; `false` otherwise.
@discardableResult
public final func forgetUser() -> Bool {
@objc public final func forgetUser() -> Bool {
appUserDefaults.clear()
return true
}
Expand All @@ -102,7 +102,7 @@ public final class DeskPro: Messenger {
///
/// - Returns: `true` if the push registration token is successfully set; `false` otherwise.
@discardableResult
public final func setPushRegistrationToken(token: String) -> Bool {
@objc public final func setPushRegistrationToken(token: String) -> Bool {
appUserDefaults.setDeviceToken(token)
return true
}
Expand All @@ -121,7 +121,7 @@ public final class DeskPro: Messenger {
/// - Returns: `true` if the push notification is related to DeskPro; `false` otherwise.
///
/// - Tag: isDeskProPushNotification
public static func isDeskProPushNotification(data: [AnyHashable: Any]) -> Bool {
@objc public static func isDeskProPushNotification(data: [AnyHashable: Any]) -> Bool {
if let issuer = data["issuer"] as? String {
return issuer == "deskpro-messenger"
} else {
Expand All @@ -137,7 +137,7 @@ public final class DeskPro: Messenger {
///
/// - Parameter pushNotification: The push notification data to be handled.
///
public final func handlePushNotification(pushNotification: PushNotificationData) {
@objc public final func handlePushNotification(pushNotification: PushNotificationData) {
// TODO: Not yet implemented
}

Expand All @@ -147,7 +147,7 @@ public final class DeskPro: Messenger {
///
/// - Returns: A [PresentBuilder](x-source-tag://PresentBuilder) instance to start building presentation paths.
///
public final func present() -> PresentBuilder {
@objc public final func present() -> PresentBuilder {
let url = messengerConfig.appUrl//.appending(messengerConfig.appId)
//return PresentBuilder(url: url, containingViewController: containingViewController)
return PresentBuilder(url: url, appId: messengerConfig.appId, coordinator: coordinator)
Expand All @@ -157,7 +157,7 @@ public final class DeskPro: Messenger {
///
/// This method closes the currently displayed chat view, terminating the user's interaction with the DeskPro content.
///
public final func close() {
@objc public final func close() {
// TODO: Not yet implemented
}

Expand All @@ -167,7 +167,7 @@ public final class DeskPro: Messenger {
///
/// - Returns: The number of unread conversations in the inbox.
///
public final func getUnreadConversationCount() -> Int {
@objc public final func getUnreadConversationCount() -> Int {
// TODO: Not yet implemented
return 0
}
Expand All @@ -176,7 +176,8 @@ public final class DeskPro: Messenger {
///
/// This method turns on logging for the DeskPro SDK, allowing detailed information to be logged for debugging and troubleshooting purposes.
///
public final func enableLogging() {
@objc public final func enableLogging() {
// TODO: Not yet implemented
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation
/// UserDefaults utility class for managing user information and JWT tokens in the DeskPro Messenger module.
///
/// The class provides methods for retrieving, storing, and clearing user information, device tokens and JWT tokens using the UserDefaults API.
class AppUserDefaults {
final class DeskproUserDefaults {

/// UserDefaults instance.
let prefs = UserDefaults.standard
Expand Down
45 changes: 43 additions & 2 deletions Sources/Logs/EventRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@
import Foundation

/// Notifies the outside subscriber if an event occured. Prints all of the events if the autologging is enabled
public final class EventRouter {
@objc public final class EventRouter: NSObject {

/// Invoked when an event occurs
public var handleEventCallback: ((DeskproEvent) -> Void)? = nil
@objc public var objcHandleEventCallback: ((ObjcDeskproEventData) -> Void)? = nil
private var enableAutologging: Bool

/// Initializes the EventRouter class
///
///- Parameter enableAutologging: If true, the EventRouter class will print all of the events that occur (during debug mode).
///
init(enableAutologging: Bool = false) {
@objc public init(enableAutologging: Bool = false) {
self.enableAutologging = enableAutologging
}

Expand All @@ -29,6 +30,36 @@ public final class EventRouter {

handleEventCallback?(event)
}

@objc func objcHandleOrLogEvent(event: ObjcDeskproEventData) {
if enableAutologging {
dprint("[DeskproLogger]: \(event.debugDescription)")
}

objcHandleEventCallback?(event)
}
}

@objc public final class ObjcDeskproEventData: NSObject {
@objc public var event: ObjcDeskproEvent
@objc public var data: String

@objc init(event: ObjcDeskproEvent, data: String) {
self.event = event
self.data = data
}

@objc public override var debugDescription: String {
"\(Date.nowString) [AppEvent] \(data)"
}
}

@objc public enum ObjcDeskproEvent: Int {
case newChat
case chatEnded
case newChatMessage
case chatUploadRequest
case custom
}

/// An event that occurs during a chat session. The observation of these events occurs through the EventRouter class
Expand Down Expand Up @@ -65,6 +96,16 @@ public enum DeskproEvent {
}
}

var toObjcEvent: ObjcDeskproEvent {
switch self {
case .newChat(_): return .newChat
case .chatEnded(_): return .chatEnded
case .newChatMessage(_): return .newChatMessage
case .chatUploadRequest(_): return .chatUploadRequest
case .custom(_): return .custom
}
}

/// Raw event JSON in string format
public var data: String {
switch self {
Expand Down
10 changes: 5 additions & 5 deletions Sources/MessengerConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ import Foundation
/// Configuration data class for initializing the Messenger feature in the application.
///
/// This data class holds configuration parameters required for setting up and initializing the Messenger feature within the application. The configuration includes the base URL of the Messenger service, the application ID, and the application key.
public final class MessengerConfig {
@objc public final class MessengerConfig: NSObject {

public var appUrl: String
public var appId: String
public var appKey: String?
@objc public var appUrl: String
@objc public var appId: String
@objc public var appKey: String?

///- Parameter appUrl: The base URL of the Messenger service.
///- Parameter appId: The unique identifier for the application using the Messenger feature.
///- Parameter appKey: The secret key for authenticating the application with the Messenger service.
public init(appUrl: String, appId: String, appKey: String? = nil) {
@objc public init(appUrl: String, appId: String, appKey: String? = nil) {
self.appUrl = appUrl
self.appId = appId
self.appKey = appKey
Expand Down
Loading

0 comments on commit 9bcb8f4

Please sign in to comment.