Browse Source

feat: 添加键盘埋点和asa上传

Destiny 5 months ago
parent
commit
896ece5d69

+ 22 - 0
ios/AiKeyboard/KeyboardViewController.swift

@@ -9,6 +9,7 @@ import UIKit
 import Lottie
 import Lottie
 import SnapKit
 import SnapKit
 import MarqueeLabel
 import MarqueeLabel
+import GravityEngineSDK
 
 
 enum KeyboardType: Int {
 enum KeyboardType: Int {
     case help     = 0  // 帮聊
     case help     = 0  // 帮聊
@@ -219,6 +220,7 @@ class KeyboardViewController: UIInputViewController {
             self.navigateToLogin()
             self.navigateToLogin()
         }
         }
         view.backBtnClosure = {
         view.backBtnClosure = {
+            GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.login_close)
             self.clearPopView()
             self.clearPopView()
             self.loginView.isHidden = true
             self.loginView.isHidden = true
             self.nowShowView?.isHidden = false
             self.nowShowView?.isHidden = false
@@ -234,6 +236,7 @@ class KeyboardViewController: UIInputViewController {
             self.navigateToMembership()
             self.navigateToMembership()
         }
         }
         view.backBtnClosure = {
         view.backBtnClosure = {
+            GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.vip_close)
             self.clearPopView()
             self.clearPopView()
             self.vipView.isHidden = true
             self.vipView.isHidden = true
             self.nowShowView?.isHidden = false
             self.nowShowView?.isHidden = false
@@ -565,6 +568,7 @@ extension KeyboardViewController: KeyboardMenuViewDelegate, KeyboardExchangeView
     // 亲密度按钮点击
     // 亲密度按钮点击
     @objc func heartBtnClickAction() {
     @objc func heartBtnClickAction() {
         
         
+        GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.initmacy_click)
         let url = URL(string: "com.qihuan.zhuiaijianpan:///intimacy")!
         let url = URL(string: "com.qihuan.zhuiaijianpan:///intimacy")!
         openURL(url)
         openURL(url)
     }
     }
@@ -586,12 +590,21 @@ extension KeyboardViewController: KeyboardMenuViewDelegate, KeyboardExchangeView
         
         
         KeyboardFunctionPopView.show(view: self.view, selectType: self.chooseType) { type in
         KeyboardFunctionPopView.show(view: self.view, selectType: self.chooseType) { type in
             self.chooseType = type
             self.chooseType = type
+            switch type {
+            case .help:
+                GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.mode_help)
+            case .teach:
+                GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.mode_teach)
+            case .prologue:
+                GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.mode_prologue)
+            }
         }
         }
     }
     }
     
     
     // 菜单按钮点击
     // 菜单按钮点击
     @objc func menuBtnClickAction() {
     @objc func menuBtnClickAction() {
         
         
+        GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.menu_click)
         clearPopView()
         clearPopView()
         self.menuView.isHidden = false
         self.menuView.isHidden = false
     }
     }
@@ -606,12 +619,14 @@ extension KeyboardViewController: KeyboardMenuViewDelegate, KeyboardExchangeView
     // 会员按钮点击
     // 会员按钮点击
     func vipBtnClickAction() {
     func vipBtnClickAction() {
         
         
+        GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.menu_vip)
         navigateToMembership()
         navigateToMembership()
     }
     }
     
     
     // 定制人设
     // 定制人设
     func diyBtnClickAction() {
     func diyBtnClickAction() {
         
         
+        GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.menu_diy)
         let url = URL(string: "com.qihuan.zhuiaijianpan:///character/custom")!
         let url = URL(string: "com.qihuan.zhuiaijianpan:///character/custom")!
         openURL(url)
         openURL(url)
     }
     }
@@ -619,18 +634,21 @@ extension KeyboardViewController: KeyboardMenuViewDelegate, KeyboardExchangeView
     // 人设市场
     // 人设市场
     func marketBtnClickAction() {
     func marketBtnClickAction() {
         
         
+        GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.menu_market)
         let url = URL(string: "com.qihuan.zhuiaijianpan:///character/market")!
         let url = URL(string: "com.qihuan.zhuiaijianpan:///character/market")!
         openURL(url)
         openURL(url)
     }
     }
     
     
     // 跳转到主应用的登录页面
     // 跳转到主应用的登录页面
     @objc func navigateToLogin() {
     @objc func navigateToLogin() {
+        GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.login_click)
         let url = URL(string: "com.qihuan.zhuiaijianpan:///login")!
         let url = URL(string: "com.qihuan.zhuiaijianpan:///login")!
         openURL(url)
         openURL(url)
     }
     }
 
 
     // 跳转到主应用的会员页面
     // 跳转到主应用的会员页面
     @objc func navigateToMembership() {
     @objc func navigateToMembership() {
+        GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.vip_click)
         let url = URL(string: "com.qihuan.zhuiaijianpan:///member")!
         let url = URL(string: "com.qihuan.zhuiaijianpan:///member")!
         openURL(url)
         openURL(url)
     }
     }
@@ -718,6 +736,7 @@ extension KeyboardViewController: KeyboardMenuViewDelegate, KeyboardExchangeView
             // 当为系统键盘时不需要调接口
             // 当为系统键盘时不需要调接口
             if selectKeyboard.type == "system" {
             if selectKeyboard.type == "system" {
                 
                 
+                GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.keyboard_system)
                 self.keyboardList = keyboardList
                 self.keyboardList = keyboardList
                 self.chooseKeyboard = selectKeyboard
                 self.chooseKeyboard = selectKeyboard
                 self.requestCharacterList()
                 self.requestCharacterList()
@@ -729,6 +748,7 @@ extension KeyboardViewController: KeyboardMenuViewDelegate, KeyboardExchangeView
                 
                 
                 requestChooseKeyboard(keyboardId: keyboardId) {
                 requestChooseKeyboard(keyboardId: keyboardId) {
                     
                     
+                    GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.keyborad_custom)
                     self.keyboardList = keyboardList
                     self.keyboardList = keyboardList
                     self.chooseKeyboard = selectKeyboard
                     self.chooseKeyboard = selectKeyboard
                     self.requestCharacterList()
                     self.requestCharacterList()
@@ -1114,6 +1134,7 @@ extension KeyboardViewController {
         
         
         self.clearPopView()
         self.clearPopView()
         self.loginView.isHidden = false
         self.loginView.isHidden = false
+        GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.login_show)
     }
     }
     
     
     // 弹出vip页面
     // 弹出vip页面
