Browse Source

[new]引力引擎插件库

zk 1 năm trước cách đây
commit
a6737be9b4
54 tập tin đã thay đổi với 3735 bổ sung0 xóa
  1. 29 0
      .gitignore
  2. 33 0
      .metadata
  3. 3 0
      CHANGELOG.md
  4. 1 0
      LICENSE
  5. 15 0
      README.md
  6. 4 0
      analysis_options.yaml
  7. 9 0
      android/.gitignore
  8. 74 0
      android/build.gradle
  9. 3 0
      android/gradle.properties
  10. BIN
      android/gradle/wrapper/gradle-wrapper.jar
  11. 7 0
      android/gradle/wrapper/gradle-wrapper.properties
  12. 249 0
      android/gradlew
  13. 92 0
      android/gradlew.bat
  14. 1 0
      android/settings.gradle
  15. 2 0
      android/src/main/AndroidManifest.xml
  16. 23 0
      android/src/main/java/com/atmob/gravity_engine/BoxingUtil.java
  17. 364 0
      android/src/main/java/com/atmob/gravity_engine/GravityEnginePlugin.java
  18. 27 0
      android/src/main/java/com/atmob/gravity_engine/ParamsUtil.java
  19. 38 0
      ios/.gitignore
  20. 0 0
      ios/Assets/.gitkeep
  21. 14 0
      ios/Classes/GEDefine.swift
  22. 165 0
      ios/Classes/GravityEnginePlugin.swift
  23. 66 0
      ios/Classes/IDFAManager.swift
  24. BIN
      ios/GravityEngineSDK.framework/GravityEngineSDK
  25. 79 0
      ios/GravityEngineSDK.framework/Headers/GEAutoTrackProtocol.h
  26. 26 0
      ios/GravityEngineSDK.framework/Headers/GEAutoTrackPublicHeader.h
  27. 129 0
      ios/GravityEngineSDK.framework/Headers/GEConfig.h
  28. 217 0
      ios/GravityEngineSDK.framework/Headers/GEConstant.h
  29. 43 0
      ios/GravityEngineSDK.framework/Headers/GEDeviceInfo.h
  30. 16 0
      ios/GravityEngineSDK.framework/Headers/GEEditableEventModel.h
  31. 39 0
      ios/GravityEngineSDK.framework/Headers/GEEventModel.h
  32. 21 0
      ios/GravityEngineSDK.framework/Headers/GEFirstEventModel.h
  33. 23 0
      ios/GravityEngineSDK.framework/Headers/GEOverwriteEventModel.h
  34. 35 0
      ios/GravityEngineSDK.framework/Headers/GEPresetProperties.h
  35. 36 0
      ios/GravityEngineSDK.framework/Headers/GESecretKey.h
  36. 55 0
      ios/GravityEngineSDK.framework/Headers/GESecurityPolicy.h
  37. 23 0
      ios/GravityEngineSDK.framework/Headers/GEUpdateEventModel.h
  38. 688 0
      ios/GravityEngineSDK.framework/Headers/GravityEngineSDK.h
  39. 50 0
      ios/GravityEngineSDK.framework/Headers/GravitySDK.h
  40. 50 0
      ios/GravityEngineSDK.framework/Headers/UIView+GravityEngine.h
  41. BIN
      ios/GravityEngineSDK.framework/Info.plist
  42. 6 0
      ios/GravityEngineSDK.framework/Modules/module.modulemap
  43. 125 0
      ios/GravityEngineSDK.framework/PrivacyInfo.xcprivacy
  44. BIN
      ios/GravityEngineSDK.framework/_CodeSignature/CodeDirectory
  45. BIN
      ios/GravityEngineSDK.framework/_CodeSignature/CodeRequirements
  46. BIN
      ios/GravityEngineSDK.framework/_CodeSignature/CodeRequirements-1
  47. 372 0
      ios/GravityEngineSDK.framework/_CodeSignature/CodeResources
  48. BIN
      ios/GravityEngineSDK.framework/_CodeSignature/CodeSignature
  49. 14 0
      ios/Resources/PrivacyInfo.xcprivacy
  50. 39 0
      ios/gravity_engine.podspec
  51. 88 0
      lib/gravity_engine.dart
  52. 189 0
      lib/gravity_engine_method_channel.dart
  53. 81 0
      lib/gravity_engine_platform_interface.dart
  54. 72 0
      pubspec.yaml

+ 29 - 0
.gitignore

@@ -0,0 +1,29 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
+/pubspec.lock
+**/doc/api/
+.dart_tool/
+build/

+ 33 - 0
.metadata

@@ -0,0 +1,33 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+  revision: "80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819"
+  channel: "stable"
+
+project_type: plugin
+
+# Tracks metadata for the flutter migrate command
+migration:
+  platforms:
+    - platform: root
+      create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+      base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+    - platform: android
+      create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+      base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+    - platform: ios
+      create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+      base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+
+  # User provided section
+
+  # List of Local paths (relative to this file) that should be
+  # ignored by the migrate tool.
+  #
+  # Files that are not part of the templates will be ignored by default.
+  unmanaged_files:
+    - 'lib/main.dart'
+    - 'ios/Runner.xcodeproj/project.pbxproj'

+ 3 - 0
CHANGELOG.md

@@ -0,0 +1,3 @@
+## 0.0.1
+
+* TODO: Describe initial release.

+ 1 - 0
LICENSE

@@ -0,0 +1 @@
+TODO: Add your license here.

+ 15 - 0
README.md

