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

chore: CustomerIO wrapper rewrite #279

Draft
wants to merge 2 commits into
base: feature/cdp/native-logging
Choose a base branch
from
Draft
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
19 changes: 19 additions & 0 deletions ios/wrappers/CioRctWrapper.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#import <React/RCTBridgeModule.h>


@interface RCT_EXTERN_REMAP_MODULE(NativeCustomerIO, CioRctWrapper, NSObject)

RCT_EXTERN_METHOD(initialize:(id)config logLevel:(NSString *)logLevel)
RCT_EXTERN_METHOD(identify:(NSString *)identify traits:(NSDictionary *)traits)
RCT_EXTERN_METHOD(clearIdentify)
RCT_EXTERN_METHOD(track:(NSString *)name properties:(NSDictionary *)properties)
RCT_EXTERN_METHOD(screen:(NSString *)title category: (NSString *)category properties:(NSDictionary *))
RCT_EXTERN_METHOD(setProfileAttributes: (NSDictionary *)attributes)
RCT_EXTERN_METHOD(setDeviceAttributes: (NSDictionary *)attributes)

+ (BOOL)requiresMainQueueSetup
{
return NO;
}

@end
119 changes: 119 additions & 0 deletions ios/wrappers/CioRctWrapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import CioDataPipelines
import CioMessagingInApp
import CioMessagingPush
import UserNotifications
import React

func flush() {
#if DEBUG
CustomerIO.shared.flush()
#endif
}

@objc(CioRctWrapper)
class CioRctWrapper: NSObject {

@objc var moduleRegistry: RCTModuleRegistry!

private var logger: CioLogger!

@objc
func initialize(_ configJson: AnyObject, logLevel: String) {
do {
logger = CioLoggerWrapper.getInstance(moduleRegistry: moduleRegistry, logLevel: CioLogLevel(rawValue: logLevel) ?? .none)

logger.debug("Initializing CIO with config: \(configJson)")
let rtcConfig = try RCTCioConfig.from(configJson)
let cioInitConfig = cioInitializeConfig(from: rtcConfig, logLevel: logLevel)
CustomerIO.initialize(withConfig: cioInitConfig.cdp)
if let inAppConfig = cioInitConfig.inApp {
// In app initializes UIView(s) which would crash if run from non-UI queues
DispatchQueue.main.async {
MessagingInApp.initialize(withConfig: inAppConfig)
MessagingInApp.shared.setEventListener(self)
}
}
flush()
} catch {
logger.error("Couldn't initialize CustomerIO: \(error)")
}
}

@objc
func identify(_ userId: String? = nil, traits: [String: Any]? = nil) {
if let userId, let traits {
CustomerIO.shared.identify(userId: userId, traits: traits)
} else if let userId {
CustomerIO.shared.identify(userId: userId, traits: traits)
} else {
logger.error("CustomerIO.identify called without an ID or traits")
}
flush()
}

@objc
func clearIdentify() {
CustomerIO.shared.clearIdentify()
flush()
}

@objc
func track(_ name: String, properties: [String: Any]?) {
CustomerIO.shared.track(name: name, properties: properties)
flush()
}

@objc
func screen(_ title: String, category: String?, properties: [String: Any]?) {
CustomerIO.shared.screen(title: title, category: category, properties: properties)
flush()
}

@objc
func setProfileAttributes(_ attrs: [String: Any]) {
CustomerIO.shared.profileAttributes = attrs
flush()
}

@objc
func setDeviceAttributes(_ attrs: [String: Any]) {
CustomerIO.shared.deviceAttributes = attrs
flush()
}
}

extension CioRctWrapper: InAppEventListener {
private func sendEvent(eventType: String, message: InAppMessage, actionValue: String? = nil, actionName: String? = nil) {
var body = [
CustomerioConstants.eventType: eventType,
CustomerioConstants.messageId: message.messageId,
CustomerioConstants.deliveryId: message.deliveryId
]
if let actionValue = actionValue {
body[CustomerioConstants.actionValue] = actionValue
}
if let actionName = actionName {
body[CustomerioConstants.actionName] = actionName
}
CustomerioInAppMessaging.shared?.sendEvent(
withName: CustomerioConstants.inAppEventListener,
body: body
)
}

func messageShown(message: InAppMessage) {
sendEvent(eventType: CustomerioConstants.messageShown, message: message)
}

func messageDismissed(message: InAppMessage) {
sendEvent(eventType: CustomerioConstants.messageDismissed, message: message)
}

func errorWithMessage(message: InAppMessage) {
sendEvent(eventType: CustomerioConstants.errorWithMessage, message: message)
}

func messageActionTaken(message: InAppMessage, actionValue: String, actionName: String) {
sendEvent(eventType: CustomerioConstants.messageActionTaken, message: message, actionValue: actionValue, actionName: actionName)
}
}
58 changes: 58 additions & 0 deletions ios/wrappers/utils/CioConfigUtils.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import CioInternalCommon
import CioDataPipelines
import CioMessagingInApp

extension Region: Decodable {}

let logLevels = Set<String>(CioLogLevel.allCases.map(\.rawValue))

struct QASettings: Decodable {
let cdnHost: String
let apiHost: String
}

struct RCTCioConfig: Decodable {
let cdpApiKey: String
let siteId: String?
let region: Region?
let trackApplicationLifecycleEvents: Bool?
let enableInApp: Bool?
let qa: QASettings?

static func from(_ json: AnyObject) throws -> Self {
let data = try JSONSerialization.data(withJSONObject: json, options: [])
let instance = try JSONDecoder().decode(Self.self, from: data)
return instance
}
}

struct CioConfig {
let cdp: SDKConfigBuilderResult
let inApp: MessagingInAppConfigOptions?
}

func ifNotNil<V, K>(_ value: V?, thenPassItTo: (V) -> K) {
if let value {
_ = thenPassItTo(value)
}
}

func cioInitializeConfig(from config: RCTCioConfig, logLevel: String?) -> CioConfig {

let cdpConfigBuilder = SDKConfigBuilder(cdpApiKey: config.cdpApiKey)
let cioLogLevel = CioLogLevel(rawValue: logLevel ?? "no log level")
ifNotNil(config.siteId, thenPassItTo: cdpConfigBuilder.migrationSiteId)
ifNotNil(config.region, thenPassItTo: cdpConfigBuilder.region)
ifNotNil(config.trackApplicationLifecycleEvents, thenPassItTo: cdpConfigBuilder.trackApplicationLifecycleEvents)
ifNotNil(cioLogLevel, thenPassItTo: cdpConfigBuilder.logLevel)
ifNotNil(config.qa?.cdnHost, thenPassItTo: cdpConfigBuilder.cdnHost)
ifNotNil(config.qa?.apiHost, thenPassItTo: cdpConfigBuilder.apiHost)

var inAppConfig: MessagingInAppConfigOptions? = nil

if let siteId = config.siteId, let region = config.region, let enableInApp = config.enableInApp, enableInApp {
inAppConfig = MessagingInAppConfigBuilder(siteId: siteId, region: region).build()
}

return CioConfig(cdp: cdpConfigBuilder.build(), inApp: inAppConfig)
}
File renamed without changes.
44 changes: 0 additions & 44 deletions src/CustomerioConfig.tsx

This file was deleted.

22 changes: 0 additions & 22 deletions src/CustomerioEnum.tsx

This file was deleted.

Loading
Loading