@@ -1121,6 +1142,7 @@ extension KeyboardViewController {
         
         
         self.clearPopView()
         self.clearPopView()
         self.vipView.isHidden = false
         self.vipView.isHidden = false
+        GravityEngineSDK.sharedInstance()?.track(KeyboardPoint.vip_show)
     }
     }
     
     
     // 关闭其他弹出页
     // 关闭其他弹出页

+ 44 - 0
ios/AiKeyboard/Marco/KeyboardPoint.swift

@@ -0,0 +1,44 @@
+//
+//  KeyboardPoint.swift
+//  Runner
+//
+//  Created by Destiny on 2025/6/18.
+//
+
+struct KeyboardPoint {
+    
+    // 模式选择-帮聊
+    static let mode_help = "za_05000"
+    // 模式选择-教你说
+    static let mode_teach = "za_05001"
+    // 模式选择-开场白
+    static let mode_prologue = "za_05002"
+    // 键盘选择-通用键盘
+    static let keyboard_system = "za_05003"
+    // 键盘选择-专属键盘
+    static let keyborad_custom = "za_05004"
+    // 登录弹窗-展示
+    static let login_show = "za_05005"
+    // 登录弹窗-点击【登录】
+    static let login_click = "za_05006"
+    // 登录弹窗-点击【关闭】
+    static let login_close = "za_05007"
+    // 解锁会员弹窗-展示
+    static let vip_show = "za_05008"
+    // 解锁会员弹窗-点击【登录】
+    static let vip_click = "za_05009"
+    // 解锁会员弹窗-点击【关闭】
+    static let vip_close = "za_05010"
+    // 设置入口-点击
+    static let menu_click = "za_05011"
+    // 设置入口-点击【定制人设】
+    static let menu_diy = "za_05012"
+    // 设置入口-点击【人设市场】
+    static let menu_market = "za_05013"
+    // 设置入口-点击【解锁会员】
+    static let menu_vip = "za_05014"
+    // 亲密度-点击
+    static let initmacy_click = "za_05015"
+    // 键盘-点击【发送】
+    static let send_click = "za_05016"
+}

+ 36 - 0
ios/AiKeyboard/Network/KeyboardApi.swift

@@ -9,6 +9,7 @@ import Foundation
 import UIKit
 import UIKit
 import AdSupport
 import AdSupport
 import AppTrackingTransparency
 import AppTrackingTransparency
+import GravityEngineSDK
 
 
 enum NetworkEnvironment {
 enum NetworkEnvironment {
     case local
     case local
@@ -118,6 +119,8 @@ struct KeyboardApi {
         if let authToken = KeyboardSharedDataManager.shared.getToken() {
         if let authToken = KeyboardSharedDataManager.shared.getToken() {
             KeyboardApi.updateAuthToken(authToken: authToken)
             KeyboardApi.updateAuthToken(authToken: authToken)
         }
         }
+        
+        initGravity()
     }
     }
     
     
     // 初始化idfa
     // 初始化idfa
@@ -135,9 +138,13 @@ struct KeyboardApi {
                         let idfa = ASIdentifierManager.shared().advertisingIdentifier
                         let idfa = ASIdentifierManager.shared().advertisingIdentifier
                         debugPrint("IDFA: \(idfa.uuidString)")
                         debugPrint("IDFA: \(idfa.uuidString)")
                         KeyboardApi.updateIDFA(idfa: idfa.uuidString)
                         KeyboardApi.updateIDFA(idfa: idfa.uuidString)
+                        
+                    
                     } else {
                     } else {
                         
                         
                         debugPrint("无法获取idfa")
                         debugPrint("无法获取idfa")
+                        
+                        initGravity()
                     }
                     }
                     
                     
                   
                   
@@ -150,12 +157,41 @@ struct KeyboardApi {
                     let idfa = ASIdentifierManager.shared().advertisingIdentifier
                     let idfa = ASIdentifierManager.shared().advertisingIdentifier
                     KeyboardApi.updateIDFA(idfa: idfa.uuidString)
                     KeyboardApi.updateIDFA(idfa: idfa.uuidString)
                     debugPrint("IDFA: \(idfa)")
                     debugPrint("IDFA: \(idfa)")
+                    
+                    initGravity()
                 } else {
                 } else {
                     debugPrint("用户拒绝广告追踪")
                     debugPrint("用户拒绝广告追踪")
+                    
+                    initGravity()
                 }
                 }
             }
             }
         }
         }
     }
     }