@@ -0,0 +1,15 @@
+# gravity_engine
+
+引力引擎SDK插件
+
+## Getting Started
+
+This project is a starting point for a Flutter
+[plug-in package](https://flutter.dev/to/develop-plugins),
+a specialized package that includes platform-specific implementation code for
+Android and/or iOS.
+
+For help getting started with Flutter development, view the
+[online documentation](https://docs.flutter.dev), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
+

+ 4 - 0
analysis_options.yaml

@@ -0,0 +1,4 @@
+include: package:flutter_lints/flutter.yaml
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options

+ 9 - 0
android/.gitignore

@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.cxx

+ 74 - 0
android/build.gradle

@@ -0,0 +1,74 @@
+group = "com.atmob.gravity_engine"
+version = "1.0"
+
+buildscript {
+    repositories {
+        google()
+        mavenCentral()
+    }
+
+    dependencies {
+        classpath("com.android.tools.build:gradle:7.3.0")
+    }
+}
+
+rootProject.allprojects {
+    repositories {
+        google()
+        mavenCentral()
+        maven { url 'https://nexus.gravity-engine.com/repository/maven-releases/' }
+        maven { url 'https://nexus.gravity-engine.com/repository/maven-snapshots/' }
+    }
+}
+
+// 加载 local.properties 文件
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+    localPropertiesFile.withInputStream { stream ->
+        localProperties.load(stream)
+    }
+}
+
+// 读取变量
+def flutterSdk = localProperties.getProperty('flutter.sdk')
+
+apply plugin: "com.android.library"
+
+android {
+    if (project.android.hasProperty("namespace")) {
+        namespace = "com.atmob.gravity_engine"
+    }
+
+    compileSdk = 34
+
+    compileOptions {
+        sourceCompatibility = JavaVersion.VERSION_1_8
+        targetCompatibility = JavaVersion.VERSION_1_8
+    }
+
+    defaultConfig {
+        minSdk = 21
+    }
+
+    dependencies {
+        //flutter
+        compileOnly files("$flutterSdk/bin/cache/artifacts/engine/android-arm/flutter.jar")
+
+        //AndroidX
+        compileOnly "androidx.annotation:annotation:1.1.0"
+
+        //引力引擎
+        implementation "cn.gravity.android:GravityEngineSDK:4.8.6"
+    }
+
+    testOptions {
+        unitTests.all {
+            testLogging {
+                events "passed", "skipped", "failed", "standardOut", "standardError"
+                outputs.upToDateWhen { false }
+                showStandardStreams = true
+            }
+        }
+    }
+}

+ 3 - 0
android/gradle.properties

@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
+android.useAndroidX=true
+android.enableJetifier=true

BIN
android/gradle/wrapper/gradle-wrapper.jar


+ 7 - 0
android/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists

+ 249 - 0
android/gradlew

@@ -0,0 +1,249 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"

+ 92 - 0
android/gradlew.bat

@@ -0,0 +1,92 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 1 - 0
android/settings.gradle

@@ -0,0 +1 @@
+rootProject.name = 'gravity_engine'

+ 2 - 0
android/src/main/AndroidManifest.xml

@@ -0,0 +1,2 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.atmob.gravity_engine"></manifest>

+ 23 - 0
android/src/main/java/com/atmob/gravity_engine/BoxingUtil.java

@@ -0,0 +1,23 @@
+package com.atmob.gravity_engine;
+
+public class BoxingUtil {
+    private BoxingUtil() {
+
+    }
+
+    public static boolean boxing(Boolean b) {
+        return b != null && b;
+    }
+
+    public static int boxing(Integer integer) {
+        return integer == null ? 0 : integer;
+    }
+
+    public static long boxing(Long l) {
+        return l == null ? 0 : l;
+    }
+
+    public static float boxing(Float f) {
+        return f == null ? 0f : f;
+    }
+}

+ 364 - 0
android/src/main/java/com/atmob/gravity_engine/GravityEnginePlugin.java

@@ -0,0 +1,364 @@
+package com.atmob.gravity_engine;
+
+import android.content.Context;
+import android.text.TextUtils;
+import androidx.annotation.NonNull;
+import org.json.JSONObject;
+import android.util.Log;
+import java.util.Map;
+import java.util.Objects;
+import cn.gravity.android.GEConfig;
+import cn.gravity.android.GravityEngineSDK;
+import cn.gravity.android.InitializeCallback;
+import io.flutter.embedding.engine.plugins.FlutterPlugin;
+import io.flutter.plugin.common.MethodCall;
+import io.flutter.plugin.common.MethodChannel;
+import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
+import io.flutter.plugin.common.MethodChannel.Result;
+
+/**
+ * GravityEnginePlugin
+ */
+public class GravityEnginePlugin implements FlutterPlugin, MethodCallHandler {
+
+    /* Method names */
+    private static final String METHOD_INITIALIZE = "initialize";
+    private static final String METHOD_TRACK = "track";
+    private static final String METHOD_TRACK_PAY = "trackPay";
+    private static final String METHOD_LOGIN = "login";
+    private static final String METHOD_LOGOUT = "logout";
+    private static final String METHOD_TRACK_AD_LOAD_EVENT = "trackAdLoadEvent";
+    private static final String METHOD_TRACK_AD_SHOW_EVENT = "trackAdShowEvent";
+    private static final String METHOD_TRACK_AD_CLICK_EVENT = "trackAdClickEvent";
+    private static final String METHOD_TRACK_AD_PLAY_START_EVENT = "trackAdPlayStartEvent";
+    private static final String METHOD_TRACK_AD_PLAY_END_EVENT = "trackAdPlayEndEvent";
+
+    /* Arguments */
+    // Initialize
+    private static final String ARG_ACCESS_TOKEN = "accessToken";
+    private static final String ARG_DEBUG = "debug";
+    private static final String ARG_CLIENT_ID = "clientId";
+    private static final String ARG_CHANNEL = "channel";
+
+    // Track event
+    private static final String ARG_EVENT_ID = "eventId";
+    private static final String ARG_EVENT_PRAMS = "eventParams";
+
+    // Track pay
+    private static final String ARG_ORDER_NO = "orderNo";
+    private static final String ARG_AMOUNT = "amount";
+    private static final String ARG_CURRENCY = "currency";
+    private static final String ARG_PAY_TYPE = "payType";
+    private static final String ARG_ITEM_NAME = "itemName";
+
+    //Track ad
+    private static final String AD_UNION_TYPE = "adUnionType";
+    private static final String AD_PLACEMENT_ID = "adPlacementId";
+    private static final String AD_SOURCE_ID = "adSourceId";
+    private static final String AD_TYPE = "adType";
+    private static final String AD_N_TYPE = "adnType";
+    private static final String AD_ECPM = "ecpm";
+    private static final String AD_DURATION = "duration";
+    private static final String AD_IS_PLAY_OVER = "isPlayOver";
+
+    private MethodChannel methodChannel;
+    private Context applicationContext;
+
+    private volatile GravityEngineSDK gravityEngineSDK;
+    private volatile boolean isInitialized = false;
+
+    @Override
+    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
+        applicationContext = flutterPluginBinding.getApplicationContext();
+        methodChannel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "gravity_engine");
+        methodChannel.setMethodCallHandler(this);
+    }
+
+    @Override
+    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
+        switch (call.method) {
+            case METHOD_INITIALIZE:
+                initialize(call, result);
+                break;
+            case METHOD_TRACK:
+                track(call, result);
+                break;
+            case METHOD_TRACK_PAY:
+                trackPay(call, result);
+                break;
+            case METHOD_LOGIN:
+                login(call, result);
+                break;
+            case METHOD_LOGOUT:
+                logout(call, result);
+                break;
+            case METHOD_TRACK_AD_LOAD_EVENT:
+                trackAdLoadEvent(call, result);
+                break;
+            case METHOD_TRACK_AD_SHOW_EVENT:
+                trackAdShowEvent(call, result);
+                break;
+            case METHOD_TRACK_AD_CLICK_EVENT:
+                trackAdClickEvent(call, result);
+                break;
+            case METHOD_TRACK_AD_PLAY_START_EVENT:
+                trackAdPlayStartEvent(call, result);
+                break;
+            case METHOD_TRACK_AD_PLAY_END_EVENT:
+                trackAdPlayEndEvent(call, result);
+                break;
+            default:
+                result.notImplemented();
+        }
+    }
+
+
+    private void initialize(MethodCall call, Result result) {
+        try {
+            String accessToken = call.argument(ARG_ACCESS_TOKEN);
+            boolean debug = Boolean.TRUE.equals(call.argument(ARG_DEBUG));
+            String clientId = call.argument(ARG_CLIENT_ID);
+            String channel = call.argument(ARG_CHANNEL);
+
+            if (accessToken == null || clientId == null || channel == null) {
+                result.error("-1", "GravityEngine init failed, msg: missing required arguments", null);
+                return;
+            }
+            GravityEngineSDK gravityEngineSdk = getGravityEngineSdk(accessToken, debug);
+            if (gravityEngineSdk == null) {
+                result.error("-1", "GravityEngine init failed, msg: getGravityEngineSdk failed", null);
+            } else {
+                gravityEngineSdk.initialize(accessToken, clientId, clientId, channel, new InitializeCallback() {
+
+                    boolean isCallback = false;
+
+                    @Override
+                    public void onFailed(String s, JSONObject jsonObject) {
+                        Log.e("GravityEngineSDK", "onFailed: " + s);
+                        if (isCallback) {
+                            return;
+                        }
+                        isCallback = true;
+                        result.error(s, "GravityEngine init failed, msg: " + jsonObject, null);
+                    }
+
+                    @Override
+                    public void onSuccess(JSONObject responseJson, JSONObject registerBody) {
+                        Log.e("GravityEngineSDK", "onSuccess: ");
+                        isInitialized = true;
+                        if (isCallback) {
+                            return;
+                        }
+                        isCallback = true;
+                        result.success(isFromPromote(responseJson));
+                    }
+
+                    private Boolean isFromPromote(JSONObject responseJson) {
+                        if (responseJson == null) {
+                            return false;
+                        }
+                        String clickCompany = responseJson.optString("clickCompany");
+                        return !TextUtils.isEmpty(clickCompany) && !Objects.equals("natural", clickCompany);
+                    }
+                }, true);
+            }
+        } catch (Exception e) {
+            result.error("-1", "GravityEngine init failed, msg: " + e.getMessage(), null);
+        }
+    }
+
+    private GravityEngineSDK getGravityEngineSdk(String accessToken, boolean debug) {
+        if (gravityEngineSDK == null) {
+            synchronized (this) {
+                if (gravityEngineSDK == null) {
+                    GEConfig config = GEConfig.getInstance(applicationContext, accessToken);
+                    config.setMode(debug ? GEConfig.ModeEnum.DEBUG : GEConfig.ModeEnum.NORMAL);
+                    try {
+                        gravityEngineSDK = GravityEngineSDK.setupAndStart(config);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+        return gravityEngineSDK;
+    }
+
+    private void track(MethodCall call, Result result) {
+        String eventId = call.argument(ARG_EVENT_ID);
+        Map<String, Object> eventParams = call.argument(ARG_EVENT_PRAMS);
+        if (eventId == null) {
+            result.error("-1", "GravityEngine track failed, msg: missing required arguments", null);
+            return;
+        }
+        if (!isInitialized || gravityEngineSDK == null) {
+            result.error("-1", "GravityEngine track failed, msg: GravityEngineSDK is not initialized", null);
+            return;
+        }
+        JSONObject params = null;
+        if (eventParams != null) {
+            try {
+                params = new JSONObject(eventParams);
+            } catch (Exception e) {
+                result.error("-1", "GravityEngine track failed, msg: parse eventParams failed", null);
+                return;
+            }
+        }
+        gravityEngineSDK.track(eventId, params);
+        result.success(null);
+    }
+
+    private void trackPay(MethodCall call, Result result) {
+        Integer amount = call.argument(ARG_AMOUNT);
+        String currency = call.argument(ARG_CURRENCY);
+        String orderNo = call.argument(ARG_ORDER_NO);
+        String itemName = call.argument(ARG_ITEM_NAME);
+        String payType = call.argument(ARG_PAY_TYPE);
+        if (amount == null || currency == null || orderNo == null || itemName == null || payType == null) {
+            result.error("-1", "GravityEngine trackPay failed, msg: missing required arguments", null);
+            return;
+        }
+        if (!isInitialized || gravityEngineSDK == null) {
+            result.error("-1", "GravityEngine trackPay failed, msg: GravityEngineSDK is not initialized", null);
+            return;
+        }
+        try {
+            gravityEngineSDK.trackPayEvent(amount, currency, orderNo, itemName, payType);
+            result.success(null);
+        } catch (Exception e) {
+            result.error("-1", "GravityEngine trackPay failed, msg: " + e.getMessage(), null);
+        }
+    }
+
+    private void login(MethodCall call, Result result) {
+        if (!isInitialized || gravityEngineSDK == null) {
+            result.error("-1", "GravityEngine login failed, msg: GravityEngineSDK is not initialized", null);
+            return;
+        }
+        String clientId = call.argument(ARG_CLIENT_ID);
+        if (clientId == null) {
+            result.error("-1", "GravityEngine login failed, msg: missing required arguments", null);
+            return;
+        }
+        try {
+            gravityEngineSDK.login(clientId);
+            result.success(null);
+        } catch (Exception e) {
+            result.error("-1", "GravityEngine login failed, msg: " + e.getMessage(), null);
+        }
+    }
+
+
+    private void trackAdLoadEvent(MethodCall call, Result result) {
+        try {
+            if (!isInitialized || gravityEngineSDK == null) {
+                result.error("-1", "GravityEngine track failed, msg: GravityEngineSDK is not initialized", null);
+                return;
+            }
+            String adUnionType = call.argument(AD_UNION_TYPE);
+            String adPlacementId = call.argument(AD_PLACEMENT_ID);
+            String adSourceId = call.argument(AD_SOURCE_ID);
+            String adType = call.argument(AD_TYPE);
+            String adnType = call.argument(AD_N_TYPE);
+            gravityEngineSDK.trackAdLoadEvent(adUnionType, adPlacementId, adSourceId, adType, adnType);
+            result.success(null);
+        } catch (Exception e) {
+            result.error("-1", "GravityEngine trackAdLoadEvent failed, msg: " + e.getMessage(), null);
+        }
+    }
+
+    private void trackAdShowEvent(MethodCall call, Result result) {
+        try {
+            if (!isInitialized || gravityEngineSDK == null) {
+                result.error("-1", "GravityEngine track failed, msg: GravityEngineSDK is not initialized", null);
+                return;
+            }
+            String adUnionType = call.argument(AD_UNION_TYPE);
+            String adPlacementId = call.argument(AD_PLACEMENT_ID);
+            String adSourceId = call.argument(AD_SOURCE_ID);
+            String adType = call.argument(AD_TYPE);
+            String adnType = call.argument(AD_N_TYPE);
+            float ecpm = ParamsUtil.getFloat(call.arguments(), AD_ECPM, 0f);
+            gravityEngineSDK.trackAdShowEvent(adUnionType, adPlacementId, adSourceId, adType, adnType, ecpm);
+            result.success(null);
+        } catch (Exception e) {
+            result.error("-1", "GravityEngine trackAdShowEvent failed, msg: " + e.getMessage(), null);
+        }
+    }
+
+    private void trackAdClickEvent(MethodCall call, Result result) {
+        try {
+            if (!isInitialized || gravityEngineSDK == null) {
+                result.error("-1", "GravityEngine track failed, msg: GravityEngineSDK is not initialized", null);
+                return;
+            }
+            String adUnionType = call.argument(AD_UNION_TYPE);
+            String adPlacementId = call.argument(AD_PLACEMENT_ID);
+            String adSourceId = call.argument(AD_SOURCE_ID);
+            String adType = call.argument(AD_TYPE);
+            String adnType = call.argument(AD_N_TYPE);
+            float ecpm = ParamsUtil.getFloat(call.arguments(), AD_ECPM, 0f);
+            gravityEngineSDK.trackAdClickEvent(adUnionType, adPlacementId, adSourceId, adType, adnType, ecpm);
+            result.success(null);
+        } catch (Exception e) {
+            result.error("-1", "GravityEngine trackAdClickEvent failed, msg: " + e.getMessage(), null);
+        }
+    }
+
+    private void trackAdPlayStartEvent(MethodCall call, Result result) {
+        try {
+            if (!isInitialized || gravityEngineSDK == null) {
+                result.error("-1", "GravityEngine track failed, msg: GravityEngineSDK is not initialized", null);
+                return;
+            }
+            String adUnionType = call.argument(AD_UNION_TYPE);
+            String adPlacementId = call.argument(AD_PLACEMENT_ID);
+            String adSourceId = call.argument(AD_SOURCE_ID);
+            String adType = call.argument(AD_TYPE);
+            String adnType = call.argument(AD_N_TYPE);
+            float ecpm = ParamsUtil.getFloat(call.arguments(), AD_ECPM, 0f);
+            gravityEngineSDK.trackAdPlayStartEvent(adUnionType, adPlacementId, adSourceId, adType, adnType, ecpm);
+            result.success(null);
+        } catch (Exception e) {
+            result.error("-1", "GravityEngine trackAdPlayStartEvent failed, msg: " + e.getMessage(), null);
+        }
+    }
+
+    private void trackAdPlayEndEvent(MethodCall call, Result result) {
+        try {
+            if (!isInitialized || gravityEngineSDK == null) {
+                result.error("-1", "GravityEngine track failed, msg: GravityEngineSDK is not initialized", null);
+                return;
+            }
+            String adUnionType = call.argument(AD_UNION_TYPE);
+            String adPlacementId = call.argument(AD_PLACEMENT_ID);
+            String adSourceId = call.argument(AD_SOURCE_ID);
+            String adType = call.argument(AD_TYPE);
+            String adnType = call.argument(AD_N_TYPE);
+            float ecpm = ParamsUtil.getFloat(call.arguments(), AD_ECPM, 0f);
+            Integer duration = call.argument(AD_DURATION);
+            Boolean isPlayOver = call.argument(AD_IS_PLAY_OVER);
+            gravityEngineSDK.trackAdPlayEndEvent(adUnionType, adPlacementId, adSourceId, adType, adnType, ecpm, BoxingUtil.boxing(duration), BoxingUtil.boxing(isPlayOver));
+            result.success(null);
+        } catch (Exception e) {
+            result.error("-1", "GravityEngine trackAdPlayEndEvent failed, msg: " + e.getMessage(), null);
+        }
+    }
+
+    private void logout(MethodCall call, Result result) {
+        if (!isInitialized || gravityEngineSDK == null) {
+            result.error("-1", "GravityEngine logout failed, msg: GravityEngineSDK is not initialized", null);
+            return;
+        }
+        try {
+            gravityEngineSDK.logout(() -> result.success(null));
+        } catch (Exception e) {
+            result.error("-1", "GravityEngine logout failed, msg: " + e.getMessage(), null);
+        }
+    }
+
+    @Override
+    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
+        methodChannel.setMethodCallHandler(null);
+    }
+}

+ 27 - 0
android/src/main/java/com/atmob/gravity_engine/ParamsUtil.java

@@ -0,0 +1,27 @@
+package com.atmob.gravity_engine;
+
+import java.util.Map;
+
+public class ParamsUtil {
+
+
+    public static float getFloat(Map<String, Object> params, String param, float defaultValue) {
+        if (params == null) {
+            return defaultValue;
+        }
+        if (!params.containsKey(param)) {
+            return defaultValue;
+        }
+        Object target = params.get(param);
+        if (target == null) {
+            return defaultValue;
+        }
+        if (target instanceof Float) {
+            return (Float) target;
+        }
+        if (target instanceof Double) {
+            return ((Double) target).floatValue();
+        }
+        return defaultValue;
+    }
+}

+ 38 - 0
ios/.gitignore

@@ -0,0 +1,38 @@
+.idea/
+.vagrant/
+.sconsign.dblite
+.svn/
+
+.DS_Store
+*.swp
+profile
+
+DerivedData/
+build/
+GeneratedPluginRegistrant.h
+GeneratedPluginRegistrant.m
+
+.generated/
+
+*.pbxuser
+*.mode1v3
+*.mode2v3
+*.perspectivev3
+
+!default.pbxuser
+!default.mode1v3
+!default.mode2v3
+!default.perspectivev3
+
+xcuserdata
+
+*.moved-aside
+
+*.pyc
+*sync/
+Icon?
+.tags*
+
+/Flutter/Generated.xcconfig
+/Flutter/ephemeral/
+/Flutter/flutter_export_environment.sh

+ 0 - 0
ios/Assets/.gitkeep


+ 14 - 0
ios/Classes/GEDefine.swift

@@ -0,0 +1,14 @@
+//
+//  GEDefine.swift
+//  gravity_engine
+//
+//  Created by leon on 2024/9/26.
+//
+
+import Foundation
+
+func DebugPrint(_ items: Any..., separator: String = " ", terminator: String = "\n") {
+    #if DEBUG
+    Swift.print(items.map { "\($0)" }.joined(separator: separator), terminator: terminator)
+    #endif
+}

+ 165 - 0
ios/Classes/GravityEnginePlugin.swift

@@ -0,0 +1,165 @@
+
+import Flutter
+import UIKit
+import GravityEngineSDK
+
+public class GravityEnginePlugin: NSObject, FlutterPlugin {
+
+    // Method names
+    private static let METHOD_INITIALIZE = "initialize"
+    private static let METHOD_TRACK = "track"
+    private static let METHOD_TRACK_PAY = "trackPay"
+
+    // Arguments
+    private static let ARG_ACCESS_TOKEN = "accessToken"
+    private static let ARG_DEBUG = "debug"
+    private static let ARG_CLIENT_ID = "clientId"
+    private static let ARG_CHANNEL = "channel"
+
+    //ios>>>
+    private static let ARG_APPID = "appId"
+    //<<<ios
+
+    private static let ARG_EVENT_ID = "eventId"
+    private static let ARG_EVENT_PARAMS = "eventParams"
+
+    private static let ARG_ORDER_NO = "orderNo"
+    private static let ARG_AMOUNT = "amount"
+    private static let ARG_CURRENCY = "currency"
+    private static let ARG_PAY_TYPE = "payType"
+    private static let ARG_ITEM_NAME = "itemName"
+
+    public static var gravityEngineSDK: GravityEngineSDK?
+    private static var isInitialized = false
+
+    public static func register(with registrar: FlutterPluginRegistrar) {
+        let channel = FlutterMethodChannel(name: "gravity_engine", binaryMessenger: registrar.messenger())
+        let instance = GravityEnginePlugin()
+        registrar.addMethodCallDelegate(instance, channel: channel)
+    }
+
+    public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
+        switch call.method {
+        case GravityEnginePlugin.METHOD_INITIALIZE:
+            DebugPrint("GravityEnginePlugin.METHOD_INITIALIZE = \(call.method)");
+            IDFAManager.getIDFA(call: call, result: result)
+        case GravityEnginePlugin.METHOD_TRACK:
+            DebugPrint("GravityEnginePlugin.METHOD_TRACK = \(call.method)");
+            GravityEnginePlugin.track(call: call, result: result)
+        case GravityEnginePlugin.METHOD_TRACK_PAY:
+            DebugPrint("GravityEnginePlugin.METHOD_TRACK_PAY = \(call.method)");
+            GravityEnginePlugin.trackPay(call: call, result: result)
+        default:
+            result(FlutterMethodNotImplemented)
+        }
+    }
+
+    //init
+    public static func initialize(call: FlutterMethodCall, result: @escaping FlutterResult, idfa: String) {
+        guard let args = call.arguments as? [String: Any],
+              let accessToken = args[GravityEnginePlugin.ARG_ACCESS_TOKEN] as? String,
+              let appid = args[GravityEnginePlugin.ARG_APPID] as? String,
+              let debug = args[GravityEnginePlugin.ARG_DEBUG] as? Bool,
+              let channel = args[GravityEnginePlugin.ARG_CHANNEL] as? String else {
+            result(FlutterError(code: "-1", message: "Missing required arguments", details: nil))
+            return
+        }
+
+        //配置引力引擎
+        let config = GEConfig();
+        config.appid = appid;
+        config.accessToken = accessToken;
+        if debug{
+            config.debugMode = GravityEngineDebugMode.on;
+        }else{
+            config.debugMode = [];
+        }
+        GravityEngineSDK.start(with: config);
+        let instance = GravityEngineSDK.sharedInstance(withAppid: config.appid);
+
+        //全局引力引擎实例
+        gravityEngineSDK = instance
+
+        // 开启自动采集
+        gravityEngineSDK?.enableAutoTrack(GravityEngineAutoTrackEventType.eventTypeAll);
+
+        //获取idfv
+        var idfv = ""
+        if let idfVendor = UIDevice.current.identifierForVendor {
+            idfv = idfVendor.uuidString
+            DebugPrint("引力引擎 IDFV == \(idfv)")
+        } else {
+            DebugPrint("引力引擎 无法获取 IDFV")
+        }
+        
+        //获取当前版本号
+        var appVersionName = 1
+        if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
+            appVersionName = Int(appVersion) ?? 1
+        }
+        //自动归因
+        let enableAsa = true
+        //其他参数
+        let userCaid1MD5 = ""
+        let userCaid2MD5 = ""
+        let enableSyncAttribution = true
+
+        //初始化sdk
+        gravityEngineSDK?.initializeGravityEngine(withClientId: idfv, withUserName: idfv, withVersion: Int32(appVersionName), withAsaEnable:enableAsa, withIdfa:idfa, withIdfv:idfv, withCaid1:userCaid1MD5, withCaid2:userCaid2MD5, withSyncAttribution:enableSyncAttribution, withSuccessCallback: { response in
+//            DebugPrint("gravity engine initialize success, response is ", response);
+            self.isInitialized = true
+            result(response)
+        }, withErrorCallback: { error in
+//            DebugPrint("gravity engine initialize failed, and error is", error);
+            result(FlutterError(code: "-1", message: "Initialization failed", details: error.localizedDescription))
+        });
+
+        // 获取用户信息
+        //        instance?.queryUserInfo(successCallback: { response in
+        ////            print("user info \(response)")
+        //        }, withErrorCallback: { error in
+        ////            print("get user info error \(error)")
+        //        })
+
+        //设置公共属性
+        var superProperties: [String : Any] = ["channel":channel]
+        gravityEngineSDK?.setSuperProperties(superProperties)
+
+    }
+
+    //event
+    private static func track(call: FlutterMethodCall, result: @escaping FlutterResult) {
+        guard let args = call.arguments as? [String: Any],
+              let eventId = args[GravityEnginePlugin.ARG_EVENT_ID] as? String else {
+            result(FlutterError(code: "-1", message: "Missing eventId", details: nil))
+            return
+        }
+        guard isInitialized, let sdk = gravityEngineSDK else {
+            result(FlutterError(code: "-1", message: "SDK not initialized", details: nil))
+            return
+        }
+        let eventParams = args[GravityEnginePlugin.ARG_EVENT_PARAMS] as? [String: Any]
+        sdk.track(eventId, properties: eventParams)
+        result(nil)
+    }
+
+    //pay
+    private static func trackPay(call: FlutterMethodCall, result: @escaping FlutterResult) {
+        guard let args = call.arguments as? [String: Any],
+              let orderNo = args[GravityEnginePlugin.ARG_ORDER_NO] as? String,
+              let amount = args[GravityEnginePlugin.ARG_AMOUNT] as? Int,
+              let currency = args[GravityEnginePlugin.ARG_CURRENCY] as? String,
+              let itemName = args[GravityEnginePlugin.ARG_ITEM_NAME] as? String,
+              let payType = args[GravityEnginePlugin.ARG_PAY_TYPE] as? String else {
+            result(FlutterError(code: "-1", message: "Missing required arguments", details: nil))
+            return
+        }
+        guard isInitialized, let sdk = gravityEngineSDK else {
+            result(FlutterError(code: "-1", message: "SDK not initialized", details: nil))
+            return
+        }
+        sdk.trackPayEvent(withAmount: Int32(amount), withPayType: payType, withOrderId: orderNo, withPayReason: itemName, withPayMethod: currency)
+        result(nil)
+    }
+
+}

