├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ ├── config.yml
│ ├── feature_request.yml
│ └── maintainer-blank.yml
├── PULL_REQUEST_TEMPLATE.md
├── dependabot.yml
├── stale.yml
└── workflows
│ ├── build-examples.yml
│ ├── build.yml
│ ├── danger.yml
│ ├── lint.yml
│ ├── release.yml
│ └── test.yml
├── .gitignore
├── .periphery.yml
├── .swiftformat
├── .swiftlint.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── Package.resolved
├── Package.swift
├── PostHog.podspec
├── PostHog.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── xcshareddata
│ └── xcschemes
│ ├── PostHog.xcscheme
│ ├── PostHogExample.xcscheme
│ ├── PostHogExampleMacOS.xcscheme
│ ├── PostHogExampleStoryboard.xcscheme
│ ├── PostHogExampleTvOS.xcscheme
│ ├── PostHogExampleWatchOS Watch App.xcscheme
│ ├── PostHogExampleWithPods.xcscheme
│ ├── PostHogExampleWithSPM.xcscheme
│ ├── PostHogObjCExample.xcscheme
│ └── PostHogTests.xcscheme
├── PostHog
├── Autocapture
│ ├── AutocaptureEventProcessing.swift
│ ├── ForwardingPickerViewDelegate.swift
│ ├── PostHogAutocaptureEventTracker.swift
│ ├── PostHogAutocaptureIntegration.swift
│ ├── SwiftUI
│ │ └── View+PostHogLabel.swift
│ └── UIView+PostHogLabel.swift
├── DI.swift
├── Models
│ └── PostHogEvent.swift
├── PostHog.h
├── PostHog.modulemap
├── PostHogApi.swift
├── PostHogBatchUploadInfo.swift
├── PostHogConfig.swift
├── PostHogConsumerPayload.swift
├── PostHogContext.swift
├── PostHogExtensions.swift
├── PostHogFeatureFlags.swift
├── PostHogFileBackedQueue.swift
├── PostHogLegacyQueue.swift
├── PostHogPersonProfiles.swift
├── PostHogPropertiesSanitizer.swift
├── PostHogQueue.swift
├── PostHogSDK.swift
├── PostHogSessionManager.swift
├── PostHogStorage.swift
├── PostHogStorageManager.swift
├── PostHogSwizzler.swift
├── PostHogVersion.swift
├── Replay
│ ├── CGColor+Util.swift
│ ├── CGSize+Util.swift
│ ├── Date+Util.swift
│ ├── MethodSwizzler.swift
│ ├── NetworkSample.swift
│ ├── PostHogReplayIntegration.swift
│ ├── PostHogSessionReplayConfig.swift
│ ├── RRStyle.swift
│ ├── RRWireframe.swift
│ ├── String+Util.swift
│ ├── UIApplicationTracker.swift
│ ├── UIColor+Util.swift
│ ├── UIImage+Util.swift
│ ├── UITextInputTraits+Util.swift
│ ├── UIView+Util.swift
│ ├── URLSessionExtension.swift
│ ├── URLSessionInterceptor.swift
│ ├── URLSessionSwizzler.swift
│ ├── ViewLayoutTracker.swift
│ └── ViewTreeSnapshotStatus.swift
├── Resources
│ └── PrivacyInfo.xcprivacy
├── SwiftUI
│ ├── PostHogMaskViewModifier.swift
│ ├── PostHogNoMaskViewModifier.swift
│ ├── PostHogSwiftUIViewModifiers.swift
│ └── PostHogTagViewModifier.swift
├── UIViewController.swift
└── Utils
│ ├── ApplicationLifecyclePublisher.swift
│ ├── AssociatedKeys.swift
│ ├── Data+Gzip.swift
│ ├── DateUtils.swift
│ ├── DictUtils.swift
│ ├── Errors.swift
│ ├── FileUtils.swift
│ ├── Hedgelog.swift
│ ├── Reachability.swift
│ ├── ReadWriteLock.swift
│ ├── TimeBasedEpochGenerator.swift
│ ├── UIApplication+.swift
│ ├── UIImage+WebP.swift
│ ├── UIWindow+.swift
│ └── UUIDUtils.swift
├── PostHogExample
├── Api.swift
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── max_static.imageset
│ │ ├── Contents.json
│ │ └── max_static.png
├── ContentView.swift
├── PostHogExample.entitlements
├── PostHogExampleApp.swift
├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
└── Views
│ └── UIViewExample.swift
├── PostHogExampleAutocapture
├── LICENSE
│ └── LICENSE.txt
├── PostHogExampleAutocapture.xcodeproj
│ ├── .xcodesamplecode.plist
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── PostHogExampleAutocapture.xcscheme
└── PostHogExampleAutocapture
│ ├── ActivityIndicatorViewController.swift
│ ├── AlertControllerViewController.swift
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ ├── Flowers_1.imageset
│ │ ├── Contents.json
│ │ └── Flowers_1.png
│ ├── Flowers_2.imageset
│ │ ├── Contents.json
│ │ └── Flowers_2.png
│ ├── background.imageset
│ │ ├── Contents.json
│ │ ├── stepper_and_segment_background_1x.png
│ │ ├── stepper_and_segment_background_2x.png
│ │ └── stepper_and_segment_background_3x.png
│ ├── background_disabled.imageset
│ │ ├── Contents.json
│ │ ├── stepper_and_segment_background_disabled_1x.png
│ │ ├── stepper_and_segment_background_disabled_2x.png
│ │ └── stepper_and_segment_background_disabled_3x.png
│ ├── background_highlighted.imageset
│ │ ├── Contents.json
│ │ ├── stepper_and_segment_background_highlighted_1x.png
│ │ ├── stepper_and_segment_background_highlighted_2x.png
│ │ └── stepper_and_segment_background_highlighted_3x.png
│ ├── search_bar_background.imageset
│ │ ├── Contents.json
│ │ ├── search_bar_background_3x.png
│ │ ├── search_bar_bg_1x.png
│ │ └── search_bar_bg_2x.png
│ ├── slider_blue_track.imageset
│ │ ├── Contents.json
│ │ ├── slider_blue_track_1x.png
│ │ ├── slider_blue_track_2x.png
│ │ └── slider_blue_track_3x.png
│ ├── slider_green_track.imageset
│ │ ├── Contents.json
│ │ ├── slider_green_track_1x.png
│ │ ├── slider_green_track_2x.png
│ │ └── slider_green_track_3x.png
│ ├── stepper_and_segment_divider.imageset
│ │ ├── Contents.json
│ │ ├── stepper_and_segment_divider_3x.png
│ │ ├── stepper_and_segment_segment_divider_1x.png
│ │ └── stepper_and_segment_segment_divider_2x.png
│ ├── text_field_background.imageset
│ │ ├── Contents.json
│ │ ├── text_field_background_1x.png
│ │ ├── text_field_background_2x.png
│ │ └── text_field_background_3x.png
│ ├── text_field_purple_right_view.imageset
│ │ ├── Contents.json
│ │ ├── text_field_purple_right_view_1x.png
│ │ ├── text_field_purple_right_view_2x.png
│ │ └── text_field_purple_right_view_3x.png
│ ├── text_view_attachment.imageset
│ │ ├── Contents.json
│ │ └── Sunset_5.png
│ ├── text_view_background.colorset
│ │ └── Contents.json
│ ├── tinted_segmented_control.colorset
│ │ └── Contents.json
│ ├── tinted_stepper_control.colorset
│ │ └── Contents.json
│ └── toolbar_background.imageset
│ │ ├── Contents.json
│ │ ├── toolbar_background_1x.png
│ │ ├── toolbar_background_2x.png
│ │ └── toolbar_background_3x.png
│ ├── Base.lproj
│ ├── ActivityIndicatorViewController.storyboard
│ ├── AlertControllerViewController.storyboard
│ ├── ButtonViewController.storyboard
│ ├── ColorPickerViewController.storyboard
│ ├── Credits.rtf
│ ├── CustomPageControlViewController.storyboard
│ ├── CustomSearchBarViewController.storyboard
│ ├── CustomToolbarViewController.storyboard
│ ├── DatePickerController.storyboard
│ ├── DefaultPageControlViewController.storyboard
│ ├── DefaultSearchBarViewController.storyboard
│ ├── DefaultToolbarViewController.storyboard
│ ├── FontPickerViewController.storyboard
│ ├── ImagePickerViewController.storyboard
│ ├── ImageViewController.storyboard
│ ├── InfoPlist.strings
│ ├── LaunchScreen.storyboard
│ ├── Localizable.strings
│ ├── Main.storyboard
│ ├── MenuButtonViewController.storyboard
│ ├── PickerViewController.storyboard
│ ├── PointerInteractionButtonViewController.storyboard
│ ├── ProgressViewController.storyboard
│ ├── SegmentedControlViewController.storyboard
│ ├── SliderViewController.storyboard
│ ├── StackViewController.storyboard
│ ├── StepperViewController.storyboard
│ ├── SwitchViewController.storyboard
│ ├── SymbolViewController.storyboard
│ ├── TextFieldViewController.storyboard
│ ├── TextViewController.storyboard
│ ├── TintedToolbarViewController.storyboard
│ ├── VisualEffectViewController.storyboard
│ ├── WebViewController.storyboard
│ └── content.html
│ ├── BaseTableViewController.swift
│ ├── ButtonViewController+Configs.swift
│ ├── ButtonViewController.swift
│ ├── CaseElement.swift
│ ├── ColorPickerViewController.swift
│ ├── CustomPageControlViewController.swift
│ ├── CustomSearchBarViewController.swift
│ ├── CustomToolbarViewController.swift
│ ├── DatePickerController.swift
│ ├── DefaultPageControlViewController.swift
│ ├── DefaultSearchBarViewController.swift
│ ├── DefaultToolbarViewController.swift
│ ├── FontPickerViewController.swift
│ ├── ImagePickerViewController.swift
│ ├── ImageViewController.swift
│ ├── Info.plist
│ ├── MenuButtonViewController.swift
│ ├── OutlineViewController.swift
│ ├── PickerViewController.swift
│ ├── PointerInteractionButtonViewController.swift
│ ├── ProgressViewController.swift
│ ├── SceneDelegate.swift
│ ├── SegmentedControlViewController.swift
│ ├── SliderViewController.swift
│ ├── StackViewController.swift
│ ├── StepperViewController.swift
│ ├── SwitchViewController.swift
│ ├── SymbolViewController.swift
│ ├── TextFieldViewController.swift
│ ├── TextViewController.swift
│ ├── TintedToolbarViewController.swift
│ ├── UIKitCatalog
│ └── Base.lproj
│ │ └── Localizable.stringsdict
│ ├── VisualEffectViewController.swift
│ └── WebViewController.swift
├── PostHogExampleExternalSDK
├── ExternalSDK.swift
├── ExternalSDK
│ └── ExternalSDK.h
├── Package.swift
├── PostHogExampleExternalSDK.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── ExternalSDK.xcscheme
├── SDKClient
│ ├── ExternalSDKClient
│ │ ├── Assets.xcassets
│ │ │ ├── AccentColor.colorset
│ │ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── ContentView.swift
│ │ ├── ExternalSDKClient.entitlements
│ │ ├── ExternalSDKClientApp.swift
│ │ └── Preview Content
│ │ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ └── PostHogExampleExternalSDKClient.xcodeproj
│ │ └── project.pbxproj
├── Sources
│ └── ExternalSDK-iOS
│ │ └── ExternalSDK-iOS.swift
└── build_xcframework.sh
├── PostHogExampleMacOS
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
├── ContentView.swift
├── PostHogExampleMacOS.entitlements
├── PostHogExampleMacOSApp.swift
└── Preview Content
│ └── Preview Assets.xcassets
│ └── Contents.json
├── PostHogExampleStoryboard
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Info.plist
├── SceneDelegate.swift
└── ViewController.swift
├── PostHogExampleTvOS
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── App Icon & Top Shelf Image.brandassets
│ │ ├── App Icon - App Store.imagestack
│ │ │ ├── Back.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ ├── Front.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ │ └── Middle.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ ├── App Icon.imagestack
│ │ │ ├── Back.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ ├── Front.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ │ └── Middle.imagestacklayer
│ │ │ │ ├── Content.imageset
│ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ ├── Contents.json
│ │ ├── Top Shelf Image Wide.imageset
│ │ │ └── Contents.json
│ │ └── Top Shelf Image.imageset
│ │ │ └── Contents.json
│ └── Contents.json
├── ContentView.swift
├── PostHogExampleTvOSApp.swift
└── Preview Content
│ └── Preview Assets.xcassets
│ └── Contents.json
├── PostHogExampleWatchOS
├── PostHogExampleWatchOS Watch App
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── PostHogExampleWatchOSApp.swift
│ └── Preview Content
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
└── PostHogExampleWatchOS.xcodeproj
│ └── project.pbxproj
├── PostHogExampleWithPods
├── Podfile
├── Podfile.static
├── PostHogExampleWithPods.xcodeproj
│ ├── project.pbxproj
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── PostHogExampleWithPods.xcscheme
├── PostHogExampleWithPods
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── PostHogExampleWithPodsApp.swift
│ └── Preview Content
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
└── README.md
├── PostHogExampleWithSPM
├── .gitignore
├── PostHogExampleWithSPM.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── PostHogExampleWithSPM
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── ContentView.swift
│ ├── PostHogExampleWithSPMApp.swift
│ └── Preview Content
│ │ └── Preview Assets.xcassets
│ │ └── Contents.json
└── README.md
├── PostHogObjCExample
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Info.plist
├── SceneDelegate.h
├── SceneDelegate.m
├── ViewController.h
├── ViewController.m
└── main.m
├── PostHogTests
├── ExampleSanitizer.swift
├── PostHogApiTest.swift
├── PostHogAutocaptureEventTrackerSpec.swift
├── PostHogAutocaptureIntegrationSpec.swift
├── PostHogConfigTest.swift
├── PostHogContextTest.swift
├── PostHogFeatureFlagsTest.swift
├── PostHogFileBackedQueueTest.swift
├── PostHogLegacyQueueTest.swift
├── PostHogQueueTest.swift
├── PostHogSDKPersonProfilesTest.swift
├── PostHogSDKTest.swift
├── PostHogSessionManagerTest.swift
├── PostHogStorageManagerTest.swift
├── PostHogStorageTest.swift
├── PostHogWebPTest.swift
├── Resources
│ ├── input_1.png
│ ├── input_2.png
│ ├── input_3.png
│ ├── output_1.webp
│ ├── output_2.webp
│ └── output_3.webp
├── TestUtils
│ ├── MockPostHogServer.swift
│ ├── TestError.swift
│ ├── TestPostHog.swift
│ └── URLSession+body.swift
└── UUIDTest.swift
├── README.md
├── RELEASING.md
├── USAGE.md
├── dangerfile.js
├── scripts
├── bump-version.sh
├── commit-code.sh
├── create-tag.sh
├── prepare-release.sh
└── update-tag.sh
└── vendor
└── libwebp
├── COPYING
├── PATENTS
├── alpha_enc.c
├── alpha_processing.c
├── alpha_processing_neon.c
├── alpha_processing_sse2.c
├── alpha_processing_sse41.c
├── analysis_enc.c
├── backward_references_cost_enc.c
├── backward_references_enc.c
├── backward_references_enc.h
├── bit_reader_utils.c
├── bit_reader_utils.h
├── bit_writer_utils.c
├── bit_writer_utils.h
├── color_cache_utils.c
├── color_cache_utils.h
├── common_dec.h
├── common_sse2.h
├── common_sse41.h
├── config_enc.c
├── cost.c
├── cost_enc.c
├── cost_enc.h
├── cost_neon.c
├── cost_sse2.c
├── cpu.c
├── cpu.h
├── dec.c
├── dec_clip_tables.c
├── dec_neon.c
├── dec_sse2.c
├── dec_sse41.c
├── decode.h
├── dsp.h
├── enc.c
├── enc_neon.c
├── enc_sse2.c
├── enc_sse41.c
├── encode.h
├── endian_inl_utils.h
├── filter_enc.c
├── filters.c
├── filters_neon.c
├── filters_sse2.c
├── filters_utils.c
├── filters_utils.h
├── format_constants.h
├── frame_enc.c
├── histogram_enc.c
├── histogram_enc.h
├── huffman_encode_utils.c
├── huffman_encode_utils.h
├── huffman_utils.c
├── huffman_utils.h
├── iterator_enc.c
├── lossless.c
├── lossless.h
├── lossless_common.h
├── lossless_enc.c
├── lossless_enc_neon.c
├── lossless_enc_sse2.c
├── lossless_enc_sse41.c
├── lossless_neon.c
├── lossless_sse2.c
├── lossless_sse41.c
├── mux.h
├── mux_types.h
├── muxedit.c
├── muxi.h
├── muxinternal.c
├── muxread.c
├── near_lossless_enc.c
├── neon.h
├── palette.c
├── palette.h
├── picture_csp_enc.c
├── picture_enc.c
├── picture_psnr_enc.c
├── picture_rescale_enc.c
├── picture_tools_enc.c
├── predictor_enc.c
├── quant.h
├── quant_enc.c
├── quant_levels_dec_utils.c
├── quant_levels_utils.c
├── quant_levels_utils.h
├── random_utils.c
├── random_utils.h
├── rescaler.c
├── rescaler_neon.c
├── rescaler_sse2.c
├── rescaler_utils.c
├── rescaler_utils.h
├── sharpyuv.c
├── sharpyuv.h
├── sharpyuv_cpu.c
├── sharpyuv_cpu.h
├── sharpyuv_csp.c
├── sharpyuv_csp.h
├── sharpyuv_dsp.c
├── sharpyuv_dsp.h
├── sharpyuv_gamma.c
├── sharpyuv_gamma.h
├── sharpyuv_neon.c
├── sharpyuv_sse2.c
├── ssim.c
├── ssim_sse2.c
├── syntax_enc.c
├── thread_utils.c
├── thread_utils.h
├── token_enc.c
├── tree_enc.c
├── types.h
├── upsampling.c
├── upsampling_neon.c
├── upsampling_sse2.c
├── upsampling_sse41.c
├── utils.c
├── utils.h
├── vp8_dec.h
├── vp8i_dec.h
├── vp8i_enc.h
├── vp8l_enc.c
├── vp8li_dec.h
├── vp8li_enc.h
├── webp_enc.c
├── webpi_dec.h
├── yuv.c
├── yuv.h
├── yuv_neon.c
├── yuv_sse2.c
└── yuv_sse41.c
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @marandaneto
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: 🐞 Bug Report
2 | description: Tell us about something that's not working the way we (probably) intend.
3 | labels: ["Platform: iOS", "bug"]
4 | body:
5 |
6 |
7 | - type: input
8 | id: version
9 | attributes:
10 | label: Version
11 | description: SDK Version
12 | placeholder: 3.0.0 ← should look like this
13 | validations:
14 | required: true
15 |
16 | - type: textarea
17 | id: repro
18 | attributes:
19 | label: Steps to Reproduce
20 | description: How can we see what you're seeing? Specific is terrific.
21 | placeholder: |-
22 | 1. foo
23 | 2. bar
24 | 3. baz
25 | validations:
26 | required: true
27 |
28 | - type: textarea
29 | id: expected
30 | attributes:
31 | label: Expected Result
32 | validations:
33 | required: true
34 |
35 | - type: textarea
36 | id: actual
37 | attributes:
38 | label: Actual Result
39 | description: Logs? Screenshots? Yes, please.
40 | validations:
41 | required: true
42 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Ask in the forums
4 | url: https://posthog.com/questions
5 | about: A place to ask questions.
6 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | name: 💡 Feature Request
2 | description: Tell us about a problem our SDK could solve but doesn't.
3 | labels: ["enhancement"]
4 | body:
5 | - type: textarea
6 | id: problem
7 | attributes:
8 | label: Problem Statement
9 | description: What problem could we solve that it doesn't?
10 | placeholder: |-
11 | I want to make whirled peas, but it doesn't blend.
12 | validations:
13 | required: true
14 |
15 | - type: textarea
16 | id: expected
17 | attributes:
18 | label: Solution Brainstorm
19 | description: We know you have bright ideas to share ... share away, friend.
20 | placeholder: |-
21 | Add a blender to it.
22 | validations:
23 | required: false
24 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/maintainer-blank.yml:
--------------------------------------------------------------------------------
1 | name: Blank Issue
2 | description: Blank Issue. Reserved for maintainers.
3 | body:
4 | - type: textarea
5 | id: description
6 | attributes:
7 | label: Description
8 | description: Please describe the issue.
9 | validations:
10 | required: true
11 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## :bulb: Motivation and Context
2 |
3 |
4 |
5 |
6 | ## :green_heart: How did you test it?
7 |
8 |
9 | ## :pencil: Checklist
10 |
11 |
12 | - [ ] I reviewed the submitted code.
13 | - [ ] I added tests to verify the changes.
14 | - [ ] I updated the docs if needed.
15 | - [ ] No breaking change or entry added to the changelog.
16 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | schedule:
6 | interval: weekly
7 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | daysUntilStale: 60
2 | daysUntilClose: 7
3 | exemptLabels:
4 | - pinned
5 | - security
6 | staleLabel: wontfix
7 | # Comment to post when marking an issue as stale. Set to `false` to disable
8 | markComment: >
9 | This issue has been automatically marked as stale because it has not had
10 | recent activity. It will be closed if no further activity occurs. Thank you
11 | for your contributions.
12 | closeComment: true
13 |
--------------------------------------------------------------------------------
/.github/workflows/build-examples.yml:
--------------------------------------------------------------------------------
1 | name: Build Examples
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 | paths-ignore:
8 | - "**/*.md"
9 | jobs:
10 | build:
11 | runs-on: macos-14
12 | steps:
13 | - uses: actions/checkout@v4
14 | - uses: maxim-lobanov/setup-xcode@v1
15 | with:
16 | xcode-version: latest-stable
17 | - name: Build Example
18 | run: make buildExamples
19 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 | paths-ignore:
8 | - "**/*.md"
9 | jobs:
10 | build:
11 | runs-on: macos-14
12 | steps:
13 | - uses: actions/checkout@v4
14 | - uses: maxim-lobanov/setup-xcode@v1
15 | with:
16 | xcode-version: latest-stable
17 | - name: Build SDK
18 | run: make buildSdk
19 |
--------------------------------------------------------------------------------
/.github/workflows/danger.yml:
--------------------------------------------------------------------------------
1 | name: "Danger"
2 | on:
3 | pull_request:
4 | types: [opened, synchronize, reopened, edited, ready_for_review]
5 |
6 | jobs:
7 | build:
8 | name: Changelog
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | with:
13 | fetch-depth: 0
14 | - run: npx danger ci
15 | env:
16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yml:
--------------------------------------------------------------------------------
1 | name: Lint
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 | paths-ignore:
8 | - "**/*.md"
9 | jobs:
10 | lint:
11 | runs-on: macos-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 |
15 | - name: Bootstrap
16 | run: make bootstrap
17 |
18 | - name: Run lints
19 | run: make lint
20 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: 'Release'
2 | on:
3 | release:
4 | # runs for stable and pre-releases
5 | types: [published]
6 |
7 | jobs:
8 | cancel-previous-workflow:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Cancel Previous Runs
12 | uses: styfle/cancel-workflow-action@85880fa0301c86cca9da44039ee3bb12d3bedbfa # pin@0.12.1
13 | with:
14 | access_token: ${{ github.token }}
15 |
16 | release:
17 | name: Release
18 | runs-on: macos-14
19 | env:
20 | COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }} # Using Manoel's token for now
21 |
22 | steps:
23 | - name: Git checkout
24 | uses: actions/checkout@v4
25 | - uses: maxim-lobanov/setup-xcode@v1
26 | with:
27 | xcode-version: '16.2'
28 |
29 | - name: Bootstrap
30 | run: make bootstrap
31 |
32 | - name: Release
33 | run: make releaseCocoaPods
34 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Tests
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 | paths-ignore:
8 | - "**/*.md"
9 | jobs:
10 | test:
11 | runs-on: macos-14
12 | steps:
13 | - uses: actions/checkout@v4
14 | - uses: maxim-lobanov/setup-xcode@v1
15 | with:
16 | xcode-version: latest-stable
17 | - name: Test SDK
18 | run: make test
--------------------------------------------------------------------------------
/.periphery.yml:
--------------------------------------------------------------------------------
1 | retain_public: true
2 | targets:
3 | - PostHog
4 |
--------------------------------------------------------------------------------
/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | excluded: # case-sensitive paths to ignore during linting. Takes precedence over `included`
2 | - PostHogExample
3 | - PostHogExampleWithSPM
4 | - PostHogExampleAutocapture
5 | - PostHogTests
6 | - PostHog/Utils/ReadWriteLock.swift
7 | - PostHog/Utils/Reachability.swift
8 | - PostHog/Utils/Data+Gzip.swift
9 | - .build
10 | - Pods
11 |
12 | disabled_rules:
13 | - force_cast
14 | - todo
15 | - trailing_comma
16 | - opening_brace
17 |
18 | line_length:
19 | warning: 160
20 | ignores_comments: true
21 | excluded_lines_patterns: [
22 | # long deprecation messages
23 | \@available(.*/*deprecated.*)
24 | ]
25 |
26 | file_length:
27 | warning: 1000
28 | error: 1200
29 |
30 | identifier_name:
31 | excluded:
32 | - id
33 | - ^ph_.*$
34 |
35 | function_body_length:
36 | - 1000 # warning
37 | - 1200 # error
38 |
39 | type_body_length:
40 | - 1000 # warning
41 | - 1200 # error
42 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | If you would like to contribute code to `posthog-ios` you can do so through
4 | GitHub by forking the repository and opening a pull request against `main`.
5 |
6 | ## Development Guide
7 |
8 | 1. Install Xcode
9 | 2. Open the **file** `PostHog.xcodeproj` project in Xcode
10 | 3. Run `make bootstrap` to install all dependencies.
11 |
12 | When submitting code, please make every effort to follow existing conventions
13 | and style in order to keep the code as readable as possible. Please also make
14 | sure your code compiles by `make build`. In addition please consider adding
15 | unit tests covering your change, this will make your change much more likely to be accepted
16 |
17 | Above all, thank you for contributing!
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [2023] [PostHog]
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "CwlCatchException",
6 | "repositoryURL": "https://github.com/mattgallagher/CwlCatchException.git",
7 | "state": {
8 | "branch": null,
9 | "revision": "3ef6999c73b6938cc0da422f2c912d0158abb0a0",
10 | "version": "2.2.0"
11 | }
12 | },
13 | {
14 | "package": "CwlPreconditionTesting",
15 | "repositoryURL": "https://github.com/mattgallagher/CwlPreconditionTesting.git",
16 | "state": {
17 | "branch": null,
18 | "revision": "2ef56b2caf25f55fa7eef8784c30d5a767550f54",
19 | "version": "2.2.1"
20 | }
21 | },
22 | {
23 | "package": "Nimble",
24 | "repositoryURL": "https://github.com/Quick/Nimble.git",
25 | "state": {
26 | "branch": null,
27 | "revision": "edaedc1ec86f14ac6e2ca495b94f0ff7150d98d0",
28 | "version": "12.3.0"
29 | }
30 | },
31 | {
32 | "package": "OHHTTPStubs",
33 | "repositoryURL": "https://github.com/AliSoftware/OHHTTPStubs.git",
34 | "state": {
35 | "branch": null,
36 | "revision": "12f19662426d0434d6c330c6974d53e2eb10ecd9",
37 | "version": "9.1.0"
38 | }
39 | },
40 | {
41 | "package": "Quick",
42 | "repositoryURL": "https://github.com/Quick/Quick.git",
43 | "state": {
44 | "branch": null,
45 | "revision": "16910e406be96e08923918315388c3e989deac9e",
46 | "version": "6.1.0"
47 | }
48 | }
49 | ]
50 | },
51 | "version": 1
52 | }
53 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.3
2 | import PackageDescription
3 |
4 | let package = Package(
5 | name: "PostHog",
6 | platforms: [
7 | // TODO: add .visionOS(.v1), when SPM is >= 5.9
8 | .macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6),
9 | ],
10 | products: [
11 | // Products define the executables and libraries a package produces, and make them visible to other packages.
12 | .library(
13 | name: "PostHog",
14 | targets: ["PostHog"]
15 | ),
16 | ],
17 | dependencies: [
18 | // Dependencies declare other packages that this package depends on.
19 | .package(url: "https://github.com/Quick/Quick.git", from: "6.0.0"),
20 | .package(url: "https://github.com/Quick/Nimble.git", from: "12.0.0"),
21 | .package(url: "https://github.com/AliSoftware/OHHTTPStubs.git", from: "9.0.0"),
22 | ],
23 | targets: [
24 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
25 | // Targets can depend on other targets in this package, and on products in packages this package depends on.
26 | .target(
27 | name: "PostHog",
28 | dependencies: ["phlibwebp"],
29 | path: "PostHog",
30 | resources: [
31 | .copy("Resources/PrivacyInfo.xcprivacy"),
32 | ]
33 | ),
34 | .target(
35 | name: "phlibwebp",
36 | path: "vendor/libwebp",
37 | publicHeadersPath: ".",
38 | cSettings: [
39 | .headerSearchPath("."),
40 | ]
41 | ),
42 | .testTarget(
43 | name: "PostHogTests",
44 | dependencies: [
45 | "PostHog",
46 | "Quick",
47 | "Nimble",
48 | "OHHTTPStubs",
49 | .product(name: "OHHTTPStubsSwift", package: "OHHTTPStubs"),
50 | ],
51 | path: "PostHogTests",
52 | resources: [
53 | .process("Resources"),
54 | ]
55 | ),
56 | ]
57 | )
58 |
--------------------------------------------------------------------------------
/PostHog.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "PostHog"
3 | s.version = "3.19.3"
4 | s.summary = "The hassle-free way to add posthog to your iOS app."
5 |
6 | s.description = <<-DESC
7 | PostHog for iOS provides a single API that lets you
8 | integrate with over 100s of tools.
9 | DESC
10 |
11 | s.homepage = "http://posthog.com/"
12 | s.license = { :type => 'MIT' }
13 | s.author = { "PostHog" => "engineering@posthog.com" }
14 | s.source = { :git => "https://github.com/PostHog/posthog-ios.git", :tag => s.version.to_s }
15 | s.social_media_url = 'https://twitter.com/PostHog'
16 | s.readme = "https://raw.githubusercontent.com/PostHog/posthog-ios/#{s.version.to_s}/README.md"
17 | s.changelog = "https://raw.githubusercontent.com/PostHog/posthog-ios/#{s.version.to_s}/CHANGELOG.md"
18 |
19 | s.ios.deployment_target = '13.0'
20 | s.tvos.deployment_target = '13.0'
21 | s.osx.deployment_target = "10.15"
22 | s.watchos.deployment_target = "6.0"
23 | s.visionos.deployment_target = "1.0"
24 | s.swift_versions = "5.3"
25 |
26 | s.frameworks = 'Foundation'
27 |
28 | s.source_files = [
29 | 'PostHog/**/*.{swift,h,hpp,m,mm,c,cpp}',
30 | 'vendor/libwebp/**/*.{h,c}'
31 | ]
32 | s.resource_bundles = { "PostHog" => "PostHog/Resources/PrivacyInfo.xcprivacy" }
33 | end
34 |
--------------------------------------------------------------------------------
/PostHog.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PostHog.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PostHog.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PostHog/Autocapture/AutocaptureEventProcessing.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AutocaptureEventProcessing.swift
3 | // PostHog
4 | //
5 | // Created by Yiannis Josephides on 30/10/2024.
6 | //
7 |
8 | #if os(iOS) || targetEnvironment(macCatalyst)
9 | import Foundation
10 |
11 | protocol AutocaptureEventProcessing: AnyObject {
12 | func process(source: PostHogAutocaptureEventTracker.EventSource, event: PostHogAutocaptureEventTracker.EventData)
13 | }
14 | #endif
15 |
--------------------------------------------------------------------------------
/PostHog/Autocapture/UIView+PostHogLabel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+PostHogLabel.swift
3 | // PostHog
4 | //
5 | // Created by Yiannis Josephides on 04/12/2024.
6 | //
7 |
8 | #if os(iOS) || targetEnvironment(macCatalyst)
9 | import UIKit
10 |
11 | public extension UIView {
12 | /**
13 | Adds a custom label to this view for use with PostHog's auto-capture functionality.
14 |
15 | By setting a custom label, you can easily identify and filter interactions with this specific element in your analytics data.
16 |
17 | ### Usage
18 | ```swift
19 | let myView = UIView()
20 | myView.postHogLabel = "customLabel"
21 | ```
22 | */
23 | var postHogLabel: String? {
24 | get { objc_getAssociatedObject(self, &AssociatedKeys.phLabel) as? String }
25 | set { objc_setAssociatedObject(self, &AssociatedKeys.phLabel, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
26 | }
27 | }
28 |
29 | #endif
30 |
--------------------------------------------------------------------------------
/PostHog/DI.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DI.swift
3 | // PostHog
4 | //
5 | // Created by Yiannis Josephides on 17/12/2024.
6 | //
7 |
8 | // swiftlint:disable:next type_name
9 | enum DI {
10 | static var main = Container()
11 |
12 | final class Container {
13 | lazy var appLifecyclePublisher: AppLifecyclePublishing = ApplicationLifecyclePublisher.shared
14 | lazy var sessionManager: PostHogSessionManager = .init()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/PostHog/PostHog.h:
--------------------------------------------------------------------------------
1 | //
2 | // PostHog.h
3 | // PostHog
4 | //
5 | // Created by Ben White on 10.01.23.
6 | //
7 |
8 | #import
9 |
10 | //! Project version number for PostHog.
11 | FOUNDATION_EXPORT double PostHogVersionNumber;
12 |
13 | //! Project version string for PostHog.
14 | FOUNDATION_EXPORT const unsigned char PostHogVersionString[];
15 |
16 | // In this header, you should import all the public headers of your framework using statements like #import
17 | #import
18 | #import
19 | #import
20 | #import
21 | #import
22 | #import
23 | #import
24 | #import
25 | #import
26 | #import
27 | #import
28 | #import
29 | #import
30 | #import
31 | #import
32 | #import
33 | #import
34 | #import
35 | #import
36 | #import
37 | #import
38 | #import
39 | #import
40 | #import
41 | #import
42 | #import
43 | #import
44 | #import
45 | #import
46 | #import
47 | #import
48 | #import
49 | #import
50 | #import
51 | #import
52 | #import
53 | #import
54 | #import
55 | #import
56 | #import
57 | #import
58 | #import
59 | #import
60 | #import
61 |
--------------------------------------------------------------------------------
/PostHog/PostHog.modulemap:
--------------------------------------------------------------------------------
1 | framework module PostHog {
2 | umbrella header "PostHog.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHog/PostHogBatchUploadInfo.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogBatchUploadInfo.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 13.10.23.
6 | //
7 |
8 | import Foundation
9 |
10 | struct PostHogBatchUploadInfo {
11 | let statusCode: Int?
12 | let error: Error?
13 | }
14 |
--------------------------------------------------------------------------------
/PostHog/PostHogConsumerPayload.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogConsumerPayload.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 13.10.23.
6 | //
7 |
8 | import Foundation
9 |
10 | struct PostHogConsumerPayload {
11 | let events: [PostHogEvent]
12 | let completion: (Bool) -> Void
13 | }
14 |
--------------------------------------------------------------------------------
/PostHog/PostHogExtensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogExtensions.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 13.10.23.
6 | //
7 |
8 | import Foundation
9 |
10 | /**
11 | # Notifications
12 |
13 | This helper module encapsulates all notifications that we trigger from within the SDK.
14 |
15 | */
16 |
17 | public extension PostHogSDK {
18 | @objc static let didStartNotification = Notification.Name("PostHogDidStart") // object: nil
19 | @objc static let didReceiveFeatureFlags = Notification.Name("PostHogDidReceiveFeatureFlags") // object: nil
20 | }
21 |
--------------------------------------------------------------------------------
/PostHog/PostHogLegacyQueue.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogLegacyQueue.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 30.10.23.
6 | //
7 |
8 | import Foundation
9 |
10 | // Migrates the Old Queue (v2) to the new Queue (v3)
11 | func migrateOldQueue(queue: URL, oldQueue: URL) {
12 | if !FileManager.default.fileExists(atPath: oldQueue.path) {
13 | return
14 | }
15 |
16 | defer {
17 | deleteSafely(oldQueue)
18 | }
19 |
20 | do {
21 | let data = try Data(contentsOf: oldQueue)
22 | let array = try JSONSerialization.jsonObject(with: data) as? [Any]
23 |
24 | if array == nil {
25 | return
26 | }
27 |
28 | for item in array! {
29 | guard let event = item as? [String: Any] else {
30 | continue
31 | }
32 | let timestamp = event["timestamp"] as? String ?? toISO8601String(Date())
33 |
34 | let timestampDate = toISO8601Date(timestamp) ?? Date()
35 |
36 | let filename = "\(timestampDate.timeIntervalSince1970)"
37 |
38 | let contents = try JSONSerialization.data(withJSONObject: event)
39 |
40 | try contents.write(to: queue.appendingPathComponent(filename))
41 | }
42 | } catch {
43 | hedgeLog("Failed to migrate queue \(error)")
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/PostHog/PostHogPersonProfiles.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogPersonProfiles.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 09.09.24.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Determines the behavior for processing user profiles.
11 | /// - `never`: We won't process persons for any event. This means that anonymous users will not be merged once
12 | /// they sign up or login, so you lose the ability to create funnels that track users from anonymous to identified.
13 | /// All events (including `$identify`) will be sent with `$process_person_profile: False`.
14 | /// - `always`: We will process persons data for all events.
15 | /// - `identifiedOnly`: (default): we will only process persons when you call `identify`, `alias`, and `group`, Anonymous users won't get person profiles.
16 | @objc(PostHogPersonProfiles) public enum PostHogPersonProfiles: Int {
17 | case never
18 | case always
19 | case identifiedOnly
20 | }
21 |
--------------------------------------------------------------------------------
/PostHog/PostHogPropertiesSanitizer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogPropertiesSanitizer.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 06.08.24.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Protocol to sanitize the event properties
11 | @objc(PostHogPropertiesSanitizer) public protocol PostHogPropertiesSanitizer {
12 | /// Sanitizes the event properties
13 | /// - Parameter properties: the event properties to sanitize
14 | /// - Returns: the sanitized properties
15 | ///
16 | /// Obs: `inout` cannot be used in Swift protocols, so you need to clone the properties
17 | ///
18 | /// ```swift
19 | /// private class ExampleSanitizer: PostHogPropertiesSanitizer {
20 | /// public func sanitize(_ properties: [String: Any]) -> [String: Any] {
21 | /// var sanitizedProperties = properties
22 | /// // Perform sanitization
23 | /// // For example, removing keys with empty values
24 | /// for (key, value) in properties {
25 | /// if let stringValue = value as? String, stringValue.isEmpty {
26 | /// sanitizedProperties.removeValue(forKey: key)
27 | /// }
28 | /// }
29 | /// return sanitizedProperties
30 | /// }
31 | /// }
32 | /// ```
33 | @objc func sanitize(_ properties: [String: Any]) -> [String: Any]
34 | }
35 |
--------------------------------------------------------------------------------
/PostHog/PostHogSwizzler.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogSwizzler.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 26.03.24.
6 | //
7 |
8 | import Foundation
9 |
10 | func swizzle(forClass: AnyClass, original: Selector, new: Selector) {
11 | guard let originalMethod = class_getInstanceMethod(forClass, original) else { return }
12 | guard let swizzledMethod = class_getInstanceMethod(forClass, new) else { return }
13 | method_exchangeImplementations(originalMethod, swizzledMethod)
14 | }
15 |
--------------------------------------------------------------------------------
/PostHog/PostHogVersion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogVersion.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 13.10.23.
6 | //
7 |
8 | import Foundation
9 |
10 | // if you change this, make sure to also change it in the podspec and check if the script scripts/bump-version.sh still works
11 | // This property is internal only
12 | public var postHogVersion = "3.19.3"
13 |
14 | public let postHogiOSSdkName = "posthog-ios"
15 | // This property is internal only
16 | public var postHogSdkName = postHogiOSSdkName
17 |
--------------------------------------------------------------------------------
/PostHog/Replay/CGColor+Util.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CGColor+Util.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 21.03.24.
6 | //
7 |
8 | #if os(iOS)
9 |
10 | import Foundation
11 | import UIKit
12 |
13 | extension CGColor {
14 | func toRGBString() -> String? {
15 | // see dicussion: https://github.com/PostHog/posthog-ios/issues/226
16 | // Allow only CGColors with an intiialized value of `numberOfComponents` with a value in 3...4 range
17 | // Loading dynamic colors from storyboard sometimes leads to some random values for numberOfComponents like `105553118884896` which crashes the app
18 | guard
19 | 3 ... 4 ~= numberOfComponents, // check range
20 | let components = components, // we now assume it's safe to access `components`
21 | components.count >= 3
22 | else {
23 | return nil
24 | }
25 |
26 | let red = Int(components[0] * 255)
27 | let green = Int(components[1] * 255)
28 | let blue = Int(components[2] * 255)
29 |
30 | return String(format: "#%02X%02X%02X", red, green, blue)
31 | }
32 | }
33 | #endif
34 |
--------------------------------------------------------------------------------
/PostHog/Replay/CGSize+Util.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CGSize+Util.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 24.07.24.
6 | //
7 |
8 | #if os(iOS)
9 | import Foundation
10 |
11 | extension CGSize {
12 | func hasSize() -> Bool {
13 | if width == 0 || height == 0 {
14 | return false
15 | }
16 | return true
17 | }
18 | }
19 | #endif
20 |
--------------------------------------------------------------------------------
/PostHog/Replay/Date+Util.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Date+Util.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 21.03.24.
6 | //
7 |
8 | import Foundation
9 |
10 | extension Date {
11 | func toMillis() -> Int64 {
12 | Int64(timeIntervalSince1970 * 1000)
13 | }
14 | }
15 |
16 | public func dateToMillis(_ date: Date) -> Int64 {
17 | date.toMillis()
18 | }
19 |
--------------------------------------------------------------------------------
/PostHog/Replay/NetworkSample.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NetworkSample.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 26.03.24.
6 | //
7 |
8 | #if os(iOS)
9 | import Foundation
10 |
11 | struct NetworkSample {
12 | let sessionId: String
13 | let timeOrigin: Date
14 | let entryType = "resource"
15 | var name: String?
16 | var responseStatus: Int?
17 | var initiatorType = "fetch"
18 | var httpMethod: String?
19 | var duration: Int64?
20 | var decodedBodySize: Int64?
21 |
22 | init(sessionId: String, timeOrigin: Date, url: String? = nil) {
23 | self.timeOrigin = timeOrigin
24 | self.sessionId = sessionId
25 | name = url
26 | }
27 |
28 | func toDict() -> [String: Any] {
29 | var dict: [String: Any] = [
30 | "timestamp": timeOrigin.toMillis(),
31 | "entryType": entryType,
32 | "initiatorType": initiatorType,
33 | ]
34 |
35 | if let name = name {
36 | dict["name"] = name
37 | }
38 |
39 | if let responseStatus = responseStatus {
40 | dict["responseStatus"] = responseStatus
41 | }
42 |
43 | if let httpMethod = httpMethod {
44 | dict["method"] = httpMethod
45 | }
46 |
47 | if let duration = duration {
48 | dict["duration"] = duration
49 | }
50 |
51 | if let decodedBodySize = decodedBodySize {
52 | dict["transferSize"] = decodedBodySize
53 | }
54 |
55 | return dict
56 | }
57 | }
58 | #endif
59 |
--------------------------------------------------------------------------------
/PostHog/Replay/String+Util.swift:
--------------------------------------------------------------------------------
1 | //
2 | // String+Util.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 21.03.24.
6 | //
7 |
8 | import Foundation
9 |
10 | extension String {
11 | func mask() -> String {
12 | String(repeating: "*", count: count)
13 | }
14 | }
15 |
16 | extension Optional where Wrapped == String {
17 | var isNilOrEmpty: Bool {
18 | (self ?? "").isEmpty
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/PostHog/Replay/UIColor+Util.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Util.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 21.03.24.
6 | //
7 | #if os(iOS)
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | extension UIColor {
13 | func toRGBString() -> String? {
14 | cgColor.toRGBString()
15 | }
16 | }
17 | #endif
18 |
--------------------------------------------------------------------------------
/PostHog/Replay/UIImage+Util.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Util.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 27.11.24.
6 | //
7 |
8 | #if os(iOS)
9 | import Foundation
10 | import UIKit
11 |
12 | extension UIImage {
13 | func toBase64(_ compressionQuality: CGFloat = 0.3) -> String? {
14 | toWebPBase64(compressionQuality) ?? toJpegBase64(compressionQuality)
15 | }
16 |
17 | private func toWebPBase64(_ compressionQuality: CGFloat) -> String? {
18 | webpData(compressionQuality: compressionQuality).map { data in
19 | "data:image/webp;base64,\(data.base64EncodedString())"
20 | }
21 | }
22 |
23 | private func toJpegBase64(_ compressionQuality: CGFloat) -> String? {
24 | jpegData(compressionQuality: compressionQuality).map { data in
25 | "data:image/jpeg;base64,\(data.base64EncodedString())"
26 | }
27 | }
28 | }
29 |
30 | public func imageToBase64(_ image: UIImage, _ compressionQuality: CGFloat = 0.3) -> String? {
31 | image.toBase64(compressionQuality)
32 | }
33 | #endif
34 |
--------------------------------------------------------------------------------
/PostHog/Replay/UITextInputTraits+Util.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UITextInputTraits+Util.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 21.03.24.
6 | //
7 |
8 | #if os(iOS)
9 | import Foundation
10 | import UIKit
11 |
12 | private let sensibleTypes: [UITextContentType] = [
13 | .newPassword, .oneTimeCode, .creditCardNumber,
14 | .telephoneNumber, .emailAddress, .password,
15 | .username, .URL, .name, .nickname,
16 | .middleName, .familyName, .nameSuffix,
17 | .namePrefix, .organizationName, .location,
18 | .fullStreetAddress, .streetAddressLine1,
19 | .streetAddressLine2, .addressCity, .addressState,
20 | .addressCityAndState, .postalCode,
21 | ]
22 |
23 | extension UITextInputTraits {
24 | func isSensitiveText() -> Bool {
25 | if isSecureTextEntry ?? false {
26 | return true
27 | }
28 |
29 | if let contentType = textContentType, let contentType = contentType {
30 | return sensibleTypes.contains(contentType)
31 | }
32 |
33 | return false
34 | }
35 | }
36 | #endif
37 |
--------------------------------------------------------------------------------
/PostHog/Replay/ViewLayoutTracker.swift:
--------------------------------------------------------------------------------
1 | #if os(iOS)
2 | import Foundation
3 | import UIKit
4 |
5 | enum ViewLayoutTracker {
6 | private(set) static var hasChanges = false
7 | private static var hasSwizzled = false
8 |
9 | static func viewDidLayout(view _: UIView) {
10 | hasChanges = true
11 | }
12 |
13 | static func clear() {
14 | hasChanges = false
15 | }
16 |
17 | static func swizzleLayoutSubviews() {
18 | if hasSwizzled {
19 | return
20 | }
21 | swizzle(forClass: UIView.self,
22 | original: #selector(UIView.layoutSubviews),
23 | new: #selector(UIView.layoutSubviewsOverride))
24 | hasSwizzled = true
25 | }
26 |
27 | static func unSwizzleLayoutSubviews() {
28 | if !hasSwizzled {
29 | return
30 | }
31 | swizzle(forClass: UIView.self,
32 | original: #selector(UIView.layoutSubviews),
33 | new: #selector(UIView.layoutSubviewsOverride))
34 | hasSwizzled = false
35 | }
36 | }
37 |
38 | extension UIView {
39 | @objc func layoutSubviewsOverride() {
40 | guard Thread.isMainThread else {
41 | return
42 | }
43 | layoutSubviewsOverride()
44 | ViewLayoutTracker.viewDidLayout(view: self)
45 | }
46 | }
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/PostHog/Replay/ViewTreeSnapshotStatus.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewTreeSnapshotStatus.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 20.03.24.
6 | //
7 |
8 | import Foundation
9 |
10 | class ViewTreeSnapshotStatus {
11 | var sentFullSnapshot: Bool = false
12 | var sentMetaEvent: Bool = false
13 | var keyboardVisible: Bool = false
14 | var lastSnapshot: Bool = false
15 | }
16 |
--------------------------------------------------------------------------------
/PostHog/Resources/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyCollectedDataTypes
6 |
7 |
8 | NSPrivacyCollectedDataType
9 | NSPrivacyCollectedDataTypeProductInteraction
10 | NSPrivacyCollectedDataTypeLinked
11 |
12 | NSPrivacyCollectedDataTypeTracking
13 |
14 | NSPrivacyCollectedDataTypePurposes
15 |
16 | NSPrivacyCollectedDataTypePurposeAnalytics
17 |
18 |
19 |
20 | NSPrivacyCollectedDataType
21 | NSPrivacyCollectedDataTypeOtherUsageData
22 | NSPrivacyCollectedDataTypeLinked
23 |
24 | NSPrivacyCollectedDataTypeTracking
25 |
26 | NSPrivacyCollectedDataTypePurposes
27 |
28 | NSPrivacyCollectedDataTypePurposeAnalytics
29 |
30 |
31 |
32 | NSPrivacyAccessedAPITypes
33 |
34 |
35 | NSPrivacyAccessedAPIType
36 | NSPrivacyAccessedAPICategoryUserDefaults
37 | NSPrivacyAccessedAPITypeReasons
38 |
39 | CA92.1
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/PostHog/SwiftUI/PostHogMaskViewModifier.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogMaskViewModifier.swift
3 | // PostHog
4 | //
5 | // Created by Yiannis Josephides on 09/10/2024.
6 | //
7 |
8 | #if os(iOS) && canImport(SwiftUI)
9 |
10 | import SwiftUI
11 |
12 | public extension View {
13 | /**
14 | Marks a SwiftUI View to be masked in PostHog session replay recordings.
15 |
16 | Because of the nature of how we intercept SwiftUI view hierarchy (and how it maps to UIKit),
17 | we can't always be 100% confident that a view should be masked and may accidentally mark a
18 | sensitive view as non-sensitive instead.
19 |
20 | Use this modifier to explicitly mask sensitive views in session replay recordings.
21 |
22 | For example:
23 | ```swift
24 | // This view will be masked in recordings
25 | SensitiveDataView()
26 | .postHogMask()
27 |
28 | // Conditionally mask based on a flag
29 | SensitiveDataView()
30 | .postHogMask(shouldMask)
31 | ```
32 |
33 | - Parameter isEnabled: Whether masking should be enabled. Defaults to true.
34 | - Returns: A modified view that will be masked in session replay recordings when enabled
35 | */
36 | func postHogMask(_ isEnabled: Bool = true) -> some View {
37 | modifier(
38 | PostHogTagViewModifier { uiViews in
39 | uiViews.forEach { $0.postHogNoCapture = isEnabled }
40 | } onRemove: { uiViews in
41 | uiViews.forEach { $0.postHogNoCapture = false }
42 | }
43 | )
44 | }
45 | }
46 |
47 | extension UIView {
48 | var postHogNoCapture: Bool {
49 | get { objc_getAssociatedObject(self, &AssociatedKeys.phNoCapture) as? Bool ?? false }
50 | set { objc_setAssociatedObject(self, &AssociatedKeys.phNoCapture, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
51 | }
52 | }
53 | #endif
54 |
--------------------------------------------------------------------------------
/PostHog/SwiftUI/PostHogNoMaskViewModifier.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogNoMaskViewModifier.swift
3 | // PostHog
4 | //
5 | // Created by Yiannis Josephides on 09/10/2024.
6 | //
7 |
8 | #if os(iOS) && canImport(SwiftUI)
9 |
10 | import SwiftUI
11 |
12 | public extension View {
13 | /**
14 | Marks a SwiftUI View to be excluded from masking in PostHog session replay recordings.
15 |
16 | There are cases where PostHog SDK will unintentionally mask some SwiftUI views.
17 |
18 | Because of the nature of how we intercept SwiftUI view hierarchy (and how it maps to UIKit),
19 | we can't always be 100% confident that a view should be masked. For that reason, we prefer to
20 | take a proactive and prefer to mask views if we're not sure.
21 |
22 | Use this modifier to prevent views from being masked in session replay recordings.
23 |
24 | For example:
25 | ```swift
26 | // This view may be accidentally masked by PostHog SDK
27 | SomeSafeView()
28 |
29 | // This custom view (and all its subviews) will not be masked in recordings
30 | SomeSafeView()
31 | .postHogNoMask()
32 | ```
33 |
34 | - Returns: A modified view that will not be masked in session replay recordings
35 | */
36 | func postHogNoMask() -> some View {
37 | modifier(
38 | PostHogTagViewModifier { uiViews in
39 | uiViews.forEach { $0.postHogNoMask = true }
40 | } onRemove: { uiViews in
41 | uiViews.forEach { $0.postHogNoMask = false }
42 | }
43 | )
44 | }
45 | }
46 |
47 | extension UIView {
48 | var postHogNoMask: Bool {
49 | get { objc_getAssociatedObject(self, &AssociatedKeys.phNoMask) as? Bool ?? false }
50 | set { objc_setAssociatedObject(self, &AssociatedKeys.phNoMask, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) }
51 | }
52 | }
53 |
54 | #endif
55 |
--------------------------------------------------------------------------------
/PostHog/SwiftUI/PostHogSwiftUIViewModifiers.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogSwiftUIViewModifiers.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 05.09.24.
6 | //
7 |
8 | #if canImport(SwiftUI)
9 | import Foundation
10 | import SwiftUI
11 |
12 | public extension View {
13 | /**
14 | Marks a SwiftUI View to be tracked as a $screen event in PostHog when onAppear is called.
15 |
16 | - Parameters:
17 | - screenName: The name of the screen. Defaults to the type of the view.
18 | - properties: Additional properties to be tracked with the screen.
19 | - Returns: A modified view that will be tracked as a screen in PostHog.
20 | */
21 | func postHogScreenView(_ screenName: String? = nil,
22 | _ properties: [String: Any]? = nil) -> some View
23 | {
24 | let viewEventName = screenName ?? "\(type(of: self))"
25 | return modifier(PostHogSwiftUIViewModifier(viewEventName: viewEventName,
26 | screenEvent: true,
27 | properties: properties))
28 | }
29 |
30 | func postHogViewSeen(_ event: String,
31 | _ properties: [String: Any]? = nil) -> some View
32 | {
33 | modifier(PostHogSwiftUIViewModifier(viewEventName: event,
34 | screenEvent: false,
35 | properties: properties))
36 | }
37 | }
38 |
39 | private struct PostHogSwiftUIViewModifier: ViewModifier {
40 | let viewEventName: String
41 |
42 | let screenEvent: Bool
43 |
44 | let properties: [String: Any]?
45 |
46 | func body(content: Content) -> some View {
47 | content.onAppear {
48 | if screenEvent {
49 | PostHogSDK.shared.screen(viewEventName, properties: properties)
50 | } else {
51 | PostHogSDK.shared.capture(viewEventName, properties: properties)
52 | }
53 | }
54 | }
55 | }
56 |
57 | #endif
58 |
--------------------------------------------------------------------------------
/PostHog/Utils/AssociatedKeys.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AssociatedKeys.swift
3 | // PostHog
4 | //
5 | // Created by Yiannis Josephides on 04/12/2024.
6 | //
7 |
8 | import Foundation
9 |
10 | enum AssociatedKeys {
11 | static var phForwardingDelegate: UInt8 = 0
12 | static var phNoCapture: UInt8 = 0
13 | static var phNoMask: UInt8 = 0
14 | static var phController: UInt8 = 0
15 | static var phView: UInt8 = 0
16 | static var phLabel: UInt8 = 0
17 | }
18 |
--------------------------------------------------------------------------------
/PostHog/Utils/DateUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DateUtils.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 27.10.23.
6 | //
7 |
8 | import Foundation
9 |
10 | private func newDateFormatter() -> DateFormatter {
11 | let dateFormatter = DateFormatter()
12 | dateFormatter.locale = Locale(identifier: "en_US_POSIX")
13 | dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
14 |
15 | dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
16 | return dateFormatter
17 | }
18 |
19 | public func toISO8601String(_ date: Date) -> String {
20 | let dateFormatter = newDateFormatter()
21 | return dateFormatter.string(from: date)
22 | }
23 |
24 | public func toISO8601Date(_ date: String) -> Date? {
25 | let dateFormatter = newDateFormatter()
26 | return dateFormatter.date(from: date)
27 | }
28 |
29 | var now: () -> Date = { Date() }
30 |
--------------------------------------------------------------------------------
/PostHog/Utils/DictUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DictUtils.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 27.10.23.
6 | //
7 |
8 | import Foundation
9 |
10 | public func sanitizeDictionary(_ dict: [String: Any]?) -> [String: Any]? {
11 | if dict == nil || dict!.isEmpty {
12 | return nil
13 | }
14 |
15 | var newDict = dict!
16 |
17 | for (key, value) in newDict where !isValidObject(value) {
18 | if value is URL {
19 | newDict[key] = (value as! URL).absoluteString
20 | continue
21 | }
22 | if value is Date {
23 | newDict[key] = ISO8601DateFormatter().string(from: (value as! Date))
24 | continue
25 | }
26 |
27 | newDict.removeValue(forKey: key)
28 | hedgeLog("property: \(key) isn't serializable, dropping the item")
29 | }
30 |
31 | return newDict
32 | }
33 |
34 | private func isValidObject(_ object: Any) -> Bool {
35 | if object is String || object is Bool || object is any Numeric || object is NSNumber {
36 | return true
37 | }
38 | if object is [Any?] || object is [String: Any?] {
39 | return JSONSerialization.isValidJSONObject(object)
40 | }
41 | // workaround [object] since isValidJSONObject only accepts an Array or Dict
42 | return JSONSerialization.isValidJSONObject([object])
43 | }
44 |
--------------------------------------------------------------------------------
/PostHog/Utils/Errors.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Errors.swift
3 | // PostHog
4 | //
5 | // Created by Ben White on 21.03.23.
6 | //
7 |
8 | import Foundation
9 |
10 | struct InternalPostHogError: Error, CustomStringConvertible {
11 | let description: String
12 |
13 | init(description: String, fileID: StaticString = #fileID, line: UInt = #line) {
14 | self.description = "\(description) (\(fileID):\(line))"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/PostHog/Utils/FileUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FileUtils.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 30.10.23.
6 | //
7 |
8 | import Foundation
9 |
10 | public func deleteSafely(_ file: URL) {
11 | if FileManager.default.fileExists(atPath: file.path) {
12 | do {
13 | try FileManager.default.removeItem(at: file)
14 | } catch {
15 | hedgeLog("Error trying to delete file \(file.path) \(error)")
16 | }
17 | }
18 | }
19 |
20 | /// Check if provided directory exists
21 | func directoryExists(_ directory: URL) -> Bool {
22 | var isDirectory: ObjCBool = false
23 | return FileManager.default.fileExists(atPath: directory.path, isDirectory: &isDirectory) && isDirectory.boolValue
24 | }
25 |
26 | func createDirectoryAtURLIfNeeded(url: URL) {
27 | if FileManager.default.fileExists(atPath: url.path) { return }
28 | do {
29 | try FileManager.default.createDirectory(atPath: url.path, withIntermediateDirectories: true)
30 | } catch {
31 | hedgeLog("Error creating storage directory: \(error)")
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/PostHog/Utils/Hedgelog.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Hedgelog.swift
3 | // PostHog
4 | //
5 | // Created by Ben White on 07.02.23.
6 | //
7 |
8 | import Foundation
9 |
10 | var hedgeLogEnabled = false
11 |
12 | func toggleHedgeLog(_ enabled: Bool) {
13 | hedgeLogEnabled = enabled
14 | }
15 |
16 | // Meant for internally logging PostHog related things
17 | func hedgeLog(_ message: String) {
18 | if !hedgeLogEnabled { return }
19 | print("[PostHog] \(message)")
20 | }
21 |
--------------------------------------------------------------------------------
/PostHog/Utils/ReadWriteLock.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3 | * This product includes software developed at Datadog (https://www.datadoghq.com/).
4 | * Copyright 2019-Present Datadog, Inc.
5 | */
6 |
7 | import Foundation
8 |
9 | /// A property wrapper using a fair, POSIX conforming reader-writer lock for atomic
10 | /// access to the value. It is optimised for concurrent reads and exclusive writes.
11 | ///
12 | /// The wrapper is a class to prevent copying the lock, it creates and initilaizes a `pthread_rwlock_t`.
13 | /// An additional method `mutate` allow to safely mutate the value in-place (to read it
14 | /// and write it while obtaining the lock only once).
15 | @propertyWrapper
16 | public final class ReadWriteLock {
17 | /// The wrapped value.
18 | private var value: Value
19 |
20 | /// The lock object.
21 | private var rwlock = pthread_rwlock_t()
22 |
23 | public init(wrappedValue value: Value) {
24 | pthread_rwlock_init(&rwlock, nil)
25 | self.value = value
26 | }
27 |
28 | deinit {
29 | pthread_rwlock_destroy(&rwlock)
30 | }
31 |
32 | /// The wrapped value.
33 | ///
34 | /// The `get` will acquire the lock for reading while the `set` will acquire for
35 | /// writing.
36 | public var wrappedValue: Value {
37 | get {
38 | pthread_rwlock_rdlock(&rwlock)
39 | defer { pthread_rwlock_unlock(&rwlock) }
40 | return value
41 | }
42 | set {
43 | pthread_rwlock_wrlock(&rwlock)
44 | value = newValue
45 | pthread_rwlock_unlock(&rwlock)
46 | }
47 | }
48 |
49 | /// Provides a non-escaping closure for mutation.
50 | /// The lock will be acquired once for writing before invoking the closure.
51 | ///
52 | /// - Parameter closure: The closure with the mutable value.
53 | @discardableResult
54 | public func mutate(_ closure: (inout Value) -> T) -> T {
55 | pthread_rwlock_wrlock(&rwlock)
56 | defer {
57 | pthread_rwlock_unlock(&rwlock)
58 | }
59 | return closure(&value)
60 | }
61 | }
62 |
63 | func synchronized(_ lock: Any, closure: () -> Void) {
64 | objc_sync_enter(lock)
65 | closure()
66 | objc_sync_exit(lock)
67 | }
68 |
--------------------------------------------------------------------------------
/PostHog/Utils/UIApplication+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIApplication+.swift
3 | // PostHog
4 | //
5 | // Created by Yiannis Josephides on 11/11/2024.
6 | //
7 |
8 | #if os(iOS) || os(tvOS)
9 | import UIKit
10 |
11 | extension UIApplication {
12 | static func getCurrentWindow(filterForegrounded: Bool = true) -> UIWindow? {
13 | let windowScenes = UIApplication.shared
14 | .connectedScenes
15 | .compactMap { $0 as? UIWindowScene }
16 | .filter {
17 | !filterForegrounded || $0.activationState == .foregroundActive
18 | }
19 |
20 | for scene in windowScenes {
21 | // attempt to retrieve directly from UIWindowScene
22 | if #available(iOS 15.0, tvOS 15.0, *) {
23 | if let keyWindow = scene.keyWindow {
24 | return keyWindow
25 | }
26 | } else {
27 | // check scene.windows.isKeyWindow
28 | for window in scene.windows where window.isKeyWindow {
29 | return window
30 | }
31 | }
32 |
33 | // check scene.delegate.window property
34 | let sceneDelegate = scene.delegate as? UIWindowSceneDelegate
35 | if let target = sceneDelegate, let window = target.window {
36 | return window
37 | }
38 | }
39 |
40 | return nil
41 | }
42 | }
43 | #endif
44 |
--------------------------------------------------------------------------------
/PostHog/Utils/UIWindow+.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIWindow+.swift
3 | // PostHog
4 | //
5 | // Created by Yiannis Josephides on 03/12/2024.
6 | //
7 |
8 | #if os(iOS) || os(tvOS)
9 | import Foundation
10 | import UIKit
11 |
12 | /**
13 | Known keyboard window (private) types
14 |
15 | ## UIRemoteKeyboardWindow
16 | This is the window that manages the actual keyboard
17 |
18 | The following system view controllers were observed to be presented in a UIRemoteKeyboardWindow window
19 | - UIInputWindowController
20 | - UICompatibilityInputViewController
21 | - UISystemInputAssistantViewController
22 | - UIPredictionViewController
23 | - UISystemKeyboardDockController
24 | - TUIEmojiSearchInputViewController
25 | - STKPrewarmingViewController
26 | - STKStickerRemoteSearchViewController
27 | - _UIRemoteInputViewController
28 | - _UISceneHostingViewController
29 | - STKEmojiAndStickerCollectionViewController
30 |
31 | ## UITextEffectsWindow
32 | Hosts system components like the magnifying glass for text selection, predictive text suggestions, copy/paste menus, input accessory views etc.
33 |
34 | The following system view controllers were observed to be presented in a UITextEffectsWindow window
35 | - UIInputWindowController
36 | - UICompatibilityInputViewController
37 |
38 | These view controllers should not appear in a $screen event. If they do, then it means that they are presented in a UIWindow not listed below
39 | */
40 | private let knownKeyboardWindowTypes: [String] = [
41 | "UIRemoteKeyboardWindow",
42 | "UITextEffectsWindow",
43 | ]
44 |
45 | extension UIWindow {
46 | var isKeyboardWindow: Bool {
47 | knownKeyboardWindowTypes.contains(String(describing: type(of: self)))
48 | }
49 | }
50 | #endif
51 |
--------------------------------------------------------------------------------
/PostHog/Utils/UUIDUtils.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UUIDUtils.swift
3 | // PostHog
4 | //
5 | // Created by Manoel Aranda Neto on 17.06.24.
6 | //
7 |
8 | // Inspired and adapted from https://github.com/nthState/UUIDV7/blob/main/Sources/UUIDV7/UUIDV7.swift
9 | // but using SecRandomCopyBytes
10 |
11 | import Foundation
12 |
13 | extension UUID {
14 | static func v7() -> Self {
15 | TimeBasedEpochGenerator.shared.v7()
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/PostHogExample/Api.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Api.swift
3 | // PostHogExample
4 | //
5 | // Created by Ben White on 06.02.23.
6 | //
7 |
8 | import Foundation
9 | import OSLog
10 |
11 | struct PostHogBeerInfo: Codable, Identifiable {
12 | let id: Int
13 | var name: String
14 | var first_brewed: String
15 | }
16 |
17 | class Api: ObservableObject {
18 | @Published var beers = [PostHogBeerInfo]()
19 |
20 | var logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "main")
21 |
22 | func listBeers(completion _: @escaping ([PostHogBeerInfo]) -> Void) {
23 | // guard let url = URL(string: "https://api.punkapi.com/v2/beers") else {
24 | // return
25 | // }
26 | //
27 | // logger.info("Requesting beers list...")
28 | // URLSession.shared.dataTask(with: url) { _, _, _ in
29 | // let beers = try! JSONDecoder().decode([PostHogBeerInfo].self, from: data!)
30 | //
31 | // DispatchQueue.main.async {
32 | // completion(beers)
33 | // }
34 | // }.resume()
35 | }
36 |
37 | func failingRequest() -> URLSessionDataTask? {
38 | guard let url = URL(string: "https://api.github.com/user") else {
39 | return nil
40 | }
41 |
42 | logger.info("Requesting protected endpoint...")
43 | let task = URLSession.shared.dataTask(with: url) { data, _, _ in
44 | if data == nil {
45 | return
46 | }
47 | print("Response", String(decoding: data!, as: UTF8.self))
48 | }
49 |
50 | task.resume()
51 |
52 | return task
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/PostHogExample/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // PostHogExample
4 | //
5 | // Created by Ben White on 10.01.23.
6 | //
7 |
8 | import Foundation
9 | import PostHog
10 | import UIKit
11 |
12 | class AppDelegate: NSObject, UIApplicationDelegate {
13 | func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
14 | let config = PostHogConfig(
15 | apiKey: "phc_QFbR1y41s5sxnNTZoyKG2NJo2RlsCIWkUfdpawgb40D"
16 | )
17 | // the ScreenViews for SwiftUI does not work, the names are not useful
18 | config.captureScreenViews = false
19 | config.captureApplicationLifecycleEvents = false
20 | // config.flushAt = 1
21 | // config.flushIntervalSeconds = 30
22 | config.debug = true
23 | config.sendFeatureFlagEvent = false
24 | config.sessionReplay = true
25 | config.sessionReplayConfig.screenshotMode = true
26 | config.sessionReplayConfig.maskAllTextInputs = true
27 | config.sessionReplayConfig.maskAllImages = true
28 |
29 | PostHogSDK.shared.setup(config)
30 | // PostHogSDK.shared.debug()
31 | // PostHogSDK.shared.capture("App started!")
32 | // PostHogSDK.shared.reset()
33 |
34 | // PostHogSDK.shared.identify("Manoel")
35 |
36 | let defaultCenter = NotificationCenter.default
37 |
38 | #if os(iOS) || os(tvOS)
39 | defaultCenter.addObserver(self,
40 | selector: #selector(receiveFeatureFlags),
41 | name: PostHogSDK.didReceiveFeatureFlags,
42 | object: nil)
43 | #endif
44 |
45 | return true
46 | }
47 |
48 | @objc func receiveFeatureFlags() {
49 | print("user receiveFeatureFlags callback")
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/PostHogExample/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/PostHogExample/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExample/Assets.xcassets/max_static.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "max_static.png",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/PostHogExample/Assets.xcassets/max_static.imageset/max_static.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExample/Assets.xcassets/max_static.imageset/max_static.png
--------------------------------------------------------------------------------
/PostHogExample/PostHogExample.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.network.client
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/PostHogExample/PostHogExampleApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogExampleApp.swift
3 | // PostHogExample
4 | //
5 | // Created by Ben White on 10.01.23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct PostHogExampleApp: App {
12 | @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
13 |
14 | var body: some Scene {
15 | WindowGroup {
16 | ContentView()
17 | .postHogScreenView() // will infer the class name (ContentView)
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/PostHogExample/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExample/Views/UIViewExample.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewExample.swift
3 | // PostHogExample
4 | //
5 | // Created by Ben White on 17.03.23.
6 | //
7 |
8 | import Foundation
9 | import SwiftUI
10 | import UIKit
11 |
12 | class ExampleUIView: UIView {
13 | private var label: UILabel = {
14 | let label = UILabel()
15 | label.translatesAutoresizingMaskIntoConstraints = false
16 | label.font = UIFont.preferredFont(forTextStyle: .title1)
17 | label.text = "Sensitive information!"
18 | label.textAlignment = .center
19 |
20 | return label
21 | }()
22 |
23 | init() {
24 | super.init(frame: .zero)
25 | backgroundColor = .systemPink
26 | accessibilityIdentifier = "ph-no-capture"
27 |
28 | addSubview(label)
29 | NSLayoutConstraint.activate([
30 | label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 16),
31 | label.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
32 | label.topAnchor.constraint(equalTo: topAnchor, constant: 20),
33 | label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -20),
34 | ])
35 | }
36 |
37 | @available(*, unavailable)
38 | required init?(coder _: NSCoder) {
39 | fatalError("init(coder:) has not been implemented")
40 | }
41 | }
42 |
43 | struct RepresentedExampleUIView: UIViewRepresentable {
44 | typealias UIViewType = ExampleUIView
45 |
46 | func makeUIView(context _: Context) -> ExampleUIView {
47 | let view = ExampleUIView()
48 |
49 | // Do some configurations here if needed.
50 | return view
51 | }
52 |
53 | func updateUIView(_: ExampleUIView, context _: Context) {
54 | // Updates the state of the specified view controller with new information from SwiftUI.
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/LICENSE/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright © 2021 Apple Inc.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
9 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture.xcodeproj/.xcodesamplecode.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | The application-specific delegate class.
6 | */
7 |
8 | import PostHog
9 | import UIKit
10 |
11 | @main
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 | func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
14 | let config = PostHogConfig(
15 | apiKey: "phc_QFbR1y41s5sxnNTZoyKG2NJo2RlsCIWkUfdpawgb40D"
16 | )
17 | config.debug = true
18 |
19 | config.captureElementInteractions = true
20 | config.captureApplicationLifecycleEvents = true
21 | config.sendFeatureFlagEvent = false
22 |
23 | config.sessionReplay = true
24 | config.captureScreenViews = true
25 | config.sessionReplayConfig.screenshotMode = true
26 | config.sessionReplayConfig.maskAllTextInputs = false
27 | config.sessionReplayConfig.maskAllImages = false
28 |
29 | PostHogSDK.shared.setup(config)
30 |
31 | PostHogSDK.shared.identify("Max Capture")
32 |
33 | return true
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/Flowers_1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Flowers_1.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/Flowers_1.imageset/Flowers_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/Flowers_1.imageset/Flowers_1.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/Flowers_2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Flowers_2.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/Flowers_2.imageset/Flowers_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/Flowers_2.imageset/Flowers_2.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "stepper_and_segment_background_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "stepper_and_segment_background_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "stepper_and_segment_background_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background.imageset/stepper_and_segment_background_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background.imageset/stepper_and_segment_background_1x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background.imageset/stepper_and_segment_background_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background.imageset/stepper_and_segment_background_2x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background.imageset/stepper_and_segment_background_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background.imageset/stepper_and_segment_background_3x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_disabled.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "stepper_and_segment_background_disabled_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "stepper_and_segment_background_disabled_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "stepper_and_segment_background_disabled_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_disabled.imageset/stepper_and_segment_background_disabled_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_disabled.imageset/stepper_and_segment_background_disabled_1x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_disabled.imageset/stepper_and_segment_background_disabled_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_disabled.imageset/stepper_and_segment_background_disabled_2x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_disabled.imageset/stepper_and_segment_background_disabled_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_disabled.imageset/stepper_and_segment_background_disabled_3x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_highlighted.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "stepper_and_segment_background_highlighted_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "stepper_and_segment_background_highlighted_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "stepper_and_segment_background_highlighted_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_highlighted.imageset/stepper_and_segment_background_highlighted_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_highlighted.imageset/stepper_and_segment_background_highlighted_1x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_highlighted.imageset/stepper_and_segment_background_highlighted_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_highlighted.imageset/stepper_and_segment_background_highlighted_2x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_highlighted.imageset/stepper_and_segment_background_highlighted_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/background_highlighted.imageset/stepper_and_segment_background_highlighted_3x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/search_bar_background.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "search_bar_bg_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "search_bar_bg_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "search_bar_background_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/search_bar_background.imageset/search_bar_background_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/search_bar_background.imageset/search_bar_background_3x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/search_bar_background.imageset/search_bar_bg_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/search_bar_background.imageset/search_bar_bg_1x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/search_bar_background.imageset/search_bar_bg_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/search_bar_background.imageset/search_bar_bg_2x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_blue_track.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "slider_blue_track_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "slider_blue_track_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "slider_blue_track_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_1x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_2x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_blue_track.imageset/slider_blue_track_3x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_green_track.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "slider_green_track_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "slider_green_track_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "slider_green_track_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_green_track.imageset/slider_green_track_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_green_track.imageset/slider_green_track_1x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_green_track.imageset/slider_green_track_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_green_track.imageset/slider_green_track_2x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_green_track.imageset/slider_green_track_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/slider_green_track.imageset/slider_green_track_3x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/stepper_and_segment_divider.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "stepper_and_segment_segment_divider_1x.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "stepper_and_segment_segment_divider_2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "stepper_and_segment_divider_3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/stepper_and_segment_divider.imageset/stepper_and_segment_divider_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/stepper_and_segment_divider.imageset/stepper_and_segment_divider_3x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/stepper_and_segment_divider.imageset/stepper_and_segment_segment_divider_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/stepper_and_segment_divider.imageset/stepper_and_segment_segment_divider_1x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/stepper_and_segment_divider.imageset/stepper_and_segment_segment_divider_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/stepper_and_segment_divider.imageset/stepper_and_segment_segment_divider_2x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_background.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "resizing" : {
5 | "mode" : "3-part-horizontal",
6 | "center" : {
7 | "mode" : "stretch",
8 | "width" : 0
9 | },
10 | "cap-insets" : {
11 | "right" : 1,
12 | "left" : 1
13 | }
14 | },
15 | "idiom" : "universal",
16 | "filename" : "text_field_background_1x.png",
17 | "scale" : "1x"
18 | },
19 | {
20 | "resizing" : {
21 | "mode" : "3-part-horizontal",
22 | "center" : {
23 | "mode" : "stretch",
24 | "width" : 0
25 | },
26 | "cap-insets" : {
27 | "right" : 1,
28 | "left" : 1
29 | }
30 | },
31 | "idiom" : "universal",
32 | "filename" : "text_field_background_2x.png",
33 | "scale" : "2x"
34 | },
35 | {
36 | "idiom" : "universal",
37 | "filename" : "text_field_background_3x.png",
38 | "scale" : "3x"
39 | }
40 | ],
41 | "info" : {
42 | "version" : 1,
43 | "author" : "xcode"
44 | }
45 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_background.imageset/text_field_background_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_background.imageset/text_field_background_1x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_background.imageset/text_field_background_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_background.imageset/text_field_background_2x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_background.imageset/text_field_background_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_background.imageset/text_field_background_3x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_purple_right_view.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "text_field_purple_right_view_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "text_field_purple_right_view_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "text_field_purple_right_view_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_1x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_2x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_field_purple_right_view.imageset/text_field_purple_right_view_3x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_view_attachment.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Sunset_5.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_view_attachment.imageset/Sunset_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_view_attachment.imageset/Sunset_5.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/text_view_background.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | },
6 | "colors" : [
7 | {
8 | "idiom" : "universal",
9 | "color" : {
10 | "color-space" : "srgb",
11 | "components" : {
12 | "red" : "1.000",
13 | "alpha" : "1.000",
14 | "blue" : "1.000",
15 | "green" : "1.000"
16 | }
17 | }
18 | },
19 | {
20 | "idiom" : "universal",
21 | "appearances" : [
22 | {
23 | "appearance" : "luminosity",
24 | "value" : "light"
25 | }
26 | ],
27 | "color" : {
28 | "color-space" : "srgb",
29 | "components" : {
30 | "red" : "1.000",
31 | "alpha" : "1.000",
32 | "blue" : "1.000",
33 | "green" : "1.000"
34 | }
35 | }
36 | },
37 | {
38 | "idiom" : "universal",
39 | "appearances" : [
40 | {
41 | "appearance" : "luminosity",
42 | "value" : "dark"
43 | }
44 | ],
45 | "color" : {
46 | "color-space" : "srgb",
47 | "components" : {
48 | "red" : "0.000",
49 | "alpha" : "0.000",
50 | "blue" : "0.000",
51 | "green" : "0.000"
52 | }
53 | }
54 | },
55 | {
56 | "idiom" : "ipad",
57 | "color" : {
58 | "color-space" : "srgb",
59 | "components" : {
60 | "red" : "1.000",
61 | "alpha" : "1.000",
62 | "blue" : "1.000",
63 | "green" : "1.000"
64 | }
65 | }
66 | }
67 | ]
68 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/tinted_segmented_control.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | },
6 | "colors" : [
7 | {
8 | "idiom" : "universal",
9 | "color" : {
10 | "color-space" : "srgb",
11 | "components" : {
12 | "red" : "0.031",
13 | "alpha" : "1.000",
14 | "blue" : "0.500",
15 | "green" : "0.702"
16 | }
17 | }
18 | },
19 | {
20 | "idiom" : "universal",
21 | "appearances" : [
22 | {
23 | "appearance" : "luminosity",
24 | "value" : "light"
25 | }
26 | ],
27 | "color" : {
28 | "color-space" : "srgb",
29 | "components" : {
30 | "red" : "0.031",
31 | "alpha" : "1.000",
32 | "blue" : "0.500",
33 | "green" : "0.702"
34 | }
35 | }
36 | },
37 | {
38 | "idiom" : "universal",
39 | "appearances" : [
40 | {
41 | "appearance" : "luminosity",
42 | "value" : "dark"
43 | }
44 | ],
45 | "color" : {
46 | "color-space" : "srgb",
47 | "components" : {
48 | "red" : "0.209",
49 | "alpha" : "1.000",
50 | "blue" : "0.500",
51 | "green" : "0.938"
52 | }
53 | }
54 | },
55 | {
56 | "idiom" : "ipad",
57 | "color" : {
58 | "color-space" : "srgb",
59 | "components" : {
60 | "red" : "0.031",
61 | "alpha" : "1.000",
62 | "blue" : "0.500",
63 | "green" : "0.702"
64 | }
65 | }
66 | }
67 | ]
68 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/tinted_stepper_control.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | },
6 | "colors" : [
7 | {
8 | "idiom" : "universal",
9 | "color" : {
10 | "color-space" : "srgb",
11 | "components" : {
12 | "red" : "0.031",
13 | "alpha" : "1.000",
14 | "blue" : "0.500",
15 | "green" : "0.702"
16 | }
17 | }
18 | },
19 | {
20 | "idiom" : "universal",
21 | "appearances" : [
22 | {
23 | "appearance" : "luminosity",
24 | "value" : "light"
25 | }
26 | ],
27 | "color" : {
28 | "color-space" : "srgb",
29 | "components" : {
30 | "red" : "0.031",
31 | "alpha" : "1.000",
32 | "blue" : "0.500",
33 | "green" : "0.702"
34 | }
35 | }
36 | },
37 | {
38 | "idiom" : "universal",
39 | "appearances" : [
40 | {
41 | "appearance" : "luminosity",
42 | "value" : "dark"
43 | }
44 | ],
45 | "color" : {
46 | "color-space" : "srgb",
47 | "components" : {
48 | "red" : "0.209",
49 | "alpha" : "1.000",
50 | "blue" : "0.500",
51 | "green" : "0.938"
52 | }
53 | }
54 | },
55 | {
56 | "idiom" : "ipad",
57 | "color" : {
58 | "color-space" : "srgb",
59 | "components" : {
60 | "red" : "0.031",
61 | "alpha" : "1.000",
62 | "blue" : "0.500",
63 | "green" : "0.702"
64 | }
65 | }
66 | }
67 | ]
68 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/toolbar_background.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "toolbar_background_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "toolbar_background_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "toolbar_background_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/toolbar_background.imageset/toolbar_background_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/toolbar_background.imageset/toolbar_background_1x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/toolbar_background.imageset/toolbar_background_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/toolbar_background.imageset/toolbar_background_2x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/toolbar_background.imageset/toolbar_background_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogExampleAutocapture/PostHogExampleAutocapture/Assets.xcassets/toolbar_background.imageset/toolbar_background_3x.png
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Base.lproj/Credits.rtf:
--------------------------------------------------------------------------------
1 | {\rtf1\ansi\ansicpg1252\cocoartf2617
2 | \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
3 | {\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
4 | {\*\expandedcolortbl;;\cssrgb\c0\c0\c0\cname textColor;}
5 | \vieww9000\viewh8400\viewkind0
6 | \pard\tx960\tx1920\tx2880\tx3840\tx4800\tx5760\tx6720\tx7680\tx8640\tx9600\qc\partightenfactor0
7 |
8 | \f0\fs20 \cf2 Demonstrates how to use {\field{\*\fldinst{HYPERLINK "https://developer.apple.com/documentation/uikit"}}{\fldrslt UIKit}}\
9 | views, controls and pickers.\
10 | }
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Base.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | Localized versions of Info.plist keys.
6 | */
7 |
8 | CFBundleGetInfoString = "v16.0, Copyright 2008-2021, Apple Inc.";
9 | NSHumanReadableCopyright = "Copyright © 2008-2021, Apple Inc.";
10 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/Base.lproj/content.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WKWebView
5 |
10 |
11 |
12 |
13 | This is HTML content inside a WKWebView.
14 | For more information refer to developer.apple.com
15 |
16 |
17 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/BaseTableViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | A base class used for all UITableViewControllers in this sample app.
6 | */
7 |
8 | import UIKit
9 |
10 | class BaseTableViewController: UITableViewController {
11 | // List of table view cell test cases.
12 | var testCells = [CaseElement]()
13 |
14 | func centeredHeaderView(_ title: String) -> UITableViewHeaderFooterView {
15 | // Set the header title and make it centered.
16 | let headerView = UITableViewHeaderFooterView()
17 | var content = UIListContentConfiguration.groupedHeader()
18 | content.text = title
19 | content.textProperties.alignment = .center
20 | headerView.contentConfiguration = content
21 | return headerView
22 | }
23 |
24 | // MARK: - UITableViewDataSource
25 |
26 | override func tableView(_: UITableView, viewForHeaderInSection section: Int) -> UIView? {
27 | centeredHeaderView(testCells[section].title)
28 | }
29 |
30 | override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
31 | testCells[section].title
32 | }
33 |
34 | override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int {
35 | 1
36 | }
37 |
38 | override func numberOfSections(in _: UITableView) -> Int {
39 | testCells.count
40 | }
41 |
42 | override func tableView(_ tableView: UITableView,
43 | cellForRowAt indexPath: IndexPath) -> UITableViewCell
44 | {
45 | let cellTest = testCells[indexPath.section]
46 | let cell = tableView.dequeueReusableCell(withIdentifier: cellTest.cellID, for: indexPath)
47 | if let view = cellTest.targetView(cell) {
48 | cellTest.configHandler(view)
49 | }
50 | return cell
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/CaseElement.swift:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | Test case element that serves our UITableViewCells.
6 | */
7 |
8 | import UIKit
9 |
10 | struct CaseElement {
11 | var title: String // Visual title of the cell (table section header title)
12 | var cellID: String // Table view cell's identifier for searching for the cell within the nib file.
13 |
14 | typealias ConfigurationClosure = (UIView) -> Void
15 | var configHandler: ConfigurationClosure // Configuration handler for setting up the cell's subview.
16 |
17 | init(title: String, cellID: String, configHandler: @escaping (V) -> Void) {
18 | self.title = title
19 | self.cellID = cellID
20 | self.configHandler = { view in
21 | guard let view = view as? V else { fatalError("Impossible") }
22 | configHandler(view)
23 | }
24 | }
25 |
26 | func targetView(_ cell: UITableViewCell?) -> UIView? {
27 | cell != nil ? cell!.contentView.subviews[0] : nil
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/CustomSearchBarViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | A view controller that demonstrates how to customize a `UISearchBar`.
6 | */
7 |
8 | import UIKit
9 |
10 | class CustomSearchBarViewController: UIViewController {
11 | // MARK: - Properties
12 |
13 | @IBOutlet var searchBar: UISearchBar!
14 |
15 | // MARK: - View Life Cycle
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 |
20 | configureSearchBar()
21 | }
22 |
23 | // MARK: - Configuration
24 |
25 | func configureSearchBar() {
26 | searchBar.showsCancelButton = true
27 | searchBar.showsBookmarkButton = true
28 |
29 | searchBar.tintColor = UIColor.systemPurple
30 |
31 | searchBar.backgroundImage = UIImage(named: "search_bar_background")
32 |
33 | // Set the bookmark image for both normal and highlighted states.
34 | let bookImage = UIImage(systemName: "bookmark")
35 | searchBar.setImage(bookImage, for: .bookmark, state: .normal)
36 |
37 | let bookFillImage = UIImage(systemName: "bookmark.fill")
38 | searchBar.setImage(bookFillImage, for: .bookmark, state: .highlighted)
39 | }
40 | }
41 |
42 | // MARK: - UISearchBarDelegate
43 |
44 | extension CustomSearchBarViewController: UISearchBarDelegate {
45 | func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
46 | Swift.debugPrint("The custom search bar keyboard \"Search\" button was tapped.")
47 |
48 | searchBar.resignFirstResponder()
49 | }
50 |
51 | func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
52 | Swift.debugPrint("The custom search bar \"Cancel\" button was tapped.")
53 |
54 | searchBar.resignFirstResponder()
55 | }
56 |
57 | func searchBarBookmarkButtonClicked(_: UISearchBar) {
58 | Swift.debugPrint("The custom \"bookmark button\" inside the search bar was tapped.")
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/DefaultPageControlViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | A view controller that demonstrates how to use `UIPageControl`.
6 | */
7 |
8 | import UIKit
9 |
10 | class PageControlViewController: UIViewController {
11 | // MARK: - Properties
12 |
13 | @IBOutlet var pageControl: UIPageControl!
14 |
15 | @IBOutlet var colorView: UIView!
16 |
17 | // Colors that correspond to the selected page. Used as the background color for `colorView`.
18 | let colors = [
19 | UIColor.black,
20 | UIColor.systemGray,
21 | UIColor.systemRed,
22 | UIColor.systemGreen,
23 | UIColor.systemBlue,
24 | UIColor.systemPink,
25 | UIColor.systemYellow,
26 | UIColor.systemIndigo,
27 | UIColor.systemOrange,
28 | UIColor.systemPurple,
29 | ]
30 |
31 | // MARK: - View Life Cycle
32 |
33 | override func viewDidLoad() {
34 | super.viewDidLoad()
35 |
36 | configurePageControl()
37 | pageControlValueDidChange()
38 | }
39 |
40 | // MARK: - Configuration
41 |
42 | func configurePageControl() {
43 | // The total number of available pages is based on the number of available colors.
44 | pageControl.numberOfPages = colors.count
45 | pageControl.currentPage = 2
46 |
47 | pageControl.pageIndicatorTintColor = UIColor.systemGreen
48 | pageControl.currentPageIndicatorTintColor = UIColor.systemPurple
49 |
50 | pageControl.addTarget(self, action: #selector(PageControlViewController.pageControlValueDidChange), for: .valueChanged)
51 | }
52 |
53 | // MARK: - Actions
54 |
55 | @objc
56 | func pageControlValueDidChange() {
57 | // Note: gesture swiping between pages is provided by `UIPageViewController` and not `UIPageControl`.
58 | Swift.debugPrint("The page control changed its current page to \(pageControl.currentPage).")
59 |
60 | colorView.backgroundColor = colors[pageControl.currentPage]
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/DefaultSearchBarViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | A view controller that demonstrates how to use a default `UISearchBar`.
6 | */
7 |
8 | import UIKit
9 |
10 | class DefaultSearchBarViewController: UIViewController {
11 | // MARK: - Properties
12 |
13 | @IBOutlet var searchBar: UISearchBar!
14 |
15 | // MARK: - View Life Cycle
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 |
20 | configureSearchBar()
21 | }
22 |
23 | // MARK: - Configuration
24 |
25 | func configureSearchBar() {
26 | searchBar.showsCancelButton = true
27 | searchBar.showsScopeBar = true
28 |
29 | searchBar.scopeButtonTitles = [
30 | NSLocalizedString("Scope One", comment: ""),
31 | NSLocalizedString("Scope Two", comment: ""),
32 | ]
33 | }
34 | }
35 |
36 | // MARK: - UISearchBarDelegate
37 |
38 | extension DefaultSearchBarViewController: UISearchBarDelegate {
39 | func searchBar(_: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
40 | Swift.debugPrint("The default search selected scope button index changed to \(selectedScope).")
41 | }
42 |
43 | func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
44 | Swift.debugPrint("The default search bar keyboard search button was tapped: \(String(describing: searchBar.text)).")
45 |
46 | searchBar.resignFirstResponder()
47 | }
48 |
49 | func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
50 | Swift.debugPrint("The default search bar cancel button was tapped.")
51 |
52 | searchBar.resignFirstResponder()
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/DefaultToolbarViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | A view controller that demonstrates how to use a default `UIToolbar`.
6 | */
7 |
8 | import UIKit
9 |
10 | class DefaultToolbarViewController: UIViewController {
11 | // MARK: - Properties
12 |
13 | @IBOutlet var toolbar: UIToolbar!
14 |
15 | // MARK: - View Life Cycle
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 |
20 | let toolbarButtonItems = [
21 | trashBarButtonItem,
22 | flexibleSpaceBarButtonItem,
23 | customTitleBarButtonItem,
24 | ]
25 | toolbar.setItems(toolbarButtonItems, animated: true)
26 | }
27 |
28 | // MARK: - UIBarButtonItem Creation and Configuration
29 |
30 | var trashBarButtonItem: UIBarButtonItem {
31 | UIBarButtonItem(barButtonSystemItem: .trash,
32 | target: self,
33 | action: #selector(DefaultToolbarViewController.barButtonItemClicked(_:)))
34 | }
35 |
36 | var flexibleSpaceBarButtonItem: UIBarButtonItem {
37 | UIBarButtonItem(barButtonSystemItem: .flexibleSpace,
38 | target: nil,
39 | action: nil)
40 | }
41 |
42 | func menuHandler(action: UIAction) {
43 | Swift.debugPrint("Menu Action '\(action.title)'")
44 | }
45 |
46 | var customTitleBarButtonItem: UIBarButtonItem {
47 | let buttonMenu = UIMenu(title: "",
48 | children: (1 ... 5).map {
49 | UIAction(title: "Option \($0)", handler: menuHandler)
50 | })
51 | return UIBarButtonItem(image: UIImage(systemName: "list.number"), menu: buttonMenu)
52 | }
53 |
54 | // MARK: - Actions
55 |
56 | @objc
57 | func barButtonItemClicked(_ barButtonItem: UIBarButtonItem) {
58 | Swift.debugPrint("A bar button item on the default toolbar was clicked: \(barButtonItem).")
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/ImagePickerViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | A view controller that demonstrates how to use `UIFontPickerViewController`.
6 | */
7 |
8 | import UIKit
9 |
10 | class ImagePickerViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
11 | // MARK: - Properties
12 |
13 | var imagePicker: UIImagePickerController!
14 | @IBOutlet var imageView: UIImageView!
15 |
16 | // MARK: - View Life Cycle
17 |
18 | override func viewDidLoad() {
19 | super.viewDidLoad()
20 |
21 | configureImagePicker()
22 | }
23 |
24 | func configureImagePicker() {
25 | imagePicker = UIImagePickerController()
26 | imagePicker.delegate = self
27 | imagePicker.mediaTypes = ["public.image"]
28 | imagePicker.sourceType = .photoLibrary
29 | }
30 |
31 | @IBAction func presentImagePicker(_: AnyObject) {
32 | present(imagePicker, animated: true)
33 | }
34 |
35 | // MARK: - UIImagePickerControllerDelegate
36 |
37 | func imagePickerController(_ picker: UIImagePickerController,
38 | didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any])
39 | {
40 | if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
41 | imageView.image = image
42 | }
43 | picker.dismiss(animated: true, completion: nil)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/ImageViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | A view controller that demonstrates how to use `UIImageView`.
6 | */
7 |
8 | import UIKit
9 |
10 | class ImageViewController: UIViewController {
11 | // MARK: - View Life Cycle
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | configureImageView()
17 | }
18 |
19 | // MARK: - Configuration
20 |
21 | func configureImageView() {
22 | // The root view of the view controller is set in Interface Builder and is an UIImageView.
23 | if let imageView = view as? UIImageView {
24 | // Fetch the images (each image is of the format Flowers_number).
25 | imageView.animationImages = (1 ... 2).map { UIImage(named: "Flowers_\($0)")! }
26 |
27 | // We want the image to be scaled to the correct aspect ratio within imageView's bounds.
28 | imageView.contentMode = .scaleAspectFit
29 |
30 | imageView.animationDuration = 5
31 | imageView.startAnimating()
32 |
33 | imageView.isAccessibilityElement = true
34 | imageView.accessibilityLabel = NSLocalizedString("Animated", comment: "")
35 |
36 | if #available(iOS 15, *) {
37 | // This case uses UIToolTipInteraction which is available on iOS 15 or later.
38 | let interaction =
39 | UIToolTipInteraction(defaultToolTip: NSLocalizedString("ImageToolTipTitle", comment: ""))
40 | imageView.addInteraction(interaction)
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/UIKitCatalog/Base.lproj/Localizable.stringsdict:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Cart Items String
6 |
7 | NSStringLocalizedFormatKey
8 | %#@items@
9 | items
10 |
11 | NSStringFormatSpecTypeKey
12 | NSStringPluralRuleType
13 | NSStringFormatValueTypeKey
14 | d
15 | one
16 | %d item
17 | other
18 | %d items
19 |
20 |
21 |
22 | Cart Tooltip String
23 |
24 | NSStringLocalizedFormatKey
25 | %#@items@
26 | items
27 |
28 | NSStringFormatSpecTypeKey
29 | NSStringPluralRuleType
30 | NSStringFormatValueTypeKey
31 | d
32 | zero
33 | Cart is Empty
34 | one
35 | Cart has %d item
36 | other
37 | Cart has %d items
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/PostHogExampleAutocapture/PostHogExampleAutocapture/WebViewController.swift:
--------------------------------------------------------------------------------
1 | /*
2 | See LICENSE folder for this sample’s licensing information.
3 |
4 | Abstract:
5 | A view controller that demonstrates how to use `WKWebView`.
6 | */
7 |
8 | import UIKit
9 | import WebKit
10 |
11 | /** NOTE:
12 | If your app customizes, interacts with, or controls the display of web content, use the WKWebView class.
13 | If you want to view a website from anywhere on the Internet, use the SFSafariViewController class.
14 | */
15 |
16 | class WebViewController: UIViewController {
17 | // MARK: - Properties
18 |
19 | @IBOutlet var webView: WKWebView!
20 |
21 | // MARK: - View Life Cycle
22 |
23 | override func viewDidLoad() {
24 | super.viewDidLoad()
25 |
26 | // So we can capture failures in "didFailProvisionalNavigation".
27 | webView.navigationDelegate = self
28 | loadAddressURL()
29 | }
30 |
31 | // MARK: - Loading
32 |
33 | func loadAddressURL() {
34 | // Set the content to local html in our app bundle.
35 | if let url = Bundle.main.url(forResource: "content", withExtension: "html") {
36 | webView.loadFileURL(url, allowingReadAccessTo: url)
37 | }
38 | }
39 | }
40 |
41 | // MARK: - WKNavigationDelegate
42 |
43 | extension WebViewController: WKNavigationDelegate {
44 | func webView(_ webView: WKWebView, didFailProvisionalNavigation _: WKNavigation!, withError error: Error) {
45 | let webKitError = error as NSError
46 | if webKitError.code == NSURLErrorNotConnectedToInternet {
47 | // Report the error inside the web view.
48 | let localizedErrorMessage = NSLocalizedString("An error occurred:", comment: "")
49 |
50 | let message = "\(localizedErrorMessage) \(error.localizedDescription)"
51 | let errorHTML =
52 | "\(message)
"
53 |
54 | webView.loadHTMLString(errorHTML, baseURL: nil)
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/ExternalSDK.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExternalSDK.swift
3 | // ExternalSDK
4 | //
5 | // Created by Yiannis Josephides on 24/01/2025.
6 | //
7 |
8 | import Foundation
9 | import PostHog
10 |
11 | public final class MyExternalSDK {
12 | public static let shared = MyExternalSDK()
13 |
14 | private init() {
15 | let config = PostHogConfig(
16 | apiKey: "phc_QFbR1y41s5sxnNTZoyKG2NJo2RlsCIWkUfdpawgb40D"
17 | )
18 |
19 | config.captureScreenViews = true
20 | config.captureApplicationLifecycleEvents = true
21 | config.debug = true
22 | config.sendFeatureFlagEvent = false
23 | config.sessionReplay = true
24 | config.sessionReplayConfig.maskAllImages = false
25 | config.sessionReplayConfig.maskAllTextInputs = false
26 | config.sessionReplayConfig.maskAllSandboxedViews = false
27 |
28 | PostHogSDK.shared.setup(config)
29 | }
30 |
31 | public func track(event: String) {
32 | PostHogSDK.shared.capture("An Event From ExternalSDK - \(event)")
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/ExternalSDK/ExternalSDK.h:
--------------------------------------------------------------------------------
1 | //
2 | // ExternalSDK.h
3 | // ExternalSDK
4 | //
5 | // Created by Yiannis Josephides on 23/01/2025.
6 | //
7 |
8 | #import
9 |
10 | //! Project version number for ExternalSDK.
11 | FOUNDATION_EXPORT double ExternalSDKVersionNumber;
12 |
13 | //! Project version string for TestBuildIssues.
14 | FOUNDATION_EXPORT const unsigned char ExternalSDKVersionString[];
15 |
16 | // In this header, you should import all the public headers of your framework using statements like #import
17 |
18 |
19 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version: 5.10
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "ExternalSDK",
8 | platforms: [.iOS(.v15)],
9 | products: [
10 | .library(
11 | name: "ExternalSDK",
12 | targets: ["ExternalSDK-iOS"]
13 | ),
14 | ],
15 | dependencies: [
16 | .package(path: "../"),
17 | ],
18 | targets: [
19 | .target(
20 | name: "ExternalSDK-iOS",
21 | dependencies: [
22 | .product(name: "PostHog", package: "posthog-ios"),
23 | .target(name: "ExternalSDK"),
24 | ]
25 | ),
26 | .binaryTarget(name: "ExternalSDK", path: "./build/bin/ExternalSDK.xcframework"),
27 | ]
28 | )
29 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/SDKClient/ExternalSDKClient/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/SDKClient/ExternalSDKClient/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | },
8 | {
9 | "appearances" : [
10 | {
11 | "appearance" : "luminosity",
12 | "value" : "dark"
13 | }
14 | ],
15 | "idiom" : "universal",
16 | "platform" : "ios",
17 | "size" : "1024x1024"
18 | },
19 | {
20 | "appearances" : [
21 | {
22 | "appearance" : "luminosity",
23 | "value" : "tinted"
24 | }
25 | ],
26 | "idiom" : "universal",
27 | "platform" : "ios",
28 | "size" : "1024x1024"
29 | },
30 | {
31 | "idiom" : "mac",
32 | "scale" : "1x",
33 | "size" : "16x16"
34 | },
35 | {
36 | "idiom" : "mac",
37 | "scale" : "2x",
38 | "size" : "16x16"
39 | },
40 | {
41 | "idiom" : "mac",
42 | "scale" : "1x",
43 | "size" : "32x32"
44 | },
45 | {
46 | "idiom" : "mac",
47 | "scale" : "2x",
48 | "size" : "32x32"
49 | },
50 | {
51 | "idiom" : "mac",
52 | "scale" : "1x",
53 | "size" : "128x128"
54 | },
55 | {
56 | "idiom" : "mac",
57 | "scale" : "2x",
58 | "size" : "128x128"
59 | },
60 | {
61 | "idiom" : "mac",
62 | "scale" : "1x",
63 | "size" : "256x256"
64 | },
65 | {
66 | "idiom" : "mac",
67 | "scale" : "2x",
68 | "size" : "256x256"
69 | },
70 | {
71 | "idiom" : "mac",
72 | "scale" : "1x",
73 | "size" : "512x512"
74 | },
75 | {
76 | "idiom" : "mac",
77 | "scale" : "2x",
78 | "size" : "512x512"
79 | }
80 | ],
81 | "info" : {
82 | "author" : "xcode",
83 | "version" : 1
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/SDKClient/ExternalSDKClient/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/SDKClient/ExternalSDKClient/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // TestBuildIssuesClient
4 | //
5 | // Created by Yiannis Josephides on 24/01/2025.
6 | //
7 |
8 | import ExternalSDK
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 | var body: some View {
13 | VStack(spacing: 16) {
14 | Button("Track Event") {
15 | MyExternalSDK.shared.track(event: "test")
16 | }
17 | Image(systemName: "globe")
18 | .imageScale(.large)
19 | .foregroundStyle(.tint)
20 | Text("Hello, world!")
21 | }
22 | .padding()
23 | }
24 | }
25 |
26 | #Preview {
27 | ContentView()
28 | }
29 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/SDKClient/ExternalSDKClient/ExternalSDKClient.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/SDKClient/ExternalSDKClient/ExternalSDKClientApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExternalSDKClientApp.swift
3 | // TestBuildIssuesClient
4 | //
5 | // Created by Yiannis Josephides on 24/01/2025.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct TestBuildIssuesClientApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/SDKClient/ExternalSDKClient/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/Sources/ExternalSDK-iOS/ExternalSDK-iOS.swift:
--------------------------------------------------------------------------------
1 | // wrapper
2 |
--------------------------------------------------------------------------------
/PostHogExampleExternalSDK/build_xcframework.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Get the directory where the script is located
4 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
5 |
6 | # Define output directories relative to script location
7 | OUTPUT_DIR="$SCRIPT_DIR/build"
8 | ARCHIVE_DIR="$OUTPUT_DIR/archives"
9 | PROJECT_PATH="$SCRIPT_DIR/PostHogExampleExternalSDK.xcodeproj"
10 |
11 | rm -rf "$OUTPUT_DIR"
12 | rm -rf "$ARCHIVE_DIR"
13 | mkdir -p "$OUTPUT_DIR"
14 | mkdir -p "$ARCHIVE_DIR"
15 |
16 | echo "Building for iOS devices..."
17 | if ! xcodebuild archive \
18 | SKIP_INSTALL=NO \
19 | BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
20 | ENABLE_MODULE_VERIFIER=YES \
21 | -project "$PROJECT_PATH" \
22 | -scheme ExternalSDK \
23 | -configuration Release \
24 | -destination "generic/platform=iOS" \
25 | -archivePath "$ARCHIVE_DIR/ExternalSDK-iOS.xcarchive" | xcpretty; then
26 | echo "Error: Failed to build framework for iOS Device"
27 | fi
28 |
29 | echo "Building for iOS simulator..."
30 | if ! xcodebuild archive \
31 | SKIP_INSTALL=NO \
32 | BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
33 | ENABLE_MODULE_VERIFIER=YES \
34 | -project "$PROJECT_PATH" \
35 | -scheme ExternalSDK \
36 | -configuration Release \
37 | -destination "generic/platform=iOS Simulator" \
38 | -archivePath "$ARCHIVE_DIR/ExternalSDK-iOS_Simulator.xcarchive" | xcpretty; then
39 | echo "Error: Failed to build framework for iOS Simulator"
40 | fi
41 |
42 | echo "Creating XCFramework..."
43 | if ! xcodebuild -create-xcframework \
44 | -archive "$ARCHIVE_DIR/ExternalSDK-iOS.xcarchive" -framework ExternalSDK.framework \
45 | -archive "$ARCHIVE_DIR/ExternalSDK-iOS_Simulator.xcarchive" -framework ExternalSDK.framework \
46 | -output "$OUTPUT_DIR/bin/ExternalSDK.xcframework" | xcpretty; then
47 | echo "Error: Failed to create XCFramework"
48 | exit 1
49 | fi
50 |
51 | echo "XCFramework created at $OUTPUT_DIR/bin/ExternalSDK.xcframework"
--------------------------------------------------------------------------------
/PostHogExampleMacOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import PostHog
3 |
4 | class AppDelegate: NSObject, NSApplicationDelegate {
5 | func applicationDidFinishLaunching(_: Notification) {
6 | let config = PostHogConfig(
7 | apiKey: "phc_QFbR1y41s5sxnNTZoyKG2NJo2RlsCIWkUfdpawgb40D"
8 | )
9 | config.debug = true
10 |
11 | PostHogSDK.shared.setup(config)
12 | // PostHogSDK.shared.capture("Event from MacOS example!")
13 | }
14 |
15 | func applicationWillTerminate(_: Notification) {
16 | // Insert code here to tear down your application
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PostHogExampleMacOS/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExampleMacOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "scale" : "1x",
6 | "size" : "16x16"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "2x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "1x",
16 | "size" : "32x32"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "2x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "1x",
26 | "size" : "128x128"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "2x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "1x",
36 | "size" : "256x256"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "2x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "1x",
46 | "size" : "512x512"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "2x",
51 | "size" : "512x512"
52 | }
53 | ],
54 | "info" : {
55 | "author" : "xcode",
56 | "version" : 1
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/PostHogExampleMacOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleMacOS/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // PostHogExampleMacOS
4 | //
5 | // Created by Manoel Aranda Neto on 10.11.23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ContentView: View {
11 | var body: some View {
12 | VStack {
13 | Image(systemName: "globe")
14 | .imageScale(.large)
15 | .foregroundStyle(.tint)
16 | Text("Hello, world!")
17 | }
18 | .padding()
19 | }
20 | }
21 |
22 | #Preview {
23 | ContentView()
24 | }
25 |
--------------------------------------------------------------------------------
/PostHogExampleMacOS/PostHogExampleMacOS.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/PostHogExampleMacOS/PostHogExampleMacOSApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogExampleMacOSApp.swift
3 | // PostHogExampleMacOS
4 | //
5 | // Created by Manoel Aranda Neto on 10.11.23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct PostHogExampleMacOSApp: App {
12 | @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
13 |
14 | var body: some Scene {
15 | WindowGroup {
16 | ContentView()
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/PostHogExampleMacOS/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleStoryboard/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // PostHogExampleStoryboard
4 | //
5 | // Created by Manoel Aranda Neto on 21.03.24.
6 | //
7 |
8 | import PostHog
9 | import UIKit
10 |
11 | @main
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 | func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
14 | // Override point for customization after application launch.
15 | let config = PostHogConfig(
16 | apiKey: "phc_QFbR1y41s5sxnNTZoyKG2NJo2RlsCIWkUfdpawgb40D"
17 | )
18 | // the ScreenViews for SwiftUI does not work, the names are not useful
19 | config.captureScreenViews = false
20 | config.captureApplicationLifecycleEvents = false
21 | // config.flushAt = 1
22 | // config.flushIntervalSeconds = 30
23 | config.debug = true
24 | config.sendFeatureFlagEvent = false
25 | config.sessionReplay = true
26 | config.sessionReplayConfig.maskAllTextInputs = true
27 | config.sessionReplayConfig.screenshotMode = true
28 | config.sessionReplayConfig.maskAllImages = true
29 | config.sessionReplayConfig.captureNetworkTelemetry = true
30 |
31 | PostHogSDK.shared.setup(config)
32 |
33 | return true
34 | }
35 |
36 | // MARK: UISceneSession Lifecycle
37 |
38 | func application(_: UIApplication,
39 | configurationForConnecting connectingSceneSession: UISceneSession,
40 | options _: UIScene.ConnectionOptions) -> UISceneConfiguration
41 | {
42 | // Called when a new scene session is being created.
43 | // Use this method to select a configuration to create the new scene with.
44 | UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
45 | }
46 |
47 | func application(_: UIApplication, didDiscardSceneSessions _: Set) {
48 | // Called when the user discards a scene session.
49 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
50 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/PostHogExampleStoryboard/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExampleStoryboard/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/PostHogExampleStoryboard/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleStoryboard/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/PostHogExampleStoryboard/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/PostHogExampleStoryboard/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIApplicationSceneManifest
6 |
7 | UIApplicationSupportsMultipleScenes
8 |
9 | UISceneConfigurations
10 |
11 | UIWindowSceneSessionRoleApplication
12 |
13 |
14 | UISceneConfigurationName
15 | Default Configuration
16 | UISceneDelegateClassName
17 | $(PRODUCT_MODULE_NAME).SceneDelegate
18 | UISceneStoryboardFile
19 | Main
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import PostHog
2 | import SwiftUI
3 | import UIKit
4 |
5 | class AppDelegate: UIResponder, UIApplicationDelegate {
6 | var window: UIWindow?
7 |
8 | func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
9 | let config = PostHogConfig(
10 | apiKey: "phc_QFbR1y41s5sxnNTZoyKG2NJo2RlsCIWkUfdpawgb40D"
11 | )
12 | config.debug = true
13 |
14 | PostHogSDK.shared.setup(config)
15 | PostHogSDK.shared.capture("Event from TvOS example!")
16 |
17 | return true
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | },
6 | "layers" : [
7 | {
8 | "filename" : "Front.imagestacklayer"
9 | },
10 | {
11 | "filename" : "Middle.imagestacklayer"
12 | },
13 | {
14 | "filename" : "Back.imagestacklayer"
15 | }
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - App Store.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "tv",
9 | "scale" : "2x"
10 | }
11 | ],
12 | "info" : {
13 | "author" : "xcode",
14 | "version" : 1
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | },
6 | "layers" : [
7 | {
8 | "filename" : "Front.imagestacklayer"
9 | },
10 | {
11 | "filename" : "Middle.imagestacklayer"
12 | },
13 | {
14 | "filename" : "Back.imagestacklayer"
15 | }
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "tv",
9 | "scale" : "2x"
10 | }
11 | ],
12 | "info" : {
13 | "author" : "xcode",
14 | "version" : 1
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "tv",
9 | "scale" : "2x"
10 | }
11 | ],
12 | "info" : {
13 | "author" : "xcode",
14 | "version" : 1
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "assets" : [
3 | {
4 | "filename" : "App Icon - App Store.imagestack",
5 | "idiom" : "tv",
6 | "role" : "primary-app-icon",
7 | "size" : "1280x768"
8 | },
9 | {
10 | "filename" : "App Icon.imagestack",
11 | "idiom" : "tv",
12 | "role" : "primary-app-icon",
13 | "size" : "400x240"
14 | },
15 | {
16 | "filename" : "Top Shelf Image Wide.imageset",
17 | "idiom" : "tv",
18 | "role" : "top-shelf-image-wide",
19 | "size" : "2320x720"
20 | },
21 | {
22 | "filename" : "Top Shelf Image.imageset",
23 | "idiom" : "tv",
24 | "role" : "top-shelf-image",
25 | "size" : "1920x720"
26 | }
27 | ],
28 | "info" : {
29 | "author" : "xcode",
30 | "version" : 1
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "tv",
9 | "scale" : "2x"
10 | }
11 | ],
12 | "info" : {
13 | "author" : "xcode",
14 | "version" : 1
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "tv",
9 | "scale" : "2x"
10 | }
11 | ],
12 | "info" : {
13 | "author" : "xcode",
14 | "version" : 1
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // PostHogExampleTvOS
4 | //
5 | // Created by Manoel Aranda Neto on 10.11.23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ContentView: View {
11 | var body: some View {
12 | VStack {
13 | Image(systemName: "globe")
14 | .imageScale(.large)
15 | .foregroundStyle(.tint)
16 | Text("Hello, world!")
17 | }
18 | .padding()
19 | }
20 | }
21 |
22 | #Preview {
23 | ContentView()
24 | }
25 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/PostHogExampleTvOSApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogExampleTvOSApp.swift
3 | // PostHogExampleTvOS
4 | //
5 | // Created by Manoel Aranda Neto on 10.11.23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct PostHogExampleTvOSApp: App {
12 | @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
13 |
14 | var body: some Scene {
15 | WindowGroup {
16 | ContentView()
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/PostHogExampleTvOS/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleWatchOS/PostHogExampleWatchOS Watch App/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExampleWatchOS/PostHogExampleWatchOS Watch App/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "watchos",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/PostHogExampleWatchOS/PostHogExampleWatchOS Watch App/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleWatchOS/PostHogExampleWatchOS Watch App/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // PostHogExampleWatchOS Watch App
4 | //
5 | // Created by Manoel Aranda Neto on 02.11.23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ContentView: View {
11 | var body: some View {
12 | VStack {
13 | Image(systemName: "globe")
14 | .imageScale(.large)
15 | .foregroundStyle(.tint)
16 | Text("Hello, world!")
17 | }
18 | .padding()
19 | }
20 | }
21 |
22 | #Preview {
23 | ContentView()
24 | }
25 |
--------------------------------------------------------------------------------
/PostHogExampleWatchOS/PostHogExampleWatchOS Watch App/PostHogExampleWatchOSApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogExampleWatchOSApp.swift
3 | // PostHogExampleWatchOS Watch App
4 | //
5 | // Created by Manoel Aranda Neto on 02.11.23.
6 | //
7 |
8 | import PostHog
9 | import SwiftUI
10 |
11 | @main
12 | struct PostHogExampleWatchOSApp: App {
13 | init() {
14 | // TODO: init on app delegate instead
15 | let config = PostHogConfig(
16 | apiKey: "phc_QFbR1y41s5sxnNTZoyKG2NJo2RlsCIWkUfdpawgb40D"
17 | )
18 |
19 | PostHogSDK.shared.setup(config)
20 | PostHogSDK.shared.debug()
21 | PostHogSDK.shared.capture("Event from WatchOS example!")
22 | }
23 |
24 | var body: some Scene {
25 | WindowGroup {
26 | ContentView()
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/PostHogExampleWatchOS/PostHogExampleWatchOS Watch App/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleWithPods/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '16.0'
2 |
3 | use_frameworks!
4 |
5 | target 'PostHogExampleWithPods' do
6 | pod 'PostHog', :path => '../'
7 | end
8 |
--------------------------------------------------------------------------------
/PostHogExampleWithPods/Podfile.static:
--------------------------------------------------------------------------------
1 | platform :ios, '16.0'
2 |
3 | target 'PostHogExampleWithPods' do
4 | pod 'PostHog', :path => '../'
5 | end
6 |
--------------------------------------------------------------------------------
/PostHogExampleWithPods/PostHogExampleWithPods/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // PostHogExampleWithPods
4 | //
5 | // Created by Manoel Aranda Neto on 24.10.23.
6 | //
7 |
8 | import Foundation
9 | import PostHog
10 | import UIKit
11 |
12 | class AppDelegate: NSObject, UIApplicationDelegate {
13 | func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
14 | let defaultCenter = NotificationCenter.default
15 |
16 | defaultCenter.addObserver(self,
17 | selector: #selector(receiveFeatureFlags),
18 | name: PostHogSDK.didReceiveFeatureFlags,
19 | object: nil)
20 |
21 | let config = PostHogConfig(
22 | apiKey: "phc_QFbR1y41s5sxnNTZoyKG2NJo2RlsCIWkUfdpawgb40D"
23 | )
24 |
25 | PostHogSDK.shared.setup(config)
26 | PostHogSDK.shared.debug()
27 | PostHogSDK.shared.capture("Event from CocoaPods example!")
28 |
29 | return true
30 | }
31 |
32 | @objc func receiveFeatureFlags() {
33 | print("receiveFeatureFlags")
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/PostHogExampleWithPods/PostHogExampleWithPods/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExampleWithPods/PostHogExampleWithPods/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/PostHogExampleWithPods/PostHogExampleWithPods/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleWithPods/PostHogExampleWithPods/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // PostHogExampleWithPods
4 | //
5 | // Created by Manoel Aranda Neto on 24.10.23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ContentView: View {
11 | var body: some View {
12 | VStack {
13 | Image(systemName: "globe")
14 | .imageScale(.large)
15 | .foregroundStyle(.tint)
16 | Text("Hello, world!")
17 | }
18 | .padding()
19 | }
20 | }
21 |
22 | #Preview {
23 | ContentView()
24 | }
25 |
--------------------------------------------------------------------------------
/PostHogExampleWithPods/PostHogExampleWithPods/PostHogExampleWithPodsApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogExampleWithPodsApp.swift
3 | // PostHogExampleWithPods
4 | //
5 | // Created by Manoel Aranda Neto on 24.10.23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct PostHogExampleWithPodsApp: App {
12 | @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
13 |
14 | var body: some Scene {
15 | WindowGroup {
16 | ContentView()
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/PostHogExampleWithPods/PostHogExampleWithPods/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleWithPods/README.md:
--------------------------------------------------------------------------------
1 | # Example with CocoaPods
2 |
3 | This is an example of how to use the PostHog iOS SDK with CocoaPods.
4 |
5 | ## Installation
6 |
7 | 1. Install CocoaPods if you haven't already:
8 |
9 |
10 |
11 | ```bash
12 | sudo gem install cocoapods
13 | ```
14 |
15 | ## Add a Podfile to the project
16 |
17 |
18 |
19 | ```text
20 | platform :ios, '16.0'
21 |
22 | use_frameworks!
23 |
24 | target '$your_project' do
25 | pod 'PostHog', '~> 3.0.0'
26 | end
27 | ```
28 |
29 | Replace `$your_project` to your project name.
30 |
31 | ## Run `pod install`
32 |
33 | ```bash
34 | pod install
35 | ```
36 |
37 | ## Open the project
38 |
39 | Always open the `*.xcworkspace` file, not the `*.xcodeproj` file.
40 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.build
3 | /Packages
4 | xcuserdata/
5 | DerivedData/
6 | .swiftpm/configuration/registries.json
7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8 | .netrc
9 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/PostHogExampleWithSPM.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/PostHogExampleWithSPM.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/PostHogExampleWithSPM/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // PostHogExampleWithPods
4 | //
5 | // Created by Manoel Aranda Neto on 24.10.23.
6 | //
7 | import Foundation
8 | import PostHog
9 | import UIKit
10 |
11 | class AppDelegate: NSObject, UIApplicationDelegate {
12 | func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
13 | let defaultCenter = NotificationCenter.default
14 |
15 | defaultCenter.addObserver(self,
16 | selector: #selector(receiveFeatureFlags),
17 | name: PostHogSDK.didReceiveFeatureFlags,
18 | object: nil)
19 |
20 | let config = PostHogConfig(
21 | apiKey: "phc_QFbR1y41s5sxnNTZoyKG2NJo2RlsCIWkUfdpawgb40D"
22 | )
23 |
24 | PostHogSDK.shared.setup(config)
25 | PostHogSDK.shared.debug()
26 | PostHogSDK.shared.capture("Event from SPM example!")
27 |
28 | return true
29 | }
30 |
31 | @objc func receiveFeatureFlags() {
32 | print("receiveFeatureFlags")
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/PostHogExampleWithSPM/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/PostHogExampleWithSPM/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/PostHogExampleWithSPM/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/PostHogExampleWithSPM/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // PostHogExampleWithSPM
4 | //
5 | // Created by Manoel Aranda Neto on 24.10.23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ContentView: View {
11 | var body: some View {
12 | VStack {
13 | Image(systemName: "globe")
14 | .imageScale(.large)
15 | .foregroundStyle(.tint)
16 | Text("Hello, world!")
17 | }
18 | .padding()
19 | }
20 | }
21 |
22 | #Preview {
23 | ContentView()
24 | }
25 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/PostHogExampleWithSPM/PostHogExampleWithSPMApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogExampleWithSPMApp.swift
3 | // PostHogExampleWithSPM
4 | //
5 | // Created by Manoel Aranda Neto on 24.10.23.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct PostHogExampleWithSPMApp: App {
12 | @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
13 |
14 | var body: some Scene {
15 | WindowGroup {
16 | ContentView()
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/PostHogExampleWithSPM/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogExampleWithSPM/README.md:
--------------------------------------------------------------------------------
1 | # Example with SPM
2 |
3 | This is an example of how to use the PostHog iOS SDK with SPM.
4 |
5 | ## Installation
6 |
7 | 1. Install Xcode if you haven't already:
8 |
9 | Follow steps from the [Xcode docs](https://developer.apple.com/xcode/resources/).
10 |
11 | ## Add a SP dependency to the project via Xcode
12 |
13 | 1. Click on the project in the Project Navigator.
14 | 2. Select the project in the Project and Targets list.
15 | 3. Select the General tab.
16 | 4. Scroll down to the Frameworks and Libraries section.
17 | 5. Click the + button.
18 | 6. Click Add Other...
19 | 7. Click Add Package Dependency
20 | 8. Enter the URL of the PostHog SDK repo or the local path to the repo.
21 |
22 | ## Import the PostHog package
23 |
24 | ```swift
25 | import PostHog
26 | ```
27 |
28 | And run the project.
29 |
--------------------------------------------------------------------------------
/PostHogObjCExample/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // PostHogObjCExample
4 | //
5 | // Created by Manoel Aranda Neto on 23.10.23.
6 | //
7 |
8 | #import
9 |
10 | @interface AppDelegate : UIResponder
11 |
12 |
13 | @end
14 |
15 |
--------------------------------------------------------------------------------
/PostHogObjCExample/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/PostHogObjCExample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/PostHogObjCExample/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/PostHogObjCExample/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/PostHogObjCExample/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/PostHogObjCExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIApplicationSceneManifest
6 |
7 | UIApplicationSupportsMultipleScenes
8 |
9 | UISceneConfigurations
10 |
11 | UIWindowSceneSessionRoleApplication
12 |
13 |
14 | UISceneConfigurationName
15 | Default Configuration
16 | UISceneDelegateClassName
17 | SceneDelegate
18 | UISceneStoryboardFile
19 | Main
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/PostHogObjCExample/SceneDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.h
3 | // PostHogObjCExample
4 | //
5 | // Created by Manoel Aranda Neto on 23.10.23.
6 | //
7 |
8 | #import
9 |
10 | @interface SceneDelegate : UIResponder
11 |
12 | @property (strong, nonatomic) UIWindow * window;
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/PostHogObjCExample/SceneDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.m
3 | // PostHogObjCExample
4 | //
5 | // Created by Manoel Aranda Neto on 23.10.23.
6 | //
7 |
8 | #import "SceneDelegate.h"
9 |
10 | @interface SceneDelegate ()
11 |
12 | @end
13 |
14 | @implementation SceneDelegate
15 |
16 |
17 | - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
18 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
19 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
20 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
21 | }
22 |
23 |
24 | - (void)sceneDidDisconnect:(UIScene *)scene {
25 | // Called as the scene is being released by the system.
26 | // This occurs shortly after the scene enters the background, or when its session is discarded.
27 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
28 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
29 | }
30 |
31 |
32 | - (void)sceneDidBecomeActive:(UIScene *)scene {
33 | // Called when the scene has moved from an inactive state to an active state.
34 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
35 | }
36 |
37 |
38 | - (void)sceneWillResignActive:(UIScene *)scene {
39 | // Called when the scene will move from an active state to an inactive state.
40 | // This may occur due to temporary interruptions (ex. an incoming phone call).
41 | }
42 |
43 |
44 | - (void)sceneWillEnterForeground:(UIScene *)scene {
45 | // Called as the scene transitions from the background to the foreground.
46 | // Use this method to undo the changes made on entering the background.
47 | }
48 |
49 |
50 | - (void)sceneDidEnterBackground:(UIScene *)scene {
51 | // Called as the scene transitions from the foreground to the background.
52 | // Use this method to save data, release shared resources, and store enough scene-specific state information
53 | // to restore the scene back to its current state.
54 | }
55 |
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/PostHogObjCExample/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // PostHogObjCExample
4 | //
5 | // Created by Manoel Aranda Neto on 23.10.23.
6 | //
7 |
8 | #import
9 |
10 | @interface ViewController : UIViewController
11 |
12 |
13 | @end
14 |
15 |
--------------------------------------------------------------------------------
/PostHogObjCExample/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // PostHogObjCExample
4 | //
5 | // Created by Manoel Aranda Neto on 23.10.23.
6 | //
7 |
8 | #import "ViewController.h"
9 |
10 | @interface ViewController ()
11 |
12 | @end
13 |
14 | @implementation ViewController
15 |
16 | - (void)viewDidLoad {
17 | [super viewDidLoad];
18 | // Do any additional setup after loading the view.
19 | }
20 |
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/PostHogObjCExample/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // PostHogObjCExample
4 | //
5 | // Created by Manoel Aranda Neto on 23.10.23.
6 | //
7 |
8 | #import
9 | #import "AppDelegate.h"
10 |
11 | int main(int argc, char * argv[]) {
12 | NSString * appDelegateClassName;
13 | @autoreleasepool {
14 | // Setup code that might create autoreleased objects goes here.
15 | appDelegateClassName = NSStringFromClass([AppDelegate class]);
16 | }
17 | return UIApplicationMain(argc, argv, nil, appDelegateClassName);
18 | }
19 |
--------------------------------------------------------------------------------
/PostHogTests/ExampleSanitizer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleSanitizer.swift
3 | // PostHogTests
4 | //
5 | // Created by Manoel Aranda Neto on 06.08.24.
6 | //
7 |
8 | import Foundation
9 | import PostHog
10 |
11 | class ExampleSanitizer: PostHogPropertiesSanitizer {
12 | public func sanitize(_ properties: [String: Any]) -> [String: Any] {
13 | var sanitizedProperties = properties
14 | // Perform sanitization
15 | // For example, removing keys with empty values
16 | for (key, value) in properties {
17 | if let stringValue = value as? String, stringValue.isEmpty {
18 | sanitizedProperties.removeValue(forKey: key)
19 | }
20 | }
21 | return sanitizedProperties
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/PostHogTests/PostHogConfigTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogConfigTest.swift
3 | // PostHogTests
4 | //
5 | // Created by Manoel Aranda Neto on 30.10.23.
6 | //
7 |
8 | import Foundation
9 | import Nimble
10 | @testable import PostHog
11 | import Quick
12 |
13 | class PostHogConfigTest: QuickSpec {
14 | override func spec() {
15 | it("init config with default values") {
16 | let config = PostHogConfig(apiKey: "123")
17 |
18 | expect(config.host) == URL(string: PostHogConfig.defaultHost)
19 | expect(config.flushAt) == 20
20 | expect(config.maxQueueSize) == 1000
21 | expect(config.maxBatchSize) == 50
22 | expect(config.flushIntervalSeconds) == 30
23 | expect(config.dataMode) == .any
24 | expect(config.sendFeatureFlagEvent) == true
25 | expect(config.preloadFeatureFlags) == true
26 | expect(config.captureApplicationLifecycleEvents) == true
27 | expect(config.captureScreenViews) == true
28 | expect(config.debug) == false
29 | expect(config.optOut) == false
30 | }
31 |
32 | it("init takes api key") {
33 | let config = PostHogConfig(apiKey: "123")
34 |
35 | expect(config.apiKey) == "123"
36 | }
37 |
38 | it("init takes host") {
39 | let config = PostHogConfig(apiKey: "123", host: "localhost:9000")
40 |
41 | expect(config.host) == URL(string: "localhost:9000")!
42 | }
43 |
44 | #if os(iOS)
45 | context("when initialized with default values for captureElementInteractions") {
46 | it("should enable autocapture by default") {
47 | let sut = PostHogConfig(apiKey: "123")
48 | expect(sut.captureElementInteractions).to(beFalse())
49 | }
50 | }
51 |
52 | context("when customized") {
53 | it("should allow disabling autocapture") {
54 | let config = PostHogConfig(apiKey: "123")
55 | config.captureElementInteractions = false
56 | expect(config.captureElementInteractions).to(beFalse())
57 | }
58 | }
59 | #endif
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/PostHogTests/PostHogStorageManagerTest.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PostHogStorageManagerTest.swift
3 | // PostHogTests
4 | //
5 | // Created by Ben White on 22.03.23.
6 | //
7 |
8 | import Foundation
9 | import Nimble
10 | @testable import PostHog
11 | import Quick
12 |
13 | class PostHogStorageManagerTest: QuickSpec {
14 | func getSut() -> PostHogStorageManager {
15 | let config = PostHogConfig(apiKey: "123")
16 | return PostHogStorageManager(config)
17 | }
18 |
19 | override func spec() {
20 | it("Generates an anonymousId") {
21 | let sut = self.getSut()
22 |
23 | let anonymousId = sut.getAnonymousId()
24 | expect(anonymousId) != nil
25 | let secondAnonymousId = sut.getAnonymousId()
26 | expect(secondAnonymousId) == anonymousId
27 |
28 | sut.reset(true)
29 | }
30 |
31 | it("Uses the anonymousId for distinctId if not set") {
32 | let sut = self.getSut()
33 |
34 | let anonymousId = sut.getAnonymousId()
35 | let distinctId = sut.getDistinctId()
36 | expect(distinctId) == anonymousId
37 |
38 | let idToSet = UUID.v7().uuidString
39 | sut.setDistinctId(idToSet)
40 | let newAnonymousId = sut.getAnonymousId()
41 | let newDistinctId = sut.getDistinctId()
42 | expect(newAnonymousId) == anonymousId
43 | expect(newAnonymousId) != newDistinctId
44 | expect(newDistinctId) == idToSet
45 |
46 | sut.reset(true)
47 | }
48 |
49 | it("Can can accept id customization via config") {
50 | let config = PostHogConfig(apiKey: "123")
51 | let fixedUuid = UUID.v7()
52 | config.getAnonymousId = { _ in fixedUuid }
53 | let sut = PostHogStorageManager(config)
54 | let anonymousId = sut.getAnonymousId()
55 | expect(anonymousId) == fixedUuid.uuidString
56 |
57 | sut.reset(true)
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/PostHogTests/Resources/input_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogTests/Resources/input_1.png
--------------------------------------------------------------------------------
/PostHogTests/Resources/input_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogTests/Resources/input_2.png
--------------------------------------------------------------------------------
/PostHogTests/Resources/input_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogTests/Resources/input_3.png
--------------------------------------------------------------------------------
/PostHogTests/Resources/output_1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogTests/Resources/output_1.webp
--------------------------------------------------------------------------------
/PostHogTests/Resources/output_2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogTests/Resources/output_2.webp
--------------------------------------------------------------------------------
/PostHogTests/Resources/output_3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trustwallet/posthog-ios/5a437567d9b6a5b4ad72b831d60c21639180ec39/PostHogTests/Resources/output_3.webp
--------------------------------------------------------------------------------
/PostHogTests/TestUtils/TestError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestError.swift
3 | // PostHog
4 | //
5 | // Created by Yiannis Josephides on 18/12/2024.
6 | //
7 |
8 | struct TestError: Error, ExpressibleByStringLiteral, CustomStringConvertible {
9 | let description: String
10 |
11 | init(_ description: String) {
12 | self.description = description
13 | }
14 |
15 | init(stringLiteral value: StringLiteralType) {
16 | description = value
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/PostHogTests/TestUtils/TestPostHog.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestPostHog.swift
3 | // PostHogTests
4 | //
5 | // Created by Ben White on 22.03.23.
6 | //
7 |
8 | import Foundation
9 | import PostHog
10 | import XCTest
11 |
12 | func getBatchedEvents(_ server: MockPostHogServer, timeout: TimeInterval = 15.0, failIfNotCompleted: Bool = true) -> [PostHogEvent] {
13 | let result = XCTWaiter.wait(for: [server.batchExpectation!], timeout: timeout)
14 |
15 | if result != XCTWaiter.Result.completed, failIfNotCompleted {
16 | XCTFail("The expected requests never arrived")
17 | }
18 |
19 | var events: [PostHogEvent] = []
20 | for request in server.batchRequests.reversed() {
21 | let items = server.parsePostHogEvents(request)
22 | events.append(contentsOf: items)
23 | }
24 |
25 | return events
26 | }
27 |
28 | func waitDecideRequest(_ server: MockPostHogServer) {
29 | let result = XCTWaiter.wait(for: [server.decideExpectation!], timeout: 15)
30 |
31 | if result != XCTWaiter.Result.completed {
32 | XCTFail("The expected requests never arrived")
33 | }
34 | }
35 |
36 | func getDecideRequest(_ server: MockPostHogServer) -> [[String: Any]] {
37 | waitDecideRequest(server)
38 |
39 | var requests: [[String: Any]] = []
40 | for request in server.decideRequests.reversed() {
41 | let item = server.parseRequest(request, gzip: false)
42 | requests.append(item!)
43 | }
44 |
45 | return requests
46 | }
47 |
48 | final class MockDate {
49 | var date = Date()
50 | }
51 |
--------------------------------------------------------------------------------
/PostHogTests/TestUtils/URLSession+body.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URLSession+body.swift
3 | // PostHogTests
4 | //
5 | // Created by Ben White on 10.04.23.
6 | //
7 |
8 | import Foundation
9 |
10 | extension URLRequest {
11 | func body() -> Data? {
12 | if httpBody != nil {
13 | return httpBody
14 | }
15 |
16 | guard let bodyStream = httpBodyStream else { return nil }
17 |
18 | bodyStream.open()
19 |
20 | // Will read 16 chars per iteration. Can use bigger buffer if needed
21 | let bufferSize = 16
22 |
23 | let buffer = UnsafeMutablePointer.allocate(capacity: bufferSize)
24 |
25 | var dat = Data()
26 |
27 | while bodyStream.hasBytesAvailable {
28 | let readDat = bodyStream.read(buffer, maxLength: bufferSize)
29 | dat.append(buffer, count: readDat)
30 | }
31 |
32 | buffer.deallocate()
33 |
34 | bodyStream.close()
35 |
36 | return dat
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/PostHog/posthog-ios/actions/workflows/build.yml?query=branch%3Amain)
2 | [](https://cocoapods.org/pods/PostHog)
3 | [](https://swift.org/package-manager)
4 | 
5 | [](https://swiftpackageindex.com/PostHog/posthog-ios)
6 |
7 | # PostHog iOS
8 |
9 | Please see the main [PostHog docs](https://posthog.com/docs).
10 |
11 | Specifically, the [iOS docs](https://posthog.com/docs/libraries/ios) details.
12 |
13 | ## Questions?
14 |
15 | ### [Check out our community page.](https://posthog.com/posts)
16 |
--------------------------------------------------------------------------------
/RELEASING.md:
--------------------------------------------------------------------------------
1 | Releasing
2 | =========
3 |
4 | 1. Update the CHANGELOG.md with the version and date.
5 | 2. Choose a tag name (e.g. `3.0.0`), this is the version number of the release.
6 | 1. Preview releases follow the pattern `3.0.0-alpha.1`, `3.0.0-beta.1`, `3.0.0-RC.1`
7 | 2. Execute the script with the tag's name, the script will update the version file and create a tag.
8 |
9 | ```bash
10 | ./scripts/prepare-release.sh 3.0.0
11 | ```
12 |
13 | 3. Go to [GH Releases](https://github.com/PostHog/posthog-ios/releases)
14 | 4. Choose a release name (e.g. `3.0.0`), and the tag you just created, ideally the same.
15 | 5. Write a description of the release.
16 | 6. Publish the release.
17 | 7. GH Action (release.yml) is doing everything else automatically.
18 | 1. SPM uses the tag name to determine the version, directly from the repo.
19 | 2. CocoaPods are published.
20 | 8. Done.
21 |
--------------------------------------------------------------------------------
/dangerfile.js:
--------------------------------------------------------------------------------
1 | async function checkChangelog() {
2 | const changelogFile = "CHANGELOG.md";
3 |
4 | // Check if skipped
5 | const skipChangelog =
6 | danger.github && (danger.github.pr.body + "").includes("#skip-changelog");
7 |
8 | if (skipChangelog) {
9 | return;
10 | }
11 |
12 | // Check if current PR has an entry in changelog
13 | const changelogContents = await danger.github.utils.fileContents(
14 | changelogFile
15 | );
16 |
17 | const hasChangelogEntry = RegExp(`#${danger.github.pr.number}\\b`).test(
18 | changelogContents
19 | );
20 |
21 | if (hasChangelogEntry) {
22 | return;
23 | }
24 |
25 | // Report missing changelog entry
26 | fail(
27 | "Please consider adding a changelog entry for the next release.",
28 | changelogFile
29 | );
30 |
31 | const prTitleFormatted = danger.github.pr.title
32 | .split(": ")
33 | .slice(-1)[0]
34 | .trim()
35 | .replace(/\.+$/, "");
36 |
37 | markdown(
38 | `
39 | ### Instructions and example for changelog
40 | Please add an entry to \`CHANGELOG.md\` to the "Next" section. Make sure the entry includes this PR's number.
41 | Example:
42 | \`\`\`markdown
43 | ## Next
44 | - ${prTitleFormatted} ([#${danger.github.pr.number}](${danger.github.pr.html_url}))
45 | \`\`\`
46 | If none of the above apply, you can opt out of this check by adding \`#skip-changelog\` to the PR description.`.trim()
47 | );
48 | }
49 |
50 | async function checkAll() {
51 | const isDraft = danger.github.pr.mergeable_state === "draft";
52 |
53 | if (isDraft) {
54 | return;
55 | }
56 |
57 | await checkChangelog();
58 | }
59 |
60 | schedule(checkAll);
61 |
--------------------------------------------------------------------------------
/scripts/bump-version.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # ./scripts/bump-version.sh
4 | # eg ./scripts/bump-version.sh "3.0.0-alpha.1"
5 |
6 | set -eux
7 |
8 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
9 | cd $SCRIPT_DIR/..
10 |
11 | NEW_VERSION="$1"
12 |
13 | # Replace `postHogVersion` with the given version
14 | perl -pi -e "s/postHogVersion = \".*\"/postHogVersion = \"$NEW_VERSION\"/" PostHog/PostHogVersion.swift
15 |
16 | # Replace `s.version` with the given version
17 | perl -pi -e "s/s.version = \".*\"/s.version = \"$NEW_VERSION\"/" PostHog.podspec
18 |
--------------------------------------------------------------------------------
/scripts/commit-code.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -euo pipefail
3 |
4 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
5 | cd $SCRIPT_DIR/..
6 |
7 | if [[ $(git status) == *"nothing to commit"* ]]; then
8 | echo "Nothing to commit."
9 | else
10 | echo "Going to push the changes."
11 | git fetch
12 | git commit -am "Update version"
13 | git push
14 | fi
15 |
--------------------------------------------------------------------------------
/scripts/create-tag.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -eux
4 |
5 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6 | cd $SCRIPT_DIR/..
7 |
8 | NEW_VERSION="$1"
9 |
10 | git tag -a ${NEW_VERSION} -m "${NEW_VERSION}"
11 | git push && git push --tags
12 |
--------------------------------------------------------------------------------
/scripts/prepare-release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -eux
4 |
5 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6 | cd $SCRIPT_DIR/..
7 |
8 | NEW_VERSION="$1"
9 |
10 | # bump version
11 | ./scripts/bump-version.sh $NEW_VERSION
12 |
13 | # commit changes
14 | ./scripts/commit-code.sh
15 |
16 | # create and push tag
17 | ./scripts/create-tag.sh $NEW_VERSION
18 |
--------------------------------------------------------------------------------
/scripts/update-tag.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -euo pipefail
3 |
4 | CURRENT_TAG="$1"
5 | TEMP_TAG="${CURRENT_TAG}-temp"
6 | GITHUB_BRANCH="${2}"
7 |
8 | echo "Going to push the tag changes."
9 | git config --global user.name 'PostHog Github Bot'
10 | git config --global user.email 'github-bot@posthog.com'
11 | git fetch
12 | git checkout ${GITHUB_BRANCH}
13 | # Create a new temporary tag after pushing the changes from the previous tag (bump version)
14 | git tag -a ${TEMP_TAG} -m "${TEMP_TAG}"
15 | # Remove the current tag
16 | git tag -d ${CURRENT_TAG}
17 | # Remove the current tag in remote machine
18 | git push --delete origin ${CURRENT_TAG}
19 | # Create a new tag that points to the temporary tag
20 | git tag ${CURRENT_TAG} ${TEMP_TAG}
21 | # Remove temporary tag
22 | git tag -d ${TEMP_TAG}
23 | # Propapate new tag to remote machine
24 | git push --tags
25 |
--------------------------------------------------------------------------------
/vendor/libwebp/COPYING:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010, Google Inc. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without
4 | modification, are permitted provided that the following conditions are
5 | met:
6 |
7 | * Redistributions of source code must retain the above copyright
8 | notice, this list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in
12 | the documentation and/or other materials provided with the
13 | distribution.
14 |
15 | * Neither the name of Google nor the names of its contributors may
16 | be used to endorse or promote products derived from this software
17 | without specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
31 |
--------------------------------------------------------------------------------
/vendor/libwebp/PATENTS:
--------------------------------------------------------------------------------
1 | Additional IP Rights Grant (Patents)
2 | ------------------------------------
3 |
4 | "These implementations" means the copyrightable works that implement the WebM
5 | codecs distributed by Google as part of the WebM Project.
6 |
7 | Google hereby grants to you a perpetual, worldwide, non-exclusive, no-charge,
8 | royalty-free, irrevocable (except as stated in this section) patent license to
9 | make, have made, use, offer to sell, sell, import, transfer, and otherwise
10 | run, modify and propagate the contents of these implementations of WebM, where
11 | such license applies only to those patent claims, both currently owned by
12 | Google and acquired in the future, licensable by Google that are necessarily
13 | infringed by these implementations of WebM. This grant does not include claims
14 | that would be infringed only as a consequence of further modification of these
15 | implementations. If you or your agent or exclusive licensee institute or order
16 | or agree to the institution of patent litigation or any other patent
17 | enforcement activity against any entity (including a cross-claim or
18 | counterclaim in a lawsuit) alleging that any of these implementations of WebM
19 | or any code incorporated within any of these implementations of WebM
20 | constitute direct or contributory patent infringement, or inducement of
21 | patent infringement, then any patent rights granted to you under this License
22 | for these implementations of WebM shall terminate as of the date such
23 | litigation is filed.
24 |
--------------------------------------------------------------------------------
/vendor/libwebp/color_cache_utils.c:
--------------------------------------------------------------------------------
1 | // Copyright 2012 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Color Cache for WebP Lossless
11 | //
12 | // Author: Jyrki Alakuijala (jyrki@google.com)
13 |
14 | #include
15 | #include
16 | #include "./color_cache_utils.h"
17 | #include "./utils.h"
18 |
19 | //------------------------------------------------------------------------------
20 | // VP8LColorCache.
21 |
22 | int VP8LColorCacheInit(VP8LColorCache* const color_cache, int hash_bits) {
23 | const int hash_size = 1 << hash_bits;
24 | ASSERT(color_cache != NULL);
25 | ASSERT(hash_bits > 0);
26 | color_cache->colors_ = (uint32_t*)WebPSafeCalloc(
27 | (uint64_t)hash_size, sizeof(*color_cache->colors_));
28 | if (color_cache->colors_ == NULL) return 0;
29 | color_cache->hash_shift_ = 32 - hash_bits;
30 | color_cache->hash_bits_ = hash_bits;
31 | return 1;
32 | }
33 |
34 | void VP8LColorCacheClear(VP8LColorCache* const color_cache) {
35 | if (color_cache != NULL) {
36 | WebPSafeFree(color_cache->colors_);
37 | color_cache->colors_ = NULL;
38 | }
39 | }
40 |
41 | void VP8LColorCacheCopy(const VP8LColorCache* const src,
42 | VP8LColorCache* const dst) {
43 | ASSERT(src != NULL);
44 | ASSERT(dst != NULL);
45 | ASSERT(src->hash_bits_ == dst->hash_bits_);
46 | memcpy(dst->colors_, src->colors_,
47 | ((size_t)1u << dst->hash_bits_) * sizeof(*dst->colors_));
48 | }
49 |
--------------------------------------------------------------------------------
/vendor/libwebp/common_dec.h:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Definitions and macros common to encoding and decoding
11 | //
12 | // Author: Skal (pascal.massimino@gmail.com)
13 |
14 | #ifndef WEBP_DEC_COMMON_DEC_H_
15 | #define WEBP_DEC_COMMON_DEC_H_
16 |
17 | // intra prediction modes
18 | enum { B_DC_PRED = 0, // 4x4 modes
19 | B_TM_PRED = 1,
20 | B_VE_PRED = 2,
21 | B_HE_PRED = 3,
22 | B_RD_PRED = 4,
23 | B_VR_PRED = 5,
24 | B_LD_PRED = 6,
25 | B_VL_PRED = 7,
26 | B_HD_PRED = 8,
27 | B_HU_PRED = 9,
28 | NUM_BMODES = B_HU_PRED + 1 - B_DC_PRED, // = 10
29 |
30 | // Luma16 or UV modes
31 | DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED,
32 | H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED,
33 | B_PRED = NUM_BMODES, // refined I4x4 mode
34 | NUM_PRED_MODES = 4,
35 |
36 | // special modes
37 | B_DC_PRED_NOTOP = 4,
38 | B_DC_PRED_NOLEFT = 5,
39 | B_DC_PRED_NOTOPLEFT = 6,
40 | NUM_B_DC_MODES = 7 };
41 |
42 | enum { MB_FEATURE_TREE_PROBS = 3,
43 | NUM_MB_SEGMENTS = 4,
44 | NUM_REF_LF_DELTAS = 4,
45 | NUM_MODE_LF_DELTAS = 4, // I4x4, ZERO, *, SPLIT
46 | MAX_NUM_PARTITIONS = 8,
47 | // Probabilities
48 | NUM_TYPES = 4, // 0: i16-AC, 1: i16-DC, 2:chroma-AC, 3:i4-AC
49 | NUM_BANDS = 8,
50 | NUM_CTX = 3,
51 | NUM_PROBAS = 11
52 | };
53 |
54 | #endif // WEBP_DEC_COMMON_DEC_H_
55 |
--------------------------------------------------------------------------------
/vendor/libwebp/dec_sse41.c:
--------------------------------------------------------------------------------
1 | // Copyright 2015 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // SSE4 version of some decoding functions.
11 | //
12 | // Author: Skal (pascal.massimino@gmail.com)
13 |
14 | #include "./dsp.h"
15 |
16 | #if defined(WEBP_USE_SSE41)
17 |
18 | #include
19 | #include "./utils.h"
20 |
21 | static void HE16_SSE41(uint8_t* dst) { // horizontal
22 | int j;
23 | const __m128i kShuffle3 = _mm_set1_epi8(3);
24 | for (j = 16; j > 0; --j) {
25 | const __m128i in = _mm_cvtsi32_si128(WebPMemToInt32(dst - 4));
26 | const __m128i values = _mm_shuffle_epi8(in, kShuffle3);
27 | _mm_storeu_si128((__m128i*)dst, values);
28 | dst += BPS;
29 | }
30 | }
31 |
32 | //------------------------------------------------------------------------------
33 | // Entry point
34 |
35 | extern void VP8DspInitSSE41(void);
36 |
37 | WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE41(void) {
38 | VP8PredLuma16[3] = HE16_SSE41;
39 | }
40 |
41 | #else // !WEBP_USE_SSE41
42 |
43 | WEBP_DSP_INIT_STUB(VP8DspInitSSE41)
44 |
45 | #endif // WEBP_USE_SSE41
46 |
--------------------------------------------------------------------------------
/vendor/libwebp/filters_utils.h:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Spatial prediction using various filters
11 | //
12 | // Author: Urvang (urvang@google.com)
13 |
14 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
15 | #ifndef WEBP_UTILS_FILTERS_UTILS_H_
16 | #define WEBP_UTILS_FILTERS_UTILS_H_
17 |
18 | #include "./types.h"
19 | #include "./dsp.h"
20 |
21 | #ifdef __cplusplus
22 | extern "C" {
23 | #endif
24 |
25 | // Fast estimate of a potentially good filter.
26 | WEBP_FILTER_TYPE WebPEstimateBestFilter(const uint8_t* data,
27 | int width, int height, int stride);
28 |
29 | #ifdef __cplusplus
30 | } // extern "C"
31 | #endif
32 |
33 | #endif // WEBP_UTILS_FILTERS_UTILS_H_
34 |
--------------------------------------------------------------------------------
/vendor/libwebp/huffman_utils.c:
--------------------------------------------------------------------------------
1 | // Copyright 2012 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Utilities for building and looking up Huffman trees.
11 | //
12 | // Author: Urvang Joshi (urvang@google.com)
13 |
14 | #include
15 | #include
16 | #include "./utils.h"
17 | #include "./format_constants.h"
18 |
19 | // Huffman data read via DecodeImageStream is represented in two (red and green)
20 | // bytes.
21 | #define MAX_HTREE_GROUPS 0x10000
22 |
23 | // Maximum code_lengths_size is 2328 (reached for 11-bit color_cache_bits).
24 | // More commonly, the value is around ~280.
25 | #define MAX_CODE_LENGTHS_SIZE \
26 | ((1 << MAX_CACHE_BITS) + NUM_LITERAL_CODES + NUM_LENGTH_CODES)
27 | // Cut-off value for switching between heap and stack allocation.
28 | #define SORTED_SIZE_CUTOFF 512
29 |
--------------------------------------------------------------------------------
/vendor/libwebp/muxread.c:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Read APIs for mux.
11 | //
12 | // Authors: Urvang (urvang@google.com)
13 | // Vikas (vikasa@google.com)
14 |
15 | #include "./muxi.h"
16 | #include "./utils.h"
17 |
18 | //------------------------------------------------------------------------------
19 | // Helper method(s).
20 |
21 | // Handy MACRO.
22 | #define SWITCH_ID_LIST(INDEX, LIST) \
23 | do { \
24 | if (idx == (INDEX)) { \
25 | const WebPChunk* const chunk = ChunkSearchList((LIST), nth, \
26 | kChunks[(INDEX)].tag); \
27 | if (chunk) { \
28 | *data = chunk->data_; \
29 | return WEBP_MUX_OK; \
30 | } else { \
31 | return WEBP_MUX_NOT_FOUND; \
32 | } \
33 | } \
34 | } while (0)
35 |
36 | #undef SWITCH_ID_LIST
37 |
--------------------------------------------------------------------------------
/vendor/libwebp/quant_levels_utils.h:
--------------------------------------------------------------------------------
1 | // Copyright 2011 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Alpha plane quantization utility
11 | //
12 | // Author: Vikas Arora (vikasa@google.com)
13 |
14 | #ifndef WEBP_UTILS_QUANT_LEVELS_UTILS_H_
15 | #define WEBP_UTILS_QUANT_LEVELS_UTILS_H_
16 |
17 | #include
18 |
19 | #include "./types.h"
20 |
21 | #ifdef __cplusplus
22 | extern "C" {
23 | #endif
24 |
25 | // Replace the input 'data' of size 'width'x'height' with 'num-levels'
26 | // quantized values. If not NULL, 'sse' will contain the sum of squared error.
27 | // Valid range for 'num_levels' is [2, 256].
28 | // Returns false in case of error (data is NULL, or parameters are invalid).
29 | int QuantizeLevels(uint8_t* const data, int width, int height, int num_levels,
30 | uint64_t* const sse);
31 |
32 | #ifdef __cplusplus
33 | } // extern "C"
34 | #endif
35 |
36 | #endif // WEBP_UTILS_QUANT_LEVELS_UTILS_H_
37 |
--------------------------------------------------------------------------------
/vendor/libwebp/random_utils.c:
--------------------------------------------------------------------------------
1 | // Copyright 2013 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Pseudo-random utilities
11 | //
12 | // Author: Skal (pascal.massimino@gmail.com)
13 |
14 | #include
15 | #include "./random_utils.h"
16 |
17 | //------------------------------------------------------------------------------
18 |
19 | // 31b-range values
20 | static const uint32_t kRandomTable[VP8_RANDOM_TABLE_SIZE] = {
21 | 0x0de15230, 0x03b31886, 0x775faccb, 0x1c88626a, 0x68385c55, 0x14b3b828,
22 | 0x4a85fef8, 0x49ddb84b, 0x64fcf397, 0x5c550289, 0x4a290000, 0x0d7ec1da,
23 | 0x5940b7ab, 0x5492577d, 0x4e19ca72, 0x38d38c69, 0x0c01ee65, 0x32a1755f,
24 | 0x5437f652, 0x5abb2c32, 0x0faa57b1, 0x73f533e7, 0x685feeda, 0x7563cce2,
25 | 0x6e990e83, 0x4730a7ed, 0x4fc0d9c6, 0x496b153c, 0x4f1403fa, 0x541afb0c,
26 | 0x73990b32, 0x26d7cb1c, 0x6fcc3706, 0x2cbb77d8, 0x75762f2a, 0x6425ccdd,
27 | 0x24b35461, 0x0a7d8715, 0x220414a8, 0x141ebf67, 0x56b41583, 0x73e502e3,
28 | 0x44cab16f, 0x28264d42, 0x73baaefb, 0x0a50ebed, 0x1d6ab6fb, 0x0d3ad40b,
29 | 0x35db3b68, 0x2b081e83, 0x77ce6b95, 0x5181e5f0, 0x78853bbc, 0x009f9494,
30 | 0x27e5ed3c
31 | };
32 |
33 | void VP8InitRandom(VP8Random* const rg, float dithering) {
34 | memcpy(rg->tab_, kRandomTable, sizeof(rg->tab_));
35 | rg->index1_ = 0;
36 | rg->index2_ = 31;
37 | rg->amp_ = (dithering < 0.0) ? 0
38 | : (dithering > 1.0) ? (1 << VP8_RANDOM_DITHER_FIX)
39 | : (uint32_t)((1 << VP8_RANDOM_DITHER_FIX) * dithering);
40 | }
41 |
42 | //------------------------------------------------------------------------------
43 |
44 |
--------------------------------------------------------------------------------
/vendor/libwebp/sharpyuv_cpu.c:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | #include "./sharpyuv_cpu.h"
11 |
12 | // Include src/dsp/cpu.c to create SharpYuvGetCPUInfo from VP8GetCPUInfo. The
13 | // function pointer is renamed in sharpyuv_cpu.h.
14 | #include "./cpu.c"
15 |
--------------------------------------------------------------------------------
/vendor/libwebp/sharpyuv_cpu.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
11 | #ifndef WEBP_SHARPYUV_SHARPYUV_CPU_H_
12 | #define WEBP_SHARPYUV_SHARPYUV_CPU_H_
13 |
14 | #include "./sharpyuv.h"
15 |
16 | // Avoid exporting SharpYuvGetCPUInfo in shared object / DLL builds.
17 | // SharpYuvInit() replaces the use of the function pointer.
18 | #undef WEBP_EXTERN
19 | #define WEBP_EXTERN extern
20 | #define VP8GetCPUInfo SharpYuvGetCPUInfo
21 | #include "./cpu.h"
22 |
23 | #endif // WEBP_SHARPYUV_SHARPYUV_CPU_H_
24 |
--------------------------------------------------------------------------------
/vendor/libwebp/sharpyuv_dsp.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Speed-critical functions for Sharp YUV.
11 |
12 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
13 | #ifndef WEBP_SHARPYUV_SHARPYUV_DSP_H_
14 | #define WEBP_SHARPYUV_SHARPYUV_DSP_H_
15 |
16 | #include "./sharpyuv_cpu.h"
17 | #include "./types.h"
18 |
19 | extern uint64_t (*SharpYuvUpdateY)(const uint16_t* src, const uint16_t* ref,
20 | uint16_t* dst, int len, int bit_depth);
21 | extern void (*SharpYuvUpdateRGB)(const int16_t* src, const int16_t* ref,
22 | int16_t* dst, int len);
23 | extern void (*SharpYuvFilterRow)(const int16_t* A, const int16_t* B, int len,
24 | const uint16_t* best_y, uint16_t* out,
25 | int bit_depth);
26 |
27 | void SharpYuvInitDsp(void);
28 |
29 | #endif // WEBP_SHARPYUV_SHARPYUV_DSP_H_
30 |
--------------------------------------------------------------------------------
/vendor/libwebp/sharpyuv_gamma.h:
--------------------------------------------------------------------------------
1 | // Copyright 2022 Google Inc. All Rights Reserved.
2 | //
3 | // Use of this source code is governed by a BSD-style license
4 | // that can be found in the COPYING file in the root of the source
5 | // tree. An additional intellectual property rights grant can be found
6 | // in the file PATENTS. All contributing project authors may
7 | // be found in the AUTHORS file in the root of the source tree.
8 | // -----------------------------------------------------------------------------
9 | //
10 | // Gamma correction utilities.
11 |
12 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header"
13 | #ifndef WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
14 | #define WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
15 |
16 | #include "./sharpyuv.h"
17 | #include "./types.h"
18 |
19 | #ifdef __cplusplus
20 | extern "C" {
21 | #endif
22 |
23 | // Initializes precomputed tables. Must be called once before calling
24 | // SharpYuvGammaToLinear or SharpYuvLinearToGamma.
25 | void SharpYuvInitGammaTables(void);
26 |
27 | // Converts a 'bit_depth'-bit gamma color value to a 16-bit linear value.
28 | uint32_t SharpYuvGammaToLinear(uint16_t v, int bit_depth,
29 | SharpYuvTransferFunctionType transfer_type);
30 |
31 | // Converts a 16-bit linear color value to a 'bit_depth'-bit gamma value.
32 | uint16_t SharpYuvLinearToGamma(uint32_t value, int bit_depth,
33 | SharpYuvTransferFunctionType transfer_type);
34 |
35 | #ifdef __cplusplus
36 | } // extern "C"
37 | #endif
38 |
39 | #endif // WEBP_SHARPYUV_SHARPYUV_GAMMA_H_
40 |
--------------------------------------------------------------------------------