+    
+    static func initGravity() {
+        
+        let config = GEConfig();
+        config.appid = "21705269";
+        config.accessToken = "ulA57gz2zpioGukhyiQFkTEjfKS1aPxw";
+        config.debugMode = GravityEngineDebugMode.on;
+
+        GravityEngineSDK.start(with: config);
+        let instance = GravityEngineSDK.sharedInstance(withAppid: config.appid);
+
+        // 开启自动采集
+        instance?.enableAutoTrack(GravityEngineAutoTrackEventType.eventTypeAll);
+        
+        var clientId = KeyboardSharedDataManager.shared.getInitIDFV()
+        if let idfa = KeyboardSharedDataManager.shared.getInitIDFA() {
+            clientId = idfa
+        }
+        
+        instance?.initializeGravityEngine(withAsaEnable: true, withClientId: clientId ?? "", withCaid1: "", withCaid2: "", withSyncAttribution: true, withChannel: "Appstore", withSuccessCallback: { response in
+            print("gravity engine initialize success, response is", response)
+        }, withErrorCallback: { error in
+            print("gravity engine initialize failed, and error is", error)
+        })
+    }
 }
 }
 
 
 extension KeyboardApi {
 extension KeyboardApi {

+ 6 - 0
ios/Podfile

@@ -31,6 +31,10 @@ platform:ios, '13.0'
 
 
 target 'Runner' do
 target 'Runner' do
   use_frameworks!
   use_frameworks!
+  
+  pod 'Alamofire'
+  
+  pod 'SwiftyJSON'
 
 
   flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
   flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
   target 'RunnerTests' do
   target 'RunnerTests' do
@@ -59,6 +63,8 @@ target 'AiKeyboard' do
   
   
   pod 'MarqueeLabel'
   pod 'MarqueeLabel'
   
   
+  pod 'GravityEngineSDK'
+  
 end
 end
 
 
 post_install do |installer|
 post_install do |installer|

+ 10 - 1
ios/Podfile.lock

@@ -26,6 +26,7 @@ PODS:
     - Flutter
     - Flutter
   - gravity_engine (0.0.1):
   - gravity_engine (0.0.1):
     - Flutter
     - Flutter
+  - GravityEngineSDK (5.0.3)
   - in_app_purchase_storekit (0.0.1):
   - in_app_purchase_storekit (0.0.1):
     - Flutter
     - Flutter
     - FlutterMacOS
     - FlutterMacOS
@@ -78,6 +79,7 @@ PODS:
   - sqflite_darwin (0.0.4):
   - sqflite_darwin (0.0.4):
     - Flutter
     - Flutter
     - FlutterMacOS
     - FlutterMacOS
+  - SwiftyJSON (5.0.2)
   - Toast-Swift (5.1.1)
   - Toast-Swift (5.1.1)
   - url_launcher_ios (0.0.1):
   - url_launcher_ios (0.0.1):
     - Flutter
     - Flutter
@@ -99,6 +101,7 @@ PODS:
     - Flutter
     - Flutter
 
 
 DEPENDENCIES:
 DEPENDENCIES:
+  - Alamofire
   - app_settings (from `.symlinks/plugins/app_settings/ios`)
   - app_settings (from `.symlinks/plugins/app_settings/ios`)
   - app_tracking_transparency (from `.symlinks/plugins/app_tracking_transparency/ios`)
   - app_tracking_transparency (from `.symlinks/plugins/app_tracking_transparency/ios`)
   - apple_pay (from `.symlinks/plugins/apple_pay/ios`)
   - apple_pay (from `.symlinks/plugins/apple_pay/ios`)
@@ -109,6 +112,7 @@ DEPENDENCIES:
   - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
   - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
   - flutter_umeng (from `.symlinks/plugins/flutter_umeng/ios`)
   - flutter_umeng (from `.symlinks/plugins/flutter_umeng/ios`)
   - gravity_engine (from `.symlinks/plugins/gravity_engine/ios`)
   - gravity_engine (from `.symlinks/plugins/gravity_engine/ios`)
+  - GravityEngineSDK
   - in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/darwin`)
   - in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/darwin`)
   - jpush_flutter (from `.symlinks/plugins/jpush_flutter/ios`)
   - jpush_flutter (from `.symlinks/plugins/jpush_flutter/ios`)
   - just_audio (from `.symlinks/plugins/just_audio/darwin`)
   - just_audio (from `.symlinks/plugins/just_audio/darwin`)
@@ -127,6 +131,7 @@ DEPENDENCIES:
   - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
   - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
   - SnapKit (~> 5.0.0)
   - SnapKit (~> 5.0.0)
   - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
   - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
+  - SwiftyJSON
   - Toast-Swift
   - Toast-Swift
   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
   - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
   - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
@@ -138,6 +143,7 @@ SPEC REPOS:
   https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git:
   https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git:
     - Alamofire
     - Alamofire
     - Bugly
     - Bugly
+    - GravityEngineSDK
     - JCore
     - JCore
     - JPush
     - JPush
     - JXSegmentedView
     - JXSegmentedView
@@ -151,6 +157,7 @@ SPEC REPOS:
     - ObjectMapper
     - ObjectMapper
     - OrderedSet
     - OrderedSet
     - SnapKit
     - SnapKit
+    - SwiftyJSON
     - Toast-Swift
     - Toast-Swift
 
 
 EXTERNAL SOURCES:
 EXTERNAL SOURCES:
@@ -220,6 +227,7 @@ SPEC CHECKSUMS:
   flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
   flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4
   flutter_umeng: 9005e3f776ff69868f0d75fbb2f11b33fbafc850
   flutter_umeng: 9005e3f776ff69868f0d75fbb2f11b33fbafc850
   gravity_engine: 750c5f2424a042f334f1154ece41d916eb148d6a
   gravity_engine: 750c5f2424a042f334f1154ece41d916eb148d6a
+  GravityEngineSDK: 2b684749e3a29650bb85ecd5bc93a7119d3eacab
   in_app_purchase_storekit: a1ce04056e23eecc666b086040239da7619cd783
   in_app_purchase_storekit: a1ce04056e23eecc666b086040239da7619cd783
   JCore: 3effa468af29935edb53e6460ef81fd3c03ee1a8
   JCore: 3effa468af29935edb53e6460ef81fd3c03ee1a8
   JPush: fcd20c0b2d6d8206af63b8517fa2d11e0a83dc6b
   JPush: fcd20c0b2d6d8206af63b8517fa2d11e0a83dc6b
@@ -244,6 +252,7 @@ SPEC CHECKSUMS:
   sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440
   sign_in_with_apple: f3bf75217ea4c2c8b91823f225d70230119b8440
   SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb
   SnapKit: 97b92857e3df3a0c71833cce143274bf6ef8e5eb
   sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
   sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d
+  SwiftyJSON: f5b1bf1cd8dd53cd25887ac0eabcfd92301c6a5a
   Toast-Swift: 7a03a532afe3a560d4044bc7c237e2864d295173
   Toast-Swift: 7a03a532afe3a560d4044bc7c237e2864d295173
   url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
   url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
   video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
   video_player_avfoundation: 7c6c11d8470e1675df7397027218274b6d2360b3
@@ -251,6 +260,6 @@ SPEC CHECKSUMS:
   webview_flutter_wkwebview: a4af96a051138e28e29f60101d094683b9f82188
   webview_flutter_wkwebview: a4af96a051138e28e29f60101d094683b9f82188
   wechat_kit: b6853fe0933b9a60a008a508e709c14f6ed2dc70
   wechat_kit: b6853fe0933b9a60a008a508e709c14f6ed2dc70
 
 
-PODFILE CHECKSUM: da36ffc2916cc119cebb699a7d0027532f94ed44
+PODFILE CHECKSUM: b57bad7b1fb502e09b9fc63dc9348b9c6f981e28
 
 
 COCOAPODS: 1.16.2
 COCOAPODS: 1.16.2

+ 20 - 0
ios/Runner.xcodeproj/project.pbxproj

@@ -55,6 +55,9 @@
 		A21E1420BB362BC7E3EB4811 /* Pods_AiKeyboard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0B5EF92DE43959D6CF5B50A3 /* Pods_AiKeyboard.framework */; };
 		A21E1420BB362BC7E3EB4811 /* Pods_AiKeyboard.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0B5EF92DE43959D6CF5B50A3 /* Pods_AiKeyboard.framework */; };
 		FE05FA2E2DCE0CFC00CBA944 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = FE05FA2D2DCE0CFC00CBA944 /* Settings.bundle */; };
 		FE05FA2E2DCE0CFC00CBA944 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = FE05FA2D2DCE0CFC00CBA944 /* Settings.bundle */; };
 		FE8F000A2DCC4D6F00AA2562 /* FlutterMethodChannelManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE8F00092DCC4D6F00AA2562 /* FlutterMethodChannelManager.swift */; };
 		FE8F000A2DCC4D6F00AA2562 /* FlutterMethodChannelManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE8F00092DCC4D6F00AA2562 /* FlutterMethodChannelManager.swift */; };