+ 66 - 0
ios/Classes/IDFAManager.swift

@@ -0,0 +1,66 @@
+//
+//  IDFAManager.swift
+//  sunoAi
+//
+//  Created by leon on 2024/4/9.
+//
+
+import Foundation
+import AppTrackingTransparency
+import AdSupport
+import Flutter
+
+class IDFAManager{
+    
+    static func getIDFA(call: FlutterMethodCall, result: @escaping FlutterResult) {
+        
+        if #available(iOS 14.0, *){//ios14以上系统 请求用户授权
+            
+            ATTrackingManager.requestTrackingAuthorization { status in
+                switch status {
+                case .authorized:
+                    let idfa = ASIdentifierManager.shared().advertisingIdentifier
+                    DebugPrint("IDFA 用户同意了授权: \(idfa.uuidString)")
+                    initGravityEngineSDK(call: call, result: result, idfa: idfa.uuidString)
+                case .denied:
+                    DebugPrint("IDFA 用户拒绝了授权")
+                    initGravityEngineSDK(call: call, result: result, idfa: "")
+                case .restricted:
+                    DebugPrint("IDFA 应用无法请求授权,可能由于限制")
+                    initGravityEngineSDK(call: call, result: result, idfa: "")
+                case .notDetermined:
+                    DebugPrint("IDFA 用户尚未做出选择")
+                    initGravityEngineSDK(call: call, result: result, idfa: "")
+                @unknown default:
+                    break
+                }
+            }
+            
+        }else{//ios14以下系统 请求用户授权
+            if ASIdentifierManager.shared().isAdvertisingTrackingEnabled {
+                let idfa = ASIdentifierManager.shared().advertisingIdentifier
+                DebugPrint("ios14以下系统 IDFA 用户同意了授权: \(idfa)")
+                initGravityEngineSDK(call: call, result: result, idfa: idfa.uuidString)
+            } else {
+                DebugPrint("ios14以下系统 IDFA 用户拒绝了授权")
+                initGravityEngineSDK(call: call, result: result, idfa: "")
+            }
+            
+        }
+        
+    }
+    
+    //四种情况下都在这里初始化引力引擎sdk
+    static func initGravityEngineSDK(call: FlutterMethodCall, result: @escaping FlutterResult, idfa:String){
+        
+        //引力引擎调用的时候需返回主线程加载 否则程序会崩溃
+        DispatchQueue.main.async {
+            if (GravityEnginePlugin.gravityEngineSDK == nil){
+                GravityEnginePlugin.initialize(call: call, result: result, idfa: idfa)
+            }
+        }
+        
+    }
+    
+}
+

BIN
ios/GravityEngineSDK.framework/GravityEngineSDK


+ 79 - 0
ios/GravityEngineSDK.framework/Headers/GEAutoTrackProtocol.h

@@ -0,0 +1,79 @@
+//
+//  GEAutoTrackProtocol.h
+//  GravityEngineSDK
+//
+//
+
+#ifndef GEAutoTrackProtocol_h
+#define GEAutoTrackProtocol_h
+
+#import <UIKit/UIKit.h>
+
+@protocol TDUIViewAutoTrackDelegate
+
+@optional
+
+/**
+ UITableView event properties
+
+ @return event properties
+ */
+- (NSDictionary *)gravityEngine_tableView:(UITableView *)tableView autoTrackPropertiesAtIndexPath:(NSIndexPath *)indexPath;
+
+/**
+ APPID UITableView event properties
+ 
+ @return event properties
+ */
+- (NSDictionary *)gravityEngineWithAppid_tableView:(UITableView *)tableView autoTrackPropertiesAtIndexPath:(NSIndexPath *)indexPath;
+
+@optional
+
+/**
+ UICollectionView event properties
+
+ @return event properties
+ */
+- (NSDictionary *)gravityEngine_collectionView:(UICollectionView *)collectionView autoTrackPropertiesAtIndexPath:(NSIndexPath *)indexPath;
+
+/**
+ APPID UICollectionView event properties
+
+ @return event properties
+ */
+- (NSDictionary *)gravityEngineWithAppid_collectionView:(UICollectionView *)collectionView autoTrackPropertiesAtIndexPath:(NSIndexPath *)indexPath;
+
+@end
+
+
+@protocol GEAutoTracker
+
+@optional
+
+- (NSDictionary *)getTrackProperties;
+
+
+- (NSDictionary *)getTrackPropertiesWithAppid;
+
+@end
+
+/**
+ Automatically track the page
+ */
+@protocol GEScreenAutoTracker <GEAutoTracker>
+
+@optional
+
+/**
+ Attributes for custom page view events
+ */
+- (NSString *)getScreenUrl;
+
+/**
+ Configure the properties of the APPID custom page view event
+ */
+- (NSDictionary *)getScreenUrlWithAppid;
+
+@end
+
+#endif /* GEAutoTrackProtocol_h */

+ 26 - 0
ios/GravityEngineSDK.framework/Headers/GEAutoTrackPublicHeader.h

@@ -0,0 +1,26 @@
+//
+//  GEAutoTrackPublicHeader.h
+//  GravityEngineSDK
+//
+//
+
+#ifndef GEAutoTrackPublicHeader_h
+#define GEAutoTrackPublicHeader_h
+
+#if __has_include(<GravityEngineSDK/GEAutoTrackProtocol.h>)
+
+#import <GravityEngineSDK/GEAutoTrackProtocol.h>
+
+#else
+#import "GEAutoTrackProtocol.h"
+#endif
+
+#if __has_include(<GravityEngineSDK/UIView+GravityEngine.h>)
+
+#import <GravityEngineSDK/UIView+GravityEngine.h>
+
+#else
+#import "UIView+GravityEngine.h"
+#endif
+
+#endif /* GEAutoTrackPublicHeader_h */

+ 129 - 0
ios/GravityEngineSDK.framework/Headers/GEConfig.h

@@ -0,0 +1,129 @@
+#import <Foundation/Foundation.h>
+
+#if __has_include(<GravityEngineSDK/GEConstant.h>)
+
+#import <GravityEngineSDK/GEConstant.h>
+
+#else
+#import "GEConstant.h"
+#endif
+
+#if __has_include(<GravityEngineSDK/GESecurityPolicy.h>)
+
+#import <GravityEngineSDK/GESecurityPolicy.h>
+
+#else
+#import "GESecurityPolicy.h"
+#endif
+
+#if TARGET_OS_IOS
+#if __has_include(<GravityEngineSDK/GESecretKey.h>)
+#import <GravityEngineSDK/GESecretKey.h>
+#else
+#import "GESecretKey.h"
+#endif
+#endif
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+@interface GEConfig : NSObject <NSCopying>
+/**
+ Set automatic burying type
+ */
+@property(assign, nonatomic) GravityEngineAutoTrackEventType autoTrackEventType;
+/**
+ Network environment for data transmission
+ */
+@property(assign, nonatomic) GravityNetworkType networkTypePolicy;
+/**
+ Data upload interval
+ */
+@property(nonatomic, strong) NSNumber *uploadInterval;
+/**
+ When there is data to upload, when the number of data cache reaches the uploadsize, upload the data immediately
+ */
+@property(nonatomic, strong) NSNumber *uploadSize;
+/**
+ Event blacklist, event names that are not counted are added here
+ */
+@property(strong, nonatomic) NSArray *disableEvents;
+/**
+ The maximum number of cached events, the default is 10000, the minimum is 5000
+ */
+@property(class, nonatomic) NSInteger maxNumEvents
+DEPRECATED_MSG_ATTRIBUTE("Please config TAConfigInfo in main info.plist");
+/**
+ Data cache expiration time, the default is 10 days, the longest is 10 days
+ */
+@property(class, nonatomic) NSInteger expirationDays
+DEPRECATED_MSG_ATTRIBUTE("Please config TAConfigInfo in main info.plist");
+/**
+ appid
+ */
+@property(atomic, copy) NSString *appid;
+/**
+ instance Token
+ */
+@property(atomic, copy) NSString *(^getInstanceName)(void);
+/**
+ Server URL
+ */
+@property(atomic, copy) NSString *configureURL;
+/**
+ Gravity AccessToken
+ */
+@property(nonatomic, copy) NSString *accessToken;
+
+/**
+ Initialize and configure background self-starting events
+ YES: Collect background self-starting events
+ NO: Do not collect background self-starting events
+ */
+@property(nonatomic, assign) BOOL trackRelaunchedInBackgroundEvents;
+/**
+ Debug Mode
+*/
+@property(nonatomic, assign) GravityEngineDebugMode debugMode;
+
+/**
+app launchOptions
+*/
+@property(nonatomic, copy) NSDictionary *launchOptions;
+
+/**
+ Initialize and configure the certificate verification policy
+*/
+@property(nonatomic, strong) GESecurityPolicy *securityPolicy;
+
+/**
+ Set default time zone
+  You can use this time zone to compare the offset of the current time zone and the default time zone
+*/
+@property(nonatomic, strong) NSTimeZone *defaultTimeZone;
+
+/**
+ instance name
+*/
+@property(nonatomic, copy) NSString *name;
+
++ (GEConfig *)defaultGEConfig;
+
+- (void)setNetworkType:(GravityEngineNetworkType)type;
+
+
+/// enable encryption
+@property(nonatomic, assign) BOOL enableEncrypt;
+
+#if TARGET_OS_IOS
+/// Get local key configuration
+@property (nonatomic, strong) GESecretKey *secretKey;
+#endif
+
+/// instance token
+- (NSString *)getMapInstanceToken;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 217 - 0
ios/GravityEngineSDK.framework/Headers/GEConstant.h

