diff --git a/.github/workflows/ampli-merge-check.ios.yml b/.github/workflows/ampli-merge-check.ios.yml index 1b6b965e..af428b98 100644 --- a/.github/workflows/ampli-merge-check.ios.yml +++ b/.github/workflows/ampli-merge-check.ios.yml @@ -19,10 +19,14 @@ jobs: - name: Checkout repo uses: actions/checkout@v2 - - name: (iOS Swift) Check the Data branch is merged before merging the Git branch - working-directory: ./ios/swift/AmpliSwiftSampleApp + - name: (iOS Swift V1) Check the Data branch is merged before merging the Git branch + working-directory: ./ios/swift/v1/AmpliSwiftSampleApp + run: ampli status --is-merged -t ${{secrets.AMPLI_TOKEN}} + + - name: (iOS Swift V2) Check the Data branch is merged before merging the Git branch + working-directory: ./ios/swift/v2/AmpliSwiftSampleApp run: ampli status --is-merged -t ${{secrets.AMPLI_TOKEN}} - name: (iOS Objective-C) Check the Data branch is merged before merging the Git branch - working-directory: ./ios/objective-c/AmpliObjectiveCSampleApp + working-directory: ./ios/objective-c/v1/AmpliObjectiveCSampleApp run: ampli status --is-merged -t ${{secrets.AMPLI_TOKEN}} diff --git a/.github/workflows/ci-build-ios-test.yml b/.github/workflows/ci-build-ios-v1-test.yml similarity index 77% rename from .github/workflows/ci-build-ios-test.yml rename to .github/workflows/ci-build-ios-v1-test.yml index 024f73f5..a20b45a9 100644 --- a/.github/workflows/ci-build-ios-test.yml +++ b/.github/workflows/ci-build-ios-v1-test.yml @@ -1,10 +1,10 @@ -name: CI - iOS Tests +name: CI - iOS V1 Tests on: pull_request: paths: - - 'ios/objective-c/**' - - 'ios/swift/**' + - 'ios/objective-c/v1/**' + - 'ios/swift/v1/**' jobs: test: @@ -31,12 +31,12 @@ jobs: uses: actions/cache@v2 with: path: | - ./ios/swift/AmpliSwiftSampleApp/Pods - ./ios/swift/AmpliSwiftSampleApp/vendor/bundle + ./ios/swift/v1/AmpliSwiftSampleApp/Pods + ./ios/swift/v1/AmpliSwiftSampleApp/vendor/bundle key: ${{ runner.os }}-ruby-${{ matrix.ruby-version }}-gems-${{ hashFiles('**/Gemfile.lock') }}-pods-${{ hashFiles('**/Podfile.lock') }} - name: Install Cocoapods For Swift - working-directory: ./ios/swift/AmpliSwiftSampleApp + working-directory: ./ios/swift/v1/AmpliSwiftSampleApp if: steps.cache-gems-pods.outputs.cache-hit != 'true' run: | gem install bundler @@ -44,8 +44,8 @@ jobs: bundle install pod install - - name: Swfit iOS Tests - working-directory: ./ios/swift/AmpliSwiftSampleApp + - name: Swift iOS Tests + working-directory: ./ios/swift/v1/AmpliSwiftSampleApp run: | pod install xcodebuild test \ @@ -59,12 +59,12 @@ jobs: uses: actions/cache@v2 with: path: | - ./ios/objective-c/AmpliObjectiveCSampleApp/Pods - ./ios/objective-c/AmpliObjectiveCSampleApp/vendor/bundle + ./ios/objective-c/v1/AmpliObjectiveCSampleApp/Pods + ./ios/objective-c/v1/AmpliObjectiveCSampleApp/vendor/bundle key: ${{ runner.os }}-ruby-${{ matrix.ruby-version }}-gems-${{ hashFiles('**/Gemfile.lock') }}-pods-${{ hashFiles('**/Podfile.lock') }} - name: Install Cocoapods For Objective-C - working-directory: ./ios/objective-c/AmpliObjectiveCSampleApp + working-directory: ./ios/objective-c/v1/AmpliObjectiveCSampleApp if: steps.cache-gems-objc-pods.outputs.cache-hit != 'true' run: | gem install bundler @@ -73,7 +73,7 @@ jobs: pod install - name: Objective-C iOS Tests - working-directory: ./ios/objective-c/AmpliObjectiveCSampleApp + working-directory: ./ios/objective-c/v1/AmpliObjectiveCSampleApp run: | pod install xcodebuild test \ diff --git a/.github/workflows/ci-build-ios-v2-test.yml b/.github/workflows/ci-build-ios-v2-test.yml new file mode 100644 index 00000000..5e2b3bdf --- /dev/null +++ b/.github/workflows/ci-build-ios-v2-test.yml @@ -0,0 +1,30 @@ +name: CI - iOS V2 Tests + +on: + pull_request: + paths: + - 'ios/swift/v2/**' + +jobs: + test: + name: Test + runs-on: macos-12 + strategy: + matrix: + ruby-version: ["2.7.x"] + steps: + - name: Check out Git repository + uses: actions/checkout@v2 + + - name: Set Xcode 14.2 + run: | + sudo xcode-select -switch /Applications/Xcode_14.2.app + + - name: Swift iOS Tests + working-directory: ./ios/swift/v2/AmpliSwiftSampleApp + run: | + xcodebuild test \ + -project AmpliSwiftSampleApp.xcodeproj \ + -scheme AmpliSwiftSampleAppTests \ + -sdk iphonesimulator \ + -destination 'platform=iOS Simulator,name=iPhone 14,OS=16.2' diff --git a/README.md b/README.md index 9a74b7a5..c1ff1719 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,12 @@ See subproject README's for details on each platform. #### [node/typescript](node/typescript) #### [nextjs/typescript](node/nextjs/ampli-app) -## iOS -#### [ios/swift](ios/swift/AmpliSwiftSampleApp) -#### [ios/objective-c](ios/objective-c/AmpliObjectiveCSampleApp) +## iOS V1 +#### [ios/swift](ios/swift/v1/AmpliSwiftSampleApp) +#### [ios/objective-c](ios/objective-c/v1/AmpliObjectiveCSampleApp) + +## iOS V2 +#### [ios/swift](ios/swift/v2/AmpliSwiftSampleApp) ## Android V1 #### [android/kotlin](android/kotlin/v1/AmpliApp) diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.pbxproj b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.pbxproj similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.pbxproj rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.pbxproj diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliObjectiveCSampleApp.xcscheme b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliObjectiveCSampleApp.xcscheme similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliObjectiveCSampleApp.xcscheme rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliObjectiveCSampleApp.xcscheme diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcworkspace/contents.xcworkspacedata b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcworkspace/contents.xcworkspacedata similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcworkspace/contents.xcworkspacedata rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcworkspace/contents.xcworkspacedata diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Ampli/Ampli.h b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Ampli/Ampli.h similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Ampli/Ampli.h rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Ampli/Ampli.h diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Ampli/Ampli.m b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Ampli/Ampli.m similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Ampli/Ampli.m rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Ampli/Ampli.m diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/AppDelegate.h b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/AppDelegate.h similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/AppDelegate.h rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/AppDelegate.h diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/AppDelegate.m b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/AppDelegate.m similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/AppDelegate.m rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/AppDelegate.m diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/AccentColor.colorset/Contents.json b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/AccentColor.colorset/Contents.json rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/AppIcon.appiconset/Contents.json rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/Contents.json b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/Contents.json similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/Contents.json rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Assets.xcassets/Contents.json diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Base.lproj/LaunchScreen.storyboard b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Base.lproj/LaunchScreen.storyboard rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Base.lproj/LaunchScreen.storyboard diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Base.lproj/Main.storyboard b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Base.lproj/Main.storyboard similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Base.lproj/Main.storyboard rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Base.lproj/Main.storyboard diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Info.plist b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Info.plist similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Info.plist rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/Info.plist diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/SceneDelegate.h b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/SceneDelegate.h similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/SceneDelegate.h rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/SceneDelegate.h diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/SceneDelegate.m b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/SceneDelegate.m similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/SceneDelegate.m rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/SceneDelegate.m diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/ViewController.h b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/ViewController.h similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/ViewController.h rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/ViewController.h diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/ViewController.m b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/ViewController.m similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/ViewController.m rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/ViewController.m diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/main.m b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/main.m similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/main.m rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleApp/main.m diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleAppTests/AmpliTests.m b/ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleAppTests/AmpliTests.m similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleAppTests/AmpliTests.m rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/AmpliObjectiveCSampleAppTests/AmpliTests.m diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/Gemfile b/ios/objective-c/v1/AmpliObjectiveCSampleApp/Gemfile similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/Gemfile rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/Gemfile diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/Podfile b/ios/objective-c/v1/AmpliObjectiveCSampleApp/Podfile similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/Podfile rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/Podfile diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/README.md b/ios/objective-c/v1/AmpliObjectiveCSampleApp/README.md similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/README.md rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/README.md diff --git a/ios/objective-c/AmpliObjectiveCSampleApp/ampli.json b/ios/objective-c/v1/AmpliObjectiveCSampleApp/ampli.json similarity index 100% rename from ios/objective-c/AmpliObjectiveCSampleApp/ampli.json rename to ios/objective-c/v1/AmpliObjectiveCSampleApp/ampli.json diff --git a/ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj b/ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj rename to ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj diff --git a/ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleApp (iOS).xcscheme b/ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleApp (iOS).xcscheme similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleApp (iOS).xcscheme rename to ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleApp (iOS).xcscheme diff --git a/ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleAppTests.xcscheme b/ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleAppTests.xcscheme similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleAppTests.xcscheme rename to ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleAppTests.xcscheme diff --git a/ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcworkspace/contents.xcworkspacedata b/ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcworkspace/contents.xcworkspacedata similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcworkspace/contents.xcworkspacedata rename to ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcworkspace/contents.xcworkspacedata diff --git a/ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift b/ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift rename to ios/swift/v1/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift diff --git a/ios/swift/AmpliSwiftSampleApp/Gemfile b/ios/swift/v1/AmpliSwiftSampleApp/Gemfile similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Gemfile rename to ios/swift/v1/AmpliSwiftSampleApp/Gemfile diff --git a/ios/swift/AmpliSwiftSampleApp/Podfile b/ios/swift/v1/AmpliSwiftSampleApp/Podfile similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Podfile rename to ios/swift/v1/AmpliSwiftSampleApp/Podfile diff --git a/ios/swift/AmpliSwiftSampleApp/README.md b/ios/swift/v1/AmpliSwiftSampleApp/README.md similarity index 85% rename from ios/swift/AmpliSwiftSampleApp/README.md rename to ios/swift/v1/AmpliSwiftSampleApp/README.md index 9497f8cf..9bc02b9a 100644 --- a/ios/swift/AmpliSwiftSampleApp/README.md +++ b/ios/swift/v1/AmpliSwiftSampleApp/README.md @@ -27,7 +27,7 @@ If you want to use your own tracking plan and Ampli SDK * Podfile - pods dependency * Shared/ * [AmpliSwiftSampleAppApp](Shared/AmpliSwiftSampleAppApp.swift) - Example user app using Ampli SDK. A good place to start. - * [TextView](Shared/TextView.swift) - Example user app using Ampli SDK. A good place to start. - * [ContentView](Shared/ContentView.swift) - Example user app using Ampli SDK. A good place to start. + * [TextView](Shared/TextView.swift) - Ampli SDK usage in a TextView. + * [ContentView](Shared/ContentView.swift) - Ampli SDK usage in a ContentView. * Ampli/ * [Ampli.swift](Shared/Ampli/Ampli.swift) - Generated SDK, don't modify by hand. Update with `ampli pull` diff --git a/ios/swift/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift b/ios/swift/v1/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift similarity index 93% rename from ios/swift/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift rename to ios/swift/v1/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift index 71abcda7..221f005c 100644 --- a/ios/swift/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift +++ b/ios/swift/v1/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift @@ -20,29 +20,29 @@ import Amplitude public typealias MiddlewareExtra = [String: Any] public enum AmpliEnvironment: Int { - case prod, dev; + case prod, dev } let ApiKey: [AmpliEnvironment: String] = [ .prod: "", .dev: "" -]; +] let AmpliObservePlan = AMPPlan() .setBranch("main") .setSource("swift-ampli") .setVersion("1") - .setVersionId("a61c3908-ca4d-4c8d-8f81-54ad3ba17b9c"); + .setVersionId("a61c3908-ca4d-4c8d-8f81-54ad3ba17b9c") public class Event { public let eventType: String public let eventProperties: [String:Any]? - public let options: EventOptions?; + public let options: EventOptions? init(eventType: String, eventProperties: [String:Any?]?, options: EventOptions?) { - self.eventType = eventType; - self.eventProperties = eventProperties?.compactMapValues { $0 }; - self.options = options; + self.eventType = eventType + self.eventProperties = eventProperties?.compactMapValues { $0 } + self.options = options } } @@ -50,16 +50,16 @@ public class GenericEvent : Event { private let eventFactory: (_ eventProperties: [String: Any?]?, _ options: EventOptions?) -> E init(eventType: String, eventProperties: [String:Any?]?, options: EventOptions?, eventFactory: @escaping (_ eventProperties: [String: Any?]?, _ options: EventOptions?) -> E) { - self.eventFactory = eventFactory; + self.eventFactory = eventFactory super.init(eventType: eventType, eventProperties: eventProperties, options: options) } public func options(_ options: EventOptions) -> E { - return self.eventFactory(self.eventProperties, options); + return self.eventFactory(self.eventProperties, options) } public func options(deviceId: String? = nil, userId: String? = nil) -> E { - return self.options(EventOptions(deviceId: deviceId, userId: userId)); + return self.options(EventOptions(deviceId: deviceId, userId: userId)) } } @@ -71,7 +71,7 @@ public class Identify : GenericEvent { eventProperties: eventProperties, options: options, eventFactory: Identify.init - ); + ) } /** @@ -87,7 +87,7 @@ public class Identify : GenericEvent { self.init([ "optionalArray": optionalArray, "requiredNumber": requiredNumber - ]); + ]) } } @@ -99,7 +99,7 @@ public class EventNoProperties : GenericEvent { eventProperties: eventProperties, options: options, eventFactory: EventNoProperties.init - ); + ) } /** @@ -108,7 +108,7 @@ public class EventNoProperties : GenericEvent { Owner: Test codegen */ public convenience init() { - self.init(nil); + self.init(nil) } } @@ -120,7 +120,7 @@ public class EventObjectTypes : GenericEvent { eventProperties: eventProperties, options: options, eventFactory: EventObjectTypes.init - ); + ) } /** @@ -138,7 +138,7 @@ public class EventObjectTypes : GenericEvent { self.init([ "requiredObject": requiredObject, "requiredObjectArray": requiredObjectArray - ]); + ]) } } @@ -155,7 +155,7 @@ public class EventWithAllProperties : GenericEvent { eventProperties: eventProperties, options: options, eventFactory: EventWithAllProperties.init - ); + ) } /** @@ -189,7 +189,7 @@ public class EventWithAllProperties : GenericEvent { "requiredInteger": requiredInteger, "requiredNumber": requiredNumber, "requiredString": requiredString - ]); + ]) } } @@ -201,7 +201,7 @@ public class EventWithArrayTypes : GenericEvent { eventProperties: eventProperties, options: options, eventFactory: EventWithArrayTypes.init - ); + ) } /** @@ -228,7 +228,7 @@ public class EventWithArrayTypes : GenericEvent { "requiredNumberArray": requiredNumberArray, "requiredObjectArray": requiredObjectArray, "requiredStringArray": requiredStringArray - ]); + ]) } } @@ -240,7 +240,7 @@ public class EventWithConstTypes : GenericEvent { eventProperties: eventProperties, options: options, eventFactory: EventWithConstTypes.init - ); + ) } /** @@ -256,7 +256,7 @@ public class EventWithConstTypes : GenericEvent { "String Const": "String-Constant", "String Const WIth Quotes": "\"String \"Const With\" Quotes\"", "String Int Const": 0 - ]); + ]) } } @@ -278,7 +278,7 @@ public class EventWithEnumTypes : GenericEvent { eventProperties: eventProperties, options: options, eventFactory: EventWithEnumTypes.init - ); + ) } /** @@ -296,7 +296,7 @@ public class EventWithEnumTypes : GenericEvent { self.init([ "optional enum": optionalEnum?.rawValue, "required enum": requiredEnum.rawValue - ]); + ]) } } @@ -308,7 +308,7 @@ public class EventWithOptionalArrayTypes : GenericEvent { eventProperties: eventProperties, options: options, eventFactory: EventMaxIntForTest.init - ); + ) } /** @@ -501,7 +501,7 @@ public class EventMaxIntForTest : GenericEvent { ) { self.init([ "intMax10": intMax10 - ]); + ]) } } @@ -542,86 +542,94 @@ public struct EventOptions { public let userId: String? public init(deviceId: String? = nil, userId: String? = nil) { - self.deviceId = deviceId; - self.userId = userId; + self.deviceId = deviceId + self.userId = userId } } public class Ampli { - private var amplitude: Amplitude?; + private var amplitude: Amplitude? public var client: Amplitude { get { - _ = isInitializedAndEnabled(); - return amplitude!; + _ = isInitializedAndEnabled() + return amplitude! } } public var isLoaded: Bool { get { - return self.amplitude != nil; + return self.amplitude != nil } } - public private(set) var disabled: Bool; + public private(set) var disabled: Bool public static let instance: Ampli = Ampli() public init() { - disabled = false; + disabled = false + } + + private func isInitializedAndEnabled() -> Bool { + if !self.isLoaded { + NSLog("Ampli is not yet initialized. Have you called `ampli.load()` on app start?") + return false + } + return !self.disabled } // options should have 'environment', 'client.api_key' or 'client.instance' public func load(_ options: LoadOptions) -> Void { - self.disabled = options.disabled ?? false; + self.disabled = options.disabled ?? false if (self.isLoaded) { - NSLog("Warning: Ampli is already initialized. Ampli.instance.load() should be called once at application start up."); - return; + NSLog("Warning: Ampli is already initialized. Ampli.instance.load() should be called once at application start up.") + return } - var apiKey: String?; + var apiKey: String? if (options.client?.apiKey != nil) { - apiKey = options.client?.apiKey; + apiKey = options.client?.apiKey } else if (options.environment != nil) { - apiKey = ApiKey[options.environment!]; + apiKey = ApiKey[options.environment!] } if (options.client?.instance != nil) { - self.amplitude = options.client?.instance; + self.amplitude = options.client?.instance } else if (apiKey != nil) { - self.amplitude = Amplitude.instance(); - self.amplitude?.initializeApiKey(apiKey!); + self.amplitude = Amplitude.instance() + self.amplitude?.initializeApiKey(apiKey!) } else { - NSLog("ampli.load() requires 'environment', 'client.apiKey', or 'client.instance'"); - return; + NSLog("ampli.load() requires 'environment', 'client.apiKey', or 'client.instance'") + return } - self.amplitude?.setPlan(options.client?.config?.plan ?? AmpliObservePlan!); + self.amplitude?.setPlan(options.client?.config?.plan ?? AmpliObservePlan!) // set ingestionMetadata information let AmpliExtrasMiddleware = AMPBlockMiddleware { (payload, next) in let ingestionMetadata: NSMutableDictionary = [ "source_name": "ios-swift-ampli", "source_version": "1.0.0" - ]; - payload.event["ingestion_metadata"] = ingestionMetadata; + ] + payload.event["ingestion_metadata"] = ingestionMetadata // Continue to next middleware - next(payload); + next(payload) } - self.amplitude?.addEventMiddleware(AmpliExtrasMiddleware); + self.amplitude?.addEventMiddleware(AmpliExtrasMiddleware) } public func track(_ event: Event, options: EventOptions? = nil, extra: MiddlewareExtra? = nil) -> Void { if (!isInitializedAndEnabled()) { - return; + return } - self.handleEventOptions(event.options, options); - amplitude?.logEvent(event.eventType, withEventProperties: event.eventProperties, withMiddlewareExtra: extra as? NSMutableDictionary); + self.handleEventOptions(event.options, options) + amplitude?.logEvent(event.eventType, withEventProperties: event.eventProperties, withMiddlewareExtra: extra as? NSMutableDictionary) } public func identify(_ userId: String?, _ event: Identify, options: EventOptions? = nil, extra: MiddlewareExtra? = nil) -> Void { if (!isInitializedAndEnabled()) { - return; + return } self.handleEventOptions(event.options, options, userId) @@ -635,9 +643,9 @@ public class Ampli { public func flush() -> Void { if (!isInitializedAndEnabled()) { - return; + return } - amplitude?.uploadEvents(); + amplitude?.uploadEvents() } /** @@ -650,7 +658,7 @@ public class Ampli { Owner: Test codegen */ public func eventNoProperties() { - self.track(EventNoProperties()); + self.track(EventNoProperties()) } /** @@ -672,7 +680,7 @@ public class Ampli { self.track(EventObjectTypes( requiredObject: requiredObject, requiredObjectArray: requiredObjectArray - )); + )) } /** @@ -709,7 +717,7 @@ public class Ampli { requiredNumber: requiredNumber, requiredString: requiredString, optionalString: optionalString - )); + )) } /** @@ -740,7 +748,7 @@ public class Ampli { requiredNumberArray: requiredNumberArray, requiredObjectArray: requiredObjectArray, requiredStringArray: requiredStringArray - )); + )) } /** @@ -753,7 +761,7 @@ public class Ampli { Owner: Test codegen */ public func eventWithConstTypes() { - self.track(EventWithConstTypes()); + self.track(EventWithConstTypes()) } /** @@ -775,7 +783,7 @@ public class Ampli { self.track(EventWithEnumTypes( requiredEnum: requiredEnum, optionalEnum: optionalEnum - )); + )) } /** @@ -806,7 +814,7 @@ public class Ampli { optionalJsonArray: optionalJsonArray, optionalNumberArray: optionalNumberArray, optionalStringArray: optionalStringArray - )); + )) } /** @@ -837,7 +845,7 @@ public class Ampli { optionalBoolean: optionalBoolean, optionalNumber: optionalNumber, optionalString: optionalString - )); + )) } /** @@ -865,7 +873,7 @@ public class Ampli { requiredTemplateProperty: requiredTemplateProperty, optionalEventProperty: optionalEventProperty, optionalTemplateProperty: optionalTemplateProperty - )); + )) } /** @@ -905,7 +913,7 @@ public class Ampli { propertyWithSnakeCase: propertyWithSnakeCase, propertyWithCamelCase: propertyWithCamelCase, propertyWithPascalCase: propertyWithPascalCase - )); + )) } /** @@ -924,25 +932,18 @@ public class Ampli { ) { self.track(EventMaxIntForTest( intMax10: intMax10 - )); - } - private func isInitializedAndEnabled() -> Bool { - if (!self.isLoaded) { - NSLog("Ampli is not yet initialized. Have you called `ampli.load()` on app start?"); - return false; - } - return !self.disabled; + )) } private func handleEventOptions(_ options: EventOptions?, _ overrideOptions: EventOptions?, _ overrideUserId: String? = nil) { - let userId = overrideUserId ?? overrideOptions?.userId ?? options?.userId; + let userId = overrideUserId ?? overrideOptions?.userId ?? options?.userId if (userId != nil) { - amplitude?.setUserId(userId); + amplitude?.setUserId(userId) } - let deviceId = overrideOptions?.deviceId ?? options?.deviceId; + let deviceId = overrideOptions?.deviceId ?? options?.deviceId if (deviceId != nil) { - amplitude?.setDeviceId(deviceId!); + amplitude?.setDeviceId(deviceId!) } } } diff --git a/ios/swift/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/.xccurrentversion b/ios/swift/v1/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/.xccurrentversion similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/.xccurrentversion rename to ios/swift/v1/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/.xccurrentversion diff --git a/ios/swift/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/Shared.xcdatamodel/contents b/ios/swift/v1/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/Shared.xcdatamodel/contents similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/Shared.xcdatamodel/contents rename to ios/swift/v1/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/Shared.xcdatamodel/contents diff --git a/ios/swift/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleAppApp.swift b/ios/swift/v1/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleAppApp.swift similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleAppApp.swift rename to ios/swift/v1/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleAppApp.swift diff --git a/ios/swift/AmpliSwiftSampleApp/Shared/Assets.xcassets/AccentColor.colorset/Contents.json b/ios/swift/v1/AmpliSwiftSampleApp/Shared/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Shared/Assets.xcassets/AccentColor.colorset/Contents.json rename to ios/swift/v1/AmpliSwiftSampleApp/Shared/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/ios/swift/AmpliSwiftSampleApp/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/swift/v1/AmpliSwiftSampleApp/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json rename to ios/swift/v1/AmpliSwiftSampleApp/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/ios/swift/AmpliSwiftSampleApp/Shared/Assets.xcassets/Contents.json b/ios/swift/v1/AmpliSwiftSampleApp/Shared/Assets.xcassets/Contents.json similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Shared/Assets.xcassets/Contents.json rename to ios/swift/v1/AmpliSwiftSampleApp/Shared/Assets.xcassets/Contents.json diff --git a/ios/swift/AmpliSwiftSampleApp/Shared/ContentView.swift b/ios/swift/v1/AmpliSwiftSampleApp/Shared/ContentView.swift similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Shared/ContentView.swift rename to ios/swift/v1/AmpliSwiftSampleApp/Shared/ContentView.swift diff --git a/ios/swift/AmpliSwiftSampleApp/Shared/Persistence.swift b/ios/swift/v1/AmpliSwiftSampleApp/Shared/Persistence.swift similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Shared/Persistence.swift rename to ios/swift/v1/AmpliSwiftSampleApp/Shared/Persistence.swift diff --git a/ios/swift/AmpliSwiftSampleApp/Shared/TextView.swift b/ios/swift/v1/AmpliSwiftSampleApp/Shared/TextView.swift similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/Shared/TextView.swift rename to ios/swift/v1/AmpliSwiftSampleApp/Shared/TextView.swift diff --git a/ios/swift/AmpliSwiftSampleApp/ampli.json b/ios/swift/v1/AmpliSwiftSampleApp/ampli.json similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/ampli.json rename to ios/swift/v1/AmpliSwiftSampleApp/ampli.json diff --git a/ios/swift/AmpliSwiftSampleApp/macOS/macOS.entitlements b/ios/swift/v1/AmpliSwiftSampleApp/macOS/macOS.entitlements similarity index 100% rename from ios/swift/AmpliSwiftSampleApp/macOS/macOS.entitlements rename to ios/swift/v1/AmpliSwiftSampleApp/macOS/macOS.entitlements diff --git a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj new file mode 100644 index 00000000..a8a8c5e3 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.pbxproj @@ -0,0 +1,679 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 55; + objects = { + +/* Begin PBXBuildFile section */ + 3E3B5FB02758045C003D95E1 /* AmpliTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E3B5FAF2758045C003D95E1 /* AmpliTests.swift */; }; + 3E3B5FB227583BC9003D95E1 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E3B5FB127583BC9003D95E1 /* TextView.swift */; }; + 3E3B5FB327583BC9003D95E1 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E3B5FB127583BC9003D95E1 /* TextView.swift */; }; + 3ECE2C3E273F7B6C004EAA2C /* AmpliSwiftSampleApp.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 3ECE2C2B273F7B65004EAA2C /* AmpliSwiftSampleApp.xcdatamodeld */; }; + 3ECE2C3F273F7B6C004EAA2C /* AmpliSwiftSampleApp.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 3ECE2C2B273F7B65004EAA2C /* AmpliSwiftSampleApp.xcdatamodeld */; }; + 3ECE2C40273F7B6C004EAA2C /* AmpliSwiftSampleAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ECE2C2D273F7B65004EAA2C /* AmpliSwiftSampleAppApp.swift */; }; + 3ECE2C41273F7B6C004EAA2C /* AmpliSwiftSampleAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ECE2C2D273F7B65004EAA2C /* AmpliSwiftSampleAppApp.swift */; }; + 3ECE2C42273F7B6C004EAA2C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ECE2C2E273F7B65004EAA2C /* ContentView.swift */; }; + 3ECE2C43273F7B6C004EAA2C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ECE2C2E273F7B65004EAA2C /* ContentView.swift */; }; + 3ECE2C44273F7B6C004EAA2C /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ECE2C2F273F7B65004EAA2C /* Persistence.swift */; }; + 3ECE2C45273F7B6C004EAA2C /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ECE2C2F273F7B65004EAA2C /* Persistence.swift */; }; + 3ECE2C46273F7B6C004EAA2C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3ECE2C30273F7B6C004EAA2C /* Assets.xcassets */; }; + 3ECE2C47273F7B6C004EAA2C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3ECE2C30273F7B6C004EAA2C /* Assets.xcassets */; }; + 3ECE2C532743332C004EAA2C /* Ampli.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ECE2C512743332C004EAA2C /* Ampli.swift */; }; + 3ECE2C542743332C004EAA2C /* Ampli.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ECE2C512743332C004EAA2C /* Ampli.swift */; }; + BA4436A82A84CCE4002F1115 /* LoggingPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4436A72A84CCE4002F1115 /* LoggingPlugin.swift */; }; + BA581AA22A8DF46300079EFE /* AmplitudeSwift in Frameworks */ = {isa = PBXBuildFile; productRef = BA581AA12A8DF46300079EFE /* AmplitudeSwift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 3E3B5FAA275803D3003D95E1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 3ECE2C26273F7B65004EAA2C /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3ECE2C34273F7B6C004EAA2C; + remoteInfo = "AmpliSwiftSampleApp (iOS)"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 3E3B5FA6275803D3003D95E1 /* AmpliSwiftSampleAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AmpliSwiftSampleAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3E3B5FAF2758045C003D95E1 /* AmpliTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AmpliTests.swift; sourceTree = ""; }; + 3E3B5FB127583BC9003D95E1 /* TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = ""; }; + 3ECE2C2C273F7B65004EAA2C /* Shared.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Shared.xcdatamodel; sourceTree = ""; }; + 3ECE2C2D273F7B65004EAA2C /* AmpliSwiftSampleAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AmpliSwiftSampleAppApp.swift; sourceTree = ""; }; + 3ECE2C2E273F7B65004EAA2C /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 3ECE2C2F273F7B65004EAA2C /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; + 3ECE2C30273F7B6C004EAA2C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 3ECE2C35273F7B6C004EAA2C /* AmpliSwiftSampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AmpliSwiftSampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 3ECE2C3B273F7B6C004EAA2C /* AmpliSwiftSampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AmpliSwiftSampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 3ECE2C3D273F7B6C004EAA2C /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = ""; }; + 3ECE2C512743332C004EAA2C /* Ampli.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Ampli.swift; sourceTree = ""; }; + BA4436A72A84CCE4002F1115 /* LoggingPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggingPlugin.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 3E3B5FA3275803D3003D95E1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3ECE2C32273F7B6C004EAA2C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BA581AA22A8DF46300079EFE /* AmplitudeSwift in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3ECE2C38273F7B6C004EAA2C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 3E3B5FA7275803D3003D95E1 /* AmpliSwiftSampleAppTests */ = { + isa = PBXGroup; + children = ( + 3E3B5FAF2758045C003D95E1 /* AmpliTests.swift */, + ); + path = AmpliSwiftSampleAppTests; + sourceTree = ""; + }; + 3ECE2C25273F7B65004EAA2C = { + isa = PBXGroup; + children = ( + 3ECE2C2A273F7B65004EAA2C /* Shared */, + 3ECE2C3C273F7B6C004EAA2C /* macOS */, + 3E3B5FA7275803D3003D95E1 /* AmpliSwiftSampleAppTests */, + 3ECE2C36273F7B6C004EAA2C /* Products */, + B8E184F982BAB6A9F0F2440E /* Pods */, + ); + sourceTree = ""; + }; + 3ECE2C2A273F7B65004EAA2C /* Shared */ = { + isa = PBXGroup; + children = ( + BA4436A62A84CCC7002F1115 /* Plugins */, + 3ECE2C502743332C004EAA2C /* Ampli */, + 3ECE2C2D273F7B65004EAA2C /* AmpliSwiftSampleAppApp.swift */, + 3E3B5FB127583BC9003D95E1 /* TextView.swift */, + 3ECE2C2E273F7B65004EAA2C /* ContentView.swift */, + 3ECE2C2F273F7B65004EAA2C /* Persistence.swift */, + 3ECE2C30273F7B6C004EAA2C /* Assets.xcassets */, + 3ECE2C2B273F7B65004EAA2C /* AmpliSwiftSampleApp.xcdatamodeld */, + ); + path = Shared; + sourceTree = ""; + }; + 3ECE2C36273F7B6C004EAA2C /* Products */ = { + isa = PBXGroup; + children = ( + 3ECE2C35273F7B6C004EAA2C /* AmpliSwiftSampleApp.app */, + 3ECE2C3B273F7B6C004EAA2C /* AmpliSwiftSampleApp.app */, + 3E3B5FA6275803D3003D95E1 /* AmpliSwiftSampleAppTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 3ECE2C3C273F7B6C004EAA2C /* macOS */ = { + isa = PBXGroup; + children = ( + 3ECE2C3D273F7B6C004EAA2C /* macOS.entitlements */, + ); + path = macOS; + sourceTree = ""; + }; + 3ECE2C502743332C004EAA2C /* Ampli */ = { + isa = PBXGroup; + children = ( + 3ECE2C512743332C004EAA2C /* Ampli.swift */, + ); + path = Ampli; + sourceTree = ""; + }; + B8E184F982BAB6A9F0F2440E /* Pods */ = { + isa = PBXGroup; + children = ( + ); + path = Pods; + sourceTree = ""; + }; + BA4436A62A84CCC7002F1115 /* Plugins */ = { + isa = PBXGroup; + children = ( + BA4436A72A84CCE4002F1115 /* LoggingPlugin.swift */, + ); + path = Plugins; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 3E3B5FA5275803D3003D95E1 /* AmpliSwiftSampleAppTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3E3B5FAE275803D3003D95E1 /* Build configuration list for PBXNativeTarget "AmpliSwiftSampleAppTests" */; + buildPhases = ( + 3E3B5FA2275803D3003D95E1 /* Sources */, + 3E3B5FA3275803D3003D95E1 /* Frameworks */, + 3E3B5FA4275803D3003D95E1 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 3E3B5FAB275803D3003D95E1 /* PBXTargetDependency */, + ); + name = AmpliSwiftSampleAppTests; + productName = AmpliSwiftSampleAppTests; + productReference = 3E3B5FA6275803D3003D95E1 /* AmpliSwiftSampleAppTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 3ECE2C34273F7B6C004EAA2C /* AmpliSwiftSampleApp (iOS) */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3ECE2C4A273F7B6C004EAA2C /* Build configuration list for PBXNativeTarget "AmpliSwiftSampleApp (iOS)" */; + buildPhases = ( + 3ECE2C31273F7B6C004EAA2C /* Sources */, + 3ECE2C32273F7B6C004EAA2C /* Frameworks */, + 3ECE2C33273F7B6C004EAA2C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "AmpliSwiftSampleApp (iOS)"; + packageProductDependencies = ( + BA581AA12A8DF46300079EFE /* AmplitudeSwift */, + ); + productName = "AmpliSwiftSampleApp (iOS)"; + productReference = 3ECE2C35273F7B6C004EAA2C /* AmpliSwiftSampleApp.app */; + productType = "com.apple.product-type.application"; + }; + 3ECE2C3A273F7B6C004EAA2C /* AmpliSwiftSampleApp (macOS) */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3ECE2C4D273F7B6C004EAA2C /* Build configuration list for PBXNativeTarget "AmpliSwiftSampleApp (macOS)" */; + buildPhases = ( + 3ECE2C37273F7B6C004EAA2C /* Sources */, + 3ECE2C38273F7B6C004EAA2C /* Frameworks */, + 3ECE2C39273F7B6C004EAA2C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "AmpliSwiftSampleApp (macOS)"; + productName = "AmpliSwiftSampleApp (macOS)"; + productReference = 3ECE2C3B273F7B6C004EAA2C /* AmpliSwiftSampleApp.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 3ECE2C26273F7B65004EAA2C /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1310; + LastUpgradeCheck = 1310; + TargetAttributes = { + 3E3B5FA5275803D3003D95E1 = { + CreatedOnToolsVersion = 13.1; + TestTargetID = 3ECE2C34273F7B6C004EAA2C; + }; + 3ECE2C34273F7B6C004EAA2C = { + CreatedOnToolsVersion = 13.1; + }; + 3ECE2C3A273F7B6C004EAA2C = { + CreatedOnToolsVersion = 13.1; + }; + }; + }; + buildConfigurationList = 3ECE2C29273F7B65004EAA2C /* Build configuration list for PBXProject "AmpliSwiftSampleApp" */; + compatibilityVersion = "Xcode 13.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 3ECE2C25273F7B65004EAA2C; + packageReferences = ( + BA581AA02A8DF46200079EFE /* XCRemoteSwiftPackageReference "Amplitude-Swift" */, + ); + productRefGroup = 3ECE2C36273F7B6C004EAA2C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 3ECE2C34273F7B6C004EAA2C /* AmpliSwiftSampleApp (iOS) */, + 3ECE2C3A273F7B6C004EAA2C /* AmpliSwiftSampleApp (macOS) */, + 3E3B5FA5275803D3003D95E1 /* AmpliSwiftSampleAppTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 3E3B5FA4275803D3003D95E1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3ECE2C33273F7B6C004EAA2C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3ECE2C46273F7B6C004EAA2C /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3ECE2C39273F7B6C004EAA2C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3ECE2C47273F7B6C004EAA2C /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 3E3B5FA2275803D3003D95E1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3E3B5FB02758045C003D95E1 /* AmpliTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3ECE2C31273F7B6C004EAA2C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3ECE2C3E273F7B6C004EAA2C /* AmpliSwiftSampleApp.xcdatamodeld in Sources */, + BA4436A82A84CCE4002F1115 /* LoggingPlugin.swift in Sources */, + 3ECE2C44273F7B6C004EAA2C /* Persistence.swift in Sources */, + 3ECE2C532743332C004EAA2C /* Ampli.swift in Sources */, + 3E3B5FB227583BC9003D95E1 /* TextView.swift in Sources */, + 3ECE2C40273F7B6C004EAA2C /* AmpliSwiftSampleAppApp.swift in Sources */, + 3ECE2C42273F7B6C004EAA2C /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3ECE2C37273F7B6C004EAA2C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3ECE2C3F273F7B6C004EAA2C /* AmpliSwiftSampleApp.xcdatamodeld in Sources */, + 3ECE2C45273F7B6C004EAA2C /* Persistence.swift in Sources */, + 3ECE2C542743332C004EAA2C /* Ampli.swift in Sources */, + 3E3B5FB327583BC9003D95E1 /* TextView.swift in Sources */, + 3ECE2C41273F7B6C004EAA2C /* AmpliSwiftSampleAppApp.swift in Sources */, + 3ECE2C43273F7B6C004EAA2C /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3E3B5FAB275803D3003D95E1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3ECE2C34273F7B6C004EAA2C /* AmpliSwiftSampleApp (iOS) */; + targetProxy = 3E3B5FAA275803D3003D95E1 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 3E3B5FAC275803D3003D95E1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.amplitude.AmpliSwiftSampleAppTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AmpliSwiftSampleApp.app/AmpliSwiftSampleApp"; + }; + name = Debug; + }; + 3E3B5FAD275803D3003D95E1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.amplitude.AmpliSwiftSampleAppTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AmpliSwiftSampleApp.app/AmpliSwiftSampleApp"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 3ECE2C48273F7B6C004EAA2C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 3ECE2C49273F7B6C004EAA2C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 3ECE2C4B273F7B6C004EAA2C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.amplitude.AmpliSwiftSampleApp; + PRODUCT_NAME = AmpliSwiftSampleApp; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 3ECE2C4C273F7B6C004EAA2C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.amplitude.AmpliSwiftSampleApp; + PRODUCT_NAME = AmpliSwiftSampleApp; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 3ECE2C4E273F7B6C004EAA2C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.amplitude.AmpliSwiftSampleApp; + PRODUCT_NAME = AmpliSwiftSampleApp; + SDKROOT = macosx; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 3ECE2C4F273F7B6C004EAA2C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 12.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.amplitude.AmpliSwiftSampleApp; + PRODUCT_NAME = AmpliSwiftSampleApp; + SDKROOT = macosx; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 3E3B5FAE275803D3003D95E1 /* Build configuration list for PBXNativeTarget "AmpliSwiftSampleAppTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3E3B5FAC275803D3003D95E1 /* Debug */, + 3E3B5FAD275803D3003D95E1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3ECE2C29273F7B65004EAA2C /* Build configuration list for PBXProject "AmpliSwiftSampleApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3ECE2C48273F7B6C004EAA2C /* Debug */, + 3ECE2C49273F7B6C004EAA2C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3ECE2C4A273F7B6C004EAA2C /* Build configuration list for PBXNativeTarget "AmpliSwiftSampleApp (iOS)" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3ECE2C4B273F7B6C004EAA2C /* Debug */, + 3ECE2C4C273F7B6C004EAA2C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3ECE2C4D273F7B6C004EAA2C /* Build configuration list for PBXNativeTarget "AmpliSwiftSampleApp (macOS)" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3ECE2C4E273F7B6C004EAA2C /* Debug */, + 3ECE2C4F273F7B6C004EAA2C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + BA581AA02A8DF46200079EFE /* XCRemoteSwiftPackageReference "Amplitude-Swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/amplitude/Amplitude-Swift"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.4.14; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + BA581AA12A8DF46300079EFE /* AmplitudeSwift */ = { + isa = XCSwiftPackageProductDependency; + package = BA581AA02A8DF46200079EFE /* XCRemoteSwiftPackageReference "Amplitude-Swift" */; + productName = AmplitudeSwift; + }; +/* End XCSwiftPackageProductDependency section */ + +/* Begin XCVersionGroup section */ + 3ECE2C2B273F7B65004EAA2C /* AmpliSwiftSampleApp.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + 3ECE2C2C273F7B65004EAA2C /* Shared.xcdatamodel */, + ); + currentVersion = 3ECE2C2C273F7B65004EAA2C /* Shared.xcdatamodel */; + path = AmpliSwiftSampleApp.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ + }; + rootObject = 3ECE2C26273F7B65004EAA2C /* Project object */; +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..94628004 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,14 @@ +{ + "pins" : [ + { + "identity" : "amplitude-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/amplitude/Amplitude-Swift", + "state" : { + "revision" : "8293ca0b09aac19b7c87f51ad0386590a066e71f", + "version" : "0.4.14" + } + } + ], + "version" : 2 +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleApp (iOS).xcscheme b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleApp (iOS).xcscheme new file mode 100644 index 00000000..ecf2397d --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleApp (iOS).xcscheme @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleAppTests.xcscheme b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleAppTests.xcscheme new file mode 100644 index 00000000..be2261d7 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleApp.xcodeproj/xcshareddata/xcschemes/AmpliSwiftSampleAppTests.xcscheme @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift new file mode 100644 index 00000000..34c5fa30 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/AmpliSwiftSampleAppTests/AmpliTests.swift @@ -0,0 +1,205 @@ +import XCTest +import AmpliSwiftSampleApp +import AmplitudeSwift + +let emptyDictionary = [String: String]() +func isEmptyDictionary(_ dict: Any?) -> Bool { + dict == nil || NSDictionary(dictionary: dict as! [String: String]).isEqual(to: emptyDictionary) +} + +class AmpliTests: XCTestCase { + private var ampli: Ampli! + + override func setUpWithError() throws { + ampli = Ampli() + } + + func initAmpliWithNewInstance(_ instanceName: String) { + ampli.load(LoadOptions(client: LoadClientOptions(configuration: Configuration( + apiKey: "test-api-key", + instanceName: instanceName, + trackingSessionEvents: false, + migrateLegacyData: false + )))) + } + + func testIdentify() throws { + let userId = "test-user-id"; + let deviceId = "test-device-id"; + + initAmpliWithNewInstance("testIdentify") + let eventCollector = EventCollectorPlugin() + ampli.client.add(plugin: eventCollector) + + let identifyProperties = Identify(requiredNumber: 22.0, optionalArray: ["optional array str"]) + let eventOptions = EventOptions(deviceId: deviceId) + + ampli.identify(userId, identifyProperties, options: eventOptions) + ampli.flush() + + XCTAssertEqual(eventCollector.events.count, 1) + let event = eventCollector.events[0] + XCTAssertEqual(event.eventType, "$identify") + XCTAssertTrue(isEmptyDictionary(event.eventProperties)) + XCTAssertEqual(event.userId, userId) + XCTAssertEqual(event.deviceId, deviceId) + } + + func testIdentifyUserIdOnEvent() { + initAmpliWithNewInstance("testIdentifyUserIdOnEvent") + let eventCollector = EventCollectorPlugin() + ampli.client.add(plugin: eventCollector) + + let eventOptionsUserId = "test-user-id-options" + let deviceId = "test-device-id" + let identifyProperties = Identify(requiredNumber: 22.0, optionalArray: ["optional array str"]) + let eventOptions = EventOptions(userId: eventOptionsUserId, deviceId: deviceId) + + ampli.identify(nil, identifyProperties, options: eventOptions) + ampli.flush() + + XCTAssertEqual(eventCollector.events.count, 1) + let event = eventCollector.events[0] + XCTAssertEqual(event.eventType, "$identify") + XCTAssertEqual(event.userId, eventOptionsUserId) + XCTAssertEqual(event.deviceId, deviceId) + XCTAssertEqual(ampli.client.getUserId(), eventOptionsUserId) + } + + func testTrackWithNoProperties() throws { + initAmpliWithNewInstance("testTrackWithNoProperties") + let eventCollector = EventCollectorPlugin() + ampli.client.add(plugin: eventCollector) + + ampli.eventNoProperties() + ampli.flush() + + XCTAssertEqual(eventCollector.events.count, 1) + let event = eventCollector.events[0] + XCTAssertEqual(event.eventType, "Event No Properties") + XCTAssertTrue(isEmptyDictionary(event.eventProperties)) + XCTAssertNil(event.userId) + XCTAssertNotNil(event.deviceId) + } + + func testTrackEventWithAllTypes() throws { + let userId = "test-user-id"; + let deviceId = "test-device-id"; + let eventOptions = EventOptions(deviceId: deviceId) + + initAmpliWithNewInstance("testTrackEventWithAllTypes") + let eventCollector = EventCollectorPlugin() + ampli.client.add(plugin: eventCollector) + + ampli.track( + EventWithAllProperties( + requiredArray: ["array element 1", "array element 2"], + requiredBoolean: true, + requiredEnum: EventWithAllProperties.RequiredEnum.enum1, + requiredInteger: 10, + requiredNumber: 2.0, + requiredString: "required string" + ).options(userId: userId), + options: eventOptions + ) + ampli.flush() + + XCTAssertEqual(eventCollector.events.count, 1) + let event = eventCollector.events[0] + XCTAssertEqual(event.eventType, "Event With All Properties") + let eventProperties = event.eventProperties + XCTAssertNotNil(event.eventProperties) + XCTAssertEqual(eventProperties!["requiredArray"] as! Array, ["array element 1", "array element 2"]) + XCTAssertEqual(eventProperties!["requiredBoolean"] as! Bool, true) + XCTAssertEqual(eventProperties!["requiredEnum"] as! String, "Enum1") + XCTAssertEqual(eventProperties!["requiredInteger"] as! Int, 10) + XCTAssertEqual(eventProperties!["requiredNumber"] as! Double, 2.0) + XCTAssertEqual(eventProperties!["requiredString"] as! String, "required string") + XCTAssertFalse(eventProperties!.keys.contains("optionalString")) + XCTAssertEqual(event.userId, userId) + XCTAssertEqual(event.deviceId, deviceId) + } + + func testSetGroup() throws { + let groupType = "test-group-type"; + let groupName = "test-group"; + + initAmpliWithNewInstance("testSetGroup") + let eventCollector = EventCollectorPlugin() + ampli.client.add(plugin: eventCollector) + + ampli.client.setGroup(groupType: groupType, groupName: groupName) + ampli.flush() + + XCTAssertEqual(eventCollector.events.count, 1) + let event = eventCollector.events[0] + XCTAssertEqual(event.eventType, "$identify") + XCTAssertTrue(isEmptyDictionary(event.eventProperties)) + let userProperties = event.userProperties + let userPropertiesSet = userProperties!["$set"] as? Dictionary + XCTAssertEqual(userPropertiesSet![groupType] as! String, groupName) + } + + func testGroupIdentify() throws { + let groupType = "test-group-type"; + let groupName = "test-group"; + + initAmpliWithNewInstance("testGroupIdentify") + let eventCollector = EventCollectorPlugin() + ampli.client.add(plugin: eventCollector) + + let groupProperties: [String:Any] = [ + "requiredBoolean": false, + "optionalString": "optional str" + ] + ampli.client.groupIdentify(groupType: groupType, groupName: groupName, groupProperties: groupProperties) + ampli.flush() + + XCTAssertEqual(eventCollector.events.count, 1) + let event = eventCollector.events[0] + XCTAssertEqual(event.eventType, "$groupidentify") + XCTAssertTrue(isEmptyDictionary(event.eventProperties)) + XCTAssertTrue(isEmptyDictionary(event.userProperties)) + let groups = event.groups + XCTAssertEqual(groups![groupType] as! String, groupName) + let groupPropertiesSet = event.groupProperties!["$set"] as? Dictionary + XCTAssertEqual(groupPropertiesSet!["requiredBoolean"] as! Bool, false) + XCTAssertEqual(groupPropertiesSet!["optionalString"] as! String, "optional str") + } + + func testGroupIdentifyNilOptionalString() throws { + let groupType = "test-group-type"; + let groupName = "test-group"; + + initAmpliWithNewInstance("testGroupIdentifyNilOptionalString") + let eventCollector = EventCollectorPlugin() + ampli.client.add(plugin: eventCollector) + + let identify = Identify() + identify.set(property: "requiredBoolean", value: false) + identify.set(property: "optionalString", value: nil) + ampli.client.groupIdentify(groupType: groupType, groupName: groupName, identify: identify) + ampli.flush() + + + XCTAssertEqual(eventCollector.events.count, 1) + let event = eventCollector.events[0] + XCTAssertEqual(event.eventType, "$groupidentify") + XCTAssertTrue(isEmptyDictionary(event.eventProperties)) + XCTAssertTrue(isEmptyDictionary(event.userProperties)) + let groups = event.groups + XCTAssertEqual(groups![groupType] as! String, groupName) + let groupPropertiesSet = event.groupProperties!["$set"] as? Dictionary + XCTAssertEqual(groupPropertiesSet!["requiredBoolean"] as! Bool, false) + XCTAssertNil(groupPropertiesSet!["optionalString"]) + } +} + +class EventCollectorPlugin: DestinationPlugin { + var events: [BaseEvent] = Array() + + public override func execute(event: BaseEvent) -> BaseEvent? { + events.append(event) + return event + } +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/README.md b/ios/swift/v2/AmpliSwiftSampleApp/README.md new file mode 100644 index 00000000..786e69ce --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/README.md @@ -0,0 +1,31 @@ +# Ampli iOS SDK 2.0 (Swift) +An example app using the Ampli Swift SDK V2. + +# Usage + +### Setup the project +You will need to do the following before running the app. +1. Set up environment variable with your API keys + 1. Go to `Edit Scheme > Run > Arguments > Environment Variables` section + 2. Set your Amplitude API key with name `AMPLITUDE_API_KEY` +2. Open `AmpliSwiftSampleApp.xcodeproj` with Xcode + +### Run the app +You can run the app using the events from our sample tracking plan. +This will log events to your Amplitude project. +* Just click on run in Xcode + +### Pull your Ampli SDK +If you want to use your own tracking plan and Ampli SDK +1. `npm i -g @amplitude/ampli` +2. `ampli pull` +3. Update `AmpliSwiftSampleAppApp`, `TextView.swift` or `ContentView.swift` to use the events from your tracking plan + +# Project structure +* README.md - you are here * +* Shared/ + * [AmpliSwiftSampleAppApp](Shared/AmpliSwiftSampleAppApp.swift) - Example user app using Ampli SDK. A good place to start. + * [TextView](Shared/TextView.swift) - Ampli SDK usage in a TextView. + * [ContentView](Shared/ContentView.swift) - Ampli SDK usage in a ContentView. + * Ampli/ + * [Ampli.swift](Shared/Ampli/Ampli.swift) - Generated SDK, don't modify by hand. Update with `ampli pull` diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift new file mode 100644 index 00000000..00f42719 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Ampli/Ampli.swift @@ -0,0 +1,924 @@ +/** + * Ampli - A strong typed wrapper for your Analytics + * + * This file is generated by Amplitude. + * To update run 'ampli pull swift-ampli-v2' + * + * Required dependencies: https://github.com/amplitude/Amplitude-Swift ~> 1.0 + * Tracking Plan Version: 1 + * Build: 1.0.0 + * Runtime: ios:swift-ampli-v2 + * + * [View Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest) + * + * [Full Setup Instructions](https://data.amplitude.com/test-codegen/Test%20Codegen/implementation/swift-ampli-v2) + */ + +import Foundation +import AmplitudeSwift + +public enum AmpliEnvironment: Int { + case prod, dev +} + +let ApiKey: [AmpliEnvironment: String] = [ + .prod: "", + .dev: "" +] + +let AmpliObservePlan = Plan( + branch: "main", + source: "swift-ampli-v2", + version: "1", + versionId: "a61c3908-ca4d-4c8d-8f81-54ad3ba17b9c" +) + +public class Event { + public let eventType: String + public let eventProperties: [String:Any]? + public let options: EventOptions? + + init(eventType: String, eventProperties: [String:Any?]?, options: EventOptions?) { + self.eventType = eventType + self.eventProperties = eventProperties?.compactMapValues { $0 } + self.options = options + } +} + +public class GenericEvent : Event { + private let eventFactory: (_ eventProperties: [String: Any?]?, _ options: EventOptions?) -> E + + init(eventType: String, eventProperties: [String:Any?]?, options: EventOptions?, eventFactory: @escaping (_ eventProperties: [String: Any?]?, _ options: EventOptions?) -> E) { + self.eventFactory = eventFactory + super.init(eventType: eventType, eventProperties: eventProperties, options: options) + } + + public func options(_ options: EventOptions) -> E { + return self.eventFactory(self.eventProperties, options) + } + + public func options(deviceId: String? = nil, userId: String? = nil) -> E { + return self.options(EventOptions(userId: userId, deviceId: deviceId)) + } +} + +public class Identify : GenericEvent { + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "$identify", + eventProperties: eventProperties, + options: options, + eventFactory: Identify.init + ) + } + + /** + Identify properties. + + - Parameter requiredNumber: Description for identify requiredNumber + - Parameter optionalArray: Description for identify optionalArray + */ + public convenience init( + requiredNumber: Double, + optionalArray: [String]? = nil + ) { + self.init([ + "optionalArray": optionalArray, + "requiredNumber": requiredNumber + ]) + } +} + +public class EventNoProperties : GenericEvent { + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "Event No Properties", + eventProperties: eventProperties, + options: options, + eventFactory: EventNoProperties.init + ) + } + + /** + Event w no properties description + + Owner: Test codegen + */ + public convenience init() { + self.init(nil) + } +} + +public class EventObjectTypes : GenericEvent { + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "Event Object Types", + eventProperties: eventProperties, + options: options, + eventFactory: EventObjectTypes.init + ) + } + + /** + Event with Object and Object Array + + Owner: Test codegen + + - Parameter requiredObject: Property Object Type + - Parameter requiredObjectArray: Property Object Array Type + */ + public convenience init( + requiredObject: Any, + requiredObjectArray: [Any] + ) { + self.init([ + "requiredObject": requiredObject, + "requiredObjectArray": requiredObjectArray + ]) + } +} + +public class EventWithAllProperties : GenericEvent { + + public enum RequiredEnum: String { + case enum1 = "Enum1" + case enum2 = "Enum2" + } + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "Event With All Properties", + eventProperties: eventProperties, + options: options, + eventFactory: EventWithAllProperties.init + ) + } + + /** + Event w all properties description + + Owner: Test codegen + + - Parameter requiredArray: Event 2 Property - Array + - Parameter requiredBoolean: Event 2 Property - Boolean + - Parameter requiredEnum: Event 2 Property - Enum + - Parameter requiredInteger: Event 2 Property - Integer * * Examples: * 5, 4, 3 + - Parameter requiredNumber: Event 2 Property - Number + - Parameter requiredString: Event 2 Property - String + - Parameter optionalString: Event 2 Property - Optional String * * Examples: * Some string, or another + */ + public convenience init( + requiredArray: [String], + requiredBoolean: Bool, + requiredEnum: EventWithAllProperties.RequiredEnum, + requiredInteger: Int, + requiredNumber: Double, + requiredString: String, + optionalString: String? = nil + ) { + self.init([ + "optionalString": optionalString, + "requiredArray": requiredArray, + "requiredBoolean": requiredBoolean, + "requiredConst": "some-const-value", + "requiredEnum": requiredEnum.rawValue, + "requiredInteger": requiredInteger, + "requiredNumber": requiredNumber, + "requiredString": requiredString + ]) + } +} + +public class EventWithArrayTypes : GenericEvent { + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "Event With Array Types", + eventProperties: eventProperties, + options: options, + eventFactory: EventWithArrayTypes.init + ) + } + + /** + Description for event with Array Types + + Owner: Test codegen + + - Parameter requiredBooleanArray: description for required boolean array + - Parameter requiredEnumArray: Description for enum array property + - Parameter requiredNumberArray: Description for required number array + - Parameter requiredObjectArray: Description for required object array + - Parameter requiredStringArray: description for required string array + */ + public convenience init( + requiredBooleanArray: [Bool], + requiredEnumArray: [String], + requiredNumberArray: [Double], + requiredObjectArray: [Any], + requiredStringArray: [String] + ) { + self.init([ + "requiredBooleanArray": requiredBooleanArray, + "requiredEnumArray": requiredEnumArray, + "requiredNumberArray": requiredNumberArray, + "requiredObjectArray": requiredObjectArray, + "requiredStringArray": requiredStringArray + ]) + } +} + +public class EventWithConstTypes : GenericEvent { + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "Event With Const Types", + eventProperties: eventProperties, + options: options, + eventFactory: EventWithConstTypes.init + ) + } + + /** + Description for event with const types + + Owner: Test codegen + */ + public convenience init() { + self.init([ + "Boolean Const": true, + "Integer Const": 10, + "Number Const": 2.2, + "String Const": "String-Constant", + "String Const WIth Quotes": "\"String \"Const With\" Quotes\"", + "String Int Const": 0 + ]) + } +} + +public class EventWithEnumTypes : GenericEvent { + + public enum OptionalEnum: String { + case optionalEnum1 = "optional enum 1" + case optionalEnum2 = "optional enum 2" + } + + public enum RequiredEnum: String { + case requiredEnum1 = "required enum 1" + case requiredEnum2 = "required enum 2" + } + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "Event With Enum Types", + eventProperties: eventProperties, + options: options, + eventFactory: EventWithEnumTypes.init + ) + } + + /** + Description for event with enum types + + Owner: Test codegen + + - Parameter requiredEnum: Description for optional enum + - Parameter optionalEnum: Description for required enum + */ + public convenience init( + requiredEnum: EventWithEnumTypes.RequiredEnum, + optionalEnum: EventWithEnumTypes.OptionalEnum? = nil + ) { + self.init([ + "optional enum": optionalEnum?.rawValue, + "required enum": requiredEnum.rawValue + ]) + } +} + +public class EventWithOptionalArrayTypes : GenericEvent { + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "Event With Optional Array Types", + eventProperties: eventProperties, + options: options, + eventFactory: EventWithOptionalArrayTypes.init + ) + } + + /** + Description for event with optional array types + + Owner: Test codegen + + - Parameter optionalBooleanArray: Description for optional boolean array + - Parameter optionalEnumArray: Description for optional enum array + - Parameter optionalJsonArray: Description for optional object array + - Parameter optionalNumberArray: Description for optional number array + - Parameter optionalStringArray: Description for optional string array + */ + public convenience init( + optionalBooleanArray: [Bool]? = nil, + optionalEnumArray: [String]? = nil, + optionalJsonArray: [Any]? = nil, + optionalNumberArray: [Double]? = nil, + optionalStringArray: [String]? = nil + ) { + self.init([ + "optionalBooleanArray": optionalBooleanArray, + "optionalEnumArray": optionalEnumArray, + "optionalJSONArray": optionalJsonArray, + "optionalNumberArray": optionalNumberArray, + "optionalStringArray": optionalStringArray + ]) + } +} + +public class EventWithOptionalProperties : GenericEvent { + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "Event With Optional Properties", + eventProperties: eventProperties, + options: options, + eventFactory: EventWithOptionalProperties.init + ) + } + + /** + Event w optional properties description + + Owner: Test codegen + + - Parameter optionalArrayNumber: Property has no description provided in tracking plan. + - Parameter optionalArrayString: Property has no description provided in tracking plan. + - Parameter optionalBoolean: Property has no description provided in tracking plan. + - Parameter optionalNumber: Property has no description provided in tracking plan. + - Parameter optionalString: Optional String property description + */ + public convenience init( + optionalArrayNumber: [Double]? = nil, + optionalArrayString: [String]? = nil, + optionalBoolean: Bool? = nil, + optionalNumber: Double? = nil, + optionalString: String? = nil + ) { + self.init([ + "optionalArrayNumber": optionalArrayNumber, + "optionalArrayString": optionalArrayString, + "optionalBoolean": optionalBoolean, + "optionalNumber": optionalNumber, + "optionalString": optionalString + ]) + } +} + +public class EventWithTemplateProperties : GenericEvent { + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "Event With Template Properties", + eventProperties: eventProperties, + options: options, + eventFactory: EventWithTemplateProperties.init + ) + } + + /** + Event with template properties description + + Owner: Test codegen + + - Parameter requiredEventProperty: required_event_property description + - Parameter requiredTemplateProperty: required_template_property description + - Parameter optionalEventProperty: optional_event_property description + - Parameter optionalTemplateProperty: optional_template_property description + */ + public convenience init( + requiredEventProperty: String, + requiredTemplateProperty: String, + optionalEventProperty: Double? = nil, + optionalTemplateProperty: Double? = nil + ) { + self.init([ + "optional_event_property": optionalEventProperty, + "optional_template_property": optionalTemplateProperty, + "required_event_property": requiredEventProperty, + "required_template_property": requiredTemplateProperty + ]) + } +} + +public class EventWithDifferentCasingTypes : GenericEvent { + + public enum EnumWithSpace: String { + case enumWithSpace = "enum with space" + } + + public enum EnumSnakeCase: String { + case enumSnakeCase = "enum_snake_case" + } + + public enum EnumCamelCase: String { + case enumCamelCase = "enumCamelCase" + } + + public enum EnumPascalCase: String { + case enumPascalCase = "EnumPascalCase" + } + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "event withDifferent_CasingTypes", + eventProperties: eventProperties, + options: options, + eventFactory: EventWithDifferentCasingTypes.init + ) + } + + /** + Description for case with space + + Owner: Test codegen + + - Parameter enumWithSpace: Description for enum with space + - Parameter enumSnakeCase: description_for_enum_snake_case + - Parameter enumCamelCase: descriptionForEnumCamelCase + - Parameter enumPascalCase: DescirptionForEnumPascalCase + - Parameter propertyWithSpace: Description for case with space + - Parameter propertyWithSnakeCase: Description_for_snake_case + - Parameter propertyWithCamelCase: descriptionForCamelCase + - Parameter propertyWithPascalCase: DescriptionForPascalCase + */ + public convenience init( + enumWithSpace: EventWithDifferentCasingTypes.EnumWithSpace, + enumSnakeCase: EventWithDifferentCasingTypes.EnumSnakeCase, + enumCamelCase: EventWithDifferentCasingTypes.EnumCamelCase, + enumPascalCase: EventWithDifferentCasingTypes.EnumPascalCase, + propertyWithSpace: String, + propertyWithSnakeCase: String, + propertyWithCamelCase: String, + propertyWithPascalCase: String + ) { + self.init([ + "enum with space": enumWithSpace.rawValue, + "enum_snake_case": enumSnakeCase.rawValue, + "enumCamelCase": enumCamelCase.rawValue, + "EnumPascalCase": enumPascalCase.rawValue, + "property with space": propertyWithSpace, + "property_with_snake_case": propertyWithSnakeCase, + "propertyWithCamelCase": propertyWithCamelCase, + "PropertyWithPascalCase": propertyWithPascalCase + ]) + } +} + +public class EventMaxIntForTest : GenericEvent { + + private init(_ eventProperties: [String: Any?]?, _ options: EventOptions? = nil) { + super.init( + eventType: "EventMaxIntForTest", + eventProperties: eventProperties, + options: options, + eventFactory: EventMaxIntForTest.init + ) + } + + /** + Event to test schema validation + + Owner: Test codegen + + - Parameter intMax10: property to test schema validation + */ + public convenience init( + intMax10: Int + ) { + self.init([ + "intMax10": intMax10 + ]) + } +} + +public struct LoadClientOptions { + public let apiKey: String? + public let instance: Amplitude? + public let configuration: Configuration? + + public init(apiKey: String? = nil, instance: Amplitude? = nil, configuration: Configuration? = nil) { + self.apiKey = apiKey + self.instance = instance + self.configuration = configuration + } +} + +public struct LoadOptions { + public let environment: AmpliEnvironment? + public let disabled: Bool? + public let client: LoadClientOptions? + + public init(environment: AmpliEnvironment? = nil, disabled: Bool? = nil, client: LoadClientOptions? = nil) { + self.environment = environment + self.disabled = disabled + self.client = client + } +} + +public class Ampli { + private var amplitude: Amplitude? + public var client: Amplitude { + get { + _ = isInitializedAndEnabled() + return amplitude! + } + } + + public var isLoaded: Bool { + get { + return self.amplitude != nil + } + } + + public private(set) var disabled: Bool + + public static let instance: Ampli = Ampli() + + public init() { + disabled = false + } + + private func isInitializedAndEnabled() -> Bool { + if !self.isLoaded { + NSLog("Ampli is not yet initialized. Have you called `ampli.load()` on app start?") + return false + } + return !self.disabled + } + + // options should have 'environment', 'client.api_key' or 'client.instance' + public func load(_ options: LoadOptions) -> Void { + self.disabled = options.disabled ?? false + if self.isLoaded { + NSLog("Warning: Ampli is already initialized. Ampli.instance.load() should be called once at application start up.") + return + } + + var apiKey: String? + + if let clientApiKey = options.client?.apiKey { + apiKey = clientApiKey + } else if let configurationApiKey = options.client?.configuration?.apiKey { + apiKey = configurationApiKey + } else if let environment = options.environment { + apiKey = ApiKey[environment] + } + + if let instance = options.client?.instance { + self.amplitude = instance + } else if let apiKey = apiKey { + let configuration = options.client?.configuration ?? Configuration( + apiKey: apiKey + ) + if configuration.plan == nil { + configuration.plan = AmpliObservePlan + } + if configuration.ingestionMetadata == nil { + configuration.ingestionMetadata = IngestionMetadata( + sourceName: "ios-swift-ampli-v2", sourceVersion: "1.0.0" + ) + } + self.amplitude = Amplitude(configuration: configuration) + } else { + NSLog("ampli.load() requires 'environment', 'client.apiKey', or 'client.instance'") + return + } + } + + public func track(_ event: Event, options: EventOptions? = nil) -> Void { + if !isInitializedAndEnabled() { + return + } + let eventOptions = getEventOptions(event.options, options) + amplitude?.track(eventType: event.eventType, eventProperties: event.eventProperties, options: eventOptions) + } + + public func identify(_ userId: String?, _ event: Identify, options: EventOptions? = nil) -> Void { + if !isInitializedAndEnabled() { + return + } + let eventOptions = getEventOptions(event.options, options, userId) + amplitude?.identify(userProperties: event.eventProperties, options: eventOptions) + } + + public func flush() -> Void { + if !isInitializedAndEnabled() { + return + } + amplitude?.flush() + } + + /** + Event No Properties + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/Event%20No%20Properties) + + Event w no properties description + + Owner: Test codegen + */ + public func eventNoProperties() { + self.track(EventNoProperties()) + } + + /** + Event Object Types + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/Event%20Object%20Types) + + Event with Object and Object Array + + Owner: Test codegen + + - Parameter requiredObject: Property Object Type + - Parameter requiredObjectArray: Property Object Array Type + */ + public func eventObjectTypes( + requiredObject: Any, + requiredObjectArray: [Any] + ) { + self.track(EventObjectTypes( + requiredObject: requiredObject, + requiredObjectArray: requiredObjectArray + )) + } + + /** + Event With All Properties + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/Event%20With%20All%20Properties) + + Event w all properties description + + Owner: Test codegen + + - Parameter requiredArray: Event 2 Property - Array + - Parameter requiredBoolean: Event 2 Property - Boolean + - Parameter requiredEnum: Event 2 Property - Enum + - Parameter requiredInteger: Event 2 Property - Integer * * Examples: * 5, 4, 3 + - Parameter requiredNumber: Event 2 Property - Number + - Parameter requiredString: Event 2 Property - String + - Parameter optionalString: Event 2 Property - Optional String * * Examples: * Some string, or another + */ + public func eventWithAllProperties( + requiredArray: [String], + requiredBoolean: Bool, + requiredEnum: EventWithAllProperties.RequiredEnum, + requiredInteger: Int, + requiredNumber: Double, + requiredString: String, + optionalString: String? = nil + ) { + self.track(EventWithAllProperties( + requiredArray: requiredArray, + requiredBoolean: requiredBoolean, + requiredEnum: requiredEnum, + requiredInteger: requiredInteger, + requiredNumber: requiredNumber, + requiredString: requiredString, + optionalString: optionalString + )) + } + + /** + Event With Array Types + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/Event%20With%20Array%20Types) + + Description for event with Array Types + + Owner: Test codegen + + - Parameter requiredBooleanArray: description for required boolean array + - Parameter requiredEnumArray: Description for enum array property + - Parameter requiredNumberArray: Description for required number array + - Parameter requiredObjectArray: Description for required object array + - Parameter requiredStringArray: description for required string array + */ + public func eventWithArrayTypes( + requiredBooleanArray: [Bool], + requiredEnumArray: [String], + requiredNumberArray: [Double], + requiredObjectArray: [Any], + requiredStringArray: [String] + ) { + self.track(EventWithArrayTypes( + requiredBooleanArray: requiredBooleanArray, + requiredEnumArray: requiredEnumArray, + requiredNumberArray: requiredNumberArray, + requiredObjectArray: requiredObjectArray, + requiredStringArray: requiredStringArray + )) + } + + /** + Event With Const Types + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/Event%20With%20Const%20Types) + + Description for event with const types + + Owner: Test codegen + */ + public func eventWithConstTypes() { + self.track(EventWithConstTypes()) + } + + /** + Event With Enum Types + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/Event%20With%20Enum%20Types) + + Description for event with enum types + + Owner: Test codegen + + - Parameter requiredEnum: Description for optional enum + - Parameter optionalEnum: Description for required enum + */ + public func eventWithEnumTypes( + requiredEnum: EventWithEnumTypes.RequiredEnum, + optionalEnum: EventWithEnumTypes.OptionalEnum? = nil + ) { + self.track(EventWithEnumTypes( + requiredEnum: requiredEnum, + optionalEnum: optionalEnum + )) + } + + /** + Event With Optional Array Types + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/Event%20With%20Optional%20Array%20Types) + + Description for event with optional array types + + Owner: Test codegen + + - Parameter optionalBooleanArray: Description for optional boolean array + - Parameter optionalEnumArray: Description for optional enum array + - Parameter optionalJsonArray: Description for optional object array + - Parameter optionalNumberArray: Description for optional number array + - Parameter optionalStringArray: Description for optional string array + */ + public func eventWithOptionalArrayTypes( + optionalBooleanArray: [Bool]? = nil, + optionalEnumArray: [String]? = nil, + optionalJsonArray: [Any]? = nil, + optionalNumberArray: [Double]? = nil, + optionalStringArray: [String]? = nil + ) { + self.track(EventWithOptionalArrayTypes( + optionalBooleanArray: optionalBooleanArray, + optionalEnumArray: optionalEnumArray, + optionalJsonArray: optionalJsonArray, + optionalNumberArray: optionalNumberArray, + optionalStringArray: optionalStringArray + )) + } + + /** + Event With Optional Properties + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/Event%20With%20Optional%20Properties) + + Event w optional properties description + + Owner: Test codegen + + - Parameter optionalArrayNumber: Property has no description provided in tracking plan. + - Parameter optionalArrayString: Property has no description provided in tracking plan. + - Parameter optionalBoolean: Property has no description provided in tracking plan. + - Parameter optionalNumber: Property has no description provided in tracking plan. + - Parameter optionalString: Optional String property description + */ + public func eventWithOptionalProperties( + optionalArrayNumber: [Double]? = nil, + optionalArrayString: [String]? = nil, + optionalBoolean: Bool? = nil, + optionalNumber: Double? = nil, + optionalString: String? = nil + ) { + self.track(EventWithOptionalProperties( + optionalArrayNumber: optionalArrayNumber, + optionalArrayString: optionalArrayString, + optionalBoolean: optionalBoolean, + optionalNumber: optionalNumber, + optionalString: optionalString + )) + } + + /** + Event With Template Properties + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/Event%20With%20Template%20Properties) + + Event with template properties description + + Owner: Test codegen + + - Parameter requiredEventProperty: required_event_property description + - Parameter requiredTemplateProperty: required_template_property description + - Parameter optionalEventProperty: optional_event_property description + - Parameter optionalTemplateProperty: optional_template_property description + */ + public func eventWithTemplateProperties( + requiredEventProperty: String, + requiredTemplateProperty: String, + optionalEventProperty: Double? = nil, + optionalTemplateProperty: Double? = nil + ) { + self.track(EventWithTemplateProperties( + requiredEventProperty: requiredEventProperty, + requiredTemplateProperty: requiredTemplateProperty, + optionalEventProperty: optionalEventProperty, + optionalTemplateProperty: optionalTemplateProperty + )) + } + + /** + event withDifferent_CasingTypes + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/event%20withDifferent_CasingTypes) + + Description for case with space + + Owner: Test codegen + + - Parameter enumWithSpace: Description for enum with space + - Parameter enumSnakeCase: description_for_enum_snake_case + - Parameter enumCamelCase: descriptionForEnumCamelCase + - Parameter enumPascalCase: DescirptionForEnumPascalCase + - Parameter propertyWithSpace: Description for case with space + - Parameter propertyWithSnakeCase: Description_for_snake_case + - Parameter propertyWithCamelCase: descriptionForCamelCase + - Parameter propertyWithPascalCase: DescriptionForPascalCase + */ + public func eventWithDifferentCasingTypes( + enumWithSpace: EventWithDifferentCasingTypes.EnumWithSpace, + enumSnakeCase: EventWithDifferentCasingTypes.EnumSnakeCase, + enumCamelCase: EventWithDifferentCasingTypes.EnumCamelCase, + enumPascalCase: EventWithDifferentCasingTypes.EnumPascalCase, + propertyWithSpace: String, + propertyWithSnakeCase: String, + propertyWithCamelCase: String, + propertyWithPascalCase: String + ) { + self.track(EventWithDifferentCasingTypes( + enumWithSpace: enumWithSpace, + enumSnakeCase: enumSnakeCase, + enumCamelCase: enumCamelCase, + enumPascalCase: enumPascalCase, + propertyWithSpace: propertyWithSpace, + propertyWithSnakeCase: propertyWithSnakeCase, + propertyWithCamelCase: propertyWithCamelCase, + propertyWithPascalCase: propertyWithPascalCase + )) + } + + /** + EventMaxIntForTest + + [View in Tracking Plan](https://data.amplitude.com/test-codegen/Test%20Codegen/events/main/latest/EventMaxIntForTest) + + Event to test schema validation + + Owner: Test codegen + + - Parameter intMax10: property to test schema validation + */ + public func eventMaxIntForTest( + intMax10: Int + ) { + self.track(EventMaxIntForTest( + intMax10: intMax10 + )) + } + + private func getEventOptions(_ options: EventOptions?, _ overrideOptions: EventOptions?, _ overrideUserId: String? = nil) -> EventOptions { + let eventOptions = EventOptions() + if let options = options { + eventOptions.mergeEventOptions(eventOptions: options) + } + if let overrideOptions = overrideOptions { + eventOptions.mergeEventOptions(eventOptions: overrideOptions) + } + if let overrideUserId = overrideUserId { + eventOptions.userId = overrideUserId + } + return eventOptions + } +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/.xccurrentversion b/ios/swift/v2/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/.xccurrentversion new file mode 100644 index 00000000..775cb510 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/.xccurrentversion @@ -0,0 +1,8 @@ + + + + + _XCCurrentVersionName + Shared.xcdatamodel + + diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/Shared.xcdatamodel/contents b/ios/swift/v2/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/Shared.xcdatamodel/contents new file mode 100644 index 00000000..9ed2921a --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleApp.xcdatamodeld/Shared.xcdatamodel/contents @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleAppApp.swift b/ios/swift/v2/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleAppApp.swift new file mode 100644 index 00000000..06bb9eb7 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/AmpliSwiftSampleAppApp.swift @@ -0,0 +1,116 @@ +// +// AmpliSwiftSampleAppApp.swift +// Shared +// +// Created by Qingzhuo Zhen on 11/12/21. +// + +import SwiftUI +import AmplitudeSwift + +@main +struct AmpliSwiftSampleAppApp: App { + let persistenceController = PersistenceController.shared + + var body: some Scene { + // 'Ampli.instance' is the default instance of Ampli() + // + // When you pull your tracking plan you can use the defaults and call load() without arguments + // This requires connecting your account via `ampli pull` which will set you API key in the generated Ampli SDK + // + // OR Specify a AmpliEnvironment + // ampli.load(LoadOptions(environment: AmpliEnvironment.dev)) + // + // OR Provide a specific Amplitude API key + // ampli.load(LoadOptions(client: LoadClientOptions(apiKey: "Custom api key"))) + // + // OR Use an existing Amplitude instance + // requires "import AmplitudeSwift" + // let instance = Amplitude(configuration: Configuration(apiKey: "Custom api key", instanceName: "instanceName")) + // ampli.load(LoadOptions(client: LoadClientOptions(instance: instance))) + // + // For testing you can disable ampli + // ampli.load(LoadOptions(disabled: ProcessInfo.processInfo.environment["IS_TESTING"] == "true" ? true: false)) + // + // Make as many Ampli instances as you want + // let ampli2 = Ampli() + // ampli2.load(LoadOptions(client: LoadClientOptions(apiKey: "api-key-2"))) + + let apiKey = ProcessInfo.processInfo.environment["AMPLITUDE_API_KEY"] ?? "test-api-key" + let ampli = Ampli.instance + + // Load + ampli.load(LoadOptions(client: LoadClientOptions(apiKey: apiKey))) + + ampli.client.add(plugin: LoggingPlugin()) + + // Identify + ampli.identify("ampli-swift-user", Identify(requiredNumber: 22.0, optionalArray: ["optional string"])) + + // Set group + ampli.client.setGroup(groupType: "ampli group type", groupName: "ampli swift group") + + // GroupIdentify + let groupProperties = ["requiredBoolean": true] + ampli.client.groupIdentify(groupType: "ampli group type", groupName: "ampli swift group", groupProperties: groupProperties) + + // Track events with dedicated event methods + ampli.eventNoProperties() + ampli.eventMaxIntForTest(intMax10: 20) + ampli.eventWithConstTypes() + + // Track using event instances and ampli.track(event, options, extra) + let eventWithAllProperties = EventWithAllProperties( + requiredArray: ["array element 1", "array element 2"], + requiredBoolean: true, + requiredEnum: EventWithAllProperties.RequiredEnum.enum1, + requiredInteger: 10, + requiredNumber: 2.0, + requiredString: "required string", + optionalString: nil + ) + ampli.track(eventWithAllProperties) + + ampli.eventObjectTypes( + requiredObject: ["prop1": 3, "prop2": "abc"], + requiredObjectArray: [1, true, "string", ["prop1": 23, "prop2": "xyz"]] + ) + + ampli.eventWithEnumTypes( + requiredEnum: EventWithEnumTypes.RequiredEnum.requiredEnum2 + ) + + ampli.eventWithOptionalArrayTypes( + optionalBooleanArray: [false, true] + ) + + ampli.eventWithOptionalProperties( + optionalString: "optional string" + ) + + ampli.eventWithDifferentCasingTypes( + enumWithSpace: EventWithDifferentCasingTypes.EnumWithSpace.enumWithSpace, + enumSnakeCase: EventWithDifferentCasingTypes.EnumSnakeCase.enumSnakeCase, + enumCamelCase: EventWithDifferentCasingTypes.EnumCamelCase.enumCamelCase, + enumPascalCase: EventWithDifferentCasingTypes.EnumPascalCase.enumPascalCase, + propertyWithSpace: "property with space", + propertyWithSnakeCase: "property with snake case", + propertyWithCamelCase: "property with camel case", + propertyWithPascalCase: "property with pascal case" + ) + + ampli.eventWithTemplateProperties( + requiredEventProperty: "event property", + requiredTemplateProperty: "template property", + optionalEventProperty: 1.23 + ) + + ampli.flush() + + return WindowGroup { + ContentView() + .environment(\.managedObjectContext, persistenceController.container.viewContext) + TextView() + } + } +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/Assets.xcassets/AccentColor.colorset/Contents.json b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000..eb878970 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..c136eaff --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,148 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/Assets.xcassets/Contents.json b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/ContentView.swift b/ios/swift/v2/AmpliSwiftSampleApp/Shared/ContentView.swift new file mode 100644 index 00000000..e6dd96ab --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/ContentView.swift @@ -0,0 +1,93 @@ +// +// ContentView.swift +// Shared +// +// Created by Qingzhuo Zhen on 11/12/21. +// + +import SwiftUI +import CoreData + +struct ContentView: View { + @Environment(\.managedObjectContext) private var viewContext + + @FetchRequest( + sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)], + animation: .default) + private var items: FetchedResults + private var ampli: Ampli = Ampli.instance + + + var body: some View { + NavigationView { + List { + ForEach(items) { item in + NavigationLink { + Text("Item at \(item.timestamp!, formatter: itemFormatter)") + } label: { + Text(item.timestamp!, formatter: itemFormatter) + } + } + .onDelete(perform: deleteItems) + } + .toolbar { +#if os(iOS) + ToolbarItem(placement: .navigationBarTrailing) { + EditButton() + } +#endif + ToolbarItem { + Button(action: addItem) { + Label("Add Item With Event Sent", systemImage: "plus") + } + } + } + Text("Select an item") + } + } + + private func addItem() { + ampli.eventMaxIntForTest(intMax10: 9) + withAnimation { + let newItem = Item(context: viewContext) + newItem.timestamp = Date() + + do { + try viewContext.save() + } catch { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + let nsError = error as NSError + fatalError("Unresolved error \(nsError), \(nsError.userInfo)") + } + } + } + + private func deleteItems(offsets: IndexSet) { + withAnimation { + offsets.map { items[$0] }.forEach(viewContext.delete) + + do { + try viewContext.save() + } catch { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + let nsError = error as NSError + fatalError("Unresolved error \(nsError), \(nsError.userInfo)") + } + } + } +} + +private let itemFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateStyle = .short + formatter.timeStyle = .medium + return formatter +}() + +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) + } +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/Persistence.swift b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Persistence.swift new file mode 100644 index 00000000..2c6004e2 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Persistence.swift @@ -0,0 +1,55 @@ +// +// Persistence.swift +// Shared +// +// Created by Qingzhuo Zhen on 11/12/21. +// + +import CoreData + +struct PersistenceController { + static let shared = PersistenceController() + + static var preview: PersistenceController = { + let result = PersistenceController(inMemory: true) + let viewContext = result.container.viewContext + for _ in 0..<10 { + let newItem = Item(context: viewContext) + newItem.timestamp = Date() + } + do { + try viewContext.save() + } catch { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + let nsError = error as NSError + fatalError("Unresolved error \(nsError), \(nsError.userInfo)") + } + return result + }() + + let container: NSPersistentContainer + + init(inMemory: Bool = false) { + container = NSPersistentContainer(name: "AmpliSwiftSampleApp") + if inMemory { + container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") + } + container.loadPersistentStores(completionHandler: { (storeDescription, error) in + if let error = error as NSError? { + // Replace this implementation with code to handle the error appropriately. + // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + + /* + Typical reasons for an error here include: + * The parent directory does not exist, cannot be created, or disallows writing. + * The persistent store is not accessible, due to permissions or data protection when the device is locked. + * The device is out of space. + * The store could not be migrated to the current model version. + Check the error message to determine what the actual problem was. + */ + fatalError("Unresolved error \(error), \(error.userInfo)") + } + }) + } +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/Plugins/LoggingPlugin.swift b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Plugins/LoggingPlugin.swift new file mode 100644 index 00000000..de01c4b2 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/Plugins/LoggingPlugin.swift @@ -0,0 +1,18 @@ +import Foundation +import AmplitudeSwift + +class LoggingPlugin: BeforePlugin { + let jsonEncoder: JSONEncoder + + override init() { + self.jsonEncoder = JSONEncoder() + self.jsonEncoder.outputFormatting = [.prettyPrinted] + } + + public override func execute(event: BaseEvent) -> BaseEvent? { + let jsonData = try? jsonEncoder.encode(event) + let json = jsonData != nil ? String(data: jsonData!, encoding: String.Encoding.utf8) : "" + print(String(format:"[ampli] event=\(json ?? "")")) + return event + } +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/Shared/TextView.swift b/ios/swift/v2/AmpliSwiftSampleApp/Shared/TextView.swift new file mode 100644 index 00000000..7cc3dd7b --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/Shared/TextView.swift @@ -0,0 +1,30 @@ +// +// TextView.swift +// AmpliSwiftSampleApp +// +// Created by Qingzhuo Zhen on 12/1/21. +// + +import SwiftUI + +struct TextView: View { + var body: some View { + let ampli = Ampli.instance + + ampli.eventWithArrayTypes( + requiredBooleanArray: [true], + requiredEnumArray: ["Enum1"], + requiredNumberArray: [5.0, 6.0], + requiredObjectArray: [["key1": "value1"], ["key2": "value2"]], + requiredStringArray: ["string1", "string2"] + ) + + return Text("Welcome to Ampli Swift!") + } +} + +struct TextView_Previews: PreviewProvider { + static var previews: some View { + TextView() + } +} diff --git a/ios/swift/v2/AmpliSwiftSampleApp/ampli.json b/ios/swift/v2/AmpliSwiftSampleApp/ampli.json new file mode 100644 index 00000000..48e94e08 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/ampli.json @@ -0,0 +1,14 @@ +{ + "OrgId": "132559", + "WorkspaceId": "77b37977-cb3a-42eb-bce3-09f5f7c3adb7", + "SourceId": "ff1de76c-80bb-42ea-8d39-63402f588c7f", + "Path": "./Shared/Ampli", + "Branch": "main", + "Version": "1.0.0", + "Runtime": "ios:swift-ampli-v2", + "VersionId": "a61c3908-ca4d-4c8d-8f81-54ad3ba17b9c", + "OmitApiKeys": true, + "Platform": "iOS", + "Language": "Swift", + "SDK": "Amplitude-Swift ~> 1.0" +} \ No newline at end of file diff --git a/ios/swift/v2/AmpliSwiftSampleApp/macOS/macOS.entitlements b/ios/swift/v2/AmpliSwiftSampleApp/macOS/macOS.entitlements new file mode 100644 index 00000000..f2ef3ae0 --- /dev/null +++ b/ios/swift/v2/AmpliSwiftSampleApp/macOS/macOS.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-only + + +