+		FEC75C9F2E029F72009C29C3 /* AsaManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEC75C9E2E029F69009C29C3 /* AsaManager.swift */; };
+		FEC75CA22E02A544009C29C3 /* String+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEC75CA12E02A544009C29C3 /* String+Extension.swift */; };
+		FEC75CA42E02BFC3009C29C3 /* KeyboardPoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEC75CA32E02BFB4009C29C3 /* KeyboardPoint.swift */; };
 		FED899712DD1D044001808D5 /* KeyboardTipsPopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED899702DD1D044001808D5 /* KeyboardTipsPopView.swift */; };
 		FED899712DD1D044001808D5 /* KeyboardTipsPopView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED899702DD1D044001808D5 /* KeyboardTipsPopView.swift */; };
 		FED899792DD3446A001808D5 /* KeyboardGuideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED899782DD3446A001808D5 /* KeyboardGuideView.swift */; };
 		FED899792DD3446A001808D5 /* KeyboardGuideView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FED899782DD3446A001808D5 /* KeyboardGuideView.swift */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
@@ -168,6 +171,9 @@
 		FE05FA2D2DCE0CFC00CBA944 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
 		FE05FA2D2DCE0CFC00CBA944 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
 		FE8F00052DCC4A7B00AA2562 /* AiKeyboard.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AiKeyboard.entitlements; sourceTree = "<group>"; };
 		FE8F00052DCC4A7B00AA2562 /* AiKeyboard.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AiKeyboard.entitlements; sourceTree = "<group>"; };
 		FE8F00092DCC4D6F00AA2562 /* FlutterMethodChannelManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlutterMethodChannelManager.swift; sourceTree = "<group>"; };
 		FE8F00092DCC4D6F00AA2562 /* FlutterMethodChannelManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlutterMethodChannelManager.swift; sourceTree = "<group>"; };
+		FEC75C9E2E029F69009C29C3 /* AsaManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsaManager.swift; sourceTree = "<group>"; };
+		FEC75CA12E02A544009C29C3 /* String+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extension.swift"; sourceTree = "<group>"; };
+		FEC75CA32E02BFB4009C29C3 /* KeyboardPoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardPoint.swift; sourceTree = "<group>"; };
 		FED899702DD1D044001808D5 /* KeyboardTipsPopView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardTipsPopView.swift; sourceTree = "<group>"; };
 		FED899702DD1D044001808D5 /* KeyboardTipsPopView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardTipsPopView.swift; sourceTree = "<group>"; };
 		FED899782DD3446A001808D5 /* KeyboardGuideView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardGuideView.swift; sourceTree = "<group>"; };
 		FED899782DD3446A001808D5 /* KeyboardGuideView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardGuideView.swift; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
@@ -251,6 +257,7 @@
 		045829FF2DB8EBB900C1792D /* Marco */ = {
 		045829FF2DB8EBB900C1792D /* Marco */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				FEC75CA32E02BFB4009C29C3 /* KeyboardPoint.swift */,
 				04582A002DB8EBC700C1792D /* KeyboardConst.swift */,
 				04582A002DB8EBC700C1792D /* KeyboardConst.swift */,
 			);
 			);
 			path = Marco;
 			path = Marco;
@@ -396,6 +403,8 @@
 		97C146F01CF9000F007C117D /* Runner */ = {
 		97C146F01CF9000F007C117D /* Runner */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				FEC75CA02E02A4DC009C29C3 /* Category */,
+				FEC75C9E2E029F69009C29C3 /* AsaManager.swift */,
 				043D62352DCB0DF8005D12EE /* Runner.entitlements */,
 				043D62352DCB0DF8005D12EE /* Runner.entitlements */,
 				97C146FA1CF9000F007C117D /* Main.storyboard */,
 				97C146FA1CF9000F007C117D /* Main.storyboard */,
 				97C146FD1CF9000F007C117D /* Assets.xcassets */,
 				97C146FD1CF9000F007C117D /* Assets.xcassets */,
@@ -411,6 +420,14 @@
 			path = Runner;
 			path = Runner;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
 		};
 		};
+		FEC75CA02E02A4DC009C29C3 /* Category */ = {
+			isa = PBXGroup;
+			children = (
+				FEC75CA12E02A544009C29C3 /* String+Extension.swift */,
+			);
+			path = Category;
+			sourceTree = "<group>";
+		};
 /* End PBXGroup section */
 /* End PBXGroup section */
 
 
 /* Begin PBXNativeTarget section */
 /* Begin PBXNativeTarget section */
@@ -702,6 +719,7 @@
 				04582A402DBF8FD500C1792D /* KeyboardNetworkManager.swift in Sources */,
 				04582A402DBF8FD500C1792D /* KeyboardNetworkManager.swift in Sources */,
 				045829FE2DB8E6D300C1792D /* KeyboardCharacterCell.swift in Sources */,
 				045829FE2DB8E6D300C1792D /* KeyboardCharacterCell.swift in Sources */,
 				04582A4F2DC203DD00C1792D /* ChatModel.swift in Sources */,
 				04582A4F2DC203DD00C1792D /* ChatModel.swift in Sources */,
+				FEC75CA42E02BFC3009C29C3 /* KeyboardPoint.swift in Sources */,
 				04582A492DC07ED100C1792D /* UserModel.swift in Sources */,
 				04582A492DC07ED100C1792D /* UserModel.swift in Sources */,
 				04582A472DC07ECA00C1792D /* KeyboardModel.swift in Sources */,
 				04582A472DC07ECA00C1792D /* KeyboardModel.swift in Sources */,
 				04582A052DB8F26200C1792D /* UIView+Extension.swift in Sources */,
 				04582A052DB8F26200C1792D /* UIView+Extension.swift in Sources */,
