Skip to content

Commit

Permalink
Release candidate for URL Build Updates
Browse files Browse the repository at this point in the history
Contains changes to how URLs for API and Chat urls are computed to factor in hublet and environment more.

Also contains some changes to demo app for editable config that were included in a test flight build but not shipped in an SDK update yet.
  • Loading branch information
jasonconnery committed Nov 11, 2024
1 parent d90077c commit 8ee8889
Show file tree
Hide file tree
Showing 19 changed files with 370 additions and 76 deletions.
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,19 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),

## [1.0.4] - 2024-XX-XX

## [1.0.2] - in progress
### In Progress

- Added additional support for different hublets and environments when forming chat and api urls

## [1.0.3] - 2024-05-22

### Fixed

- Addressed bad merge causing compiler issues

## [1.0.2] - 2024-05-22

### Fixed

Expand Down Expand Up @@ -35,4 +46,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
### Deprecated
### Removed
### Fixed
### Security
### Security
8 changes: 6 additions & 2 deletions Demo/HubspotDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
968FB4C32B173A8600D6FC68 /* Hubspot-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 968FB4C22B173A8600D6FC68 /* Hubspot-Info.plist */; };
96AA34F32B45D0D8004FED6D /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 96AA34F22B45D0D8004FED6D /* Localizable.xcstrings */; };
96B54C062B63B9CF00AF5545 /* DemoPlaceholderFeatureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96B54C052B63B9CF00AF5545 /* DemoPlaceholderFeatureView.swift */; };
96BF7DF22C5A77CB00E50806 /* EditConfigView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96BF7DF12C5A77CB00E50806 /* EditConfigView.swift */; };
96D9BA422B56CBB700E0A3E8 /* CustomPropertiesListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D9BA412B56CBB700E0A3E8 /* CustomPropertiesListView.swift */; };
96D9BA462B5EAF9600E0A3E8 /* NotificationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D9BA452B5EAF9600E0A3E8 /* NotificationsView.swift */; };
96E75DAA2B0E70B2002DC1F5 /* FloatingButtonExampleContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96E75DA92B0E70B2002DC1F5 /* FloatingButtonExampleContainerView.swift */; };
Expand All @@ -48,6 +49,7 @@
968FB4C22B173A8600D6FC68 /* Hubspot-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Hubspot-Info.plist"; sourceTree = "<group>"; };
96AA34F22B45D0D8004FED6D /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
96B54C052B63B9CF00AF5545 /* DemoPlaceholderFeatureView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoPlaceholderFeatureView.swift; sourceTree = "<group>"; };
96BF7DF12C5A77CB00E50806 /* EditConfigView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditConfigView.swift; sourceTree = "<group>"; };
96D9BA412B56CBB700E0A3E8 /* CustomPropertiesListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPropertiesListView.swift; sourceTree = "<group>"; };
96D9BA432B5E762700E0A3E8 /* HubspotDemo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = HubspotDemo.entitlements; sourceTree = "<group>"; };
96D9BA452B5EAF9600E0A3E8 /* NotificationsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -167,6 +169,7 @@
isa = PBXGroup;
children = (
96E88BBE2B07857400F29EB5 /* SDKOptionsView.swift */,
96BF7DF12C5A77CB00E50806 /* EditConfigView.swift */,
);
path = Debug;
sourceTree = "<group>";
Expand Down Expand Up @@ -268,6 +271,7 @@
968FB4BF2B10F02000D6FC68 /* ToolbarWithChatButtonView.swift in Sources */,
96E75DAA2B0E70B2002DC1F5 /* FloatingButtonExampleContainerView.swift in Sources */,
96E88BBF2B07857400F29EB5 /* SDKOptionsView.swift in Sources */,
96BF7DF22C5A77CB00E50806 /* EditConfigView.swift in Sources */,
968FB4BD2B10BDFC00D6FC68 /* NavToolbarWithChatButtonView.swift in Sources */,
968FB4B72B0F7D9F00D6FC68 /* PlaceholderView.swift in Sources */,
9624CDCD2B068528009FFC2D /* HubspotDemoApp.swift in Sources */,
Expand Down Expand Up @@ -433,7 +437,7 @@
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_STRICT_CONCURRENCY = minimal;
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
};
Expand Down Expand Up @@ -471,7 +475,7 @@
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_STRICT_CONCURRENCY = minimal;
SWIFT_STRICT_CONCURRENCY = complete;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
};
Expand Down
26 changes: 25 additions & 1 deletion Demo/HubspotDemo/AppViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,23 @@ class AppViewModel: ObservableObject {
@MainActor
func setupHubspot() {
do {
try HubspotManager.configure()
if let newPortalId: String = UserDefaults.standard[.overridePortalId],
let newHublet: String = UserDefaults.standard[.overrideHublet],
let envStr: String = UserDefaults.standard[.overrideEnv],
let newEnv = HubspotEnvironment(rawValue: envStr)
{
let newChatFlow: String? = UserDefaults.standard[.overrideDefaultChatFlow]

// User has previously edited the config via settings, so use those instead of the default which looks for the info plist in the bundle
// This way could also be used to support different test / production env at run time based on variables
HubspotManager.configure(portalId: newPortalId,
hublet: newHublet,
defaultChatFlow: newChatFlow,
environment: newEnv)
} else {
// the default configure which reads from file dropped into the project, for convenience.
try HubspotManager.configure()
}

// If we already configured the demo with a token and email previously, re-set the user identity
if let existingToken: String = UserDefaults.standard[.idToken],
Expand Down Expand Up @@ -117,6 +133,10 @@ class AppViewModel: ObservableObject {
enum StorageKeys: String {
case idToken
case userEmail
case overridePortalId
case overrideHublet
case overrideEnv
case overrideDefaultChatFlow
}

extension UserDefaults {
Expand All @@ -128,6 +148,10 @@ extension UserDefaults {
setValue(newValue, forKey: storageKey.rawValue)
}
}

func removeObject(forStorageKey: StorageKeys) {
removeObject(forKey: forStorageKey.rawValue)
}
}

struct CustomProperty: Identifiable, Codable {
Expand Down
111 changes: 111 additions & 0 deletions Demo/HubspotDemo/Debug/EditConfigView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// EditConfigView.swift
// Hubspot Mobile SDK Demo Application
//
// Copyright © 2024 Hubspot, Inc.

import HubspotMobileSDK
import SwiftUI

struct EditConfigView: View {
@Environment(\.dismiss) var dismiss

@State var enteredPortalId: String = ""
@State var enteredHublet: String = ""
@State var selectedEnvironment: HubspotEnvironment = .production
@State var enteredDefaultChatFlow: String = ""

@State var showReset = false

/// True when the state variables differ from the current values
var hasChanges: Bool {
let portalMatches = enteredPortalId.trimmingCharacters(in: .whitespacesAndNewlines) != HubspotManager.shared.portalId
let hubletMatches = enteredHublet.trimmingCharacters(in: .whitespacesAndNewlines) != HubspotManager.shared.hublet
let flowMatches = enteredDefaultChatFlow.trimmingCharacters(in: .whitespacesAndNewlines) != HubspotManager.shared.defaultChatFlow
let envMatches = selectedEnvironment == HubspotManager.shared.environment

return !portalMatches || !hubletMatches || !flowMatches || !envMatches
}

var body: some View {
VStack {
List {
Section {
TextField("Portal ID", text: $enteredPortalId)
TextField("Hublet", text: $enteredHublet)
TextField("Chat Flow", text: $enteredDefaultChatFlow)
Picker("Environment", selection: $selectedEnvironment, content: {
Text("Production")
.tag(HubspotEnvironment.production)
Text("QA")
.tag(HubspotEnvironment.qa)
}).pickerStyle(.segmented)
Button(action: saveChanges, label: {
Label("Save Config", systemImage: "slider.horizontal.3")
}).disabled(!hasChanges)
}
Section {
Text("Clear any edited values previously saved, and go back to using the bundled config values")
Button(role: .destructive, action: { showReset = true }, label: {
Label("Reset to default", systemImage: "minus.square")
})
.confirmationDialog("Reset Config", isPresented: $showReset) {
Button("Reset", role: .destructive, action: resetConfig)
}
}

Section {
Text("Note: Editing the config during runtime may result in some inconsistent behaviour after editing. Fully stopping the app via multi tasker and relaunching may be a convenient way to reset any inconsistent behaviour due to run time config changes.")
.font(.callout)
}
}.onAppear(perform: setInitialValues)
}
.navigationTitle("Edit Config")
}

func setInitialValues() {
enteredPortalId = HubspotManager.shared.portalId ?? ""
enteredHublet = HubspotManager.shared.hublet ?? ""
selectedEnvironment = HubspotManager.shared.environment
enteredDefaultChatFlow = HubspotManager.shared.defaultChatFlow ?? ""
}

func saveChanges() {
guard hasChanges else {
return
}

let enteredPortalId = enteredPortalId.trimmingCharacters(in: .whitespacesAndNewlines)
let enteredHublet = enteredHublet.trimmingCharacters(in: .whitespacesAndNewlines)
let enteredDefaultChatFlow = enteredDefaultChatFlow.trimmingCharacters(in: .whitespacesAndNewlines)

UserDefaults.standard[.overridePortalId] = enteredPortalId
UserDefaults.standard[.overrideHublet] = enteredHublet
UserDefaults.standard[.overrideEnv] = selectedEnvironment.rawValue
UserDefaults.standard[.overrideDefaultChatFlow] = enteredDefaultChatFlow

logger.trace("Updating configuration on shared manager")
HubspotManager.configure(portalId: enteredPortalId,
hublet: enteredHublet,
defaultChatFlow: enteredDefaultChatFlow,
environment: selectedEnvironment)

dismiss()
}

func resetConfig() {
UserDefaults.standard.removeObject(forStorageKey: .overridePortalId)
UserDefaults.standard.removeObject(forStorageKey: .overrideHublet)
UserDefaults.standard.removeObject(forStorageKey: .overrideEnv)
UserDefaults.standard.removeObject(forStorageKey: .overrideDefaultChatFlow)

logger.trace("Triggering initial configure call")
try? HubspotManager.configure()
dismiss()
}
}

#Preview {
NavigationStack {
EditConfigView()
}
}
3 changes: 3 additions & 0 deletions Demo/HubspotDemo/Debug/SDKOptionsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ struct SDKOptionsView: View {
detailRow(label: "Hublet", value: manager.hublet ?? "<Not Available>")
detailRow(label: "Environment", value: manager.environment.description)
detailRow(label: "Default Chat Flow", value: manager.defaultChatFlow ?? "<Not Available>")
NavigationLink(destination: EditConfigView(), label: {
Text("Edit Config")
})
}
}

Expand Down
3 changes: 2 additions & 1 deletion Demo/HubspotDemo/HubspotDemoApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ struct HubspotDemoApp: App {
}

/// Example of a app level notification delegate that also forwards calls to hubspot delegate
class DemoAppNotificationDelegate: NSObject, ObservableObject, UNUserNotificationCenterDelegate {
@MainActor
class DemoAppNotificationDelegate: NSObject, ObservableObject, @preconcurrency UNUserNotificationCenterDelegate {
/// Count of recent pushes received in the foreground
@Published var countOfpushesReceived = 0
/// Count of the notifications received we think are for hubspot content
Expand Down
41 changes: 28 additions & 13 deletions Demo/HubspotDemo/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,15 @@
},
"Chat" : {

},
"Chat Flow" : {

},
"Chat with us" : {

},
"Clear any edited values previously saved, and go back to using the bundled config values" : {

},
"Clear data" : {

Expand Down Expand Up @@ -118,15 +124,6 @@
},
"Default flow - value taken from initial config: %@" : {

},
"Demo 1" : {

},
"Demo 2" : {

},
"Demo 3" : {

},
"Details" : {

Expand All @@ -136,6 +133,9 @@
},
"Dismiss" : {

},
"Edit Config" : {

},
"Email" : {

Expand Down Expand Up @@ -270,6 +270,9 @@
},
"Not set" : {

},
"Note: Editing the config during runtime may result in some inconsistent behaviour after editing. Fully stopping the app via multi tasker and relaunching may be a convenient way to reset any inconsistent behaviour due to run time config changes." : {

},
"Notifications" : {

Expand Down Expand Up @@ -312,7 +315,10 @@
"Portal ID" : {

},
"Preview" : {
"Production" : {

},
"QA" : {

},
"Recent Pushes" : {
Expand All @@ -323,6 +329,18 @@
},
"Request Token" : {

},
"Reset" : {

},
"Reset Config" : {

},
"Reset to default" : {

},
"Save Config" : {

},
"SDK Options" : {

Expand Down Expand Up @@ -392,9 +410,6 @@
},
"This is tab 3" : {

},
"This is the preview content" : {

},
"Token" : {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import HubspotMobileSDK
import SwiftUI

struct NavToolbarWithChatButtonView: View {
@State var showingChat = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import HubspotMobileSDK
import SwiftUI

struct ToolbarWithChatButtonView: View {
@State var showingChat = false

Expand Down
Loading

0 comments on commit 8ee8889

Please sign in to comment.