@@ -0,0 +1,217 @@
+//
+//  GEConstant.h
+//  GravityEngineSDK
+//
+//  Copyright © 2020 gravityengine. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+/**
+Debug Mode
+
+- GravityEngineDebugOff : Not enabled by default
+*/
+typedef NS_OPTIONS(NSInteger, GravityEngineDebugMode
+) {
+/**
+ Not enabled by default
+ */
+GravityEngineDebugOff = 0,
+
+
+/**
+ Enable Debug Mode,Data will persist
+ */
+GravityEngineDebugOn = 1 << 1,
+
+};
+
+
+/**
+ Log Level
+
+ - GELoggingLevelNone : Not enabled by default
+ */
+typedef NS_OPTIONS(NSInteger, GELoggingLevel
+) {
+/**
+ Not enabled by default
+ */
+GELoggingLevelNone = 0,
+
+/**
+ Error Log
+ */
+GELoggingLevelError = 1 << 0,
+
+/**
+ Info  Log
+ */
+GELoggingLevelInfo = 1 << 1,
+
+/**
+ Debug Log
+ */
+GELoggingLevelDebug = 1 << 2,
+};
+
+/**
+ Https Certificate Verification Mode
+*/
+typedef NS_OPTIONS(NSInteger, GESSLPinningMode
+) {
+/**
+ The default authentication method will only verify the certificate returned by the server in the system's trusted certificate list
+*/
+GESSLPinningModeNone = 0,
+
+/**
+ The public key of the verification certificate
+*/
+GESSLPinningModePublicKey = 1 << 0,
+
+/**
+ Verify all contents of the certificate
+*/
+GESSLPinningModeCertificate = 1 << 1
+};
+
+/**
+ Custom HTTPS Authentication
+*/
+typedef NSURLSessionAuthChallengeDisposition (^TDURLSessionDidReceiveAuthenticationChallengeBlock)(
+        NSURLSession *_Nullable session, NSURLAuthenticationChallenge *_Nullable challenge,
+        NSURLCredential *_Nullable __autoreleasing
+
+*
+_Nullable credential
+);
+
+
+/**
+ Network Type Enum
+
+ - GENetworkTypeDefault :  3G、4G、WIFI
+ */
+typedef NS_OPTIONS(NSInteger, GravityEngineNetworkType
+) {
+
+/**
+ 3G、4G、WIFI
+ */
+GENetworkTypeDefault = 0,
+
+/**
+ only WIFI
+ */
+GENetworkTypeOnlyWIFI = 1 << 0,
+
+/**
+ 2G、3G、4G、WIFI
+ */
+GENetworkTypeALL = 1 << 1,
+};
+
+/**
+ Auto-Tracking Enum
+
+ - GravityEngineEventTypeNone           : auto-tracking is not enabled by default
+ */
+typedef NS_OPTIONS(NSInteger, GravityEngineAutoTrackEventType
+) {
+
+/**
+ auto-tracking is not enabled by default
+ */
+GravityEngineEventTypeNone = 0,
+
+/*
+ Active Events
+ */
+GravityEngineEventTypeAppStart = 1 << 0,
+
+/**
+ Inactive Events
+ */
+GravityEngineEventTypeAppEnd = 1 << 1,
+
+/**
+ Clicked events
+ */
+GravityEngineEventTypeAppClick = 1 << 2,
+
+/**
+ View Page Events
+ */
+GravityEngineEventTypeAppViewScreen = 1 << 3,
+
+/**
+ Crash Events
+ */
+GravityEngineEventTypeAppViewCrash = 1 << 4,
+
+/**
+ Installation Events
+ */
+GravityEngineEventTypeAppInstall = 1 << 5,
+/**
+ All  Events
+ */
+GravityEngineEventTypeAll =
+GravityEngineEventTypeAppStart | GravityEngineEventTypeAppEnd | GravityEngineEventTypeAppClick |
+GravityEngineEventTypeAppInstall | GravityEngineEventTypeAppViewScreen
+
+};
+
+typedef NS_OPTIONS(NSInteger, GravityNetworkType
+) {
+GravityNetworkTypeNONE = 0,
+        GravityNetworkType2G = 1 << 0,
+        GravityNetworkType3G = 1 << 1,
+        GravityNetworkType4G = 1 << 2,
+        GravityNetworkTypeWIFI = 1 << 3,
+        GravityNetworkType5G = 1 << 4,
+        GravityNetworkTypeALL = 0xFF,
+};
+
+
+typedef NS_OPTIONS(NSInteger, GEThirdPartyShareType
+) {
+GEThirdPartyShareTypeNONE = 0,
+        GEThirdPartyShareTypeAPPSFLYER = 1 << 0,
+        GEThirdPartyShareTypeIRONSOURCE = 1 << 1,
+        GEThirdPartyShareTypeADJUST = 1 << 2,
+        GEThirdPartyShareTypeBRANCH = 1 << 3,
+        GEThirdPartyShareTypeTOPON = 1 << 4,
+        GEThirdPartyShareTypeTRACKING = 1 << 5,
+        GEThirdPartyShareTypeTRADPLUS = 1 << 6,
+        GEThirdPartyShareTypeAPPLOVIN = 1 << 7,
+        GEThirdPartyShareTypeKOCHAVA = 1 << 8,
+        GEThirdPartyShareTypeTALKINGDATA = 1 << 9,
+        GEThirdPartyShareTypeFIREBASE = 1 << 10,
+
+
+        TDThirdPartyShareTypeNONE = GEThirdPartyShareTypeNONE,
+        TDThirdPartyShareTypeAPPSFLYER = GEThirdPartyShareTypeAPPSFLYER,
+        TDThirdPartyShareTypeIRONSOURCE = GEThirdPartyShareTypeIRONSOURCE,
+        TDThirdPartyShareTypeADJUST = GEThirdPartyShareTypeADJUST,
+        TDThirdPartyShareTypeBRANCH = GEThirdPartyShareTypeBRANCH,
+        TDThirdPartyShareTypeTOPON = GEThirdPartyShareTypeTOPON,
+        TDThirdPartyShareTypeTRACKING = GEThirdPartyShareTypeTRACKING,
+        TDThirdPartyShareTypeTRADPLUS = GEThirdPartyShareTypeTRADPLUS,
+
+};
+
+//MARK: - Data reporting status
+typedef NS_ENUM(NSInteger, GETrackStatus
+) {
+/// Suspend reporting
+GETrackStatusPause,
+/// Stop reporting and clear cache
+GETrackStatusStop,
+/// Suspend reporting and continue to persist data
+GETrackStatusSaveOnly,
+/// reset normal
+GETrackStatusNormal
+};

+ 43 - 0
ios/GravityEngineSDK.framework/Headers/GEDeviceInfo.h

@@ -0,0 +1,43 @@
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+        FOUNDATION_EXTERN
+NSString *const VERSION;
+
+@interface GEDeviceInfo : NSObject
+
++ (GEDeviceInfo *)sharedManager;
+
+
+@property(nonatomic, copy) NSString *uniqueId;
+@property(nonatomic, copy) NSString *deviceId;
+@property(nonatomic, copy) NSString *appVersion;
+@property(nonatomic, readonly) BOOL isFirstOpen;
+@property(nonatomic, copy) NSString *libName;
+@property(nonatomic, copy) NSString *libVersion;
+
++ (NSString *)libVersion;
+
++ (NSString *)bundleId;
+
+- (void)ge_updateData;
+
+- (NSDictionary *)ge_collectProperties;
+
++ (NSDate *)ge_getInstallTime;
+
+- (NSDictionary *)getAutomaticData;
+
++ (NSString *)currentRadio;
+
++ (NSTimeInterval)uptime;
+
++ (NSString *)bootTimeSec;
+
++ (NSDate *)systemUpdateTime;
+
+- (NSString *)ge_iphoneType;
+@end
+
+NS_ASSUME_NONNULL_END

+ 16 - 0
ios/GravityEngineSDK.framework/Headers/GEEditableEventModel.h

@@ -0,0 +1,16 @@
+
+#if __has_include(<GravityEngineSDK/GEUpdateEventModel.h>)
+
+#import <GravityEngineSDK/GEUpdateEventModel.h>
+
+#else
+#import "GEUpdateEventModel.h"
+#endif
+
+#if __has_include(<GravityEngineSDK/GEOverwriteEventModel.h>)
+
+#import <GravityEngineSDK/GEOverwriteEventModel.h>
+
+#else
+#import "GEOverwriteEventModel.h"
+#endif

+ 39 - 0
ios/GravityEngineSDK.framework/Headers/GEEventModel.h

@@ -0,0 +1,39 @@
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NS_OPTIONS(NSInteger, TimeValueType) {
+    GETimeValueTypeNone = 0,
+    GETimeValueTypeTimeOnly = 1 << 0,
+    GETimeValueTypeAll = 1 << 1,
+};
+
+typedef NSString *kEDEventTypeName;
+
+FOUNDATION_EXTERN kEDEventTypeName
+const GE_EVENT_TYPE_TRACK_FIRST;
+FOUNDATION_EXTERN kEDEventTypeName
+const GE_EVENT_TYPE_TRACK_UPDATE;
+FOUNDATION_EXTERN kEDEventTypeName
+const GE_EVENT_TYPE_TRACK_OVERWRITE;
+
+@interface GEEventModel : NSObject
+
+- (instancetype)init
+
+NS_UNAVAILABLE;
+
++ (instancetype)new
+
+NS_UNAVAILABLE;
+
+@property(nonatomic, copy, readonly) NSString *eventName;
+@property(nonatomic, copy, readonly) kEDEventTypeName eventType; // Default is GE_EVENT_TYPE_TRACK
+
+@property(nonatomic, strong) NSDictionary *properties;
+
+- (void)configTime:(NSDate *)time timeZone:(NSTimeZone * _Nullable)timeZone;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 21 - 0
ios/GravityEngineSDK.framework/Headers/GEFirstEventModel.h

@@ -0,0 +1,21 @@
+
+#if __has_include(<GravityEngineSDK/GEEventModel.h>)
+
+#import <GravityEngineSDK/GEEventModel.h>
+
+#else
+#import "GEEventModel.h"
+#endif
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GEFirstEventModel : GEEventModel
+
+- (instancetype)initWithEventName:(NSString * _Nullable)eventName;
+
+- (instancetype)initWithEventName:(NSString * _Nullable)eventName firstCheckID:(NSString *)firstCheckID;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 23 - 0
ios/GravityEngineSDK.framework/Headers/GEOverwriteEventModel.h

@@ -0,0 +1,23 @@
+//
+//  GEOverwriteEventModel.h
+//  GravityEngineSDK
+//
+//
+
+#if __has_include(<GravityEngineSDK/GEEventModel.h>)
+
+#import <GravityEngineSDK/GEEventModel.h>
+
+#else
+#import "GEEventModel.h"
+#endif
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GEOverwriteEventModel : GEEventModel
+
+- (instancetype)initWithEventName:(NSString *)eventName eventID:(NSString *)eventID;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 35 - 0
ios/GravityEngineSDK.framework/Headers/GEPresetProperties.h

@@ -0,0 +1,35 @@
+//
+//  GEPresetProperties.h
+//  GravityEngineSDK
+//
+//  Copyright © 2021 gravityengine. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GEPresetProperties : NSObject
+
+@property(nonatomic, copy, readonly) NSString *bundle_id;
+@property(nonatomic, copy, readonly) NSString *carrier;
+@property(nonatomic, copy, readonly) NSString *device_id;
+@property(nonatomic, copy, readonly) NSString *device_model;
+@property(nonatomic, copy, readonly) NSString *manufacturer;
+@property(nonatomic, copy, readonly) NSString *network_type;
+@property(nonatomic, copy, readonly) NSString *os;
+@property(nonatomic, copy, readonly) NSString *os_version;
+@property(nonatomic, copy, readonly) NSNumber *screen_height;
+@property(nonatomic, copy, readonly) NSNumber *screen_width;
+@property(nonatomic, copy, readonly) NSString *system_language;
+@property(nonatomic, copy, readonly) NSNumber *zone_offset;
+@property(nonatomic, copy, readonly) NSString *install_time;
+
+/**
+ * The key of the returned event preset property starts with "#", and it is not recommended to use it directly as the property of the event
+ */
+- (NSDictionary *)toEventPresetProperties;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 36 - 0
ios/GravityEngineSDK.framework/Headers/GESecretKey.h

@@ -0,0 +1,36 @@
+//
+//  GESecretKey.h
+//  GravityEngineSDK
+//
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GESecretKey : NSObject <NSCopying>
+
+/// Initialize key information
+- (instancetype)initWithVersion:(NSUInteger)version publicKey:(NSString *)publicKey;
+
+/// Initialize key information
+/// @param version key version number
+/// @param publicKey public key
+/// @param asymmetricEncryption asymmetric encryption type
+/// @param symmetricEncryption Symmetric encryption type
+- (instancetype)initWithVersion:(NSUInteger)version
+                      publicKey:(NSString *)publicKey
+           asymmetricEncryption:(NSString *)asymmetricEncryption
+            symmetricEncryption:(NSString *)symmetricEncryption;
+
+@property(nonatomic, assign, readonly) NSUInteger version;
+@property(nonatomic, copy, readonly) NSString *publicKey;
+@property(nonatomic, copy, readonly) NSString *symmetricEncryption;
+@property(nonatomic, copy, readonly) NSString *asymmetricEncryption;
+
+/// Whether the key information is available
+@property(nonatomic, assign, readonly) BOOL isValid;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 55 - 0
ios/GravityEngineSDK.framework/Headers/GESecurityPolicy.h