@@ -741,7 +759,9 @@
 			files = (
 			files = (
 				043D62372DCB0E7A005D12EE /* KeyboardSharedDataManager.swift in Sources */,
 				043D62372DCB0E7A005D12EE /* KeyboardSharedDataManager.swift in Sources */,
 				74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
 				74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+				FEC75C9F2E029F72009C29C3 /* AsaManager.swift in Sources */,
 				1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
 				1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+				FEC75CA22E02A544009C29C3 /* String+Extension.swift in Sources */,
 				FE8F000A2DCC4D6F00AA2562 /* FlutterMethodChannelManager.swift in Sources */,
 				FE8F000A2DCC4D6F00AA2562 /* FlutterMethodChannelManager.swift in Sources */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;

+ 1 - 1
ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme

@@ -51,7 +51,7 @@
       </Testables>
       </Testables>
    </TestAction>
    </TestAction>
    <LaunchAction
    <LaunchAction
-      buildConfiguration = "Release"
+      buildConfiguration = "Debug"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
       launchStyle = "0"
       launchStyle = "0"

+ 152 - 0
ios/Runner/AsaManager.swift

@@ -0,0 +1,152 @@
+//
+//  AsaManager.swift
+//  Runner
+//
+//  Created by Destiny on 2025/6/18.
+//
+
+import Foundation
+import SwiftyJSON
+import Alamofire
+
+class AsaManager {
+    
+    static let shared = AsaManager()
+    
+    var hostUrl = "http://asafrontend.mokiwi.com/api"
+    
+    var orgId = "8941670"
+    
+    var sign = "c50d251bcb2eec9345844df434e3a09d&kiwi".md5
+    
+    func addAttributionReport(completion:@escaping ((Bool) -> ())) {
+        
+        if self.payDataNotExist() {
+            completion(false)
+            return
+        }
+        
+        var dict: [String: Any] = [String: Any]()
+        if let payLoad: [String: Any] = UserDefaults.standard.object(forKey: "ASA_ATTRIBUTION_PAYLOAD") as? [String : Any] {
+            
+            if let campaignId = payLoad["campaignId"] as? Int {
+//                if campaignId == 1234567890 {
+//                    completion(false)
+//                    return
+//                } else {
+                    dict["campaign_id"] = campaignId
+//                }
+            }
+            
+            if let adGroupId = payLoad["adGroupId"] as? Int {
+                dict["ad_group_id"] = adGroupId
+            }
+            
+            if let keywordId = payLoad["keywordId"] as? Int {
+                dict["keyword_id"] = keywordId
+            }
+            
+            let formatter = DateFormatter()
+            formatter.timeZone = TimeZone.autoupdatingCurrent
+            formatter.dateFormat = "yyyy-MM-dd"
+            let todayDate = formatter.string(from: Date())
+            dict["date"] = todayDate
+            dict["timezone"] = "ORTZ"
+        }
+        
+        let urlString = String(format: "%@/asabackendData/add?org_id=%@&sign=%@", hostUrl, orgId, sign )
+        
+        let headers = ["Content-Type": "application/json"]
+        
+        // 使用Alamofire发送POST请求
+        AF.request(urlString, method: .post, parameters: dict, encoding: JSONEncoding.default, headers: HTTPHeaders(headers)).response { response in
+            switch response.result {
+            case .success(let value):
+                let json = try? JSON(data: value ?? Data())
+                print("AppSaManager responseObject: \(String(describing: json))")
+                if json?["code"] == 10000 {
+                    print("AppSaManager asa用户 提交成功")
+                    completion(true)
+                } else {
+                    print("AppSaManager asa用户 提交失败")
+                    completion(false)
+                }
+            case .failure(let error):
+                print("AppSaManager asa用户 error: \(error)")
+                completion(false)
+            }
+        }
+    }
+    
+    func addEventAttribution(eventDict: [String: Any]) {
+        
+        if self.payDataNotExist() {
+            return
+        }
+        
+        var dict: [String: Any] = [String: Any]()
+        if let payLoad: [String: Any] = UserDefaults.standard.object(forKey:  "ASA_ATTRIBUTION_PAYLOAD") as? [String : Any] {
+        
+            if let campaignId = payLoad["campaignId"] as? Int {
+//                if campaignId == 1234567890 {
+//                    return
+//                } else {
+                    dict["campaign_id"] = campaignId
+//                }
+            }
+
+            if let adGroupId = payLoad["adGroupId"] as? Int {
+                dict["ad_group_id"] = adGroupId
+            }
+            
+            if let keywordId = payLoad["keywordId"] as? Int {
+                dict["keyword_id"] = keywordId
+            }
+            
+            let formatter = DateFormatter()
+            formatter.timeZone = TimeZone.autoupdatingCurrent
+            formatter.dateFormat = "yyyy-MM-dd"
+            let todayDate = formatter.string(from: Date())
+            dict["date"] = todayDate
+            dict["timezone"] = "ORTZ"
+            if let idfa = KeyboardSharedDataManager.shared.getInitIDFA() {
+                dict["unique_device"] = KeyboardSharedDataManager.shared.getInitIDFA()
+            } else {
+                dict["unique_device"] = KeyboardSharedDataManager.shared.getInitIDFV()
+            }
+        }
+        
+        for (key, value) in eventDict {
+            dict[key] = value
+        }
+        
+        let urlString = String(format: "%@/asabackendDataDetail/add?org_id=%@&sign=%@&debug=true", hostUrl, orgId, sign )
+        
+        let headers = ["Content-Type": "application/json"]
+        
+        let parameters = ["backend_data_detail": dict]
+        
+        // 使用Alamofire发送POST请求
+        AF.request(urlString, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: HTTPHeaders(headers)).response { response in
+            switch response.result {
+            case .success(let value):
+                let json = try? JSON(data: value ?? Data())
+                print("AppSaManager responseObject: \(String(describing: json))")
+                if json?["code"] == 10000 {
+                    print("AppSaManager asa用户 提交成功")
+                } else {
+                    print("AppSaManager asa用户 提交失败")
+                }
+            case .failure(let error):
+                print("AppSaManager asa用户 error: \(error)")
+            }
+        }
+    }
+    
+    func payDataNotExist() -> Bool {
+        guard UserDefaults.standard.object(forKey: "ASA_ATTRIBUTION_PAYLOAD") is [String: Any] else {
+            return true
+        }
+        return false
+    }
+}

+ 38 - 0
ios/Runner/Category/String+Extension.swift

@@ -0,0 +1,38 @@
+//
+//  String+Extension.swift
+//  Runner
+//
+//  Created by Destiny on 2025/6/18.
+//
+
+import Foundation
+import CommonCrypto
+
+extension String {
+    
+    /// 原生md5
+    public var md5: String {
+        guard let data = data(using: .utf8) else {
+            return self
+        }
+        var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH))
+        
+        #if swift(>=5.0)
+        
+        _ = data.withUnsafeBytes { (bytes: UnsafeRawBufferPointer) in
+            return CC_MD5(bytes.baseAddress, CC_LONG(data.count), &digest)
+        }
+        
+        #else
+        
+        _ = data.withUnsafeBytes { bytes in
+            return CC_MD5(bytes, CC_LONG(data.count), &digest)
+        }
+        
+        #endif
+        
+        return digest.map { String(format: "%02x", $0) }.joined()
+        
+    }
+    
+}

+ 87 - 0
ios/Runner/FlutterMethodChannelManager.swift

