From 1396144ee5761accc3be1d5a6a29404661b5a9d2 Mon Sep 17 00:00:00 2001 From: Ahmed Ali <142905621+Ahmed-CIO@users.noreply.github.com> Date: Wed, 27 Mar 2024 01:36:04 +0400 Subject: [PATCH] docs: [vision-os-sample-app][10/n] Profile Attributes (#668) --- .../VisionOS.xcodeproj/project.pbxproj | 4 ++ .../APIViews/ProfileAttributesView.swift | 53 +++++++++++++++++++ .../CommonViews/PropertiesInputView.swift | 2 +- Apps/VisionOS/VisionOS/MainScreen.swift | 7 ++- Apps/VisionOS/VisionOS/Storage/Payloads.swift | 2 + 5 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 Apps/VisionOS/VisionOS/APIViews/ProfileAttributesView.swift diff --git a/Apps/VisionOS/VisionOS.xcodeproj/project.pbxproj b/Apps/VisionOS/VisionOS.xcodeproj/project.pbxproj index 47952cb00..e3a597280 100644 --- a/Apps/VisionOS/VisionOS.xcodeproj/project.pbxproj +++ b/Apps/VisionOS/VisionOS.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 6023AD372B9137F0001540EF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6023AD362B9137F0001540EF /* AppDelegate.swift */; }; 6066B2632BAFC86F005A4135 /* TrackEventsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6066B2622BAFC86F005A4135 /* TrackEventsView.swift */; }; + 6066B2652BAFCBEB005A4135 /* ProfileAttributesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6066B2642BAFCBEB005A4135 /* ProfileAttributesView.swift */; }; 60B151FB2BAB4AA9003C4726 /* DataPipelines in Frameworks */ = {isa = PBXBuildFile; productRef = 60B151FA2BAB4AA9003C4726 /* DataPipelines */; }; 60C32BEC2BABAD4D006F5DC3 /* ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60C32BEB2BABAD4D006F5DC3 /* ViewModel.swift */; }; 60C32BF62BABAFBE006F5DC3 /* LineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6023AD4B2B9153EB001540EF /* LineView.swift */; }; @@ -41,6 +42,7 @@ 6023AD4A2B9153EB001540EF /* FloatingTitleTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatingTitleTextField.swift; sourceTree = ""; }; 6023AD4B2B9153EB001540EF /* LineView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LineView.swift; sourceTree = ""; }; 6066B2622BAFC86F005A4135 /* TrackEventsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrackEventsView.swift; sourceTree = ""; }; + 6066B2642BAFCBEB005A4135 /* ProfileAttributesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileAttributesView.swift; sourceTree = ""; }; 606F2C202B9B79F3004E7318 /* PropertiesInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertiesInputView.swift; sourceTree = ""; }; 60B792DB2BAFC0F700E8F886 /* TrackEventsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackEventsView.swift; sourceTree = ""; }; 60C32BEB2BABAD4D006F5DC3 /* ViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewModel.swift; sourceTree = ""; }; @@ -102,6 +104,7 @@ 60E792512BACDE72003736F4 /* SDKInitializationView.swift */, 60DE3F7A2BAD38C600C6816C /* IdentifyView.swift */, 6066B2622BAFC86F005A4135 /* TrackEventsView.swift */, + 6066B2642BAFCBEB005A4135 /* ProfileAttributesView.swift */, ); path = APIViews; sourceTree = ""; @@ -277,6 +280,7 @@ 60C32BFB2BABAFBE006F5DC3 /* MainLayoutView.swift in Sources */, 60F967542B91288400A4E95E /* Payloads.swift in Sources */, 60DE3F7D2BAD392000C6816C /* CodeSnippetHelper.swift in Sources */, + 6066B2652BAFCBEB005A4135 /* ProfileAttributesView.swift in Sources */, 60F967372B9125D000A4E95E /* MainScreen.swift in Sources */, 60F9675B2B912C1000A4E95E /* TextOutputFormat.swift in Sources */, 60F9675D2B912C1000A4E95E /* MarkdownTheme.swift in Sources */, diff --git a/Apps/VisionOS/VisionOS/APIViews/ProfileAttributesView.swift b/Apps/VisionOS/VisionOS/APIViews/ProfileAttributesView.swift new file mode 100644 index 000000000..99256b00c --- /dev/null +++ b/Apps/VisionOS/VisionOS/APIViews/ProfileAttributesView.swift @@ -0,0 +1,53 @@ +import MarkdownUI +import SwiftUI + +private func profileAttributeCodeSnippet(_ attributes: [Attribute]) -> String { + if attributes.isEmpty { + return "// enter profile attributes" + } else { + let attributesStr = propertiesToTutorialString(attributes) + return + """ + CustomerIO.shared.profileAttributes = \(attributesStr) + """ + } +} + +struct ProfileAttributesView: View { + @ObservedObject var state = AppState.shared + + @State private var attributes: [Attribute] = [] + + let onSuccess: (_ profileAttributes: [Attribute]) -> Void + + var body: some View { + VStack(alignment: .leading) { + Markdown { + """ + You can set/update user attributes at any point in your app by setting values in the + `CustomerIO.shared.profileAttributes` dictionary. + If you are interested to learn about how profile attributes is being used, + [click here](https://customer.io/docs/journeys/attributes/#attribute-segment). + + ```swift + \(profileAttributeCodeSnippet(attributes)) + ``` + """ + } + + + PropertiesInputView(terminology: .attributes, properties: $attributes) + + Button("Set/Update profile attribute") { + onSuccess(attributes) + } + } + } +} + +#Preview { + MainLayoutView(selectedExample: .constant(.profileAttributes)) { + ProfileAttributesView { _ in + } + } +} diff --git a/Apps/VisionOS/VisionOS/CommonViews/PropertiesInputView.swift b/Apps/VisionOS/VisionOS/CommonViews/PropertiesInputView.swift index 5585f769f..e03ab4335 100644 --- a/Apps/VisionOS/VisionOS/CommonViews/PropertiesInputView.swift +++ b/Apps/VisionOS/VisionOS/CommonViews/PropertiesInputView.swift @@ -2,7 +2,7 @@ import MarkdownUI import SwiftUI enum PropertiesTerminology: String { - case properties, traits + case properties, traits, attributes var capitalize: String { "\(self)".capitalized diff --git a/Apps/VisionOS/VisionOS/MainScreen.swift b/Apps/VisionOS/VisionOS/MainScreen.swift index 958232fcb..805110823 100644 --- a/Apps/VisionOS/VisionOS/MainScreen.swift +++ b/Apps/VisionOS/VisionOS/MainScreen.swift @@ -68,7 +68,12 @@ struct MainScreen: View { CustomerIO.shared.flush() } case .profileAttributes: - Text("Profile Attribute") + ProfileAttributesView { attributes in + CustomerIO.shared.profileAttributes = attributes.toDictionary() + viewModel.successMessage = "Profile attributes set successfully" + // For debug purpose only + CustomerIO.shared.flush() + } } } } diff --git a/Apps/VisionOS/VisionOS/Storage/Payloads.swift b/Apps/VisionOS/VisionOS/Storage/Payloads.swift index f4771b62f..3c300a731 100644 --- a/Apps/VisionOS/VisionOS/Storage/Payloads.swift +++ b/Apps/VisionOS/VisionOS/Storage/Payloads.swift @@ -60,6 +60,8 @@ extension [Property] { } } +typealias Attribute = Property + struct Event: Codable { var name: String var properties: [Property] = []