@@ -0,0 +1,55 @@
+
+/**
+ Thinks AFNetworking: https://github.com/AFNetworking/AFNetworking
+ */
+#import <Foundation/Foundation.h>
+
+#if __has_include(<GravityEngineSDK/GEConstant.h>)
+
+#import <GravityEngineSDK/GEConstant.h>
+
+#else
+#import "GEConstant.h"
+#endif
+
+NS_ASSUME_NONNULL_BEGIN
+
+
+@interface GESecurityPolicy : NSObject <NSCopying>
+
+@property(nonatomic, assign) BOOL allowInvalidCertificates;
+@property(nonatomic, assign) BOOL validatesDomainName;
+@property(nonatomic, copy) TDURLSessionDidReceiveAuthenticationChallengeBlock sessionDidReceiveAuthenticationChallenge;
+
++ (instancetype)policyWithPinningMode:(GESSLPinningMode)pinningMode;
+
++ (instancetype)defaultPolicy;
+
+- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain;
+
+@end
+
+#ifndef __Require_Quiet
+#define __Require_Quiet(assertion, exceptionLabel)                            \
+      do                                                                          \
+      {                                                                           \
+          if ( __builtin_expect(!(assertion), 0) )                                \
+          {                                                                       \
+              goto exceptionLabel;                                                \
+          }                                                                       \
+      } while ( 0 )
+#endif
+
+#ifndef __Require_noErr_Quiet
+#define __Require_noErr_Quiet(errorCode, exceptionLabel)                      \
+      do                                                                          \
+      {                                                                           \
+          if ( __builtin_expect(0 != (errorCode), 0) )                            \
+          {                                                                       \
+              goto exceptionLabel;                                                \
+          }                                                                       \
+      } while ( 0 )
+#endif
+
+
+NS_ASSUME_NONNULL_END

+ 23 - 0
ios/GravityEngineSDK.framework/Headers/GEUpdateEventModel.h

@@ -0,0 +1,23 @@
+//
+//  GEUpdateEventModel.h
+//  GravityEngineSDK
+//
+//
+
+#if __has_include(<GravityEngineSDK/GEEventModel.h>)
+
+#import <GravityEngineSDK/GEEventModel.h>
+
+#else
+#import "GEEventModel.h"
+#endif
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface GEUpdateEventModel : GEEventModel
+
+- (instancetype)initWithEventName:(NSString *)eventName eventID:(NSString *)eventID;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 688 - 0
ios/GravityEngineSDK.framework/Headers/GravityEngineSDK.h

@@ -0,0 +1,688 @@
+#import <Foundation/Foundation.h>
+
+#if TARGET_OS_IOS
+#import <UIKit/UIKit.h>
+
+#if __has_include(<GravityEngineSDK/GEAutoTrackPublicHeader.h>)
+#import <GravityEngineSDK/GEAutoTrackPublicHeader.h>
+#else
+#import "GEAutoTrackPublicHeader.h"
+#endif
+
+#elif TARGET_OS_OSX
+#import <AppKit/AppKit.h>
+#endif
+
+#if __has_include(<GravityEngineSDK/GEFirstEventModel.h>)
+
+#import <GravityEngineSDK/GEFirstEventModel.h>
+
+#else
+#import "GEFirstEventModel.h"
+#endif
+
+#if __has_include(<GravityEngineSDK/GEEditableEventModel.h>)
+
+#import <GravityEngineSDK/GEEditableEventModel.h>
+
+#else
+#import "GEEditableEventModel.h"
+#endif
+
+
+#if __has_include(<GravityEngineSDK/GEConfig.h>)
+
+#import <GravityEngineSDK/GEConfig.h>
+
+#else
+#import "GEConfig.h"
+#endif
+
+#if __has_include(<GravityEngineSDK/GEPresetProperties.h>)
+
+#import <GravityEngineSDK/GEPresetProperties.h>
+
+#else
+#import "GEPresetProperties.h"
+#endif
+
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ GravityEngine API
+ 
+ ## Initialization
+ 
+ ```objective-c
+ GravityEngineSDK *instance = [GravityEngineSDK startWithAppId:@"YOUR_APPID" withUrl:@"YOUR_SERVER_URL"];
+ ```
+ 
+ ## Track Event
+ 
+ ```objective-c
+ instance.track("some_event");
+ ```
+or
+ ```objective-c
+ [[GravityEngineSDK sharedInstanceWithAppid:@"YOUR_APPID"] track:@"some_event"];
+ ```
+ If you only have one instance in your project, you can also use
+ ```objective-c
+ [[GravityEngineSDK sharedInstance] track:@"some_event"];
+ ```
+
+ */
+
+typedef void (^CallbackWithSuccess)(NSDictionary *response);
+
+typedef void (^CallbackWithError)(NSError *error);
+
+@interface GravityEngineSDK : NSObject
+
+#pragma mark - Tracking
+
+/**
+ Get default instance
+
+ @return SDK instance
+ */
++ (nullable GravityEngineSDK
+
+*)
+sharedInstance;
+
+/**
+  Get one instance according to appid or instanceName
+
+  @param appid APP ID or instanceName
+  @return SDK instance
+  */
++ (nullable GravityEngineSDK
+
+*)sharedInstanceWithAppid:(NSString *)
+appid;
+
+/**
+  Initialization method
+  After the SDK initialization is complete, the saved instance can be obtained through this api
+
+  @param config initialization configuration
+  @return one instance
+  */
++ (GravityEngineSDK *)startWithConfig:(nullable GEConfig
+
+*)
+config;
+
+/**
+  Initialization method
+  After the SDK initialization is complete, the saved instance can be obtained through this api
+
+  @param appId appId
+  @param url server url
+  @param config initialization configuration object
+  @return one instance
+  */
++ (GravityEngineSDK *)startWithAppId:(NSString *)appId withUrl:(NSString *)url withConfig:(nullable GEConfig
+
+*)
+config;
+
+
+#pragma mark - Other API
+
+/**
+ register GravityEngine
+ */
+- (void)initializeGravityEngineWithClientId:(NSString *)clientId withUserName:(NSString *)userName withVersion:(int)version withAsaEnable:(bool)enableAsa withIdfa:(NSString *)idfa withIdfv:(NSString *)idfv withCaid1:(NSString *)caid1_md5 withCaid2:(NSString *)caid2_md5 withSyncAttribution:(bool)syncAttribution withSuccessCallback:(CallbackWithSuccess)successCallback withErrorCallback:(CallbackWithError)errorCallback;
+
+- (void)initializeGravityEngineWithClientId:(NSString *)clientId withUserName:(NSString *)userName withVersion:(int)version withAsaEnable:(bool)enableAsa withIdfa:(NSString *)idfa withIdfv:(NSString *)idfv withCaid1:(NSString *)caid1_md5 withCaid2:(NSString *)caid2_md5 withSyncAttribution:(bool)syncAttribution withCreateTime:(long)createTimestamp withCompany:(NSString *)company withSuccessCallback:(CallbackWithSuccess)successCallback withErrorCallback:(CallbackWithError)errorCallback;
+
+- (void)queryUserInfoWithSuccessCallback:(void (^)(NSDictionary *_Nonnull
+                                                   data))successCallback withErrorCallback:(CallbackWithError)errorCallback;
+
+- (void)resetClientID:(NSString *)newClientID withSuccessCallback:(CallbackWithSuccess)successCallback withErrorCallback:(CallbackWithError)errorCallback;
+
+- (void)uploadDeviceInfoWithIdfa:(NSString *)idfa withIdfv:(NSString *)idfv withCaid1:(NSString *)caid1_md5 withCaid2:(NSString *)caid2_md5;
+
+/**
+ * 上报业务注册事件
+ *
+ */
+- (void)trackRegisterEvent;
+
+/**
+ * 上报付费事件
+ *
+ * @param payAmount  付费金额 单位为分
+ * @param payType    货币类型 按照国际标准组织ISO 4217中规范的3位字母,例如CNY人民币、USD美金等
+ * @param orderId    订单号
+ * @param payReason  付费原因 例如:购买钻石、办理月卡
+ * @param payMethod  付费方式 例如:支付宝、微信、银联等
+ */
+- (void)trackPayEventWithAmount:(int)payAmount withPayType:(NSString *)payType withOrderId:(NSString *)orderId withPayReason:(NSString *)payReason withPayMethod:(NSString *)payMethod;
+
+/**
+ * 上报提现事件
+ *
+ * @param payAmount  提现金额 单位为分
+ * @param payType    货币类型 按照国际标准组织ISO 4217中规范的3位字母,例如CNY人民币、USD美金等
+ * @param orderId    订单号
+ * @param payReason  提现原因 例如:用户首次提现、用户抽奖提现
+ * @param payMethod  提现支付方式 例如:支付宝、微信、银联等
+ */
+- (void)trackWithdrawEvent:(int)payAmount withPayType:(NSString *)payType withOrderId:(NSString *)orderId withPayReason:(NSString *)payReason withPayMethod:(NSString *)payMethod;
+
+/**
+ * 上报广告事件
+ *
+ * @param adUnionType   广告聚合平台类型  (取值为:topon、gromore、admore、self,分别对应Topon、Gromore、Admore、自建聚合)
+ * @param adPlacementId 广告瀑布流ID
+ * @param adSourceId    广告源ID
+ * @param adType        广告类型 (取值为:reward、banner、 native 、interstitial、 splash ,分别对应激励视频广告、横幅广告、信息流广告、插屏广告、开屏广告)
+ * @param adAdnType       广告平台类型(取值为:csj、gdt、ks、 mint 、baidu,分别对应为穿山甲、优量汇、快手联盟、Mintegral、百度联盟)
+ * @param ecpm          预估ECPM价格(单位为元)
+ * @param duration      广告播放时长(单位为秒)
+ * @param isPlayOver    广告是否播放完毕
+ */
+- (void)trackAdLoadEventWithUninType:(NSString *)adUnionType withPlacementId:(NSString *)adPlacementId withSourceId:(NSString *)adSourceId withAdType:(NSString *)adType withAdnType:(NSString *)adAdnType;
+
+- (void)trackAdShowEventWithUninType:(NSString *)adUnionType withPlacementId:(NSString *)adPlacementId withSourceId:(NSString *)adSourceId withAdType:(NSString *)adType withAdnType:(NSString *)adAdnType withEcpm:(NSNumber *)ecpm;
+
+- (void)trackAdSkipEventWithUninType:(NSString *)adUnionType withPlacementId:(NSString *)adPlacementId withSourceId:(NSString *)adSourceId withAdType:(NSString *)adType withAdnType:(NSString *)adAdnType withEcpm:(NSNumber *)ecpm;
+
+- (void)trackAdClickEventWithUninType:(NSString *)adUnionType withPlacementId:(NSString *)adPlacementId withSourceId:(NSString *)adSourceId withAdType:(NSString *)adType withAdnType:(NSString *)adAdnType withEcpm:(NSNumber *)ecpm;
+
+- (void)trackAdPlayStartEventWithUninType:(NSString *)adUnionType withPlacementId:(NSString *)adPlacementId withSourceId:(NSString *)adSourceId withAdType:(NSString *)adType withAdnType:(NSString *)adAdnType withEcpm:(NSNumber *)ecpm;
+
+- (void)trackAdPlayEndEventWithUninType:(NSString *)adUnionType withPlacementId:(NSString *)adPlacementId withSourceId:(NSString *)adSourceId withAdType:(NSString *)adType withAdnType:(NSString *)adAdnType withEcpm:(NSNumber *)ecpm withDruation:(NSNumber *)duration withIsPlayOver:(BOOL)isPlayOver;
+
+
+/**
+ * 绑定数数账号
+ *
+ * @param taAccountId    数数的account_id
+ * @param taDistinctId  数数的distinct_id
+ */
+- (void)bindTAThirdPlatformWithAccountId:(NSString *)taAccountId withDistinctId:(NSString *)taDistinctId;
+
+#pragma mark - Action Track
+
+/**
+ Track Events
+
+ @param event         event name
+ */
+- (void)track:(NSString *)event;
+
+
+/**
+ Track Events
+
+ @param event         event name
+ @param propertieDict event properties
+ */
+- (void)track:(NSString *)event properties:(nullable NSDictionary
+
+*)
+propertieDict;
+
+/**
+ Track Events
+
+ @param event         event name
+ @param propertieDict event properties
+ @param time          event trigger time
+ */
+- (void)track:(NSString *)event properties:(nullable NSDictionary
+
+*)
+propertieDict time
+:(NSDate *)time __attribute__((deprecated("please use track:properties:time:timeZone: method")));
+
+/**
+ Track Events
+ 
+  @param event event name
+  @param propertieDict event properties
+  @param time event trigger time
+  @param timeZone event trigger time time zone
+  */
+- (void)track:(NSString *)event properties:(nullable NSDictionary
+
+*)
+propertieDict time
+:(NSDate *)
+time timeZone
+:(NSTimeZone *)
+timeZone;
+
+/**
+ Track Events
+ 
+  @param eventModel event Model
+  */
+- (void)trackWithEventModel:(GEEventModel *)eventModel;
+
+/**
+ Get the events collected in the App Extension and report them
+ 
+  @param appGroupId The app group id required for data sharing
+  */
+- (void)trackFromAppExtensionWithAppGroupId:(NSString *)appGroupId;
+
+#pragma mark -
+
+/**
+ Timing Events
+ Record the event duration, call this method to start the timing, stop the timing when the target event is uploaded, and add the attribute #duration to the event properties, in seconds.
+ */
+- (void)timeEvent:(NSString *)event;
+
+/**
+ Identify
+ Set the distinct ID to replace the default UUID distinct ID.
+ */
+- (void)identify:(NSString *)distinctId;
+
+/**
+ Get Distinctid
+ Get a visitor ID: The #distinct_id value in the reported data.
+ */
+- (NSString *)getDistinctId;
+
+/**
+ Get sdk version
+ */
++ (NSString *)getSDKVersion;
+
+/**
+ Login
+ Set the account ID. Each setting overrides the previous value. Login events will be uploaded.
+
+ @param clientId client ID
+ */
+- (void)login:(NSString *)clientId;
+
+/**
+ Logout with completion
+ Clearing the account ID and upload user logout events.
+ */
+- (void)logoutWithCompletion:(void (^)(void))completion;
+
+/**
+ User_Set
+ Sets the user property, replacing the original value with the new value if the property already exists.
+
+ @param properties user properties
+ */
+- (void)user_set:(NSDictionary *)properties;
+
+/**
+ User_Set
+
+ @param properties user properties
+ @param time event trigger time
+*/
+- (void)user_set:(NSDictionary *)properties withTime:(NSDate * _Nullable)time;
+
+/**
+ User_Unset
+ 
+ @param propertyName user properties
+ */
+- (void)user_unset:(NSString *)propertyName;
+
+/**
+ User_Unset
+ Reset user properties.
+
+ @param propertyName user properties
+ @param time event trigger time
+*/
+- (void)user_unset:(NSString *)propertyName withTime:(NSDate * _Nullable)time;
+
+/**
+ User_SetOnce
+ Sets a single user attribute, ignoring the new attribute value if the attribute already exists.
+
+ @param properties user properties
+ */
+- (void)user_set_once:(NSDictionary *)properties;
+
+/**
+ User_SetOnce
+
+ @param properties user properties
+ @param time event trigger time
+*/
+- (void)user_set_once:(NSDictionary *)properties withTime:(NSDate * _Nullable)time;
+
+/**
+ User_Add
+ Adds the numeric type user attributes.
+
+ @param properties user properties
+ */
+- (void)user_increment:(NSDictionary *)properties;
+
+/**
+ User_Add
+
+ @param properties user properties
+ @param time event trigger time
+*/
+- (void)user_increment:(NSDictionary *)properties withTime:(NSDate * _Nullable)time;
+
+/**
+ User_Add
+
+  @param propertyName  propertyName
+  @param propertyValue propertyValue
+ */
+- (void)user_increment:(NSString *)propertyName andPropertyValue:(NSNumber *)propertyValue;
+
+/**
+ User_Add
+
+ @param propertyName  propertyName
+ @param propertyValue propertyValue
+ @param time event trigger time
+*/
+- (void)user_increment:(NSString *)propertyName andPropertyValue:(NSNumber *)propertyValue withTime:(NSDate * _Nullable)time;
+
+/**
+ User_Number_Max
+ Get max number and save it
+
+ @param properties user properties
+ */
+- (void)user_number_max:(NSDictionary *)properties;
+
+/**
+ User_Number_Max
+
+ @param properties user properties
+ @param time event trigger time
+*/
+- (void)user_number_max:(NSDictionary *)properties withTime:(NSDate * _Nullable)time;
+
+/**
+ User_Number_Max
+
+  @param propertyName  propertyName
+  @param propertyValue propertyValue
+ */
+- (void)user_number_max:(NSString *)propertyName andPropertyValue:(NSNumber *)propertyValue;
+
+/**
+ User_Number_Max
+
+ @param propertyName  propertyName
+ @param propertyValue propertyValue
+ @param time event trigger time
+*/
+- (void)user_number_max:(NSString *)propertyName andPropertyValue:(NSNumber *)propertyValue withTime:(NSDate * _Nullable)time;
+
+/**
+ User_Number_Min
+ Get min number and save it
+
+ @param properties user properties
+ */
+- (void)user_number_min:(NSDictionary *)properties;
+
+/**
+ User_Number_Min
+
+ @param properties user properties
+ @param time event trigger time
+*/
+- (void)user_number_min:(NSDictionary *)properties withTime:(NSDate * _Nullable)time;
+
+/**
+ User_Number_Min
+
+  @param propertyName  propertyName
+  @param propertyValue propertyValue
+ */
+- (void)user_number_min:(NSString *)propertyName andPropertyValue:(NSNumber *)propertyValue;
+
+/**
+ User_Number_Min
+
+ @param propertyName  propertyName
+ @param propertyValue propertyValue
+ @param time event trigger time
+*/
+- (void)user_number_min:(NSString *)propertyName andPropertyValue:(NSNumber *)propertyValue withTime:(NSDate * _Nullable)time;
+
+/**
+ User_Delete
+ Delete the user attributes,This operation is not reversible and should be performed with caution.
+ */
+- (void)user_delete;
+
+/**
+ User_Delete
+ 
+ @param time event trigger time
+ */
+- (void)user_delete:(NSDate * _Nullable)time;
+
+/**
+ User_Append
+ Append a user attribute of the List type.
+ 
+ @param properties user properties
+*/
+- (void)user_append:(NSDictionary
+
+<NSString *, NSArray *> *)
+properties;
+
+/**
+ User_Append
+ The element appended to the library needs to be done to remove the processing,and then import.
+ 
+ @param properties user properties
+ @param time event trigger time
+*/
+- (void)user_append:(NSDictionary
+
+<NSString *, NSArray *> *)
+properties withTime
+:(
+NSDate *_Nullable
+)
+time;
+
+/**
+ User_UniqAppend
+ 
+ @param properties user properties
+*/
+- (void)user_uniqAppend:(NSDictionary
+
+<NSString *, NSArray *> *)
+properties;
+
+/**
+ User_UniqAppend
+ 
+ @param properties user properties
+ @param time event trigger time
+*/
+- (void)user_uniqAppend:(NSDictionary
+
+<NSString *, NSArray *> *)
+properties withTime
+:(
+NSDate *_Nullable
+)
+time;
+
++ (void)setCustomerLibInfoWithLibName:(NSString *)libName libVersion:(NSString *)libVersion;
+
+/**
+ Static Super Properties
+ Set the public event attribute, which will be included in every event uploaded after that. The public event properties are saved without setting them each time.
+  *
+ */
+- (void)setSuperProperties:(NSDictionary *)properties;
+
+/**
+ Unset Super Property
+ Clears a public event attribute.
+ */
+- (void)unsetSuperProperty:(NSString *)property;
+
+/**
+ Clear Super Properties
+ Clear all public event attributes.
+ */
+- (void)clearSuperProperties;
+
+/**
+ Get Static Super Properties
+ Gets the public event properties that have been set.
+ */
+- (NSDictionary *)currentSuperProperties;
+
+/**
+ Dynamic super properties
+ Set dynamic public properties. Each event uploaded after that will contain a public event attribute.
+ */
+- (void)registerDynamicSuperProperties:(NSDictionary
+
+<NSString *, id> *(^)(void))
+dynamicSuperProperties;
+
+/**
+ Gets prefabricated properties for all events.
+ */
+- (GEPresetProperties *)getPresetProperties;
+
+/**
+ Set the network conditions for uploading. By default, the SDK will set the network conditions as 3G, 4G and Wifi to upload data
+ */
+- (void)setNetworkType:(GravityEngineNetworkType)type;
+
+#if TARGET_OS_IOS
+
+/**
+ Enable Auto-Tracking
+
+ @param eventType Auto-Tracking type
+
+ */
+- (void)enableAutoTrack:(GravityEngineAutoTrackEventType)eventType;
+
+/**
+ Enable the auto tracking function.
+
+ @param eventType  Auto-Tracking type
+ @param properties properties
+ */
+- (void)enableAutoTrack:(GravityEngineAutoTrackEventType)eventType properties:(NSDictionary *)properties;
+
+/**
+ Enable the auto tracking function.
+
+ @param eventType  Auto-Tracking type
+ @param callback callback
+ In the callback, eventType indicates the type of automatic collection, properties indicates the event properties before storage, and this block can return a dictionary for adding new properties
+ */
+- (void)enableAutoTrack:(GravityEngineAutoTrackEventType)eventType callback:(NSDictionary *(^)(GravityEngineAutoTrackEventType eventType, NSDictionary *properties))callback;
+
+/**
+ Set and Update the value of a custom property for Auto-Tracking
+ 
+ @param eventType  A list of GravityEngineAutoTrackEventType, indicating the types of automatic collection events that need to be enabled
+ @param properties properties
+ */
+- (void)setAutoTrackProperties:(GravityEngineAutoTrackEventType)eventType properties:(NSDictionary *)properties;
+
+/**
+ Ignore the Auto-Tracking of a page
+
+ @param controllers Ignore the name of the UIViewController
+ */
+- (void)ignoreAutoTrackViewControllers:(NSArray *)controllers;
+
+/**
+ Ignore the Auto-Tracking  of click event
+
+ @param aClass ignored controls  Class
+ */
+- (void)ignoreViewType:(Class)aClass;
+
+#endif
+
+//MARK: -
+
+/**
+ Get DeviceId
+ */
+- (NSString *)getDeviceId;
+
+- (NSString *)getCurrentClientId;
+
+/**
+ H5 is connected with the native APP SDK and used in conjunction with the addWebViewUserAgent interface
+
+ @param webView webView
+ @param request NSURLRequest request
+ @return YES:Process this request NO: This request has not been processed
+ */
+- (BOOL)showUpWebView:(id)webView WithRequest:(NSURLRequest *)request;
+
+/**
+ When connecting data with H5, you need to call this interface to configure UserAgent
+ */
+//- (void)addWebViewUserAgent;
+
+/**
+ Set Log level
+
+ */
++ (void)setLogLevel:(GELoggingLevel)level;
+
+/**
+ Empty the cache queue. When this api is called, the data in the current cache queue will attempt to be reported.
+ If the report succeeds, local cache data will be deleted.
+ */
+- (void)flush;
+
+- (void)flushWithCompletion:(void (^)(void))completion;
+
+- (void)testTest;
+
+/**
+ Switch reporting status
+
+ @param status GETrackStatus reporting status
+ */
+- (void)setTrackStatus:(GETrackStatus)status;
+
++ (void)calibrateTimeWithNtp:(NSString *)ntpServer;
+
++ (void)calibrateTime:(NSTimeInterval)timestamp;
+
+- (NSString *)getTimeString:(NSDate *)date;
+
+#if TARGET_OS_IOS
+- (void)enableThirdPartySharing:(GEThirdPartyShareType)type;
+
+- (void)enableThirdPartySharing:(GEThirdPartyShareType)type customMap:(NSDictionary<NSString *, NSObject *> *)customMap;
+#endif
+
++ (nullable NSString
+
+*)
+getLocalRegion;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 50 - 0
ios/GravityEngineSDK.framework/Headers/GravitySDK.h