@@ -8,6 +8,7 @@
 import Flutter
 import Flutter
 import UIKit
 import UIKit
 import StoreKit
 import StoreKit
+import AdServices
 
 
 class FlutterMethodChannelManager: NSObject {
 class FlutterMethodChannelManager: NSObject {
     
     
@@ -17,6 +18,8 @@ class FlutterMethodChannelManager: NSObject {
     // 方法通道
     // 方法通道
     var keyboardChannel: FlutterMethodChannel?
     var keyboardChannel: FlutterMethodChannel?
     
     
+    var retryCount = 0
+    
     // 私有初始化方法
     // 私有初始化方法
     private override init() {
     private override init() {
         super.init()
         super.init()
@@ -87,6 +90,15 @@ class FlutterMethodChannelManager: NSObject {
                 } else {
                 } else {
                     result(FlutterError(code: "INVALID_ARGUMENTS", message: "无效的参数", details: nil))
                     result(FlutterError(code: "INVALID_ARGUMENTS", message: "无效的参数", details: nil))
                 }
                 }
+            case "initAttr":
+                self.initAttribution()
+            case "addASAPayReport":
+                if let args = call.arguments as? [String: Any],
+                   let price = args["price"] as? Float {
+                    AsaManager.shared.addEventAttribution(eventDict: ["event_name": "pay", "event_val": price])
+                } else {
+                    result(FlutterError(code: "INVALID_ARGUMENTS", message: "无效的参数", details: nil))
+                }
             default:
             default:
                 result(FlutterMethodNotImplemented)
                 result(FlutterMethodNotImplemented)
             }
             }
@@ -123,6 +135,81 @@ class FlutterMethodChannelManager: NSObject {
 
 
 extension FlutterMethodChannelManager {
 extension FlutterMethodChannelManager {
     
     
+    func initAttribution() {
+        
+        if #available(iOS 14.3, *) {
+            do {
+                let appleAttributionToken = try AAAttribution.attributionToken()
+                // 尝试获取归因信息
+                getASA(token: appleAttributionToken)
+            } catch let error {
+                print("Error fetching attribution token: \(error.localizedDescription)")
+            }
+        }
+    }
+    
+    // 开始获取归因结果
+    func getASA(token: String) {
+        
+        guard retryCount < 3 else { return }
+        
+        let configuration = URLSessionConfiguration.default
+        let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: nil)
+        let asaUrl = URL(string: "https://api-adservices.apple.com/api/v1/")!
+        
+        var request = URLRequest(url: asaUrl)
+        request.httpMethod = "POST"
+        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
+        request.httpBody = token.data(using: .utf8)
+        
+        let task = session.dataTask(with: request) { data, response, error in
+            if let error = error {
+                print("sendASAToken error = \(error)")
+                // 5秒后重试
+                DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
+                    self.getASA(token: token)
+                }
+                return
+            }
+            
+            guard let data = data, let payloadDic = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
+                print("sendASAToken error payload = nil")
+                // 5秒后重试
+                DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
+                    self.getASA(token: token)
+                }
+                return
+            }
+            
+            print("sendASAToken payload = \(payloadDic)")
+            
+            if let attribution = payloadDic["attribution"] {
+                UserDefaults.standard.set(payloadDic, forKey: "ASA_ATTRIBUTION_PAYLOAD")
+                UserDefaults.standard.synchronize()
+                
+                // 调用奇异果数据上报接口
+                let appSaManager = AsaManager.shared
+                appSaManager.addAttributionReport { isSuccess in
+                    print("asaReportWithCompletion = ", isSuccess)
+    
+                    if isSuccess {
+                        let isRegister = UserDefaults.standard.bool(forKey: "isRegisterKey")
+                        if !isRegister {
+                            AsaManager.shared.addEventAttribution(eventDict: ["event_name": "active", "event_val": 1])
+                            AsaManager.shared.addEventAttribution(eventDict: ["event_name": "register", "event_val": 1])
+                            UserDefaults.standard.setValue(true, forKey: "isRegisterKey")
+                        }
+                    }
+                }
+            }
+        }
+        task.resume()
+        retryCount += 1
+    }
+}
+
+extension FlutterMethodChannelManager {
+    
     private func checkProductDiscount(appleGoodId: String, completion: @escaping (Bool) -> Void) {
     private func checkProductDiscount(appleGoodId: String, completion: @escaping (Bool) -> Void) {
         
         
         if #available(iOS 15.0, *) {
         if #available(iOS 15.0, *) {

+ 12 - 0
lib/data/consts/constants.dart

@@ -59,6 +59,9 @@ class Constants {
 
 
   // 是否首次进入活动页
   // 是否首次进入活动页
   static const String isFirstIntoDiscount = 'isFirstIntoDiscount';
   static const String isFirstIntoDiscount = 'isFirstIntoDiscount';
+
+  // 首次支付成功
+  static const String isFirstPaySuccess = 'isFirstPaySuccess';
 }
 }
 
 
 String getBaseUrl() {
 String getBaseUrl() {
@@ -90,6 +93,15 @@ void setFirstIntoDiscount(bool isFirst) {
   KVUtil.putBool(Constants.isFirstIntoDiscount, isFirst);
   KVUtil.putBool(Constants.isFirstIntoDiscount, isFirst);
 }
 }
 
 
+bool isFirstPaySuccess() {
+  return KVUtil.getBool(Constants.isFirstPaySuccess, true);
+}
+
+void setFirstPaySuccess(bool isFirst) {
+  KVUtil.putBool(Constants.isFirstPaySuccess, isFirst);
+}
+
+
 bool isNotHWChannel() {
 bool isNotHWChannel() {
   String? channel = KVUtil.getString(
   String? channel = KVUtil.getString(
     Constants.appChanelName,
     Constants.appChanelName,

+ 5 - 0
lib/device/platform_ios_info.dart

@@ -2,6 +2,7 @@ import 'dart:io';
 
 
 import 'package:app_tracking_transparency/app_tracking_transparency.dart';
 import 'package:app_tracking_transparency/app_tracking_transparency.dart';
 import 'package:device_info_plus/device_info_plus.dart';
 import 'package:device_info_plus/device_info_plus.dart';
+import 'package:keyboard/utils/method_chanel_ios_util.dart';
 import '../widget/platform_util.dart';
 import '../widget/platform_util.dart';
 import 'atmob_platform_info.dart';
 import 'atmob_platform_info.dart';
 
 
@@ -22,10 +23,14 @@ class PlatformIosInfo {
         if (newStatus == TrackingStatus.authorized) {
         if (newStatus == TrackingStatus.authorized) {
           atmobPlatformInfo.setIdfa(
           atmobPlatformInfo.setIdfa(
               await AppTrackingTransparency.getAdvertisingIdentifier());
               await AppTrackingTransparency.getAdvertisingIdentifier());
+          MethodChanelIOSUtil.initAttr();
         }
         }
       } else if (status == TrackingStatus.authorized) {
       } else if (status == TrackingStatus.authorized) {
         atmobPlatformInfo
         atmobPlatformInfo
             .setIdfa(await AppTrackingTransparency.getAdvertisingIdentifier());
             .setIdfa(await AppTrackingTransparency.getAdvertisingIdentifier());
+        MethodChanelIOSUtil.initAttr();
+      } else {
+        MethodChanelIOSUtil.initAttr();
       }
       }
     }
     }
   }
   }

+ 0 - 1
lib/module/store/new_discount/new_discount_controller.dart

@@ -10,7 +10,6 @@ import 'package:injectable/injectable.dart';
 import 'package:keyboard/base/base_controller.dart';
 import 'package:keyboard/base/base_controller.dart';
 import 'package:keyboard/data/bean/character_info.dart';
 import 'package:keyboard/data/bean/character_info.dart';
 import 'package:keyboard/data/repository/config_repository.dart';
 import 'package:keyboard/data/repository/config_repository.dart';
-import 'package:keyboard/module/login/login_page.dart';
 import 'package:keyboard/module/store/new_discount/member_card_bean.dart';
 import 'package:keyboard/module/store/new_discount/member_card_bean.dart';
 import 'package:keyboard/utils/error_handler.dart';
 import 'package:keyboard/utils/error_handler.dart';
 import 'package:keyboard/utils/method_chanel_ios_util.dart';
 import 'package:keyboard/utils/method_chanel_ios_util.dart';

+ 111 - 110
lib/module/store/store_controller.dart

@@ -235,116 +235,117 @@ class StoreController extends BaseController implements PaymentStatusCallback {
   }
   }
 
 
   void clickPayNow() {
   void clickPayNow() {
-    EventHandler.report(EventId.event_02004);
-    if (selectedGoodsInfoItem == null) {
-      ToastUtil.show(StringName.memberPleaseChoiceGoods);
-      return;
-    }
-    if (selectedPayWay == null) {
-      ToastUtil.show(StringName.memberPleaseChoicePayment);
-      return;
-    }
-    if (!isAgree.value) {
-      MemberAgreementDialog.show(
-        btnConfirm: () {
-          isAgree.value = true;
-          clickPayNow();
-        },
-      );
-      return;
-    }
-    AtmobLog.d(tag, 'clickPayNow: ${selectedGoodsInfoItem!.toJson()}');
-    final buyGoods = selectedGoodsInfoItem!;
-    final buyPayWay = selectedPayWay!;
-
-    selectedGoodsInfoItem?.realAmount = selectedGoodsInfoItem?.amount;
-
-    if (selectedGoodsInfoItem?.discountPriceDesc != null && selectedGoodsInfoItem?.firstAmount != null) {
-      if (isDiscount.value) {
-        selectedGoodsInfoItem?.realAmount = selectedGoodsInfoItem?.firstAmount;
-      }
-    }
-
-    int goodsId = buyGoods.id;
-    int payPlatform = buyPayWay.payPlatform;
-    int payMethod = buyPayWay.payMethod;
-    int payWayType = getPayWayType(
-      payMethod: payMethod,
-      payPlatform: payPlatform,
-    );
-
-    LoadingDialog.show(StringName.payLoading);
-    storeRepository
-        .submitAndRequestPay(
-          goodsId: goodsId,
-          payPlatform: payPlatform,
-          payMethod: payMethod,
-        )
-        .then((response) {
-          if (payWayType == PayWayType.paymentWayWechat) {
-            _onWeChatPay(
-              response.outTradeNo,
-              response.wechatPayPrepayJson!,
-              payMethod,
-              buyGoods,
-              buyPayWay,
-            );
-          } else if (payWayType == PayWayType.paymentWayWechatScan) {
-            _onWechatScanPay(
-              response.outTradeNo,
-              response.wechatPayQrcodeUrl!,
-              buyPayWay,
-              buyGoods,
-            );
-          } else if (payWayType == PayWayType.paymentWayAlipay) {
-            _onAliPay(
-              response.outTradeNo,
-              response.alipayOrderString!,
-              payMethod,
-              buyGoods,
-              buyPayWay,
-            );
-          } else if (payWayType == PayWayType.paymentWayAlipayScan) {
-            _onAliScanPay(
-              response.outTradeNo,
-              response.alipayQrcodeHtml!,
-              buyPayWay,
-              buyGoods,
-            );
-          } else if (payWayType == PayWayType.paymentWayApple) {
-            _onApplePay(
-              response.outTradeNo,
-              response.appAccountToken ?? "",
-              buyPayWay,
-              buyGoods,
-            );
-          } else {
-            ToastUtil.show(StringName.payNotSupport);
-          }
-        })
-        .catchError((error) {
-          LoadingDialog.hide();
-          if (error is ServerErrorException) {
-            if (error.code == ErrorCode.payOrderError) {
-              refreshStoreData();
-              ToastUtil.show(error.message);
-            } else if (error.code == ErrorCode.noLoginError) {
-              ToastUtil.show(StringName.accountNoLogin);
-              LoginDialog.show();
-            } else {
-              ToastUtil.show(error.message);
-              paymentFail();
-            }
-          } else {
-            ToastUtil.show(StringName.memberPaymentFailed);
-            paymentFail();
-          }
-        })
-        .whenComplete(() {
-          if (PlatformUtil.isAndroid) {
-            LoadingDialog.hide();
-          }
-        });
+    MethodChanelIOSUtil.addASAPayReport(880.0);
+    // EventHandler.report(EventId.event_02004);
+    // if (selectedGoodsInfoItem == null) {
+    //   ToastUtil.show(StringName.memberPleaseChoiceGoods);
+    //   return;
+    // }
+    // if (selectedPayWay == null) {
+    //   ToastUtil.show(StringName.memberPleaseChoicePayment);
+    //   return;
+    // }
+    // if (!isAgree.value) {
+    //   MemberAgreementDialog.show(
+    //     btnConfirm: () {
+    //       isAgree.value = true;
+    //       clickPayNow();
+    //     },
+    //   );
+    //   return;
+    // }
+    // AtmobLog.d(tag, 'clickPayNow: ${selectedGoodsInfoItem!.toJson()}');
+    // final buyGoods = selectedGoodsInfoItem!;
+    // final buyPayWay = selectedPayWay!;
+    //
+    // selectedGoodsInfoItem?.realAmount = selectedGoodsInfoItem?.amount;
+    //
+    // if (selectedGoodsInfoItem?.discountPriceDesc != null && selectedGoodsInfoItem?.firstAmount != null) {
+    //   if (isDiscount.value) {
+    //     selectedGoodsInfoItem?.realAmount = selectedGoodsInfoItem?.firstAmount;
+    //   }
+    // }
+    //
+    // int goodsId = buyGoods.id;
+    // int payPlatform = buyPayWay.payPlatform;
+    // int payMethod = buyPayWay.payMethod;
+    // int payWayType = getPayWayType(
+    //   payMethod: payMethod,
+    //   payPlatform: payPlatform,
+    // );
+    //
+    // LoadingDialog.show(StringName.payLoading);
+    // storeRepository
+    //     .submitAndRequestPay(
+    //       goodsId: goodsId,
+    //       payPlatform: payPlatform,
+    //       payMethod: payMethod,
+    //     )
+    //     .then((response) {
+    //       if (payWayType == PayWayType.paymentWayWechat) {
+    //         _onWeChatPay(
+    //           response.outTradeNo,
+    //           response.wechatPayPrepayJson!,
+    //           payMethod,
+    //           buyGoods,
+    //           buyPayWay,
+    //         );
+    //       } else if (payWayType == PayWayType.paymentWayWechatScan) {
+    //         _onWechatScanPay(
+    //           response.outTradeNo,
+    //           response.wechatPayQrcodeUrl!,
+    //           buyPayWay,
+    //           buyGoods,
+    //         );
+    //       } else if (payWayType == PayWayType.paymentWayAlipay) {
+    //         _onAliPay(
+    //           response.outTradeNo,
+    //           response.alipayOrderString!,
+    //           payMethod,
+    //           buyGoods,
+    //           buyPayWay,
+    //         );
+    //       } else if (payWayType == PayWayType.paymentWayAlipayScan) {
+    //         _onAliScanPay(
+    //           response.outTradeNo,
+    //           response.alipayQrcodeHtml!,
+    //           buyPayWay,
+    //           buyGoods,
+    //         );
+    //       } else if (payWayType == PayWayType.paymentWayApple) {
+    //         _onApplePay(
+    //           response.outTradeNo,
+    //           response.appAccountToken ?? "",
+    //           buyPayWay,
+    //           buyGoods,
+    //         );
+    //       } else {
+    //         ToastUtil.show(StringName.payNotSupport);
+    //       }
+    //     })
+    //     .catchError((error) {
+    //       LoadingDialog.hide();
+    //       if (error is ServerErrorException) {
+    //         if (error.code == ErrorCode.payOrderError) {
+    //           refreshStoreData();
+    //           ToastUtil.show(error.message);
+    //         } else if (error.code == ErrorCode.noLoginError) {
+    //           ToastUtil.show(StringName.accountNoLogin);
+    //           LoginDialog.show();
+    //         } else {
+    //           ToastUtil.show(error.message);
+    //           paymentFail();
+    //         }
+    //       } else {
+    //         ToastUtil.show(StringName.memberPaymentFailed);
+    //         paymentFail();
+    //       }
+    //     })
+    //     .whenComplete(() {
+    //       if (PlatformUtil.isAndroid) {
+    //         LoadingDialog.hide();
+    //       }
+    //     });
   }
   }
 
 
   void paymentFail() {
   void paymentFail() {

+ 15 - 0
lib/utils/method_chanel_ios_util.dart

@@ -137,4 +137,19 @@ class MethodChanelIOSUtil {
       return false; // 发生错误时返回 false
       return false; // 发生错误时返回 false
     }
     }
   }
   }