@@ -0,0 +1,50 @@
+
+#import <Foundation/Foundation.h>
+
+#if __has_include(<GravityEngineSDK/GravityEngineSDK.h>)
+
+#import <GravityEngineSDK/GravityEngineSDK.h>
+
+#else
+#import "GravityEngineSDK.h"
+#endif
+
+#if __has_include(<GravityEngineSDK/GEFirstEventModel.h>)
+
+#import <GravityEngineSDK/GEFirstEventModel.h>
+
+#else
+#import "GEFirstEventModel.h"
+#endif
+
+#if __has_include(<GravityEngineSDK/GEEditableEventModel.h>)
+
+#import <GravityEngineSDK/GEEditableEventModel.h>
+
+#else
+#import "GEEditableEventModel.h"
+#endif
+
+#if __has_include(<GravityEngineSDK/GEConfig.h>)
+
+#import <GravityEngineSDK/GEConfig.h>
+
+#else
+#import "GEConfig.h"
+#endif
+
+#if __has_include(<GravityEngineSDK/GEPresetProperties.h>)
+
+#import <GravityEngineSDK/GEPresetProperties.h>
+
+#else
+#import "GEPresetProperties.h"
+#endif
+
+#if __has_include(<GravityEngineSDK/GEDeviceInfo.h>)
+
+#import <GravityEngineSDK/GEDeviceInfo.h>
+
+#else
+#import "GEDeviceInfo.h"
+#endif

+ 50 - 0
ios/GravityEngineSDK.framework/Headers/UIView+GravityEngine.h

@@ -0,0 +1,50 @@
+//
+//  UIView+GravityEngine.h
+//  GravityEngineSDK
+//
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface UIView (GravityEngine)
+
+/**
+ Set the control element ID
+ */
+@property(copy, nonatomic) NSString *gravityEngineViewID;
+
+/**
+ Configure the control element ID of APPID
+ */
+@property(strong, nonatomic) NSDictionary *gravityEngineViewIDWithAppid;
+
+/**
+ Ignore the click event of a control
+ */
+@property(nonatomic, assign) BOOL gravityEngineIgnoreView;
+
+/**
+ Configure APPID to ignore the click event of a control
+ */
+@property(strong, nonatomic) NSDictionary *gravityEngineIgnoreViewWithAppid;
+
+/**
+ Properties of custom control click event
+ */
+@property(strong, nonatomic) NSDictionary *gravityEngineViewProperties;
+
+/**
+ Configure the properties of the APPID custom control click event
+ */
+@property(strong, nonatomic) NSDictionary *gravityEngineViewPropertiesWithAppid;
+
+/**
+ gravityEngineDelegate
+ */
+@property(nonatomic, weak, nullable) id gravityEngineDelegate;
+
+@end
+
+NS_ASSUME_NONNULL_END

BIN
ios/GravityEngineSDK.framework/Info.plist


+ 6 - 0
ios/GravityEngineSDK.framework/Modules/module.modulemap

@@ -0,0 +1,6 @@
+framework module GravityEngineSDK {
+  umbrella header "GravityEngineSDK.h"
+  export *
+
+  module * { export * }
+}

+ 125 - 0
ios/GravityEngineSDK.framework/PrivacyInfo.xcprivacy

@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>NSPrivacyTracking</key>
+	<true/>
+	<key>NSPrivacyCollectedDataTypes</key>
+	<array>
+		<dict>
+			<key>NSPrivacyCollectedDataType</key>
+			<string>NSPrivacyCollectedDataTypeDeviceID</string>
+			<key>NSPrivacyCollectedDataTypeLinked</key>
+			<true/>
+			<key>NSPrivacyCollectedDataTypeTracking</key>
+			<true/>
+			<key>NSPrivacyCollectedDataTypePurposes</key>
+			<array>
+				<string>NSPrivacyCollectedDataTypePurposeThirdPartyAdvertising</string>
+				<string>NSPrivacyCollectedDataTypePurposeDeveloperAdvertising</string>
+				<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyCollectedDataType</key>
+			<string>NSPrivacyCollectedDataTypePerformanceData</string>
+			<key>NSPrivacyCollectedDataTypeLinked</key>
+			<false/>
+			<key>NSPrivacyCollectedDataTypeTracking</key>
+			<false/>
+			<key>NSPrivacyCollectedDataTypePurposes</key>
+			<array>
+				<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyCollectedDataType</key>
+			<string>NSPrivacyCollectedDataTypeOtherDataTypes</string>
+			<key>NSPrivacyCollectedDataTypeLinked</key>
+			<false/>
+			<key>NSPrivacyCollectedDataTypeTracking</key>
+			<false/>
+			<key>NSPrivacyCollectedDataTypePurposes</key>
+			<array>
+				<string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyCollectedDataType</key>
+			<string>NSPrivacyCollectedDataTypeProductInteraction</string>
+			<key>NSPrivacyCollectedDataTypeLinked</key>
+			<false/>
+			<key>NSPrivacyCollectedDataTypeTracking</key>
+			<false/>
+			<key>NSPrivacyCollectedDataTypePurposes</key>
+			<array>
+				<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyCollectedDataType</key>
+			<string>NSPrivacyCollectedDataTypeCrashData</string>
+			<key>NSPrivacyCollectedDataTypeLinked</key>
+			<false/>
+			<key>NSPrivacyCollectedDataTypeTracking</key>
+			<false/>
+			<key>NSPrivacyCollectedDataTypePurposes</key>
+			<array>
+				<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyCollectedDataType</key>
+			<string>NSPrivacyCollectedDataTypeUserID</string>
+			<key>NSPrivacyCollectedDataTypeLinked</key>
+			<false/>
+			<key>NSPrivacyCollectedDataTypeTracking</key>
+			<false/>
+			<key>NSPrivacyCollectedDataTypePurposes</key>
+			<array>
+				<string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
+			</array>
+		</dict>
+	</array>
+	<key>NSPrivacyTrackingDomains</key>
+	<array>
+		<string>backend.gravity-engine.com</string>
+	</array>
+	<key>NSPrivacyAccessedAPITypes</key>
+	<array>
+		<dict>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>1C8F.1</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>E174.1</string>
+				<string>7D9E.1</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategorySystemBootTime</string>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>35F9.1</string>
+			</array>
+		</dict>
+		<dict>
+			<key>NSPrivacyAccessedAPIType</key>
+			<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
+			<key>NSPrivacyAccessedAPITypeReasons</key>
+			<array>
+				<string>C617.1</string>
+			</array>
+		</dict>
+	</array>
+</dict>
+</plist>

BIN
ios/GravityEngineSDK.framework/_CodeSignature/CodeDirectory


BIN
ios/GravityEngineSDK.framework/_CodeSignature/CodeRequirements


BIN
ios/GravityEngineSDK.framework/_CodeSignature/CodeRequirements-1


+ 372 - 0
ios/GravityEngineSDK.framework/_CodeSignature/CodeResources

@@ -0,0 +1,372 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>files</key>
+	<dict>
+		<key>Headers/GEAutoTrackProtocol.h</key>
+		<data>
+		2ZPYyh7pG1NYb/qjn7PfXXVUCx4=
+		</data>
+		<key>Headers/GEAutoTrackPublicHeader.h</key>
+		<data>
+		b4xv1klqj24rh1CjDoYDeL+ItvY=
+		</data>
+		<key>Headers/GEConfig.h</key>
+		<data>
+		Z9isONSqqp4p45F24xHI3NJ4bVo=
+		</data>
+		<key>Headers/GEConstant.h</key>
+		<data>
+		miBCmIaI9KYF4vp9da31UqXLg5g=
+		</data>
+		<key>Headers/GEDeviceInfo.h</key>
+		<data>
+		svtSveXTL3DTSjDs4LT0cqfgmTc=
+		</data>
+		<key>Headers/GEEditableEventModel.h</key>
+		<data>
+		c9rygICMCnLp4c45Y2MkP8RdQp8=
+		</data>
+		<key>Headers/GEEventModel.h</key>
+		<data>
+		K2VI43CvR5AqHDpY7Tx54sjC9/k=
+		</data>
+		<key>Headers/GEFirstEventModel.h</key>
+		<data>
+		loN8apfNYaOqisWeNZxhIxLUT+s=
+		</data>
+		<key>Headers/GEOverwriteEventModel.h</key>
+		<data>
+		NuMpTpJpvEDlZIwH8PWNqcpBUdo=
+		</data>
+		<key>Headers/GEPresetProperties.h</key>
+		<data>
+		UznZL9yRmuogOEy6lB5fAjvbfxU=
+		</data>
+		<key>Headers/GESecretKey.h</key>
+		<data>
+		wZv9tfKTeyxh+5OdrQn/h522ASk=
+		</data>
+		<key>Headers/GESecurityPolicy.h</key>
+		<data>
+		7Dzt5gwcMBcUaYeVvQIKZlrUB60=
+		</data>
+		<key>Headers/GEUpdateEventModel.h</key>
+		<data>
+		CKaWTdja1psL0bb9N9zvxmUmFjk=
+		</data>
+		<key>Headers/GravityEngineSDK.h</key>
+		<data>
+		IiJ6vkLw+viWVKgDSH2WMqkCqWE=
+		</data>
+		<key>Headers/GravitySDK.h</key>
+		<data>
+		qQTXdNkpHVShzdQxCvoDh6N80KU=
+		</data>
+		<key>Headers/UIView+GravityEngine.h</key>
+		<data>
+		CMQqSOfTr8ZVPeaq9llQHjcN+y8=
+		</data>
+		<key>Info.plist</key>
+		<data>
+		2lUJPOS0XZb1phyA/DALHP3VuuY=
+		</data>
+		<key>Modules/module.modulemap</key>
+		<data>
+		MzLthyQ7aajebc/OA9Zf2kc4JEk=
+		</data>
+		<key>PrivacyInfo.xcprivacy</key>
+		<data>
+		fh8OMg52bBcwBc0aloTqzllFH8A=
+		</data>
+	</dict>
+	<key>files2</key>
+	<dict>
+		<key>Headers/GEAutoTrackProtocol.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			2ZPYyh7pG1NYb/qjn7PfXXVUCx4=
+			</data>
+			<key>hash2</key>
+			<data>
+			XzDtxE79r9mPfiDU8FevLNREMVopFYqamRBgpiRZGFY=
+			</data>
+		</dict>
+		<key>Headers/GEAutoTrackPublicHeader.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			b4xv1klqj24rh1CjDoYDeL+ItvY=
+			</data>
+			<key>hash2</key>
+			<data>
+			CghufXFPnABowC0m37IEl1fLbiFItEgnKnav4fOzz5M=
+			</data>
+		</dict>
+		<key>Headers/GEConfig.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			Z9isONSqqp4p45F24xHI3NJ4bVo=
+			</data>
+			<key>hash2</key>
+			<data>
+			234GeCZakxXUhSTWA39M9SQwMFNGoY6wdI8+J0huBzM=
+			</data>
+		</dict>
+		<key>Headers/GEConstant.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			miBCmIaI9KYF4vp9da31UqXLg5g=
+			</data>
+			<key>hash2</key>
+			<data>
+			5cL68UkO1/ccgTzIxzv8xMehc+u/ZrWZFk7BGpAaaPM=
+			</data>
+		</dict>
+		<key>Headers/GEDeviceInfo.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			svtSveXTL3DTSjDs4LT0cqfgmTc=
+			</data>
+			<key>hash2</key>
+			<data>
+			JhlZHCifb/QiDH4s8Fi5Tg88tkl4FSy5lx1bolusHoI=
+			</data>
+		</dict>
+		<key>Headers/GEEditableEventModel.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			c9rygICMCnLp4c45Y2MkP8RdQp8=
+			</data>
+			<key>hash2</key>
+			<data>
+			oytoW/uKiPI3ScFZ5D8IYXAwgAuSN6CW5tffr0sUkRQ=
+			</data>
+		</dict>
+		<key>Headers/GEEventModel.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			K2VI43CvR5AqHDpY7Tx54sjC9/k=
+			</data>
+			<key>hash2</key>
+			<data>
+			BJLyEFWz93ubqaISFclhnLGNR/VkFutwMBtXP78SsBI=
+			</data>
+		</dict>
+		<key>Headers/GEFirstEventModel.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			loN8apfNYaOqisWeNZxhIxLUT+s=
+			</data>
+			<key>hash2</key>
+			<data>
+			ovp3qWg/NaSmM3s5eekysttfIcsaPun4hJpD/MhrA/I=
+			</data>
+		</dict>
+		<key>Headers/GEOverwriteEventModel.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			NuMpTpJpvEDlZIwH8PWNqcpBUdo=
+			</data>
+			<key>hash2</key>
+			<data>
+			FNomA/moSj7I6BxBgJFs0Qy6y6UIdrZpi+GYHiPMY6M=
+			</data>
+		</dict>
+		<key>Headers/GEPresetProperties.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			UznZL9yRmuogOEy6lB5fAjvbfxU=
+			</data>
+			<key>hash2</key>
+			<data>
+			VJP0ho5Fu6S8cPbPA6sK8VP7zvsur1Y0/7S4Qlcj7LQ=
+			</data>
+		</dict>
+		<key>Headers/GESecretKey.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			wZv9tfKTeyxh+5OdrQn/h522ASk=
+			</data>
+			<key>hash2</key>
+			<data>
+			gF5KxWvHfTLxyNxEZIuM0YJr/YKM/wjfN3ij4D2FSMk=
+			</data>
+		</dict>
+		<key>Headers/GESecurityPolicy.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			7Dzt5gwcMBcUaYeVvQIKZlrUB60=
+			</data>
+			<key>hash2</key>
+			<data>
+			+K/Sq3MHS2rBFo42DkC3pAyu9JL8uXhssiqqZOjzMsk=
+			</data>
+		</dict>
+		<key>Headers/GEUpdateEventModel.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			CKaWTdja1psL0bb9N9zvxmUmFjk=
+			</data>
+			<key>hash2</key>
+			<data>
+			JX8q3AVV1EhloZjPn/R5HEyYiKHDLK+rgu9XI07gYhw=
+			</data>
+		</dict>
+		<key>Headers/GravityEngineSDK.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			IiJ6vkLw+viWVKgDSH2WMqkCqWE=
+			</data>
+			<key>hash2</key>
+			<data>
+			1C2UcEJ15RpjRz1KQQTtPabqv226l1i5nPOZEKjv4Ng=
+			</data>
+		</dict>
+		<key>Headers/GravitySDK.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			qQTXdNkpHVShzdQxCvoDh6N80KU=
+			</data>
+			<key>hash2</key>
+			<data>
+			5Uw8RCUbu7lGTcOZrLWSpd+zd28mV1Eiw4evxKV8hDs=
+			</data>
+		</dict>
+		<key>Headers/UIView+GravityEngine.h</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			CMQqSOfTr8ZVPeaq9llQHjcN+y8=
+			</data>
+			<key>hash2</key>
+			<data>
+			dvopqxzRYX9I77s9tM5q4lfkO4GyGza2g21CvpbqLO4=
+			</data>
+		</dict>
+		<key>Modules/module.modulemap</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			MzLthyQ7aajebc/OA9Zf2kc4JEk=
+			</data>
+			<key>hash2</key>
+			<data>
+			x2uuYj9zFEon1bAwThSWI7hpmIaRh9WiXDKc/W8p9Wg=
+			</data>
+		</dict>
+		<key>PrivacyInfo.xcprivacy</key>
+		<dict>
+			<key>hash</key>
+			<data>
+			fh8OMg52bBcwBc0aloTqzllFH8A=
+			</data>
+			<key>hash2</key>
+			<data>
+			dYSXmHpYREIqQGsxjPWNsuJR1xiIzmsPLLQCHj3B3mk=
+			</data>
+		</dict>
+	</dict>
+	<key>rules</key>
+	<dict>
+		<key>^.*</key>
+		<true/>
+		<key>^.*\.lproj/</key>
+		<dict>
+			<key>optional</key>
+			<true/>
+			<key>weight</key>
+			<real>1000</real>
+		</dict>
+		<key>^.*\.lproj/locversion.plist$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>1100</real>
+		</dict>
+		<key>^Base\.lproj/</key>
+		<dict>
+			<key>weight</key>
+			<real>1010</real>
+		</dict>
+		<key>^version.plist$</key>
+		<true/>
+	</dict>
+	<key>rules2</key>
+	<dict>
+		<key>.*\.dSYM($|/)</key>
+		<dict>
+			<key>weight</key>
+			<real>11</real>
+		</dict>
+		<key>^(.*/)?\.DS_Store$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>2000</real>
+		</dict>
+		<key>^.*</key>
+		<true/>
+		<key>^.*\.lproj/</key>
+		<dict>
+			<key>optional</key>
+			<true/>
+			<key>weight</key>
+			<real>1000</real>
+		</dict>
+		<key>^.*\.lproj/locversion.plist$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>1100</real>
+		</dict>
+		<key>^Base\.lproj/</key>
+		<dict>
+			<key>weight</key>
+			<real>1010</real>
+		</dict>
+		<key>^Info\.plist$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+		<key>^PkgInfo$</key>
+		<dict>
+			<key>omit</key>
+			<true/>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+		<key>^embedded\.provisionprofile$</key>
+		<dict>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+		<key>^version\.plist$</key>
+		<dict>
+			<key>weight</key>
+			<real>20</real>
+		</dict>
+	</dict>
+</dict>
+</plist>

BIN
ios/GravityEngineSDK.framework/_CodeSignature/CodeSignature


+ 14 - 0
ios/Resources/PrivacyInfo.xcprivacy

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>NSPrivacyTrackingDomains</key>
+	<array/>
+	<key>NSPrivacyAccessedAPITypes</key>
+	<array/>
+	<key>NSPrivacyCollectedDataTypes</key>
+	<array/>
+	<key>NSPrivacyTracking</key>
+	<false/>
+</dict>
+</plist>

+ 39 - 0
ios/gravity_engine.podspec

@@ -0,0 +1,39 @@
+#
+# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
+# Run `pod lib lint gravity_engine.podspec` to validate before publishing.
+#
+Pod::Spec.new do |s|
+  s.name             = 'gravity_engine'
+  s.version          = '0.0.1'
+  s.summary          = '引力引擎SDK插件'
+  s.description      = <<-DESC
+引力引擎SDK插件
+                       DESC
+  s.homepage         = 'http://example.com'
+  s.license          = { :file => '../LICENSE' }
+  s.author           = { 'Your Company' => 'email@example.com' }
+  s.source           = { :path => '.' }
+  s.source_files = 'Classes/**/*'
+  s.dependency 'Flutter'
+  s.platform = :ios, '12.0'
+
+  # 引入 GravityEngineSDK.framework指定其相对路径
+  s.vendored_frameworks = 'GravityEngineSDK.framework'
+  # 添加系统库依赖
+  s.frameworks = ['Security', 'SystemConfiguration', 'AppTrackingTransparency', 'AdSupport','AdServices']
+  # 对应 libz.tbd 和 libsqlite3.tbd
+  s.libraries = ['z', 'sqlite3']
+  s.xcconfig = {
+    'OTHER_LDFLAGS' => '-ObjC'
+  }
+
+  # Flutter.framework does not contain a i386 slice.
+  s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
+  s.swift_version = '5.0'
+
+  # If your plugin requires a privacy manifest, for example if it uses any
+  # required reason APIs, update the PrivacyInfo.xcprivacy file to describe your
+  # plugin's privacy impact, and then uncomment this line. For more information,
+  # see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
+  # s.resource_bundles = {'gravity_engine_privacy' => ['Resources/PrivacyInfo.xcprivacy']}
+end