+
+  static Future<void> initAttr() async {
+    // 通知iOS键盘扩展
+    if (PlatformUtil.isIOS) {
+      _channel.invokeMethod('initAttr');
+    }
+  }
+
+  // 保存idfa到ios端
+  static Future<void> addASAPayReport(double price) async {
+    // 通知iOS键盘扩展
+    if (PlatformUtil.isIOS) {
+      _channel.invokeMethod('addASAPayReport', {'price': price});
+    }
+  }
 }
 }

+ 9 - 0
lib/utils/payment_status_manager.dart

@@ -1,8 +1,12 @@
+import 'dart:ffi';
+
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:injectable/injectable.dart';
 import 'package:injectable/injectable.dart';
 import 'package:keyboard/data/bean/goods_info.dart';
 import 'package:keyboard/data/bean/goods_info.dart';
 import 'package:keyboard/data/bean/pay_way_info.dart';
 import 'package:keyboard/data/bean/pay_way_info.dart';
+import 'package:keyboard/data/consts/constants.dart';
 import 'package:keyboard/data/repository/store_repository.dart';
 import 'package:keyboard/data/repository/store_repository.dart';
+import 'package:keyboard/utils/method_chanel_ios_util.dart';
 
 
 import 'package:synchronized/synchronized.dart';
 import 'package:synchronized/synchronized.dart';
 
 