+ 88 - 0
lib/gravity_engine.dart

@@ -0,0 +1,88 @@
+import 'gravity_engine_method_channel.dart';
+import 'gravity_engine_platform_interface.dart';
+
+class GravityEngine {
+  GravityEngine._();
+
+  static Future<bool> initialize(String appId, String accessToken,
+      String clientId, String channel, bool debug) {
+    return GravityEnginePlatform.instance
+        .initialize(appId, accessToken, clientId, channel, debug);
+  }
+
+  static Future<void> trackEvent(String eventName,
+      {Map<String, dynamic>? eventProperties}) {
+    return GravityEnginePlatform.instance
+        .trackEvent(eventName, eventProperties: eventProperties);
+  }
+
+  static Future<void> trackPay(String orderNo, String itemName, int amountCent,
+      String currency, PayType payType) {
+    return GravityEnginePlatform.instance
+        .trackPay(orderNo, itemName, amountCent, currency, payType);
+  }
+
+  static Future<void> trackAdLoadEvent(
+      String? adUnionType,
+      String? adPlacementId,
+      String? adSourceId,
+      String? adType,
+      String? adnType) {
+    return GravityEnginePlatform.instance.trackAdLoadEvent(
+        adUnionType, adPlacementId, adSourceId, adType, adnType);
+  }
+
+  static Future<void> trackAdShowEvent(
+      String? adUnionType,
+      String? adPlacementId,
+      String? adSourceId,
+      String? adType,
+      String? adnType,
+      double? ecpm) {
+    return GravityEnginePlatform.instance.trackAdShowEvent(
+        adUnionType, adPlacementId, adSourceId, adType, adnType, ecpm);
+  }
+
+  static Future<void> trackAdClickEvent(
+      String? adUnionType,
+      String? adPlacementId,
+      String? adSourceId,
+      String? adType,
+      String? adnType,
+      double? ecpm) {
+    return GravityEnginePlatform.instance.trackAdClickEvent(
+        adUnionType, adPlacementId, adSourceId, adType, adnType, ecpm);
+  }
+
+  static Future<void> trackAdPlayStartEvent(
+      String? adUnionType,
+      String? adPlacementId,
+      String? adSourceId,
+      String? adType,
+      String? adnType,
+      double? ecpm) {
+    return GravityEnginePlatform.instance.trackAdPlayStartEvent(
+        adUnionType, adPlacementId, adSourceId, adType, adnType, ecpm);
+  }
+
+  static Future<void> trackAdPlayEndEvent(
+      String? adUnionType,
+      String? adPlacementId,
+      String? adSourceId,
+      String? adType,
+      String? adnType,
+      double? ecpm,
+      int? duration,
+      bool? isPlayOver) {
+    return GravityEnginePlatform.instance.trackAdPlayEndEvent(adUnionType,
+        adPlacementId, adSourceId, adType, adnType, ecpm, duration, isPlayOver);
+  }
+
+  static Future<void> login(String clientId) {
+    return GravityEnginePlatform.instance.login(clientId);
+  }
+
+  static Future<void> logout() {
+    return GravityEnginePlatform.instance.logout();
+  }
+}

+ 189 - 0
lib/gravity_engine_method_channel.dart

@@ -0,0 +1,189 @@
+import 'dart:io';
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/services.dart';
+
+import 'gravity_engine_platform_interface.dart';
+
+/// An implementation of [GravityEnginePlatform] that uses method channels.
+class MethodChannelGravityEngine extends GravityEnginePlatform {
+  /// The method channel used to interact with the native platform.
+  @visibleForTesting
+  final methodChannel = const MethodChannel('gravity_engine');
+
+  /// Initializes the Gravity Engine SDK.
+  /// Returns `true` if the user is attributed, `false` otherwise.
+  @override
+  Future<bool> initialize(String appId, String accessToken, String clientId,
+      String channel, bool debug) async {
+    final result = await methodChannel.invokeMethod<bool>(
+      'initialize',
+      <String, dynamic>{
+        'appId': appId,
+        'accessToken': accessToken,
+        'debug': debug,
+        'clientId': clientId,
+        'channel': channel,
+      },
+    );
+    return result ?? false;
+  }
+
+  @override
+  Future<void> trackEvent(String eventName,
+      {Map<String, dynamic>? eventProperties}) async {
+    await methodChannel.invokeMethod<void>(
+      'track',
+      <String, dynamic>{
+        'eventId': eventName,
+        'eventParams': eventProperties,
+      },
+    );
+  }
+
+  @override
+  Future<void> trackPay(String orderNo, String itemName, int amountCent,
+      String currency, PayType payType) async {
+    await methodChannel.invokeMethod<void>(
+      'trackPay',
+      <String, dynamic>{
+        "orderNo": orderNo,
+        "itemName": itemName,
+        "amount": amountCent,
+        "currency": currency,
+        "payType": payType.name,
+      },
+    );
+  }
+
+  @override
+  Future<void> logout() async {
+    // if android
+    if (Platform.isAndroid) {
+      await methodChannel.invokeMethod<void>('logout');
+    }
+  }
+
+  @override
+  Future<void> login(String clientId) async {
+    // if android
+    if (Platform.isAndroid) {
+      await methodChannel.invokeMethod<void>(
+        'login',
+        <String, dynamic>{
+          'clientId': clientId,
+        },
+      );
+    }
+  }
+
+  @override
+  Future<void> trackAdLoadEvent(String? adUnionType, String? adPlacementId,
+      String? adSourceId, String? adType, String? adnType) {
+    return methodChannel.invokeMethod<void>(
+      'trackAdLoadEvent',
+      <String, dynamic>{
+        'adUnionType': adUnionType,
+        'adPlacementId': adPlacementId,
+        'adSourceId': adSourceId,
+        'adType': adType,
+        'adnType': adnType,
+      },
+    );
+  }
+
+  @override
+  Future<void> trackAdShowEvent(String? adUnionType, String? adPlacementId,
+      String? adSourceId, String? adType, String? adnType, double? ecpm) {
+    return methodChannel.invokeMethod<void>(
+      'trackAdShowEvent',
+      <String, dynamic>{
+        'adUnionType': adUnionType,
+        'adPlacementId': adPlacementId,
+        'adSourceId': adSourceId,
+        'adType': adType,
+        'adnType': adnType,
+        'ecpm': ecpm,
+      },
+    );
+  }
+
+  @override
+  Future<void> trackAdClickEvent(String? adUnionType, String? adPlacementId,
+      String? adSourceId, String? adType, String? adnType, double? ecpm) {
+    return methodChannel.invokeMethod<void>(
+      'trackAdClickEvent',
+      <String, dynamic>{
+        'adUnionType': adUnionType,
+        'adPlacementId': adPlacementId,
+        'adSourceId': adSourceId,
+        'adType': adType,
+        'adnType': adnType,
+        'ecpm': ecpm,
+      },
+    );
+  }
+
+  @override
+  Future<void> trackAdPlayStartEvent(String? adUnionType, String? adPlacementId,
+      String? adSourceId, String? adType, String? adnType, double? ecpm) {
+    return methodChannel.invokeMethod<void>(
+      'trackAdPlayStartEvent',
+      <String, dynamic>{
+        'adUnionType': adUnionType,
+        'adPlacementId': adPlacementId,
+        'adSourceId': adSourceId,
+        'adType': adType,
+        'adnType': adnType,
+        'ecpm': ecpm,
+      },
+    );
+  }
+
+  @override
+  Future<void> trackAdPlayEndEvent(
+      String? adUnionType,
+      String? adPlacementId,
+      String? adSourceId,
+      String? adType,
+      String? adnType,
+      double? ecpm,
+      int? duration,
+      bool? isPlayOver) {
+    return methodChannel.invokeMethod<void>(
+      'trackAdPlayEndEvent',
+      <String, dynamic>{
+        'adUnionType': adUnionType,
+        'adPlacementId': adPlacementId,
+        'adSourceId': adSourceId,
+        'adType': adType,
+        'adnType': adnType,
+        'ecpm': ecpm,
+        'duration': duration,
+        'isPlayOver': isPlayOver,
+      },
+    );
+  }
+}
+
+enum PayType {
+  alipay,
+  wechat,
+  apple,
+  unknown,
+}
+
+extension PayTypeExtension on PayType {
+  String get name {
+    switch (this) {
+      case PayType.alipay:
+        return "支付宝";
+      case PayType.wechat:
+        return "微信";
+      case PayType.apple:
+        return "苹果支付";
+      default:
+        return "未知";
+    }
+  }
+}

+ 81 - 0
lib/gravity_engine_platform_interface.dart

@@ -0,0 +1,81 @@
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
+
+import 'gravity_engine_method_channel.dart';
+
+abstract class GravityEnginePlatform extends PlatformInterface {
+  /// Constructs a GravityEnginePlatform.
+  GravityEnginePlatform() : super(token: _token);
+
+  static final Object _token = Object();
+
+  static GravityEnginePlatform _instance = MethodChannelGravityEngine();
+
+  /// The default instance of [GravityEnginePlatform] to use.
+  ///
+  /// Defaults to [MethodChannelGravityEngine].
+  static GravityEnginePlatform get instance => _instance;
+
+  /// Platform-specific implementations should set this with their own
+  /// platform-specific class that extends [GravityEnginePlatform] when
+  /// they register themselves.
+  static set instance(GravityEnginePlatform instance) {
+    PlatformInterface.verifyToken(instance, _token);
+    _instance = instance;
+  }
+
+  Future<bool> initialize(String appId, String accessToken, String clientId,
+      String channel, bool debug) {
+    throw UnimplementedError('initialize() has not been implemented.');
+  }
+
+  Future<void> trackEvent(String eventName,
+      {Map<String, dynamic>? eventProperties}) {
+    throw UnimplementedError('trackEvent() has not been implemented.');
+  }
+
+  Future<void> trackPay(String orderNo, String itemName, int amountCent,
+      String currency, PayType payType) {
+    throw UnimplementedError('trackPay() has not been implemented.');
+  }
+
+  Future<void> trackAdLoadEvent(String? adUnionType, String? adPlacementId,
+      String? adSourceId, String? adType, String? adnType) {
+    throw UnimplementedError('trackAdLoadEvent() has not been implemented.');
+  }
+
+  Future<void> trackAdShowEvent(String? adUnionType, String? adPlacementId,
+      String? adSourceId, String? adType, String? adnType, double? ecpm) {
+    throw UnimplementedError('trackAdShowEvent() has not been implemented.');
+  }
+
+  Future<void> trackAdClickEvent(String? adUnionType, String? adPlacementId,
+      String? adSourceId, String? adType, String? adnType, double? ecpm) {
+    throw UnimplementedError('trackAdClickEvent() has not been implemented.');
+  }
+
+  Future<void> trackAdPlayStartEvent(String? adUnionType, String? adPlacementId,
+      String? adSourceId, String? adType, String? adnType, double? ecpm) {
+    throw UnimplementedError(
+        'trackAdPlayStartEvent() has not been implemented.');
+  }
+
+  Future<void> trackAdPlayEndEvent(
+      String? adUnionType,
+      String? adPlacementId,
+      String? adSourceId,
+      String? adType,
+      String? adnType,
+      double? ecpm,
+      int? duration,
+      bool? isPlayOver) {
+    throw UnimplementedError('trackAdPlayEndEvent() has not been implemented.');
+  }
+
+  Future<void> login(String clientId) {
+    throw UnimplementedError('login() has not been implemented.');
+  }
+
+  Future<void> logout() {
+    throw UnimplementedError('logout() has not been implemented.');
+  }
+}

+ 72 - 0
pubspec.yaml

@@ -0,0 +1,72 @@
+name: gravity_engine
+description: "引力引擎SDK插件"
+version: 0.0.2
+homepage:
+
+environment:
+  sdk: ^3.5.0
+  flutter: '>=3.3.0'
+
+dependencies:
+  flutter:
+    sdk: flutter
+  plugin_platform_interface: ^2.0.2
+
+dev_dependencies:
+  flutter_test:
+    sdk: flutter
+  flutter_lints: ^4.0.0
+
+# For information on the generic Dart part of this file, see the
+# following page: https://dart.dev/tools/pub/pubspec
+
+# The following section is specific to Flutter packages.
+flutter:
+  # This section identifies this Flutter project as a plugin project.
+  # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
+  # which should be registered in the plugin registry. This is required for
+  # using method channels.
+  # The Android 'package' specifies package in which the registered class is.
+  # This is required for using method channels on Android.
+  # The 'ffiPlugin' specifies that native code should be built and bundled.
+  # This is required for using `dart:ffi`.
+  # All these are used by the tooling to maintain consistency when
+  # adding or updating assets for this project.
+  plugin:
+    platforms:
+      android:
+        package: com.atmob.gravity_engine
+        pluginClass: GravityEnginePlugin
+      ios:
+        pluginClass: GravityEnginePlugin
+
+  # To add assets to your plugin package, add an assets section, like this:
+  # assets:
+  #   - images/a_dot_burr.jpeg
+  #   - images/a_dot_ham.jpeg
+  #
+  # For details regarding assets in packages, see
+  # https://flutter.dev/to/asset-from-package
+  #
+  # An image asset can refer to one or more resolution-specific "variants", see
+  # https://flutter.dev/to/resolution-aware-images
+
+  # To add custom fonts to your plugin package, add a fonts section here,
+  # in this "flutter" section. Each entry in this list should have a
+  # "family" key with the font family name, and a "fonts" key with a
+  # list giving the asset and other descriptors for the font. For
+  # example:
+  # fonts:
+  #   - family: Schyler
+  #     fonts:
+  #       - asset: fonts/Schyler-Regular.ttf
+  #       - asset: fonts/Schyler-Italic.ttf
+  #         style: italic
+  #   - family: Trajan Pro
+  #     fonts:
+  #       - asset: fonts/TrajanPro.ttf
+  #       - asset: fonts/TrajanPro_Bold.ttf
+  #         weight: 700
+  #
+  # For details regarding fonts in packages, see
+  # https://flutter.dev/to/font-from-package