@@ -86,6 +90,11 @@ class PaymentStatusManager {
   void reportPaySuccess(
   void reportPaySuccess(
       int price, String orderId, String itemName, int paymentWay) {
       int price, String orderId, String itemName, int paymentWay) {
     EventHandler.reportPay(price, orderId, itemName, paymentWay);
     EventHandler.reportPay(price, orderId, itemName, paymentWay);
+    if (isFirstPaySuccess()) {
+      double newPrice = price.toDouble() / 100;
+      MethodChanelIOSUtil.addASAPayReport(newPrice);
+      setFirstPaySuccess(false);
+    }
   }
   }
 
 
   void checkPaymentStatus(
   void checkPaymentStatus(

+ 2 - 2
pubspec.lock

@@ -903,10 +903,10 @@ packages:
     dependency: "direct dev"
     dependency: "direct dev"
     description:
     description:
       name: json_serializable
       name: json_serializable
-      sha256: "81f04dee10969f89f604e1249382d46b97a1ccad53872875369622b5bfc9e58a"
+      sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c
       url: "https://pub.dev"
       url: "https://pub.dev"
     source: hosted
     source: hosted
-    version: "6.9.4"
+    version: "6.9.5"
   just_audio:
   just_audio:
     dependency: transitive
     dependency: transitive
     description:
     description:

+ 1 - 1
pubspec.yaml

@@ -3,7 +3,7 @@ description: "A new Flutter project."
 
 
 publish_to: 'none' # Remove this line if you wish to publish to pub.dev
 publish_to: 'none' # Remove this line if you wish to publish to pub.dev
 
 
-version: 1.1.3+17
+version: 1.1.5+19
 
 
 environment:
 environment:
   sdk: ^3.7.0
   sdk: ^3.7.0