diff --git a/Example/SensorsDataSwift/AppDelegate.swift b/Example/SensorsDataSwift/AppDelegate.swift index 315dc9b6..a564f609 100644 --- a/Example/SensorsDataSwift/AppDelegate.swift +++ b/Example/SensorsDataSwift/AppDelegate.swift @@ -34,10 +34,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate { let options = SAConfigOptions(serverURL: "http://sdk-test.cloud.sensorsdata.cn:8006/sa?project=default&token=95c73ae661f85aa0", launchOptions: launchOptions) options.maxCacheSize = 10000; options.autoTrackEventType = [.eventTypeAppClick,.eventTypeAppStart,.eventTypeAppEnd,.eventTypeAppViewScreen] + options.enableVisualizedAutoTrack = true + options.enableHeatMap = true SensorsAnalyticsSDK.start(configOptions: options) SensorsAnalyticsSDK.sharedInstance()?.setFlushNetworkPolicy(SensorsAnalyticsNetworkType.typeALL) - SensorsAnalyticsSDK.sharedInstance()?.enableHeatMap() let dict: Dictionary = ["key": "value", "key1": "value1"] SensorsAnalyticsSDK.sharedInstance()?.track("testEvent", withProperties: dict) diff --git a/SensorsAnalyticsSDK.podspec b/SensorsAnalyticsSDK.podspec index d91489ff..44f911a1 100644 --- a/SensorsAnalyticsSDK.podspec +++ b/SensorsAnalyticsSDK.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "SensorsAnalyticsSDK" - s.version = "3.1.9" + s.version = "4.0.0" s.summary = "The official iOS SDK of Sensors Analytics." s.homepage = "http://www.sensorsdata.cn" s.source = { :git => 'https://github.com/sensorsdata/sa-sdk-ios.git', :tag => "v#{s.version}" } @@ -13,14 +13,25 @@ Pod::Spec.new do |s| s.libraries = 'icucore', 'sqlite3', 'z' - s.subspec 'Common' do |c| + s.subspec 'Base' do |b| core_dir = "SensorsAnalyticsSDK/Core/" - c.source_files = core_dir + "**/*.{h,m}" - c.public_header_files = core_dir + "SensorsAnalyticsSDK.h", core_dir + "SensorsAnalyticsSDK+Public.h", core_dir + "SAAppExtensionDataManager.h", core_dir + "SASecurityPolicy.h", core_dir + "SAConfigOptions.h", core_dir + "SAConstants.h" - c.ios.source_files = "SensorsAnalyticsSDK/RemoteConfig/**/*.{h,m}", "SensorsAnalyticsSDK/ChannelMatch/**/*.{h,m}", "SensorsAnalyticsSDK/Encrypt/**/*.{h,m}", "SensorsAnalyticsSDK/Deeplink/**/*.{h,m}", "SensorsAnalyticsSDK/DebugMode/**/*.{h,m}" - c.ios.public_header_files = "SensorsAnalyticsSDK/Encrypt/SAConfigOptions+Encrypt.h", "SensorsAnalyticsSDK/Encrypt/SAEncryptProtocol.h", "SensorsAnalyticsSDK/Encrypt/SASecretKey.h", "SensorsAnalyticsSDK/ChannelMatch/SensorsAnalyticsSDK+SAChannelMatch.h" - c.ios.resource = 'SensorsAnalyticsSDK/SensorsAnalyticsSDK.bundle' - c.ios.frameworks = 'CoreTelephony' + b.source_files = core_dir + "**/*.{h,m}" + b.exclude_files = core_dir + "SAAlertController.h", core_dir + "SAAlertController.m" + b.public_header_files = core_dir + "SensorsAnalyticsSDK.h", core_dir + "SensorsAnalyticsSDK+Public.h", core_dir + "SAAppExtensionDataManager.h", core_dir + "SASecurityPolicy.h", core_dir + "SAConfigOptions.h", core_dir + "SAConstants.h" + b.ios.resource = 'SensorsAnalyticsSDK/SensorsAnalyticsSDK.bundle' + b.ios.frameworks = 'CoreTelephony' + end + + s.subspec 'Extension' do |e| + e.dependency 'SensorsAnalyticsSDK/Base' + end + + s.subspec 'Common' do |c| + c.dependency 'SensorsAnalyticsSDK/Extension' + c.public_header_files = 'SensorsAnalyticsSDK/JSBridge/SensorsAnalyticsSDK+JavaScriptBridge.h' + c.source_files = 'SensorsAnalyticsSDK/Core/SAAlertController.{h,m}', 'SensorsAnalyticsSDK/JSBridge/**/*.{h,m}' + c.ios.source_files = 'SensorsAnalyticsSDK/RemoteConfig/**/*.{h,m}', 'SensorsAnalyticsSDK/ChannelMatch/**/*.{h,m}', 'SensorsAnalyticsSDK/Encrypt/**/*.{h,m}', 'SensorsAnalyticsSDK/Deeplink/**/*.{h,m}', 'SensorsAnalyticsSDK/DebugMode/**/*.{h,m}', 'SensorsAnalyticsSDK/Core/SAAlertController.h' + c.ios.public_header_files = 'SensorsAnalyticsSDK/{Encrypt,RemoteConfig,ChannelMatch,Deeplink,DebugMode}/{SAConfigOptions,SensorsAnalyticsSDK}+*.h', 'SensorsAnalyticsSDK/Encrypt/SAEncryptProtocol.h', 'SensorsAnalyticsSDK/Encrypt/SASecretKey.h' end s.subspec 'Core' do |c| @@ -41,7 +52,7 @@ Pod::Spec.new do |s| g.ios.deployment_target = '8.0' g.dependency 'SensorsAnalyticsSDK/Common' g.source_files = "SensorsAnalyticsSDK/AutoTrack/**/*.{h,m}" - g.public_header_files = 'SensorsAnalyticsSDK/AutoTrack/SensorsAnalyticsSDK+SAAutoTrack.h' + g.public_header_files = 'SensorsAnalyticsSDK/AutoTrack/SensorsAnalyticsSDK+SAAutoTrack.h', 'SensorsAnalyticsSDK/AutoTrack/SAConfigOptions+AutoTrack.h' g.frameworks = 'UIKit' end @@ -50,7 +61,7 @@ Pod::Spec.new do |s| f.ios.deployment_target = '8.0' f.dependency 'SensorsAnalyticsSDK/AutoTrack' f.source_files = "SensorsAnalyticsSDK/Visualized/**/*.{h,m}" - f.public_header_files = 'SensorsAnalyticsSDK/Visualized/SensorsAnalyticsSDK+Visualized.h' + f.public_header_files = 'SensorsAnalyticsSDK/Visualized/SensorsAnalyticsSDK+Visualized.h', 'SensorsAnalyticsSDK/Visualized/SAConfigOptions+Visualized.h' end # 开启 GPS 定位采集 @@ -59,7 +70,7 @@ Pod::Spec.new do |s| f.frameworks = 'CoreLocation' f.dependency 'SensorsAnalyticsSDK/Core' f.source_files = "SensorsAnalyticsSDK/Location/**/*.{h,m}" - f.private_header_files = 'SensorsAnalyticsSDK/Location/**/*.h' + f.public_header_files = 'SensorsAnalyticsSDK/Location/SensorsAnalyticsSDK+Location.h' end # 开启设备方向采集 @@ -67,7 +78,7 @@ Pod::Spec.new do |s| f.ios.deployment_target = '8.0' f.dependency 'SensorsAnalyticsSDK/Core' f.source_files = 'SensorsAnalyticsSDK/DeviceOrientation/**/*.{h,m}' - f.private_header_files = 'SensorsAnalyticsSDK/DeviceOrientation/**/*.h' + f.public_header_files = 'SensorsAnalyticsSDK/DeviceOrientation/SensorsAnalyticsSDK+DeviceOrientation.h' f.frameworks = 'CoreMotion' end @@ -76,7 +87,7 @@ Pod::Spec.new do |s| f.ios.deployment_target = '8.0' f.dependency 'SensorsAnalyticsSDK/Core' f.source_files = "SensorsAnalyticsSDK/AppPush/**/*.{h,m}" - f.private_header_files = 'SensorsAnalyticsSDK/AppPush/**/*.h' + f.public_header_files = 'SensorsAnalyticsSDK/AppPush/SAConfigOptions+AppPush.h' end # 使用崩溃事件采集 @@ -84,7 +95,7 @@ Pod::Spec.new do |s| e.ios.deployment_target = '8.0' e.dependency 'SensorsAnalyticsSDK/Common' e.source_files = "SensorsAnalyticsSDK/Exception/**/*.{h,m}" - e.private_header_files = 'SensorsAnalyticsSDK/Exception/**/*.h' + e.public_header_files = 'SensorsAnalyticsSDK/Exception/SAConfigOptions+Exception.h' end # 基于 UA,使用 UIWebView 或者 WKWebView 进行打通 diff --git a/SensorsAnalyticsSDK.xcodeproj/project.pbxproj b/SensorsAnalyticsSDK.xcodeproj/project.pbxproj index cf6e1fad..61ea5be7 100644 --- a/SensorsAnalyticsSDK.xcodeproj/project.pbxproj +++ b/SensorsAnalyticsSDK.xcodeproj/project.pbxproj @@ -151,10 +151,6 @@ 881A41A1253D7B4F00854F69 /* SAAppExtensionDataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 881A40F5253D7B4F00854F69 /* SAAppExtensionDataManager.m */; }; 881A41A2253D7B4F00854F69 /* SAModuleManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 881A40F6253D7B4F00854F69 /* SAModuleManager.h */; }; 881A41A8253D7B4F00854F69 /* SAFileStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 881A40FD253D7B4F00854F69 /* SAFileStore.h */; }; - 881A41A9253D7B4F00854F69 /* WKWebView+SABridge.h in Headers */ = {isa = PBXBuildFile; fileRef = 881A40FF253D7B4F00854F69 /* WKWebView+SABridge.h */; }; - 881A41AA253D7B4F00854F69 /* SAJavaScriptBridgeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 881A4100253D7B4F00854F69 /* SAJavaScriptBridgeManager.m */; }; - 881A41AB253D7B4F00854F69 /* WKWebView+SABridge.m in Sources */ = {isa = PBXBuildFile; fileRef = 881A4101253D7B4F00854F69 /* WKWebView+SABridge.m */; }; - 881A41AC253D7B4F00854F69 /* SAJavaScriptBridgeManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 881A4102253D7B4F00854F69 /* SAJavaScriptBridgeManager.h */; }; 881A41E4253D7B5000854F69 /* SAKeyChainItemWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 881A413D253D7B4F00854F69 /* SAKeyChainItemWrapper.m */; }; 881A41F1253D7B5000854F69 /* SensorsAnalyticsSDK.h in Headers */ = {isa = PBXBuildFile; fileRef = 881A414B253D7B4F00854F69 /* SensorsAnalyticsSDK.h */; settings = {ATTRIBUTES = (Public, ); }; }; 881A41F2253D7B5000854F69 /* SAModuleProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 881A414C253D7B4F00854F69 /* SAModuleProtocol.h */; }; @@ -267,11 +263,20 @@ CB6EBAF422855222003CFBA8 /* ca.cer1 in Resources */ = {isa = PBXBuildFile; fileRef = CB6EBAF022855222003CFBA8 /* ca.cer1 */; }; CB6EBAF522855222003CFBA8 /* ca.der.cer in Resources */ = {isa = PBXBuildFile; fileRef = CB6EBAF122855222003CFBA8 /* ca.der.cer */; }; CB6EBAF622855222003CFBA8 /* SANetworkTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CB6EBAF222855222003CFBA8 /* SANetworkTests.m */; }; + F211742126E9A72C00D65E19 /* SAApplication.h in Headers */ = {isa = PBXBuildFile; fileRef = F211741F26E9A72B00D65E19 /* SAApplication.h */; }; + F211742226E9A72C00D65E19 /* SAApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = F211742026E9A72B00D65E19 /* SAApplication.m */; }; F214CE58249A07DF00A2633D /* SADatabaseUnitTest.m in Sources */ = {isa = PBXBuildFile; fileRef = F214CE57249A07DF00A2633D /* SADatabaseUnitTest.m */; }; F22E1B1B26A55C8A0033A748 /* SAAppPageLeaveTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = F22E1B1926A55C8A0033A748 /* SAAppPageLeaveTracker.h */; }; F22E1B1C26A55C8A0033A748 /* SAAppPageLeaveTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = F22E1B1A26A55C8A0033A748 /* SAAppPageLeaveTracker.m */; }; + F23CA0052701715E002EEACA /* WKWebView+SABridge.h in Headers */ = {isa = PBXBuildFile; fileRef = F23C9FFE2701715E002EEACA /* WKWebView+SABridge.h */; }; + F23CA0072701715E002EEACA /* SAJavaScriptBridgeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F23CA0002701715E002EEACA /* SAJavaScriptBridgeManager.m */; }; + F23CA0082701715E002EEACA /* SensorsAnalyticsSDK+JavaScriptBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = F23CA0012701715E002EEACA /* SensorsAnalyticsSDK+JavaScriptBridge.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F23CA0092701715E002EEACA /* WKWebView+SABridge.m in Sources */ = {isa = PBXBuildFile; fileRef = F23CA0022701715E002EEACA /* WKWebView+SABridge.m */; }; + F23CA00A2701715E002EEACA /* SAJavaScriptBridgeManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F23CA0032701715E002EEACA /* SAJavaScriptBridgeManager.h */; }; F244AE3C26B170F000D8C60B /* UIViewController+SAPageView.h in Headers */ = {isa = PBXBuildFile; fileRef = F244AE3A26B170F000D8C60B /* UIViewController+SAPageView.h */; }; F244AE3D26B170F000D8C60B /* UIViewController+SAPageView.m in Sources */ = {isa = PBXBuildFile; fileRef = F244AE3B26B170F000D8C60B /* UIViewController+SAPageView.m */; }; + F26FDDD8270312C400E1DF32 /* SAConfigOptions+AppPush.h in Headers */ = {isa = PBXBuildFile; fileRef = F26FDDD7270312C300E1DF32 /* SAConfigOptions+AppPush.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F26FDDDA2703130700E1DF32 /* SAConfigOptions+Exception.h in Headers */ = {isa = PBXBuildFile; fileRef = F26FDDD92703130700E1DF32 /* SAConfigOptions+Exception.h */; settings = {ATTRIBUTES = (Public, ); }; }; F277F5BF25CF9A43009B5CE6 /* SAApplicationDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = F277F5B125CF9A43009B5CE6 /* SAApplicationDelegateProxy.m */; }; F277F5C025CF9A43009B5CE6 /* SAUNUserNotificationCenterDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = F277F5B225CF9A43009B5CE6 /* SAUNUserNotificationCenterDelegateProxy.h */; }; F277F5C125CF9A43009B5CE6 /* SANotificationUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = F277F5B325CF9A43009B5CE6 /* SANotificationUtil.m */; }; @@ -286,6 +291,15 @@ F277F5CB25CF9A43009B5CE6 /* SAAppPushConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = F277F5BD25CF9A43009B5CE6 /* SAAppPushConstants.m */; }; F277F5E325CFCE56009B5CE6 /* NSObject+DelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = F277F5E125CFCE56009B5CE6 /* NSObject+DelegateProxy.m */; }; F277F5E425CFCE56009B5CE6 /* NSObject+DelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = F277F5E225CFCE56009B5CE6 /* NSObject+DelegateProxy.h */; }; + F2CFD14726EB04A8007A9253 /* SAConfigOptions+RemoteConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = F2CFD14526EB04A8007A9253 /* SAConfigOptions+RemoteConfig.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F2E4AB9D26EC86C800BA7F01 /* SensorsAnalyticsSDK+Location.h in Headers */ = {isa = PBXBuildFile; fileRef = F2E4AB9B26EC86C800BA7F01 /* SensorsAnalyticsSDK+Location.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F2E4AB9E26EC86C800BA7F01 /* SensorsAnalyticsSDK+Location.m in Sources */ = {isa = PBXBuildFile; fileRef = F2E4AB9C26EC86C800BA7F01 /* SensorsAnalyticsSDK+Location.m */; }; + F2E4ABA126ECAA8600BA7F01 /* SensorsAnalyticsSDK+DeviceOrientation.h in Headers */ = {isa = PBXBuildFile; fileRef = F2E4AB9F26ECAA8600BA7F01 /* SensorsAnalyticsSDK+DeviceOrientation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F2E4ABA226ECAA8600BA7F01 /* SensorsAnalyticsSDK+DeviceOrientation.m in Sources */ = {isa = PBXBuildFile; fileRef = F2E4ABA026ECAA8600BA7F01 /* SensorsAnalyticsSDK+DeviceOrientation.m */; }; + F2E4ABA526ECAC5400BA7F01 /* SensorsAnalyticsSDK+Deeplink.h in Headers */ = {isa = PBXBuildFile; fileRef = F2E4ABA326ECAC5400BA7F01 /* SensorsAnalyticsSDK+Deeplink.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F2E4ABA626ECAC5400BA7F01 /* SensorsAnalyticsSDK+Deeplink.m in Sources */ = {isa = PBXBuildFile; fileRef = F2E4ABA426ECAC5400BA7F01 /* SensorsAnalyticsSDK+Deeplink.m */; }; + F2E4ABA926ECB19200BA7F01 /* SensorsAnalyticsSDK+DebugMode.h in Headers */ = {isa = PBXBuildFile; fileRef = F2E4ABA726ECB19200BA7F01 /* SensorsAnalyticsSDK+DebugMode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F2E4ABAA26ECB19200BA7F01 /* SensorsAnalyticsSDK+DebugMode.m in Sources */ = {isa = PBXBuildFile; fileRef = F2E4ABA826ECB19200BA7F01 /* SensorsAnalyticsSDK+DebugMode.m */; }; F2E9723125E637820009A2B9 /* SAAppPushManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F2E9722F25E637820009A2B9 /* SAAppPushManager.h */; }; F2E9723225E637820009A2B9 /* SAAppPushManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F2E9723025E637820009A2B9 /* SAAppPushManager.m */; }; FC002920262C189E00A18FE3 /* SAConfigOptions+Encrypt.h in Headers */ = {isa = PBXBuildFile; fileRef = FC0028EF2629756400A18FE3 /* SAConfigOptions+Encrypt.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -473,10 +487,6 @@ 881A40F5253D7B4F00854F69 /* SAAppExtensionDataManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAAppExtensionDataManager.m; sourceTree = ""; }; 881A40F6253D7B4F00854F69 /* SAModuleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAModuleManager.h; sourceTree = ""; }; 881A40FD253D7B4F00854F69 /* SAFileStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAFileStore.h; sourceTree = ""; }; - 881A40FF253D7B4F00854F69 /* WKWebView+SABridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WKWebView+SABridge.h"; sourceTree = ""; }; - 881A4100253D7B4F00854F69 /* SAJavaScriptBridgeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAJavaScriptBridgeManager.m; sourceTree = ""; }; - 881A4101253D7B4F00854F69 /* WKWebView+SABridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "WKWebView+SABridge.m"; sourceTree = ""; }; - 881A4102253D7B4F00854F69 /* SAJavaScriptBridgeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAJavaScriptBridgeManager.h; sourceTree = ""; }; 881A413D253D7B4F00854F69 /* SAKeyChainItemWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAKeyChainItemWrapper.m; sourceTree = ""; }; 881A414B253D7B4F00854F69 /* SensorsAnalyticsSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SensorsAnalyticsSDK.h; sourceTree = ""; }; 881A414C253D7B4F00854F69 /* SAModuleProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAModuleProtocol.h; sourceTree = ""; }; @@ -593,11 +603,20 @@ CB6EBAF022855222003CFBA8 /* ca.cer1 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ca.cer1; sourceTree = ""; }; CB6EBAF122855222003CFBA8 /* ca.der.cer */ = {isa = PBXFileReference; lastKnownFileType = file; path = ca.der.cer; sourceTree = ""; }; CB6EBAF222855222003CFBA8 /* SANetworkTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SANetworkTests.m; sourceTree = ""; }; + F211741F26E9A72B00D65E19 /* SAApplication.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAApplication.h; sourceTree = ""; }; + F211742026E9A72B00D65E19 /* SAApplication.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAApplication.m; sourceTree = ""; }; F214CE57249A07DF00A2633D /* SADatabaseUnitTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SADatabaseUnitTest.m; path = SensorsAnalyticsTests/Tracker/SADatabaseUnitTest.m; sourceTree = SOURCE_ROOT; }; F22E1B1926A55C8A0033A748 /* SAAppPageLeaveTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SAAppPageLeaveTracker.h; sourceTree = ""; }; F22E1B1A26A55C8A0033A748 /* SAAppPageLeaveTracker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SAAppPageLeaveTracker.m; sourceTree = ""; }; + F23C9FFE2701715E002EEACA /* WKWebView+SABridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WKWebView+SABridge.h"; sourceTree = ""; }; + F23CA0002701715E002EEACA /* SAJavaScriptBridgeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAJavaScriptBridgeManager.m; sourceTree = ""; }; + F23CA0012701715E002EEACA /* SensorsAnalyticsSDK+JavaScriptBridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SensorsAnalyticsSDK+JavaScriptBridge.h"; sourceTree = ""; }; + F23CA0022701715E002EEACA /* WKWebView+SABridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "WKWebView+SABridge.m"; sourceTree = ""; }; + F23CA0032701715E002EEACA /* SAJavaScriptBridgeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAJavaScriptBridgeManager.h; sourceTree = ""; }; F244AE3A26B170F000D8C60B /* UIViewController+SAPageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+SAPageView.h"; sourceTree = ""; }; F244AE3B26B170F000D8C60B /* UIViewController+SAPageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+SAPageView.m"; sourceTree = ""; }; + F26FDDD7270312C300E1DF32 /* SAConfigOptions+AppPush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SAConfigOptions+AppPush.h"; sourceTree = ""; }; + F26FDDD92703130700E1DF32 /* SAConfigOptions+Exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SAConfigOptions+Exception.h"; sourceTree = ""; }; F277F5B125CF9A43009B5CE6 /* SAApplicationDelegateProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAApplicationDelegateProxy.m; sourceTree = ""; }; F277F5B225CF9A43009B5CE6 /* SAUNUserNotificationCenterDelegateProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAUNUserNotificationCenterDelegateProxy.h; sourceTree = ""; }; F277F5B325CF9A43009B5CE6 /* SANotificationUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SANotificationUtil.m; sourceTree = ""; }; @@ -612,6 +631,15 @@ F277F5BD25CF9A43009B5CE6 /* SAAppPushConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAAppPushConstants.m; sourceTree = ""; }; F277F5E125CFCE56009B5CE6 /* NSObject+DelegateProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+DelegateProxy.m"; sourceTree = ""; }; F277F5E225CFCE56009B5CE6 /* NSObject+DelegateProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+DelegateProxy.h"; sourceTree = ""; }; + F2CFD14526EB04A8007A9253 /* SAConfigOptions+RemoteConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SAConfigOptions+RemoteConfig.h"; sourceTree = ""; }; + F2E4AB9B26EC86C800BA7F01 /* SensorsAnalyticsSDK+Location.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SensorsAnalyticsSDK+Location.h"; sourceTree = ""; }; + F2E4AB9C26EC86C800BA7F01 /* SensorsAnalyticsSDK+Location.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SensorsAnalyticsSDK+Location.m"; sourceTree = ""; }; + F2E4AB9F26ECAA8600BA7F01 /* SensorsAnalyticsSDK+DeviceOrientation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SensorsAnalyticsSDK+DeviceOrientation.h"; sourceTree = ""; }; + F2E4ABA026ECAA8600BA7F01 /* SensorsAnalyticsSDK+DeviceOrientation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SensorsAnalyticsSDK+DeviceOrientation.m"; sourceTree = ""; }; + F2E4ABA326ECAC5400BA7F01 /* SensorsAnalyticsSDK+Deeplink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SensorsAnalyticsSDK+Deeplink.h"; sourceTree = ""; }; + F2E4ABA426ECAC5400BA7F01 /* SensorsAnalyticsSDK+Deeplink.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SensorsAnalyticsSDK+Deeplink.m"; sourceTree = ""; }; + F2E4ABA726ECB19200BA7F01 /* SensorsAnalyticsSDK+DebugMode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SensorsAnalyticsSDK+DebugMode.h"; sourceTree = ""; }; + F2E4ABA826ECB19200BA7F01 /* SensorsAnalyticsSDK+DebugMode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SensorsAnalyticsSDK+DebugMode.m"; sourceTree = ""; }; F2E9722F25E637820009A2B9 /* SAAppPushManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SAAppPushManager.h; sourceTree = ""; }; F2E9723025E637820009A2B9 /* SAAppPushManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SAAppPushManager.m; sourceTree = ""; }; FC0028EF2629756400A18FE3 /* SAConfigOptions+Encrypt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SAConfigOptions+Encrypt.h"; sourceTree = ""; }; @@ -806,6 +834,8 @@ children = ( 4D9B536526382F0000318B1D /* SADeviceOrientationManager.h */, 4D9B536626382F0000318B1D /* SADeviceOrientationManager.m */, + F2E4AB9F26ECAA8600BA7F01 /* SensorsAnalyticsSDK+DeviceOrientation.h */, + F2E4ABA026ECAA8600BA7F01 /* SensorsAnalyticsSDK+DeviceOrientation.m */, ); path = DeviceOrientation; sourceTree = ""; @@ -872,7 +902,6 @@ children = ( 45A56547263C174300C9C41B /* Builder */, F2346B7D25E0AE5600AA3684 /* HookDelegate */, - 881A40FE253D7B4F00854F69 /* JSBridge */, 4DA89BBC25C2BC1E003ABA43 /* Network */, 881A40D5253D7B4F00854F69 /* SALogger */, 881A4114253D7B4F00854F69 /* Tracker */, @@ -883,6 +912,8 @@ 881A40F1253D7B4F00854F69 /* SAAlertController.m */, 881A415C253D7B4F00854F69 /* SAAppExtensionDataManager.h */, 881A40F5253D7B4F00854F69 /* SAAppExtensionDataManager.m */, + F211741F26E9A72B00D65E19 /* SAApplication.h */, + F211742026E9A72B00D65E19 /* SAApplication.m */, 881A40EF253D7B4F00854F69 /* SAConfigOptions.h */, 881A4154253D7B4F00854F69 /* SAConfigOptions.m */, 881A40EA253D7B4F00854F69 /* SAConstants.h */, @@ -939,17 +970,6 @@ path = SALogger; sourceTree = ""; }; - 881A40FE253D7B4F00854F69 /* JSBridge */ = { - isa = PBXGroup; - children = ( - 881A4102253D7B4F00854F69 /* SAJavaScriptBridgeManager.h */, - 881A4100253D7B4F00854F69 /* SAJavaScriptBridgeManager.m */, - 881A40FF253D7B4F00854F69 /* WKWebView+SABridge.h */, - 881A4101253D7B4F00854F69 /* WKWebView+SABridge.m */, - ); - path = JSBridge; - sourceTree = ""; - }; 881A4103253D7B4F00854F69 /* Utils */ = { isa = PBXGroup; children = ( @@ -997,6 +1017,8 @@ children = ( 881A4225253D7B5E00854F69 /* SALocationManager.h */, 881A4226253D7B5E00854F69 /* SALocationManager.m */, + F2E4AB9B26EC86C800BA7F01 /* SensorsAnalyticsSDK+Location.h */, + F2E4AB9C26EC86C800BA7F01 /* SensorsAnalyticsSDK+Location.m */, ); path = Location; sourceTree = ""; @@ -1006,6 +1028,7 @@ children = ( 883BAAAE2669CD18008105D2 /* SAExceptionManager.h */, 883BAAAF2669CD18008105D2 /* SAExceptionManager.m */, + F26FDDD92703130700E1DF32 /* SAConfigOptions+Exception.h */, ); path = Exception; sourceTree = ""; @@ -1175,6 +1198,8 @@ children = ( A8BCC4D726872A3F00B72040 /* SADeeplinkManager.h */, A8BCC4D826872A3F00B72040 /* SADeeplinkManager.m */, + F2E4ABA326ECAC5400BA7F01 /* SensorsAnalyticsSDK+Deeplink.h */, + F2E4ABA426ECAC5400BA7F01 /* SensorsAnalyticsSDK+Deeplink.m */, ); path = Deeplink; sourceTree = ""; @@ -1184,6 +1209,8 @@ children = ( A8BCC4DC26872B6600B72040 /* SADebugModeManager.h */, A8BCC4DD26872B6600B72040 /* SADebugModeManager.m */, + F2E4ABA726ECB19200BA7F01 /* SensorsAnalyticsSDK+DebugMode.h */, + F2E4ABA826ECB19200BA7F01 /* SensorsAnalyticsSDK+DebugMode.m */, ); path = DebugMode; sourceTree = ""; @@ -1203,6 +1230,7 @@ A8CC22292685E50C00E96A03 /* SARemoteConfigModel.m */, A8CC22242685E50C00E96A03 /* SARemoteConfigOperator.h */, A8CC222C2685E50C00E96A03 /* SARemoteConfigOperator.m */, + F2CFD14526EB04A8007A9253 /* SAConfigOptions+RemoteConfig.h */, ); path = RemoteConfig; sourceTree = ""; @@ -1240,6 +1268,7 @@ A8356D872656459A00FD64AA /* AutoTrack */, 881A40D2253D7B4F00854F69 /* Core */, 4D9B536426382F0000318B1D /* DeviceOrientation */, + F23C9FFD2701715E002EEACA /* JSBridge */, 883BAAAD2669CCE5008105D2 /* Exception */, 881A4224253D7B5E00854F69 /* Location */, CB30C0AB22840F1B0004061D /* Resources */, @@ -1321,6 +1350,19 @@ path = HookDelegate; sourceTree = ""; }; + F23C9FFD2701715E002EEACA /* JSBridge */ = { + isa = PBXGroup; + children = ( + F23CA0032701715E002EEACA /* SAJavaScriptBridgeManager.h */, + F23CA0002701715E002EEACA /* SAJavaScriptBridgeManager.m */, + F23CA0012701715E002EEACA /* SensorsAnalyticsSDK+JavaScriptBridge.h */, + F23C9FFE2701715E002EEACA /* WKWebView+SABridge.h */, + F23CA0022701715E002EEACA /* WKWebView+SABridge.m */, + ); + name = JSBridge; + path = SensorsAnalyticsSDK/JSBridge; + sourceTree = SOURCE_ROOT; + }; F277F5B025CF9A43009B5CE6 /* AppPush */ = { isa = PBXGroup; children = ( @@ -1330,6 +1372,7 @@ F277F5BD25CF9A43009B5CE6 /* SAAppPushConstants.m */, F2E9722F25E637820009A2B9 /* SAAppPushManager.h */, F2E9723025E637820009A2B9 /* SAAppPushManager.m */, + F26FDDD7270312C300E1DF32 /* SAConfigOptions+AppPush.h */, F277F5BB25CF9A43009B5CE6 /* SANotificationUtil.h */, F277F5B325CF9A43009B5CE6 /* SANotificationUtil.m */, F277F5B225CF9A43009B5CE6 /* SAUNUserNotificationCenterDelegateProxy.h */, @@ -1350,11 +1393,11 @@ buildActionMask = 2147483647; files = ( 4DD1285525F872A4008C0B1E /* SAObjectIdentityProvider.h in Headers */, + F2E4ABA526ECAC5400BA7F01 /* SensorsAnalyticsSDK+Deeplink.h in Headers */, A8356DD62656459A00FD64AA /* UIGestureRecognizer+SAAutoTrack.h in Headers */, 4DD1285F25F872A4008C0B1E /* SAVisualizedSnapshotMessage.h in Headers */, 4D4DB2C825B7D19C00938842 /* SADelegateProxy.h in Headers */, 4D2D53A12591EB2100805141 /* SAEventFlush.h in Headers */, - 881A41A9253D7B4F00854F69 /* WKWebView+SABridge.h in Headers */, 4DD128C625F8A003008C0B1E /* SAVisualPropertiesConfigSources.h in Headers */, A8CC22322685E50C00E96A03 /* SARemoteConfigOperator.h in Headers */, A8CC223B2685E50C00E96A03 /* SARemoteConfigManager.h in Headers */, @@ -1363,13 +1406,13 @@ FC002920262C189E00A18FE3 /* SAConfigOptions+Encrypt.h in Headers */, A806642B26905F6C00FFDEBA /* SAChannelMatchManager.h in Headers */, A8BCC4DE26872B6600B72040 /* SADebugModeManager.h in Headers */, - 881A41AC253D7B4F00854F69 /* SAJavaScriptBridgeManager.h in Headers */, 45A565BC263C17E400C9C41B /* SAReferrerManager.h in Headers */, 4D57261E26206D5300B2AC9F /* SAVisualizedLogger.h in Headers */, 881A420F253D7B5000854F69 /* SAAlertController.h in Headers */, F277F5C025CF9A43009B5CE6 /* SAUNUserNotificationCenterDelegateProxy.h in Headers */, A8356DC32656459A00FD64AA /* SAAutoTrackProperty.h in Headers */, 4D2D53C22591EB3A00805141 /* SAReadWriteLock.h in Headers */, + F2E4ABA126ECAA8600BA7F01 /* SensorsAnalyticsSDK+DeviceOrientation.h in Headers */, A8356DBD2656459A00FD64AA /* SAAutoTrackUtils.h in Headers */, 881A4201253D7B5000854F69 /* SAAppExtensionDataManager.h in Headers */, 45A56561263C174300C9C41B /* SAIdentifier.h in Headers */, @@ -1380,10 +1423,12 @@ A8356DD42656459A00FD64AA /* SAGestureTargetActionModel.h in Headers */, F277F5C725CF9A43009B5CE6 /* SAApplicationDelegateProxy.h in Headers */, A8356DC72656459A00FD64AA /* UIScrollView+AutoTrack.h in Headers */, + F26FDDDA2703130700E1DF32 /* SAConfigOptions+Exception.h in Headers */, 881A41F1253D7B5000854F69 /* SensorsAnalyticsSDK.h in Headers */, 4D14F13F25FC5BF200113EA2 /* SAVisualizedUtils.h in Headers */, 45A565BF263C17E400C9C41B /* SAAppLifecycle.h in Headers */, F277F5C525CF9A43009B5CE6 /* SAAppPushConstants.h in Headers */, + F23CA0052701715E002EEACA /* WKWebView+SABridge.h in Headers */, A8CC22392685E50C00E96A03 /* SARemoteConfigEventObject.h in Headers */, 4DA89BC325C2BC1E003ABA43 /* SANetwork.h in Headers */, 881A41A2253D7B4F00854F69 /* SAModuleManager.h in Headers */, @@ -1400,6 +1445,7 @@ 4D4DB2C725B7D19C00938842 /* SAClassHelper.h in Headers */, 4DA89BC225C2BC1E003ABA43 /* SAReachability.h in Headers */, 4DD1285125F872A4008C0B1E /* SAApplicationStateSerializer.h in Headers */, + F23CA0082701715E002EEACA /* SensorsAnalyticsSDK+JavaScriptBridge.h in Headers */, A8356DC12656459A00FD64AA /* SAAppEndTracker.h in Headers */, A82E8957267D918100475757 /* SASecretKeyFactory.h in Headers */, 4DD1284B25F872A4008C0B1E /* SAWebElementView.h in Headers */, @@ -1414,6 +1460,7 @@ 45A56562263C174300C9C41B /* SAEventBuildStrategyProtocol.h in Headers */, 45A56564263C174300C9C41B /* SATrackEventObject.h in Headers */, A82E8950267D918100475757 /* SAAESEncryptor.h in Headers */, + F2CFD14726EB04A8007A9253 /* SAConfigOptions+RemoteConfig.h in Headers */, 881A4214253D7B5000854F69 /* SAKeyChainItemWrapper.h in Headers */, A8CC223C2685E50C00E96A03 /* SARemoteConfigCommonOperator.h in Headers */, 4DD1285A25F872A4008C0B1E /* SAVisualizedObjectSerializerManager.h in Headers */, @@ -1423,7 +1470,9 @@ A82E8959267D918100475757 /* SAEncryptManager.h in Headers */, 4DD1284E25F872A4008C0B1E /* SATypeDescription.h in Headers */, A8356DE62656459A00FD64AA /* UIApplication+AutoTrack.h in Headers */, + F23CA00A2701715E002EEACA /* SAJavaScriptBridgeManager.h in Headers */, 4DD1286825F872A4008C0B1E /* SAObjectSerializerContext.h in Headers */, + F2E4ABA926ECB19200BA7F01 /* SensorsAnalyticsSDK+DebugMode.h in Headers */, 4DD1296A25F8E451008C0B1E /* SAViewNode.h in Headers */, A8356DC52656459A00FD64AA /* SAAppTracker.h in Headers */, 883BAAB02669CD18008105D2 /* SAExceptionManager.h in Headers */, @@ -1460,16 +1509,19 @@ F244AE3C26B170F000D8C60B /* UIViewController+SAPageView.h in Headers */, 4DD1285325F872A4008C0B1E /* SAVisualizedAbstractMessage.h in Headers */, 4D2D53992591EB2100805141 /* SADatabase.h in Headers */, + F211742126E9A72C00D65E19 /* SAApplication.h in Headers */, 45A5655F263C174300C9C41B /* SAPresetProperty.h in Headers */, 4DD1285825F872A4008C0B1E /* SAPropertyDescription.h in Headers */, 4DD128C825F8A003008C0B1E /* SAVisualPropertiesTracker.h in Headers */, A8356DCB2656459A00FD64AA /* SAGestureTarget.h in Headers */, + F26FDDD8270312C400E1DF32 /* SAConfigOptions+AppPush.h in Headers */, A82E8951267D918100475757 /* SAEncryptProtocol.h in Headers */, 45A56560263C174300C9C41B /* SAIDFAHelper.h in Headers */, 4DD1281925F8721A008C0B1E /* UIView+SAElementSelector.h in Headers */, A82E8953267D918100475757 /* SAECCEncryptor.h in Headers */, A8356DDB2656459A00FD64AA /* UIViewController+AutoTrack.h in Headers */, 4D6AE7FC26086E9300A9CB08 /* SAVisualizedEventCheck.h in Headers */, + F2E4AB9D26EC86C800BA7F01 /* SensorsAnalyticsSDK+Location.h in Headers */, 45A56563263C174300C9C41B /* SAPropertyValidator.h in Headers */, 4D9B536726382F0100318B1D /* SADeviceOrientationManager.h in Headers */, 4DD1296B25F8E451008C0B1E /* SAViewNodeFactory.h in Headers */, @@ -1559,7 +1611,7 @@ TargetAttributes = { CB30BD5322840CA40004061D = { CreatedOnToolsVersion = 10.2.1; - LastSwiftMigration = 1230; + LastSwiftMigration = 1250; }; CB30C30E22843D3A0004061D = { CreatedOnToolsVersion = 10.2.1; @@ -1646,6 +1698,7 @@ 4D4DB2FB25B7D4D800938842 /* SAURLUtils.m in Sources */, 881A4228253D7B5E00854F69 /* SALocationManager.m in Sources */, A8356DDD2656459A00FD64AA /* SAAutoTrackUtils.m in Sources */, + F2E4ABAA26ECB19200BA7F01 /* SensorsAnalyticsSDK+DebugMode.m in Sources */, 4D2D53BD2591EB3A00805141 /* SAReadWriteLock.m in Sources */, 4D2D539D2591EB2100805141 /* SAEventFlush.m in Sources */, 4D14F13E25FC5BF200113EA2 /* SAVisualizedUtils.m in Sources */, @@ -1653,6 +1706,7 @@ 4D2D53A02591EB2100805141 /* SADatabase.m in Sources */, 4D4DB2CE25B7D19C00938842 /* SAClassHelper.m in Sources */, A8356DC62656459A00FD64AA /* SAScrollViewDelegateProxy.m in Sources */, + F2E4AB9E26EC86C800BA7F01 /* SensorsAnalyticsSDK+Location.m in Sources */, A8356DE52656459A00FD64AA /* SAAppViewScreenTracker.m in Sources */, 881A4220253D7B5000854F69 /* SAFileStore.m in Sources */, F277F5C625CF9A43009B5CE6 /* SAUNUserNotificationCenterDelegateProxy.m in Sources */, @@ -1665,7 +1719,6 @@ 4DD1296925F8E451008C0B1E /* UIView+SAVisualProperties.m in Sources */, 881A41E4253D7B5000854F69 /* SAKeyChainItemWrapper.m in Sources */, 4D41D9D425FF7E9300D856F4 /* UIViewController+SAElementPath.m in Sources */, - 881A41AA253D7B4F00854F69 /* SAJavaScriptBridgeManager.m in Sources */, 4DD1286F25F872A4008C0B1E /* SAVisualizedSnapshotMessage.m in Sources */, A8BCC4AC2686C42D00B72040 /* SASecretKey.m in Sources */, A82E895C267D918100475757 /* SAECCEncryptor.m in Sources */, @@ -1677,6 +1730,7 @@ 4D9B536826382F0100318B1D /* SADeviceOrientationManager.m in Sources */, 4DD1285425F872A4008C0B1E /* SAEnumDescription.m in Sources */, 4D2D53BE2591EB3A00805141 /* SAJSONUtil.m in Sources */, + F2E4ABA226ECAA8600BA7F01 /* SensorsAnalyticsSDK+DeviceOrientation.m in Sources */, A82E895E267D918100475757 /* SARSAPluginEncryptor.m in Sources */, 4DD1284C25F872A4008C0B1E /* NSInvocation+SAHelpers.m in Sources */, 4D2D537B2591EB0600805141 /* SALogMessage.m in Sources */, @@ -1693,6 +1747,7 @@ A8356DBF2656459A00FD64AA /* UIViewController+AutoTrack.m in Sources */, 45A5656B263C174300C9C41B /* SATrackEventObject.m in Sources */, A8356DC42656459A00FD64AA /* UIApplication+AutoTrack.m in Sources */, + F23CA0072701715E002EEACA /* SAJavaScriptBridgeManager.m in Sources */, A8356DD22656459A00FD64AA /* SAGestureTargetActionModel.m in Sources */, A8BCC4DA26872A3F00B72040 /* SADeeplinkManager.m in Sources */, A8356DBC2656459A00FD64AA /* SAAutoTrackManager.m in Sources */, @@ -1713,7 +1768,6 @@ 4D4DB2D025B7D19C00938842 /* SADelegateProxy.m in Sources */, 4DD1284D25F872A4008C0B1E /* SAVisualizedConnection.m in Sources */, 881A4180253D7B4F00854F69 /* SASecurityPolicy.m in Sources */, - 881A41AB253D7B4F00854F69 /* WKWebView+SABridge.m in Sources */, A82E8958267D918100475757 /* SAAESEncryptor.m in Sources */, 4D2D537A2591EB0600805141 /* SAConsoleLogger.m in Sources */, A8356DCD2656459A00FD64AA /* SAGestureViewProcessorFactory.m in Sources */, @@ -1728,6 +1782,7 @@ 4D2D53A22591EB2100805141 /* SAEventRecord.m in Sources */, 4D57261F26206D5300B2AC9F /* SAVisualizedLogger.m in Sources */, 4D2D53BB2591EB3A00805141 /* SAWeakPropertyContainer.m in Sources */, + F211742226E9A72C00D65E19 /* SAApplication.m in Sources */, A8356DD72656459A00FD64AA /* SAAppClickTracker.m in Sources */, 881A4202253D7B5000854F69 /* SAModuleManager.m in Sources */, F2E9723225E637820009A2B9 /* SAAppPushManager.m in Sources */, @@ -1740,6 +1795,7 @@ 45A5656D263C174300C9C41B /* SAPresetProperty.m in Sources */, 4DD1285E25F872A4008C0B1E /* SAVisualizedObjectSerializerManager.m in Sources */, 45A5655E263C174300C9C41B /* SASuperProperty.m in Sources */, + F2E4ABA626ECAC5400BA7F01 /* SensorsAnalyticsSDK+Deeplink.m in Sources */, 4DD1286D25F872A4008C0B1E /* SAVisualizedManager.m in Sources */, 4DD1286A25F872A4008C0B1E /* SAWebElementView.m in Sources */, F277F5BF25CF9A43009B5CE6 /* SAApplicationDelegateProxy.m in Sources */, @@ -1747,6 +1803,7 @@ 881A41A1253D7B4F00854F69 /* SAAppExtensionDataManager.m in Sources */, A8356DDA2656459A00FD64AA /* SAAppStartTracker.m in Sources */, 4D4DB2CD25B7D19C00938842 /* SAMethodHelper.m in Sources */, + F23CA0092701715E002EEACA /* WKWebView+SABridge.m in Sources */, 883BAAB12669CD18008105D2 /* SAExceptionManager.m in Sources */, 4DD1286625F872A4008C0B1E /* SAVisualizedAbstractMessage.m in Sources */, 4DD1282225F87225008C0B1E /* UIView+SAElementPath.m in Sources */, diff --git a/SensorsAnalyticsSDK/AppPush/SAAppPushManager.h b/SensorsAnalyticsSDK/AppPush/SAAppPushManager.h index 72121edd..c1ab7ae3 100644 --- a/SensorsAnalyticsSDK/AppPush/SAAppPushManager.h +++ b/SensorsAnalyticsSDK/AppPush/SAAppPushManager.h @@ -25,8 +25,9 @@ NS_ASSUME_NONNULL_BEGIN @interface SAAppPushManager : NSObject -@property (nonatomic, assign, getter=isEnable) BOOL enable; ++ (instancetype)defaultManager; +@property (nonatomic, assign, getter=isEnable) BOOL enable; @property (nonatomic, strong) SAConfigOptions *configOptions; @end diff --git a/SensorsAnalyticsSDK/AppPush/SAAppPushManager.m b/SensorsAnalyticsSDK/AppPush/SAAppPushManager.m index 5e4730d1..8bb3784e 100644 --- a/SensorsAnalyticsSDK/AppPush/SAAppPushManager.m +++ b/SensorsAnalyticsSDK/AppPush/SAAppPushManager.m @@ -29,6 +29,7 @@ #import "UIApplication+PushClick.h" #import "SensorsAnalyticsSDK+Private.h" #import "SAMethodHelper.h" +#import "SAConfigOptions+AppPush.h" #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 #import "SAUNUserNotificationCenterDelegateProxy.h" @@ -36,6 +37,15 @@ @implementation SAAppPushManager ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SAAppPushManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SAAppPushManager alloc] init]; + }); + return manager; +} + - (void)setEnable:(BOOL)enable { _enable = enable; if (enable) { @@ -45,8 +55,8 @@ - (void)setEnable:(BOOL)enable { - (void)setConfigOptions:(SAConfigOptions *)configOptions { _configOptions = configOptions; - [UIApplication sharedApplication].sensorsdata_launchOptions = configOptions.launchOptions; + self.enable = configOptions.enableTrackPush; } - (void)proxyNotifications { diff --git a/SensorsAnalyticsSDK/AppPush/SAConfigOptions+AppPush.h b/SensorsAnalyticsSDK/AppPush/SAConfigOptions+AppPush.h new file mode 100644 index 00000000..a684b625 --- /dev/null +++ b/SensorsAnalyticsSDK/AppPush/SAConfigOptions+AppPush.h @@ -0,0 +1,32 @@ +// +// SAConfigOptions+AppPush.h +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/9. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#import "SAConfigOptions.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SAConfigOptions (AppPush) + +///开启自动采集通知 +@property (nonatomic, assign) BOOL enableTrackPush API_UNAVAILABLE(macos); + +@end + +NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/AutoTrack/AppClick/Cell/SAScrollViewDelegateProxy.m b/SensorsAnalyticsSDK/AutoTrack/AppClick/Cell/SAScrollViewDelegateProxy.m index e37afeb4..745ccd1c 100644 --- a/SensorsAnalyticsSDK/AutoTrack/AppClick/Cell/SAScrollViewDelegateProxy.m +++ b/SensorsAnalyticsSDK/AutoTrack/AppClick/Cell/SAScrollViewDelegateProxy.m @@ -49,7 +49,7 @@ + (void)trackEventWithTarget:(NSObject *)target scrollView:(UIScrollView *)scrol return; } - [SAAutoTrackManager.sharedInstance.appClickTracker autoTrackEventWithScrollView:scrollView atIndexPath:indexPath]; + [SAAutoTrackManager.defaultManager.appClickTracker autoTrackEventWithScrollView:scrollView atIndexPath:indexPath]; } @end diff --git a/SensorsAnalyticsSDK/AutoTrack/AppClick/Cell/UIScrollView+AutoTrack.m b/SensorsAnalyticsSDK/AutoTrack/AppClick/Cell/UIScrollView+AutoTrack.m index ce8f04ca..7873632d 100644 --- a/SensorsAnalyticsSDK/AutoTrack/AppClick/Cell/UIScrollView+AutoTrack.m +++ b/SensorsAnalyticsSDK/AutoTrack/AppClick/Cell/UIScrollView+AutoTrack.m @@ -42,7 +42,7 @@ - (void)sensorsdata_setDelegate:(id )delegate { } // 判断是否忽略 $AppClick 事件采集 - if ([SAAutoTrackManager.sharedInstance isAutoTrackEventTypeIgnored:SensorsAnalyticsEventTypeAppClick]) { + if ([SAAutoTrackManager.defaultManager isAutoTrackEventTypeIgnored:SensorsAnalyticsEventTypeAppClick]) { return; } @@ -66,7 +66,7 @@ - (void)sensorsdata_setDelegate:(id )delegate { } // 判断是否忽略 $AppClick 事件采集 - if ([SAAutoTrackManager.sharedInstance isAutoTrackEventTypeIgnored:SensorsAnalyticsEventTypeAppClick]) { + if ([SAAutoTrackManager.defaultManager isAutoTrackEventTypeIgnored:SensorsAnalyticsEventTypeAppClick]) { return; } diff --git a/SensorsAnalyticsSDK/AutoTrack/AppClick/Gesture/Target/SAGestureTarget.m b/SensorsAnalyticsSDK/AutoTrack/AppClick/Gesture/Target/SAGestureTarget.m index 677c449a..daca29c0 100644 --- a/SensorsAnalyticsSDK/AutoTrack/AppClick/Gesture/Target/SAGestureTarget.m +++ b/SensorsAnalyticsSDK/AutoTrack/AppClick/Gesture/Target/SAGestureTarget.m @@ -52,7 +52,7 @@ - (void)trackGestureRecognizerAppClick:(UIGestureRecognizer *)gesture { return; } - [SAAutoTrackManager.sharedInstance.appClickTracker autoTrackEventWithGestureView:processor.trackableView]; + [SAAutoTrackManager.defaultManager.appClickTracker autoTrackEventWithGestureView:processor.trackableView]; } @end diff --git a/SensorsAnalyticsSDK/AutoTrack/AppClick/UIApplication+AutoTrack.m b/SensorsAnalyticsSDK/AutoTrack/AppClick/UIApplication+AutoTrack.m index 4ded4ae4..4b234df3 100644 --- a/SensorsAnalyticsSDK/AutoTrack/AppClick/UIApplication+AutoTrack.m +++ b/SensorsAnalyticsSDK/AutoTrack/AppClick/UIApplication+AutoTrack.m @@ -85,12 +85,12 @@ - (void)sa_track:(SEL)action to:(id)to from:(NSObject *)from forEvent:(UIEvent * [object isKindOfClass:[UIStepper class]] || [object isKindOfClass:[UISegmentedControl class]] || [object isKindOfClass:[UIPageControl class]]) { - [SAAutoTrackManager.sharedInstance.appClickTracker autoTrackEventWithView:(UIView *)object]; + [SAAutoTrackManager.defaultManager.appClickTracker autoTrackEventWithView:(UIView *)object]; return; } if ([event isKindOfClass:[UIEvent class]] && event.type == UIEventTypeTouches && [[[event allTouches] anyObject] phase] == UITouchPhaseEnded) { - [SAAutoTrackManager.sharedInstance.appClickTracker autoTrackEventWithView:(UIView *)object]; + [SAAutoTrackManager.defaultManager.appClickTracker autoTrackEventWithView:(UIView *)object]; } } diff --git a/SensorsAnalyticsSDK/AutoTrack/AppClick/UIView+AutoTrack.m b/SensorsAnalyticsSDK/AutoTrack/AppClick/UIView+AutoTrack.m index bd2bbf50..66b02557 100644 --- a/SensorsAnalyticsSDK/AutoTrack/AppClick/UIView+AutoTrack.m +++ b/SensorsAnalyticsSDK/AutoTrack/AppClick/UIView+AutoTrack.m @@ -40,7 +40,7 @@ - (BOOL)sensorsdata_isIgnored { return YES; } - return [SAAutoTrackManager.sharedInstance.appClickTracker isIgnoreEventWithView:self]; + return [SAAutoTrackManager.defaultManager.appClickTracker isIgnoreEventWithView:self]; } - (void)setSensorsdata_timeIntervalForLastAppClick:(NSTimeInterval)sensorsdata_timeIntervalForLastAppClick { diff --git a/SensorsAnalyticsSDK/AutoTrack/AppPageLeave/UIViewController+SAPageView.m b/SensorsAnalyticsSDK/AutoTrack/AppPageLeave/UIViewController+SAPageView.m index cbb459de..fd863cb5 100644 --- a/SensorsAnalyticsSDK/AutoTrack/AppPageLeave/UIViewController+SAPageView.m +++ b/SensorsAnalyticsSDK/AutoTrack/AppPageLeave/UIViewController+SAPageView.m @@ -29,13 +29,13 @@ @implementation UIViewController (PageLeave) - (void)sensorsdata_pageLeave_viewDidAppear:(BOOL)animated { - SAAppPageLeaveTracker *tracker = [SAAutoTrackManager sharedInstance].appPageLeaveTracker; + SAAppPageLeaveTracker *tracker = [SAAutoTrackManager defaultManager].appPageLeaveTracker; [tracker trackPageEnter:self]; [self sensorsdata_pageLeave_viewDidAppear:animated]; } - (void)sensorsdata_pageLeave_viewDidDisappear:(BOOL)animated { - SAAppPageLeaveTracker *tracker = [SAAutoTrackManager sharedInstance].appPageLeaveTracker; + SAAppPageLeaveTracker *tracker = [SAAutoTrackManager defaultManager].appPageLeaveTracker; [tracker trackPageLeave:self]; [self sensorsdata_pageLeave_viewDidDisappear:animated]; } diff --git a/SensorsAnalyticsSDK/AutoTrack/AppViewScreen/UIViewController+AutoTrack.m b/SensorsAnalyticsSDK/AutoTrack/AppViewScreen/UIViewController+AutoTrack.m index b10b6075..0ffde322 100644 --- a/SensorsAnalyticsSDK/AutoTrack/AppViewScreen/UIViewController+AutoTrack.m +++ b/SensorsAnalyticsSDK/AutoTrack/AppViewScreen/UIViewController+AutoTrack.m @@ -37,7 +37,7 @@ @implementation UIViewController (AutoTrack) - (BOOL)sensorsdata_isIgnored { - return ![[SAAutoTrackManager sharedInstance].appClickTracker shouldTrackViewController:self]; + return ![[SAAutoTrackManager defaultManager].appClickTracker shouldTrackViewController:self]; } - (NSString *)sensorsdata_screenName { @@ -68,7 +68,7 @@ - (void)sa_autotrack_viewDidAppear:(BOOL)animated { nav.sensorsdata_previousViewController = nil; } - SAAppViewScreenTracker *appViewScreenTracker = SAAutoTrackManager.sharedInstance.appViewScreenTracker; + SAAppViewScreenTracker *appViewScreenTracker = SAAutoTrackManager.defaultManager.appViewScreenTracker; // parentViewController 判断,防止开启子页面采集时候的侧滑多采集父页面 $AppViewScreen 事件 if (self.navigationController && self.parentViewController == self.navigationController) { @@ -78,7 +78,8 @@ - (void)sa_autotrack_viewDidAppear:(BOOL)animated { } } - if (SAAutoTrackManager.sharedInstance.configOptions.enableAutoTrackChildViewScreen || + + if (SAAutoTrackManager.defaultManager.configOptions.enableAutoTrackChildViewScreen || !self.parentViewController || [self.parentViewController isKindOfClass:[UITabBarController class]] || [self.parentViewController isKindOfClass:[UINavigationController class]] || diff --git a/SensorsAnalyticsSDK/AutoTrack/ElementInfo/SAViewElementInfo.m b/SensorsAnalyticsSDK/AutoTrack/ElementInfo/SAViewElementInfo.m index 39895cba..8af6423e 100644 --- a/SensorsAnalyticsSDK/AutoTrack/ElementInfo/SAViewElementInfo.m +++ b/SensorsAnalyticsSDK/AutoTrack/ElementInfo/SAViewElementInfo.m @@ -47,7 +47,7 @@ - (BOOL)isVisualView { if (!self.view.userInteractionEnabled || self.view.alpha <= 0.01 || self.view.isHidden) { return NO; } - return [SAAutoTrackManager.sharedInstance isGestureVisualView:self.view]; + return [SAAutoTrackManager.defaultManager isGestureVisualView:self.view]; } @end diff --git a/SensorsAnalyticsSDK/AutoTrack/SAAppTracker.h b/SensorsAnalyticsSDK/AutoTrack/SAAppTracker.h index c56d408d..f2b381b7 100644 --- a/SensorsAnalyticsSDK/AutoTrack/SAAppTracker.h +++ b/SensorsAnalyticsSDK/AutoTrack/SAAppTracker.h @@ -55,10 +55,6 @@ NS_ASSUME_NONNULL_BEGIN /// @param viewController UIViewController - (BOOL)isViewControllerIgnored:(UIViewController *)viewController; -/// 判断某个 ViewController 是否被忽略 -/// @param viewControllerClassName UIViewController 类名 -- (BOOL)isViewControllerStringIgnored:(NSString *)viewControllerClassName; - /// ViewController 的黑名单 - (NSDictionary *)autoTrackViewControllerBlackList; diff --git a/SensorsAnalyticsSDK/AutoTrack/SAAppTracker.m b/SensorsAnalyticsSDK/AutoTrack/SAAppTracker.m index 6e1d37fa..b8865096 100644 --- a/SensorsAnalyticsSDK/AutoTrack/SAAppTracker.m +++ b/SensorsAnalyticsSDK/AutoTrack/SAAppTracker.m @@ -80,14 +80,6 @@ - (BOOL)isViewControllerIgnored:(UIViewController *)viewController { return [self.ignoredViewControllers containsObject:screenName]; } -- (BOOL)isViewControllerStringIgnored:(NSString *)viewControllerClassName { - if (viewControllerClassName == nil) { - return NO; - } - - return [self.ignoredViewControllers containsObject:viewControllerClassName]; -} - - (NSDictionary *)autoTrackViewControllerBlackList { static dispatch_once_t onceToken; static NSDictionary *allClasses = nil; diff --git a/SensorsAnalyticsSDK/AutoTrack/SAAutoTrackManager.h b/SensorsAnalyticsSDK/AutoTrack/SAAutoTrackManager.h index 1ec911c4..5b61d359 100644 --- a/SensorsAnalyticsSDK/AutoTrack/SAAutoTrackManager.h +++ b/SensorsAnalyticsSDK/AutoTrack/SAAutoTrackManager.h @@ -26,17 +26,21 @@ NS_ASSUME_NONNULL_BEGIN +@interface SAConfigOptions (AutoTrackPrivate) + +@property (nonatomic, assign) BOOL enableAutoTrack; + +@end + @interface SAAutoTrackManager : NSObject @property (nonatomic, strong) SAConfigOptions *configOptions; - @property (nonatomic, assign, getter=isEnable) BOOL enable; - @property (nonatomic, strong) SAAppClickTracker *appClickTracker; @property (nonatomic, strong) SAAppViewScreenTracker *appViewScreenTracker; @property (nonatomic, strong) SAAppPageLeaveTracker *appPageLeaveTracker; -+ (SAAutoTrackManager *)sharedInstance; ++ (SAAutoTrackManager *)defaultManager; #pragma mark - Public diff --git a/SensorsAnalyticsSDK/AutoTrack/SAAutoTrackManager.m b/SensorsAnalyticsSDK/AutoTrack/SAAutoTrackManager.m index 8e318684..c7f1f8d3 100644 --- a/SensorsAnalyticsSDK/AutoTrack/SAAutoTrackManager.m +++ b/SensorsAnalyticsSDK/AutoTrack/SAAutoTrackManager.m @@ -38,6 +38,8 @@ #import "SAGestureViewProcessorFactory.h" #import "SACommonUtility.h" #import "UIViewController+SAPageView.h" +#import "SAApplication.h" +#import "SensorsAnalyticsSDK+SAAutoTrack.h" @interface SAAutoTrackManager () @@ -51,7 +53,14 @@ @interface SAAutoTrackManager () @implementation SAAutoTrackManager -#pragma mark - SAModuleProtocol ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SAAutoTrackManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SAAutoTrackManager alloc] init]; + }); + return manager; +} - (instancetype)init { self = [super init]; @@ -72,6 +81,14 @@ - (instancetype)init { return self; } +- (void)setConfigOptions:(SAConfigOptions *)configOptions { + if ([SAApplication isAppExtension]) { + configOptions.enableAutoTrack = NO; + } + _configOptions = configOptions; + self.enable = configOptions.enableAutoTrack; +} + - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } @@ -81,22 +98,20 @@ - (void)setEnable:(BOOL)enable { if (enable) { [self enableAutoTrack]; + } else { + [self.appPageLeaveTracker.timestamp removeAllObjects]; } } -#pragma mark - Instance - -+ (SAAutoTrackManager *)sharedInstance { - return (SAAutoTrackManager *)[SAModuleManager.sharedInstance managerForModuleType:SAModuleTypeAutoTrack]; -} - #pragma mark - SAAutoTrackModuleProtocol - (void)trackAppEndWhenCrashed { + if (!self.enable) { + return; + } if (self.appEndTracker.isIgnored) { return; } - [SACommonUtility performBlockOnMainThread:^{ if (UIApplication.sharedApplication.applicationState == UIApplicationStateActive) { [self.appEndTracker autoTrackEvent]; @@ -105,6 +120,9 @@ - (void)trackAppEndWhenCrashed { } - (void)trackPageLeaveWhenCrashed { + if (!self.enable) { + return; + } if (!self.configOptions.enableTrackPageLeave) { return; } @@ -118,6 +136,9 @@ - (void)trackPageLeaveWhenCrashed { #pragma mark - Notification - (void)appLifecycleStateDidChange:(NSNotification *)sender { + if (!self.enable) { + return; + } NSDictionary *userInfo = sender.userInfo; SAAppLifecycleState newState = [userInfo[kSAAppLifecycleNewStateKey] integerValue]; SAAppLifecycleState oldState = [userInfo[kSAAppLifecycleOldStateKey] integerValue]; @@ -261,7 +282,6 @@ - (void)enableAutoTrack { dispatch_once(&onceToken, ^{ [self enableAppViewScreenAutoTrack]; [self enableAppClickAutoTrack]; - [self enableReactNativeAutoTrack]; [self enableAppPageLeave]; }); } @@ -305,12 +325,6 @@ - (void)enableAppClickAutoTrack { } -- (void)enableReactNativeAutoTrack { - if (NSClassFromString(@"RCTUIManager") && [SAModuleManager.sharedInstance contains:SAModuleTypeReactNative]) { - [SAModuleManager.sharedInstance setEnable:YES forModuleType:SAModuleTypeReactNative]; - } -} - - (void)enableAppPageLeave { if (!self.configOptions.enableTrackPageLeave) { return; diff --git a/SensorsAnalyticsSDK/AutoTrack/SensorsAnalyticsSDK+SAAutoTrack.h b/SensorsAnalyticsSDK/AutoTrack/SensorsAnalyticsSDK+SAAutoTrack.h index a11fa857..ad6a4c25 100644 --- a/SensorsAnalyticsSDK/AutoTrack/SensorsAnalyticsSDK+SAAutoTrack.h +++ b/SensorsAnalyticsSDK/AutoTrack/SensorsAnalyticsSDK+SAAutoTrack.h @@ -39,8 +39,6 @@ NS_ASSUME_NONNULL_BEGIN @end @interface UIView (SensorsAnalytics) -- (nullable UIViewController *)sensorsAnalyticsViewController __attribute__((deprecated("已过时"))); - /// viewID @property (nonatomic, copy) NSString* sensorsAnalyticsViewID; @@ -167,20 +165,16 @@ NS_ASSUME_NONNULL_BEGIN - (void)trackViewScreen:(UIViewController *)viewController; - (void)trackViewScreen:(UIViewController *)viewController properties:(nullable NSDictionary *)properties; -#pragma mark - Deprecated - /** - * @property - * * @abstract - * 打开 SDK 自动追踪,默认只追踪App 启动 / 关闭、进入页面 + * Track $AppViewScreen事件 * - * @discussion - * 该功能自动追踪 App 的一些行为,例如 SDK 初始化、App 启动 / 关闭、进入页面 等等,具体信息请参考文档: - * https://sensorsdata.cn/manual/ios_sdk.html - * 该功能默认关闭 + * @param url 当前页面url + * @param properties 用户扩展属性 */ -- (void)enableAutoTrack __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 autoTrackEventType"))); +- (void)trackViewScreen:(NSString *)url withProperties:(NSDictionary *)properties; + +#pragma mark - Deprecated /** * @property @@ -194,32 +188,30 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)enableAutoTrack:(SensorsAnalyticsAutoTrackEventType)eventType __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 autoTrackEventType"))); -/** - * @abstract - * 过滤掉 AutoTrack 的某个事件类型 - * - * @param eventType SensorsAnalyticsAutoTrackEventType 要忽略的 AutoTrack 事件类型 - */ -- (void)ignoreAutoTrackEventType:(SensorsAnalyticsAutoTrackEventType)eventType __attribute__((deprecated("已过时,请参考enableAutoTrack:(SensorsAnalyticsAutoTrackEventType)eventType"))); +@end -/** - * @abstract - * 判断某个 ViewController 是否被忽略 - * - * @param viewControllerClassName UIViewController 类名 - * - * @return YES:被忽略; NO:没有被忽略 - */ -- (BOOL)isViewControllerStringIgnored:(NSString *)viewControllerClassName __attribute__((deprecated("已过时,请参考 -(BOOL)isViewControllerIgnored:(UIViewController *)viewController"))); +@interface SAConfigOptions (AutoTrack) + +///开启自动采集页面浏览时长 +@property (nonatomic, assign) BOOL enableTrackPageLeave API_UNAVAILABLE(macos); + +/// 是否自动采集子页面的页面浏览事件 +/// +/// 开启页面浏览事件采集时,有效。默认为不采集 +@property (nonatomic) BOOL enableAutoTrackChildViewScreen API_UNAVAILABLE(macos); /** + * @property + * * @abstract - * Track $AppViewScreen事件 + * 打开 SDK 自动追踪,默认只追踪 App 启动 / 关闭、进入页面、元素点击 * - * @param url 当前页面url - * @param properties 用户扩展属性 + * @discussion + * 该功能自动追踪 App 的一些行为,例如 SDK 初始化、App 启动 / 关闭、进入页面 等等,具体信息请参考文档: + * https://sensorsdata.cn/manual/ios_sdk.html + * 该功能默认关闭 */ -- (void)trackViewScreen:(NSString *)url withProperties:(NSDictionary *)properties __attribute__((deprecated("已过时,请参考 trackViewScreen: properties:"))); +@property (nonatomic) SensorsAnalyticsAutoTrackEventType autoTrackEventType API_UNAVAILABLE(macos); @end diff --git a/SensorsAnalyticsSDK/AutoTrack/SensorsAnalyticsSDK+SAAutoTrack.m b/SensorsAnalyticsSDK/AutoTrack/SensorsAnalyticsSDK+SAAutoTrack.m index 5f9f7b92..a3c3e43b 100644 --- a/SensorsAnalyticsSDK/AutoTrack/SensorsAnalyticsSDK+SAAutoTrack.m +++ b/SensorsAnalyticsSDK/AutoTrack/SensorsAnalyticsSDK+SAAutoTrack.m @@ -25,7 +25,6 @@ #import "SensorsAnalyticsSDK+SAAutoTrack.h" #import "SensorsAnalyticsSDK+Private.h" #import "SAAutoTrackUtils.h" -#import "UIView+AutoTrack.h" #import "SAAutoTrackManager.h" #import "SAModuleManager.h" #import "SAWeakPropertyContainer.h" @@ -45,10 +44,6 @@ - (void)setSensorsAnalyticsImageName:(NSString *)sensorsAnalyticsImageName { @implementation UIView (SensorsAnalytics) -- (UIViewController *)sensorsAnalyticsViewController { - return self.sensorsdata_viewController; -} - //viewID - (NSString *)sensorsAnalyticsViewID { return objc_getAssociatedObject(self, @"sensorsAnalyticsViewID"); @@ -106,31 +101,31 @@ - (UIViewController *)currentViewController { } - (BOOL)isAutoTrackEnabled { - return [SAAutoTrackManager.sharedInstance isAutoTrackEnabled]; + return [SAAutoTrackManager.defaultManager isAutoTrackEnabled]; } #pragma mark - Ignore - (BOOL)isAutoTrackEventTypeIgnored:(SensorsAnalyticsAutoTrackEventType)eventType { - return [SAAutoTrackManager.sharedInstance isAutoTrackEventTypeIgnored:eventType]; + return [SAAutoTrackManager.defaultManager isAutoTrackEventTypeIgnored:eventType]; } - (void)ignoreViewType:(Class)aClass { - [SAAutoTrackManager.sharedInstance.appClickTracker ignoreViewType:aClass]; + [SAAutoTrackManager.defaultManager.appClickTracker ignoreViewType:aClass]; } - (BOOL)isViewTypeIgnored:(Class)aClass { - return [SAAutoTrackManager.sharedInstance.appClickTracker isViewTypeIgnored:aClass]; + return [SAAutoTrackManager.defaultManager.appClickTracker isViewTypeIgnored:aClass]; } - (void)ignoreAutoTrackViewControllers:(NSArray *)controllers { - [SAAutoTrackManager.sharedInstance.appClickTracker ignoreAutoTrackViewControllers:controllers]; - [SAAutoTrackManager.sharedInstance.appViewScreenTracker ignoreAutoTrackViewControllers:controllers]; + [SAAutoTrackManager.defaultManager.appClickTracker ignoreAutoTrackViewControllers:controllers]; + [SAAutoTrackManager.defaultManager.appViewScreenTracker ignoreAutoTrackViewControllers:controllers]; } - (BOOL)isViewControllerIgnored:(UIViewController *)viewController { - BOOL isIgnoreAppClick = [SAAutoTrackManager.sharedInstance.appClickTracker isViewControllerIgnored:viewController]; - BOOL isIgnoreAppViewScreen = [SAAutoTrackManager.sharedInstance.appViewScreenTracker isViewControllerIgnored:viewController]; + BOOL isIgnoreAppClick = [SAAutoTrackManager.defaultManager.appClickTracker isViewControllerIgnored:viewController]; + BOOL isIgnoreAppViewScreen = [SAAutoTrackManager.defaultManager.appViewScreenTracker isViewControllerIgnored:viewController]; return isIgnoreAppClick || isIgnoreAppViewScreen; } @@ -142,7 +137,7 @@ - (void)trackViewAppClick:(UIView *)view { } - (void)trackViewAppClick:(UIView *)view withProperties:(NSDictionary *)p { - [SAAutoTrackManager.sharedInstance.appClickTracker trackEventWithView:view properties:p]; + [SAAutoTrackManager.defaultManager.appClickTracker trackEventWithView:view properties:p]; } - (void)trackViewScreen:(UIViewController *)controller { @@ -150,44 +145,23 @@ - (void)trackViewScreen:(UIViewController *)controller { } - (void)trackViewScreen:(UIViewController *)controller properties:(nullable NSDictionary *)properties { - [SAAutoTrackManager.sharedInstance.appViewScreenTracker trackEventWithViewController:controller properties:properties]; + [SAAutoTrackManager.defaultManager.appViewScreenTracker trackEventWithViewController:controller properties:properties]; } -#pragma mark - Deprecated - -- (void)enableAutoTrack { - [self enableAutoTrack:SensorsAnalyticsEventTypeAppStart | SensorsAnalyticsEventTypeAppEnd | SensorsAnalyticsEventTypeAppViewScreen]; +- (void)trackViewScreen:(NSString *)url withProperties:(NSDictionary *)properties { + [SAAutoTrackManager.defaultManager.appViewScreenTracker trackEventWithURL:url properties:properties]; } +#pragma mark - Deprecated + - (void)enableAutoTrack:(SensorsAnalyticsAutoTrackEventType)eventType { if (self.configOptions.autoTrackEventType != eventType) { self.configOptions.autoTrackEventType = eventType; - [SAModuleManager.sharedInstance setEnable:YES forModuleType:SAModuleTypeAutoTrack]; + SAAutoTrackManager.defaultManager.enable = YES; - [SAAutoTrackManager.sharedInstance updateAutoTrackEventType]; - } -} - -- (void)ignoreAutoTrackEventType:(SensorsAnalyticsAutoTrackEventType)eventType { - if (!(self.configOptions.autoTrackEventType & eventType)) { - return; + [SAAutoTrackManager.defaultManager updateAutoTrackEventType]; } - - self.configOptions.autoTrackEventType = self.configOptions.autoTrackEventType ^ eventType; - - [SAAutoTrackManager.sharedInstance updateAutoTrackEventType]; -} - -- (BOOL)isViewControllerStringIgnored:(NSString *)viewControllerClassName { - BOOL isIgnoreAppClick = [SAAutoTrackManager.sharedInstance.appClickTracker isViewControllerStringIgnored:viewControllerClassName]; - BOOL isIgnoreAppViewScreen = [SAAutoTrackManager.sharedInstance.appViewScreenTracker isViewControllerStringIgnored:viewControllerClassName]; - - return isIgnoreAppClick || isIgnoreAppViewScreen; -} - -- (void)trackViewScreen:(NSString *)url withProperties:(NSDictionary *)properties { - [SAAutoTrackManager.sharedInstance.appViewScreenTracker trackEventWithURL:url properties:properties]; } @end diff --git a/SensorsAnalyticsSDK/ChannelMatch/SAChannelMatchManager.h b/SensorsAnalyticsSDK/ChannelMatch/SAChannelMatchManager.h index 1758cf36..bc4f4bf6 100644 --- a/SensorsAnalyticsSDK/ChannelMatch/SAChannelMatchManager.h +++ b/SensorsAnalyticsSDK/ChannelMatch/SAChannelMatchManager.h @@ -23,10 +23,17 @@ NS_ASSUME_NONNULL_BEGIN +@interface SAConfigOptions (ChannelMatchPrivate) + +@property (nonatomic, assign) BOOL enableChannelMatch; + +@end + @interface SAChannelMatchManager : NSObject -@property (nonatomic, assign, getter=isEnable) BOOL enable; ++ (instancetype)defaultManager; +@property (nonatomic, assign, getter=isEnable) BOOL enable; @property (nonatomic, strong) SAConfigOptions *configOptions; @end diff --git a/SensorsAnalyticsSDK/ChannelMatch/SAChannelMatchManager.m b/SensorsAnalyticsSDK/ChannelMatch/SAChannelMatchManager.m index 497c1f28..7ee0b89a 100644 --- a/SensorsAnalyticsSDK/ChannelMatch/SAChannelMatchManager.m +++ b/SensorsAnalyticsSDK/ChannelMatch/SAChannelMatchManager.m @@ -33,6 +33,8 @@ #import "SALog.h" #import "SAFileStore.h" #import "SAJSONUtil.h" +#import "SensorsAnalyticsSDK+SAChannelMatch.h" +#import "SAApplication.h" NSString * const kSAChannelDebugFlagKey = @"com.sensorsdata.channeldebug.flag"; NSString * const kSAChannelDebugInstallEventName = @"$ChannelDebugInstall"; @@ -50,6 +52,23 @@ @interface SAChannelMatchManager () @implementation SAChannelMatchManager ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SAChannelMatchManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SAChannelMatchManager alloc] init]; + }); + return manager; +} + +- (void)setConfigOptions:(SAConfigOptions *)configOptions { + if ([SAApplication isAppExtension]) { + configOptions.enableChannelMatch = NO; + } + _configOptions = configOptions; + self.enable = configOptions.enableChannelMatch; +} + #pragma mark - - (NSMutableSet *)trackChannelEventNames { @@ -86,7 +105,7 @@ - (UIWindow *)alertWindow { #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 130000) if (@available(iOS 13.0, *)) { __block UIWindowScene *scene = nil; - [[UIApplication sharedApplication].connectedScenes.allObjects enumerateObjectsUsingBlock:^(UIScene * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + [UIApplication.sharedApplication.connectedScenes.allObjects enumerateObjectsUsingBlock:^(UIScene * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj isKindOfClass:[UIWindowScene class]]) { scene = (UIWindowScene *)obj; *stop = YES; @@ -195,11 +214,7 @@ - (void)trackAppInstallEvent:(NSString *)event properties:(NSDictionary *)proper [profileProps removeObjectForKey:SA_EVENT_PROPERTY_APP_INSTALL_DISABLE_CALLBACK]; // 再发送 profile_set_once [profileProps setValue:[NSDate date] forKey:SA_EVENT_PROPERTY_APP_INSTALL_FIRST_VISIT_TIME]; - if (sdk.configOptions.enableMultipleChannelMatch) { - [sdk set:profileProps]; - } else { - [sdk setOnce:profileProps]; - } + [sdk setOnce:profileProps]; [sdk flush]; } diff --git a/SensorsAnalyticsSDK/ChannelMatch/SensorsAnalyticsSDK+SAChannelMatch.h b/SensorsAnalyticsSDK/ChannelMatch/SensorsAnalyticsSDK+SAChannelMatch.h index 3fab02fa..a7b3c0a2 100644 --- a/SensorsAnalyticsSDK/ChannelMatch/SensorsAnalyticsSDK+SAChannelMatch.h +++ b/SensorsAnalyticsSDK/ChannelMatch/SensorsAnalyticsSDK+SAChannelMatch.h @@ -120,4 +120,11 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface SAConfigOptions (ChannelMatch) + +/// 是否在手动埋点事件中自动添加渠道匹配信息 +@property (nonatomic, assign) BOOL enableAutoAddChannelCallbackEvent API_UNAVAILABLE(macos); + +@end + NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Core/Builder/EventObject/SAEventLibObject.m b/SensorsAnalyticsSDK/Core/Builder/EventObject/SAEventLibObject.m index 886d7636..d34b3dc6 100644 --- a/SensorsAnalyticsSDK/Core/Builder/EventObject/SAEventLibObject.m +++ b/SensorsAnalyticsSDK/Core/Builder/EventObject/SAEventLibObject.m @@ -39,7 +39,7 @@ - (instancetype)init { _lib = @"macOS"; #endif _method = kSALibMethodCode; - _version = [SensorsAnalyticsSDK.sharedInstance libVersion]; + _version = [SensorsAnalyticsSDK.sdkInstance libVersion]; _appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; _detail = nil; } diff --git a/SensorsAnalyticsSDK/Core/SAAppLifecycle.m b/SensorsAnalyticsSDK/Core/SAAppLifecycle.m index 38229a6a..089610c8 100644 --- a/SensorsAnalyticsSDK/Core/SAAppLifecycle.m +++ b/SensorsAnalyticsSDK/Core/SAAppLifecycle.m @@ -24,6 +24,7 @@ #import "SAAppLifecycle.h" #import "SALog.h" +#import "SAApplication.h" #if TARGET_OS_IOS #import @@ -60,9 +61,13 @@ - (void)dealloc { } - (void)setupLaunchedState { + if ([SAApplication isAppExtension]) { + return; + } dispatch_block_t mainThreadBlock = ^(){ #if TARGET_OS_IOS - BOOL isAppStateBackground = UIApplication.sharedApplication.applicationState == UIApplicationStateBackground; + UIApplication *application = [SAApplication sharedApplication]; + BOOL isAppStateBackground = application.applicationState == UIApplicationStateBackground; #else BOOL isAppStateBackground = NO; #endif @@ -110,6 +115,10 @@ - (void)setState:(SAAppLifecycleState)state { #pragma mark - Listener - (void)setupListeners { + // app extension does not need state observer + if ([SAApplication isAppExtension]) { + return; + } // 监听 App 启动或结束事件 NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; @@ -158,7 +167,8 @@ - (void)applicationDidFinishLaunching:(NSNotification *)notification { SALogDebug(@"application did finish launching"); #if TARGET_OS_IOS - BOOL isAppStateBackground = UIApplication.sharedApplication.applicationState == UIApplicationStateBackground; + UIApplication *application = [SAApplication sharedApplication]; + BOOL isAppStateBackground = application.applicationState == UIApplicationStateBackground; self.state = isAppStateBackground ? SAAppLifecycleStateStartPassively : SAAppLifecycleStateStart; #else self.state = SAAppLifecycleStateStart; diff --git a/SensorsAnalyticsSDK/Core/SAApplication.h b/SensorsAnalyticsSDK/Core/SAApplication.h new file mode 100644 index 00000000..52c1de2c --- /dev/null +++ b/SensorsAnalyticsSDK/Core/SAApplication.h @@ -0,0 +1,32 @@ +// +// SAApplication.h +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/8. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SAApplication : NSObject + ++ (id)sharedApplication; ++ (BOOL)isAppExtension; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Core/SAApplication.m b/SensorsAnalyticsSDK/Core/SAApplication.m new file mode 100644 index 00000000..2176fe89 --- /dev/null +++ b/SensorsAnalyticsSDK/Core/SAApplication.m @@ -0,0 +1,60 @@ +// +// SAApplication.m +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/8. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#if ! __has_feature(objc_arc) +#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag on this file. +#endif + +#import "SAApplication.h" + +#if TARGET_OS_IOS +#import +#endif + +@implementation SAApplication + ++ (id)sharedApplication { +#if TARGET_OS_IOS + Class applicationClass = NSClassFromString(@"UIApplication"); + if (!applicationClass) { + return nil; + } + SEL sharedApplicationSEL = NSSelectorFromString(@"sharedApplication"); + if (!sharedApplicationSEL) { + return nil; + } + id (*sharedApplication)(id, SEL) = (id (*)(id, SEL))[applicationClass methodForSelector:sharedApplicationSEL]; + id application = sharedApplication(applicationClass, sharedApplicationSEL); + return application; +#else + return nil; +#endif +} + ++ (BOOL)isAppExtension { + NSString *bundlePath = [[NSBundle mainBundle] executablePath]; + if (!bundlePath) { + return NO; + } + + return [bundlePath containsString:@".appex/"]; +} + +@end diff --git a/SensorsAnalyticsSDK/Core/SAConfigOptions.h b/SensorsAnalyticsSDK/Core/SAConfigOptions.h index 96021fe9..762ce05b 100644 --- a/SensorsAnalyticsSDK/Core/SAConfigOptions.h +++ b/SensorsAnalyticsSDK/Core/SAConfigOptions.h @@ -45,30 +45,6 @@ NS_ASSUME_NONNULL_BEGIN /// 禁用 new 初始化 + (instancetype)new NS_UNAVAILABLE; -/** - * @property - * - * @abstract - * 打开 SDK 自动追踪,默认只追踪 App 启动 / 关闭、进入页面、元素点击 - * - * @discussion - * 该功能自动追踪 App 的一些行为,例如 SDK 初始化、App 启动 / 关闭、进入页面 等等,具体信息请参考文档: - * https://sensorsdata.cn/manual/ios_sdk.html - * 该功能默认关闭 - */ -@property (nonatomic) SensorsAnalyticsAutoTrackEventType autoTrackEventType API_UNAVAILABLE(macos); - -/// 是否自动采集子页面的页面浏览事件 -/// -/// 开启页面浏览事件采集时,有效。默认为不采集 -@property (nonatomic) BOOL enableAutoTrackChildViewScreen API_UNAVAILABLE(macos); - -/// 是否开启 WKWebView 的 H5 打通功能,该功能默认是关闭的 -@property (nonatomic) BOOL enableJavaScriptBridge; - -/// 是否自动收集 App Crash 日志,该功能默认是关闭的 -@property (nonatomic) BOOL enableTrackAppCrash API_UNAVAILABLE(macos); - /** @abstract 用于评估是否为服务器信任的安全链接。 @@ -94,7 +70,7 @@ NS_ASSUME_NONNULL_BEGIN * 两次数据发送的最小时间间隔,单位毫秒 * * @discussion - * 默认值为 15 * 1000 毫秒, 在每次调用 track、trackSignUp 以及 profileSet 等接口的时候, + * 默认值为 15 * 1000 毫秒, 在每次调用 track 和 profileSet 等接口的时候, * 都会检查如下条件,以判断是否向服务器上传数据: * 1. 是否 WIFI/3G/4G/5G 网络 * 2. 是否满足以下数据发送条件之一: @@ -112,7 +88,7 @@ NS_ASSUME_NONNULL_BEGIN * 本地缓存的最大事件数目,当累积日志量达到阈值时发送数据 * * @discussion - * 默认值为 100,在每次调用 track、trackSignUp 以及 profileSet 等接口的时候,都会检查如下条件,以判断是否向服务器上传数据: + * 默认值为 100,在每次调用 track 和 profileSet 等接口的时候,都会检查如下条件,以判断是否向服务器上传数据: * 1. 是否 WIFI/3G/4G/5G 网络 * 2. 是否满足以下数据发送条件之一: * 1) 与上次发送的时间间隔是否大于 flushInterval @@ -133,59 +109,10 @@ NS_ASSUME_NONNULL_BEGIN /// 禁用后,SDK 将不会触发事件,也不会发送网络请求 @property (nonatomic, assign) BOOL disableSDK; -/// 开启点击图 -@property (nonatomic, assign) BOOL enableHeatMap API_UNAVAILABLE(macos); - -/// 开启可视化全埋点 -@property (nonatomic, assign) BOOL enableVisualizedAutoTrack API_UNAVAILABLE(macos); - -#pragma mark - 请求远程配置策略 -/// 请求远程配置地址,默认从 serverURL 解析 -@property (nonatomic, copy) NSString *remoteConfigURL API_UNAVAILABLE(macos); - -/// 禁用随机时间请求远程配置 -@property (nonatomic, assign) BOOL disableRandomTimeRequestRemoteConfig API_UNAVAILABLE(macos); - -/// 最小间隔时长,单位:小时,默认 24 -@property (nonatomic, assign) NSInteger minRequestHourInterval API_UNAVAILABLE(macos); - -/// 最大间隔时长,单位:小时,默认 48 -@property (nonatomic, assign) NSInteger maxRequestHourInterval API_UNAVAILABLE(macos); - -/// DeepLink 中解析出来的参数是否需要保存到本地 -@property (nonatomic, assign) BOOL enableSaveDeepLinkInfo API_UNAVAILABLE(macos); - -/// DeepLink 中用户自定义来源渠道属性 key 值,可传多个。 -@property (nonatomic, copy) NSArray *sourceChannels API_UNAVAILABLE(macos); - -/// 是否在手动埋点事件中自动添加渠道匹配信息 -@property (nonatomic, assign) BOOL enableAutoAddChannelCallbackEvent API_UNAVAILABLE(macos); /// App 进入后台时是否等待数据发送结果。默认 YES,会等待数据发送结果;设置 NO,不会等待数据发送结果 @property (nonatomic, assign) BOOL flushBeforeEnterBackground; -/// 是否开启加密 -@property (nonatomic, assign) BOOL enableEncrypt API_UNAVAILABLE(macos); - -/// 存储公钥的回调。务必保存秘钥所有字段信息 -@property (nonatomic, copy) void (^saveSecretKey)(SASecretKey * _Nonnull secretKey) API_UNAVAILABLE(macos); - -/// 获取公钥的回调。务必回传秘钥所有字段信息 -@property (nonatomic, copy) SASecretKey * _Nonnull (^loadSecretKey)(void) API_UNAVAILABLE(macos); - -/// 是否开启多渠道匹配,开启后调用 profile_set,不开启则调用 profile_set_once -@property (nonatomic, assign) BOOL enableMultipleChannelMatch API_UNAVAILABLE(macos); - -/// 开启前向页面标题采集功能,默认不开启 -@property (nonatomic, assign) BOOL enableReferrerTitle API_UNAVAILABLE(macos); - -///开启自动采集通知 -@property (nonatomic, assign) BOOL enableTrackPush API_UNAVAILABLE(macos); - -///开启自动采集页面浏览时长 -@property (nonatomic, assign) BOOL enableTrackPageLeave API_UNAVAILABLE(macos); - - @end NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Core/SAConfigOptions.m b/SensorsAnalyticsSDK/Core/SAConfigOptions.m index bee20334..c52b5dbf 100644 --- a/SensorsAnalyticsSDK/Core/SAConfigOptions.m +++ b/SensorsAnalyticsSDK/Core/SAConfigOptions.m @@ -28,6 +28,41 @@ @interface SAConfigOptions () @property (atomic, strong, readwrite) NSMutableArray *encryptors; +@property (nonatomic, assign) BOOL enableTrackPush; + +@property (nonatomic, assign) BOOL enableHeatMap; +@property (nonatomic, assign) BOOL enableVisualizedAutoTrack; +@property (nonatomic, assign) BOOL enableVisualizedProperties; + +@property (nonatomic, assign) BOOL enableTrackAppCrash; + +@property (nonatomic, assign) BOOL enableEncrypt; +@property (nonatomic, copy) void (^saveSecretKey)(SASecretKey * _Nonnull secretKey); +@property (nonatomic, copy) SASecretKey * _Nonnull (^loadSecretKey)(void); + +@property (nonatomic, assign) BOOL enableSaveDeepLinkInfo; +@property (nonatomic, copy) NSArray *sourceChannels; +@property (nonatomic, assign) BOOL enableAutoAddChannelCallbackEvent; + +@property (nonatomic) BOOL enableJavaScriptBridge; + +@property (nonatomic, copy) NSString *remoteConfigURL; +@property (nonatomic, assign) BOOL disableRandomTimeRequestRemoteConfig; +@property (nonatomic, assign) NSInteger minRequestHourInterval; +@property (nonatomic, assign) NSInteger maxRequestHourInterval; + +@property (nonatomic, assign) BOOL enableTrackPageLeave; +@property (nonatomic) BOOL enableAutoTrackChildViewScreen; +@property (nonatomic) SensorsAnalyticsAutoTrackEventType autoTrackEventType; + +//private switch +@property (nonatomic, assign) BOOL enableLocation; +@property (nonatomic, assign) BOOL enableDeviceOrientation; +@property (nonatomic, assign) BOOL enableRemoteConfig; +@property (nonatomic, assign) BOOL enableChannelMatch; +@property (nonatomic, assign) BOOL enableDebugMode; +@property (nonatomic, assign) BOOL enableDeeplink; +@property (nonatomic, assign) BOOL enableAutoTrack; @end @@ -61,6 +96,13 @@ - (instancetype)initWithServerURL:(NSString *)serverURL launchOptions:(id)launch #endif #endif SensorsAnalyticsNetworkTypeWIFI; + + //default private switch + _enableRemoteConfig = YES; + _enableChannelMatch = YES; + _enableDebugMode = YES; + _enableDeeplink = YES; + _enableAutoTrack = YES; } return self; } @@ -96,20 +138,27 @@ - (id)copyWithZone:(nullable NSZone *)zone { // 全埋点 options.autoTrackEventType = self.autoTrackEventType; options.enableAutoTrackChildViewScreen = self.enableAutoTrackChildViewScreen; - options.enableReferrerTitle = self.enableReferrerTitle; options.enableHeatMap = self.enableHeatMap; options.enableVisualizedAutoTrack = self.enableVisualizedAutoTrack; + options.enableVisualizedProperties = self.enableVisualizedProperties; + // Crash 采集 options.enableTrackAppCrash = self.enableTrackAppCrash; // 渠道相关 options.enableSaveDeepLinkInfo = self.enableSaveDeepLinkInfo; options.sourceChannels = self.sourceChannels; - options.enableMultipleChannelMatch = self.enableMultipleChannelMatch; options.enableAutoAddChannelCallbackEvent = self.enableAutoAddChannelCallbackEvent; // 推送点击 options.enableTrackPush = self.enableTrackPush; // 页面浏览时长 options.enableTrackPageLeave = self.enableTrackPageLeave; + + //private switch + options.enableRemoteConfig = self.enableRemoteConfig; + options.enableChannelMatch = self.enableChannelMatch; + options.enableDebugMode = self.enableDebugMode; + options.enableDeeplink = self.enableDeeplink; + options.enableAutoTrack = self.enableAutoTrack; #endif return options; diff --git a/SensorsAnalyticsSDK/Core/SAModuleManager.h b/SensorsAnalyticsSDK/Core/SAModuleManager.h index 1882dacb..facfcb5b 100644 --- a/SensorsAnalyticsSDK/Core/SAModuleManager.h +++ b/SensorsAnalyticsSDK/Core/SAModuleManager.h @@ -23,21 +23,9 @@ NS_ASSUME_NONNULL_BEGIN -typedef NS_ENUM(NSUInteger, SAModuleType) { - SAModuleTypeLocation, - SAModuleTypeVisualized, - SAModuleTypeDeviceOrientation, - SAModuleTypeReactNative, - SAModuleTypeAppPush, - SAModuleTypeAutoTrack, - SAModuleTypeJavaScriptBridge, - SAModuleTypeRemoteConfig, - SAModuleTypeException, -}; - @interface SAModuleManager : NSObject -+ (void)startWithConfigOptions:(SAConfigOptions *)configOptions debugMode:(SensorsAnalyticsDebugMode)debugMode; ++ (void)startWithConfigOptions:(SAConfigOptions *)configOptions; + (instancetype)sharedInstance; @@ -46,21 +34,6 @@ typedef NS_ENUM(NSUInteger, SAModuleType) { /// 关闭所有的模块功能 - (void)disableAllModules; -/// 当前 SDK 中是否包含特定类型的模块 -/// @param type 需要判断的模块类型 -/// @return 是否包含 -- (BOOL)contains:(SAModuleType)type; - -/// 通过模块类型获取模块的管理类 -/// @param type 模块类型 -/// @return 模块管理类 -- (nullable id)managerForModuleType:(SAModuleType)type; - -/// 开启或关闭某种类型的模块 -/// @param enable 开启或者关闭 -/// @param type 模块类型 -- (void)setEnable:(BOOL)enable forModuleType:(SAModuleType)type; - /// 更新数据接收地址 /// @param serverURL 新的数据接收地址 - (void)updateServerURL:(NSString *)serverURL; diff --git a/SensorsAnalyticsSDK/Core/SAModuleManager.m b/SensorsAnalyticsSDK/Core/SAModuleManager.m index fde27f6a..c799d6b1 100644 --- a/SensorsAnalyticsSDK/Core/SAModuleManager.m +++ b/SensorsAnalyticsSDK/Core/SAModuleManager.m @@ -32,7 +32,6 @@ static NSString * const kSALocationModuleName = @"Location"; static NSString * const kSADeviceOrientationModuleName = @"DeviceOrientation"; static NSString * const kSADebugModeModuleName = @"DebugMode"; -static NSString * const kSAReactNativeModuleName = @"ReactNative"; static NSString * const kSAChannelMatchModuleName = @"ChannelMatch"; /// 可视化相关(可视化全埋点和点击图) static NSString * const kSAVisualizedModuleName = @"Visualized"; @@ -49,7 +48,7 @@ @interface SAModuleManager () /// 已开启的模块 -@property (nonatomic, strong) SAThreadSafeDictionary> *modules; +@property (nonatomic, strong) NSArray *moduleNames; @property (nonatomic, strong) SAConfigOptions *configOptions; @@ -57,63 +56,13 @@ @interface SAModuleManager () @implementation SAModuleManager -+ (void)startWithConfigOptions:(SAConfigOptions *)configOptions debugMode:(SensorsAnalyticsDebugMode)debugMode { ++ (void)startWithConfigOptions:(SAConfigOptions *)configOptions { SAModuleManager.sharedInstance.configOptions = configOptions; // 禁止 SDK 时,不开启其他模块 if (configOptions.disableSDK) { return; } - - // H5 打通模块 - if (configOptions.enableJavaScriptBridge) { - [SAModuleManager.sharedInstance setEnable:YES forModule:kSAJavaScriptBridgeModuleName]; - } - -#if TARGET_OS_IOS - // 推送点击模块 - if (configOptions.enableTrackPush) { - [SAModuleManager.sharedInstance setEnable:YES forModule:kSANotificationModuleName]; - } - - // 渠道联调诊断功能获取多渠道匹配开关 - [SAModuleManager.sharedInstance setEnable:YES forModule:kSAChannelMatchModuleName]; - - // 初始化 LinkHandler 处理 deepLink 相关操作 - [SAModuleManager.sharedInstance setEnable:YES forModule:kSADeeplinkModuleName]; - - // 初始化 Debug 模块 - [SAModuleManager.sharedInstance setEnable:YES forModule:kSADebugModeModuleName]; - [SAModuleManager.sharedInstance handleDebugMode:debugMode]; - - // 默认加载全埋点模块,没有判断是否开启全埋点,原因如下: - // 1. 同之前的逻辑保持一致 - // 2. 保证添加对于生命周期的监听在生命周期类的实例化之前 - if ([SAModuleManager.sharedInstance contains:SAModuleTypeAutoTrack] || configOptions.autoTrackEventType != SensorsAnalyticsEventTypeNone) { - [SAModuleManager.sharedInstance setEnable:YES forModuleType:SAModuleTypeAutoTrack]; - } - - // 可视化全埋点和点击分析 - if (configOptions.enableHeatMap || configOptions.enableVisualizedAutoTrack) { - [SAModuleManager.sharedInstance setEnable:YES forModule:kSAVisualizedModuleName]; - [SAModuleManager.sharedInstance setEnable:YES forModule:kSAJavaScriptBridgeModuleName]; - } else if ([SAModuleManager.sharedInstance contains:SAModuleTypeVisualized]) { - // 注册 handleURL - [SAModuleManager.sharedInstance setEnable:NO forModule:kSAVisualizedModuleName]; - } - - // 加密 - [SAModuleManager.sharedInstance setEnable:configOptions.enableEncrypt forModule:kSAEncryptModuleName]; - - // crash 采集 - if (configOptions.enableTrackAppCrash) { - [SAModuleManager.sharedInstance setEnable:YES forModule:kSAExceptionModuleName]; - } - - // 开启远程配置模块(因为部分模块依赖于远程配置,所以远程配置模块的初始化放到最后) - [SAModuleManager.sharedInstance setEnable:YES forModule:kSARemoteConfigModuleName]; - -#endif - + [[SAModuleManager sharedInstance] loadModulesWithConfigOptions:configOptions]; } + (instancetype)sharedInstance { @@ -121,58 +70,63 @@ + (instancetype)sharedInstance { static SAModuleManager *manager = nil; dispatch_once(&onceToken, ^{ manager = [[SAModuleManager alloc] init]; - manager.modules = [SAThreadSafeDictionary dictionary]; }); return manager; } #pragma mark - Private +- (NSString *)classNameForModule:(NSString *)moduleName { + return [NSString stringWithFormat:@"SA%@Manager", moduleName]; +} -- (NSString *)moduleNameForType:(SAModuleType)type { - switch (type) { - case SAModuleTypeLocation: - return kSALocationModuleName; - case SAModuleTypeDeviceOrientation: - return kSADeviceOrientationModuleName; - case SAModuleTypeReactNative: - return kSAReactNativeModuleName; - case SAModuleTypeAppPush: - return kSANotificationModuleName; - case SAModuleTypeAutoTrack: - return kSAAutoTrackModuleName; - case SAModuleTypeVisualized: - return kSAVisualizedModuleName; - case SAModuleTypeJavaScriptBridge: - return kSAJavaScriptBridgeModuleName; - case SAModuleTypeRemoteConfig: - return kSARemoteConfigModuleName; - case SAModuleTypeException: - return kSAExceptionModuleName; - default: - return nil; +- (id)moduleWithName:(NSString *)moduleName { + NSString *className = [self classNameForModule: moduleName]; + Class moduleClass = NSClassFromString(className); + if (!moduleClass) { + return nil; } -} + SEL sharedManagerSEL = NSSelectorFromString(@"defaultManager"); + if (![moduleClass respondsToSelector:sharedManagerSEL]) { + return nil; + } + id (*sharedManager)(id, SEL) = (id (*)(id, SEL))[moduleClass methodForSelector:sharedManagerSEL]; -- (NSString *)classNameForModule:(NSString *)moduleName { - return [NSString stringWithFormat:@"SA%@Manager", moduleName]; + id module = sharedManager(moduleClass, sharedManagerSEL); + return module; } -- (void)setEnable:(BOOL)enable forModule:(NSString *)moduleName { - if (self.modules[moduleName]) { - self.modules[moduleName].enable = enable; - } else { - NSString *className = [self classNameForModule:moduleName]; - Class cla = NSClassFromString(className); - NSAssert(cla, @"\n您使用接口开启了 %@ 模块,但是并没有集成该模块。\n • 如果使用源码集成神策分析 iOS SDK,请检查是否包含名为 %@ 的文件?\n • 如果使用 CocoaPods 集成 SDK,请修改 Podfile 文件,增加 %@ 模块的 subspec,例如:pod 'SensorsAnalyticsSDK', :subspecs => ['Core', '%@']。\n", moduleName, className, moduleName, moduleName); - if ([cla conformsToProtocol:@protocol(SAModuleProtocol)]) { - id object = [[(Class)cla alloc] init]; - if ([object respondsToSelector:@selector(setConfigOptions:)]) { - object.configOptions = self.configOptions; - } - object.enable = enable; - self.modules[moduleName] = object; +// module加载 +- (void)loadModulesWithConfigOptions:(SAConfigOptions *)configOptions { + [self loadModule:kSAJavaScriptBridgeModuleName withConfigOptions:configOptions]; +#if TARGET_OS_IOS + for (NSString *moduleName in self.moduleNames) { + if ([moduleName isEqualToString:kSAJavaScriptBridgeModuleName]) { + continue; } + [self loadModule:moduleName withConfigOptions:configOptions]; + } +#endif +} + +- (void)loadModule:(NSString *)moduleName withConfigOptions:(SAConfigOptions *)configOptions { + if (!moduleName) { + return; + } + id module = [self moduleWithName:moduleName]; + if (!module) { + return; } + if ([module conformsToProtocol:@protocol(SAModuleProtocol)] && [module respondsToSelector:@selector(setConfigOptions:)]) { + idmoduleObject = (id)module; + moduleObject.configOptions = configOptions; + } +} + +- (NSArray *)moduleNames { + return @[kSAJavaScriptBridgeModuleName, kSANotificationModuleName, kSAChannelMatchModuleName, + kSADeeplinkModuleName, kSADebugModeModuleName, kSALocationModuleName, + kSAAutoTrackModuleName, kSAVisualizedModuleName, kSAEncryptModuleName, + kSADeviceOrientationModuleName, kSAExceptionModuleName, kSARemoteConfigModuleName]; } #pragma mark - Public @@ -181,59 +135,56 @@ - (BOOL)isDisableSDK { if (self.configOptions.disableSDK) { return YES; } - id manager = (id)self.modules[kSARemoteConfigModuleName]; - return manager.isEnable ? manager.isDisableSDK : NO; + id module = [self moduleWithName:kSARemoteConfigModuleName]; + if ([module conformsToProtocol:@protocol(SARemoteConfigModuleProtocol)] && [module conformsToProtocol:@protocol(SAModuleProtocol)]) { + id manager = module; + return manager.isEnable ? manager.isDisableSDK : NO; + } + return NO; } - (void)disableAllModules { - NSArray *allKeys = self.modules.allKeys; - for (NSString *key in allKeys) { - // 这两个模块是使用接口开启,所以在 SAConfigOptions 中不存在标记,无法重新开启 - // 当定位弹窗出现时,如果关闭了定位模块,会导致弹窗消失 - if (![key isEqualToString:kSALocationModuleName] && - ![key isEqualToString:kSADeviceOrientationModuleName] && - ![key isEqualToString:kSADebugModeModuleName] && - ![key isEqualToString:kSAEncryptModuleName] - ) { - [self.modules removeObjectForKey:key]; + for (NSString *moduleName in self.moduleNames) { + id module = [self moduleWithName:moduleName]; + if (!module) { + continue; + } + if ([module conformsToProtocol:@protocol(SAModuleProtocol)] && [module respondsToSelector:@selector(setEnable:)]) { + idmoduleObject = module; + moduleObject.enable = NO; } } } -- (BOOL)contains:(SAModuleType)type { - NSString *moduleName = [self moduleNameForType:type]; - NSString *className = [self classNameForModule:moduleName]; - return [NSClassFromString(className) conformsToProtocol:@protocol(SAModuleProtocol)]; -} - -- (id)managerForModuleType:(SAModuleType)type { - NSString *name = [self moduleNameForType:type]; - return self.modules[name]; -} - -- (void)setEnable:(BOOL)enable forModuleType:(SAModuleType)type { - NSString *name = [self moduleNameForType:type]; - [self setEnable:enable forModule:name]; -} - - (void)updateServerURL:(NSString *)serverURL { - [self.modules enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { - if (!([obj conformsToProtocol:@protocol(SAModuleProtocol)] && [obj respondsToSelector:@selector(updateServerURL:)]) || !obj.isEnable) { - return; + for (NSString *moduleName in self.moduleNames) { + id module = [self moduleWithName:moduleName]; + if (!module) { + continue; + } + if ([module conformsToProtocol:@protocol(SAModuleProtocol)] && [module respondsToSelector:@selector(isEnable)] && [module respondsToSelector:@selector(updateServerURL:)]) { + idmoduleObject = module; + moduleObject.isEnable ? [module updateServerURL:serverURL] : nil; } - [obj updateServerURL:serverURL]; - }]; + } } #pragma mark - Open URL - (BOOL)canHandleURL:(NSURL *)url { - for (id obj in self.modules.allValues) { - if (![obj conformsToProtocol:@protocol(SAOpenURLProtocol)]) { + for (NSString *moduleName in self.moduleNames) { + id module = [self moduleWithName:moduleName]; + if (!module) { + continue; + } + if (![module conformsToProtocol:@protocol(SAOpenURLProtocol)]) { + continue; + } + if (![module respondsToSelector:@selector(canHandleURL:)]) { continue; } - id manager = (id)obj; - if ([manager canHandleURL:url]) { + idmoduleObject = module; + if ([moduleObject canHandleURL:url]) { return YES; } } @@ -241,13 +192,20 @@ - (BOOL)canHandleURL:(NSURL *)url { } - (BOOL)handleURL:(NSURL *)url { - for (id obj in self.modules.allValues) { - if (![obj conformsToProtocol:@protocol(SAOpenURLProtocol)]) { + for (NSString *moduleName in self.moduleNames) { + id module = [self moduleWithName:moduleName]; + if (!module) { continue; } - id manager = (id)obj; - if ([manager canHandleURL:url]) { - return [manager handleURL:url]; + if (![module conformsToProtocol:@protocol(SAOpenURLProtocol)]) { + continue; + } + if (![module respondsToSelector:@selector(canHandleURL:)] || ![module respondsToSelector:@selector(handleURL:)]) { + continue; + } + idmoduleObject = module; + if ([moduleObject canHandleURL:url]) { + return [moduleObject handleURL:url]; } } return NO; @@ -262,25 +220,37 @@ @implementation SAModuleManager (Property) - (NSDictionary *)properties { NSMutableDictionary *properties = [NSMutableDictionary dictionary]; // 兼容使用宏定义的方式源码集成 SDK - [self.modules enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { - if (!([obj conformsToProtocol:@protocol(SAPropertyModuleProtocol)] && [obj respondsToSelector:@selector(properties)]) || !obj.isEnable) { - return; + for (NSString *moduleName in self.moduleNames) { + id module = [self moduleWithName:moduleName]; + if (!module) { + continue; + } + if (![module conformsToProtocol:@protocol(SAPropertyModuleProtocol)] || ![module conformsToProtocol:@protocol(SAModuleProtocol)]) { + continue; + } + if (![module respondsToSelector:@selector(properties)] && [module respondsToSelector:@selector(isEnable)]) { + continue; + } + idmoduleObject = module; + if (!moduleObject.isEnable) { + continue; } - id manager = (id)obj; #ifndef SENSORS_ANALYTICS_DISABLE_TRACK_GPS - if ([key isEqualToString:kSALocationModuleName]) { - return [properties addEntriesFromDictionary:manager.properties]; + if ([moduleName isEqualToString:kSALocationModuleName]) { + [properties addEntriesFromDictionary:moduleObject.properties]; + continue; } #endif #ifndef SENSORS_ANALYTICS_DISABLE_TRACK_DEVICE_ORIENTATION - if ([key isEqualToString:kSADeviceOrientationModuleName]) { - return [properties addEntriesFromDictionary:manager.properties]; + if ([moduleName isEqualToString:kSADeviceOrientationModuleName]) { + [properties addEntriesFromDictionary:moduleObject.properties]; + continue; } #endif - if (manager.properties.count > 0) { - [properties addEntriesFromDictionary:manager.properties]; + if (moduleObject.properties.count > 0) { + [properties addEntriesFromDictionary:moduleObject.properties]; } - }]; + } return properties; } @@ -291,8 +261,12 @@ - (NSDictionary *)properties { @implementation SAModuleManager (ChannelMatch) - (id)channelMatchManager { - id manager = (id)self.modules[kSAChannelMatchModuleName]; - return manager.isEnable ? manager : nil; + id module = [self moduleWithName:kSAChannelMatchModuleName]; + if ([module conformsToProtocol:@protocol(SAChannelMatchModuleProtocol)] && [module conformsToProtocol:@protocol(SAModuleProtocol)]) { + id manager = module; + return manager.isEnable ? manager : nil; + } + return nil; } - (void)trackAppInstall:(NSString *)event properties:(NSDictionary *)properties disableCallback:(BOOL)disableCallback { @@ -314,7 +288,12 @@ - (NSDictionary *)channelInfoWithEvent:(NSString *)event { @implementation SAModuleManager (DebugMode) - (id)debugModeManager { - return (id)self.modules[kSADebugModeModuleName]; + id module = [self moduleWithName:kSADebugModeModuleName]; + if ([module conformsToProtocol:@protocol(SADebugModeModuleProtocol)] && [module conformsToProtocol:@protocol(SAModuleProtocol)]) { + id manager = module; + return manager.isEnable ? manager : nil; + } + return nil; } - (void)setDebugMode:(SensorsAnalyticsDebugMode)debugMode { @@ -343,8 +322,12 @@ - (void)showDebugModeWarning:(NSString *)message { @implementation SAModuleManager (Encrypt) - (id)encryptManager { - id manager = (id)self.modules[kSAEncryptModuleName]; - return manager.isEnable ? manager : nil; + id module = [self moduleWithName:kSAEncryptModuleName]; + if ([module conformsToProtocol:@protocol(SAEncryptModuleProtocol)] && [module conformsToProtocol:@protocol(SAModuleProtocol)]) { + id manager = module; + return manager.isEnable ? manager : nil; + } + return nil; } - (BOOL)hasSecretKey { @@ -366,8 +349,12 @@ - (void)handleEncryptWithConfig:(nonnull NSDictionary *)encryptConfig { @implementation SAModuleManager (Deeplink) - (id)deeplinkManager { - id manager = (id)self.modules[kSADeeplinkModuleName]; - return manager; + id module = [self moduleWithName:kSADeeplinkModuleName]; + if ([module conformsToProtocol:@protocol(SADeeplinkModuleProtocol)] && [module conformsToProtocol:@protocol(SAModuleProtocol)]) { + id manager = module; + return manager.isEnable ? manager : nil; + } + return nil; } - (void)setLinkHandlerCallback:(void (^ _Nonnull)(NSString * _Nullable, BOOL, NSInteger))linkHandlerCallback { @@ -397,8 +384,12 @@ - (void)trackDeepLinkLaunchWithURL:(NSString *)url { @implementation SAModuleManager (AutoTrack) - (id)autoTrackManager { - id manager = (id)self.modules[kSAAutoTrackModuleName]; - return manager.isEnable ? manager : nil; + id module = [self moduleWithName:kSAAutoTrackModuleName]; + if ([module conformsToProtocol:@protocol(SAAutoTrackModuleProtocol)] && [module conformsToProtocol:@protocol(SAModuleProtocol)]) { + id manager = module; + return manager.isEnable ? manager : nil; + } + return nil; } - (void)trackAppEndWhenCrashed { @@ -415,26 +406,34 @@ - (void)trackPageLeaveWhenCrashed { @implementation SAModuleManager (Visualized) +- (id)visualizedManager { + id module = [self moduleWithName:kSAVisualizedModuleName]; + if ([module conformsToProtocol:@protocol(SAVisualizedModuleProtocol)] && [module conformsToProtocol:@protocol(SAModuleProtocol)]) { + id manager = module; + return manager.isEnable ? manager : nil; + } + return nil; +} + #pragma mark properties // 采集元素属性 - (nullable NSDictionary *)propertiesWithView:(id)view { - id manager = (id)[SAModuleManager.sharedInstance managerForModuleType:SAModuleTypeVisualized]; - return [manager propertiesWithView:view]; + return [self.visualizedManager propertiesWithView:view]; } #pragma mark visualProperties // 采集元素自定义属性 - (void)visualPropertiesWithView:(id)view completionHandler:(void (^)(NSDictionary *_Nullable))completionHandler { - id manager = (id)[SAModuleManager.sharedInstance managerForModuleType:SAModuleTypeVisualized]; + id manager = self.visualizedManager; if (!manager) { return completionHandler(nil); } - [manager visualPropertiesWithView:view completionHandler:completionHandler]; + [self.visualizedManager visualPropertiesWithView:view completionHandler:completionHandler]; } // 根据属性配置,采集 App 属性值 - (void)queryVisualPropertiesWithConfigs:(NSArray *)propertyConfigs completionHandler:(void (^)(NSDictionary *_Nullable properties))completionHandler { - id manager = (id)[SAModuleManager.sharedInstance managerForModuleType:SAModuleTypeVisualized]; + id manager = self.visualizedManager; if (!manager) { return completionHandler(nil); } @@ -449,15 +448,17 @@ @implementation SAModuleManager (JavaScriptBridge) - (NSString *)javaScriptSource { NSMutableString *source = [NSMutableString string]; - [self.modules enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { - if (!([obj conformsToProtocol:@protocol(SAJavaScriptBridgeModuleProtocol)] && [obj respondsToSelector:@selector(javaScriptSource)]) || !obj.isEnable) { - return; + for (NSString *moduleName in self.moduleNames) { + id module = [self moduleWithName:moduleName]; + if (!module) { + return source; } - NSString *javaScriptSource = [(id)obj javaScriptSource]; - if (javaScriptSource.length > 0) { - [source appendString:javaScriptSource]; + if ([module conformsToProtocol:@protocol(SAJavaScriptBridgeModuleProtocol)] && [module respondsToSelector:@selector(javaScriptSource)] && [module conformsToProtocol:@protocol(SAModuleProtocol)]) { + idmoduleObject = module; + NSString *javaScriptSource = [moduleObject javaScriptSource]; + moduleObject.isEnable && javaScriptSource.length > 0 ? [source appendString:javaScriptSource] : nil; } - }]; + } return source; } @@ -466,8 +467,12 @@ - (NSString *)javaScriptSource { @implementation SAModuleManager (RemoteConfig) - (id)remoteConfigManager { - id manager = (id)self.modules[kSARemoteConfigModuleName]; - return manager.isEnable ? manager : nil; + id module = [self moduleWithName:kSARemoteConfigModuleName]; + if ([module conformsToProtocol:@protocol(SARemoteConfigModuleProtocol)] && [module conformsToProtocol:@protocol(SAModuleProtocol)]) { + id manager = module; + return manager.isEnable ? manager : nil; + } + return nil; } - (void)retryRequestRemoteConfigWithForceUpdateFlag:(BOOL)isForceUpdate { diff --git a/SensorsAnalyticsSDK/Core/SAModuleProtocol.h b/SensorsAnalyticsSDK/Core/SAModuleProtocol.h index 576cb553..2f80fc1d 100644 --- a/SensorsAnalyticsSDK/Core/SAModuleProtocol.h +++ b/SensorsAnalyticsSDK/Core/SAModuleProtocol.h @@ -21,6 +21,10 @@ #import #import "SAConfigOptions.h" +#if TARGET_OS_IOS +#import +#endif + NS_ASSUME_NONNULL_BEGIN @class SASecretKey; @@ -29,14 +33,11 @@ NS_ASSUME_NONNULL_BEGIN @protocol SAModuleProtocol -- (instancetype)init; - @property (nonatomic, assign, getter=isEnable) BOOL enable; - -@optional - @property (nonatomic, strong) SAConfigOptions *configOptions; ++ (instancetype)defaultManager; +@optional - (void)updateServerURL:(NSString *)serverURL; @end @@ -164,26 +165,6 @@ NS_ASSUME_NONNULL_BEGIN @end -@protocol SAVisualizedModuleProtocol - -/// 元素相关属性 -/// @param view 需要采集的 view -- (nullable NSDictionary *)propertiesWithView:(id)view; - -#pragma mark visualProperties - -/// 采集元素自定义属性 -/// @param view 触发事件的元素 -/// @param completionHandler 采集完成回调 -- (void)visualPropertiesWithView:(id)view completionHandler:(void (^)(NSDictionary *_Nullable visualProperties))completionHandler; - -/// 根据配置,采集属性 -/// @param propertyConfigs 自定义属性配置 -/// @param completionHandler 采集完成回调 -- (void)queryVisualPropertiesWithConfigs:(NSArray *)propertyConfigs completionHandler:(void (^)(NSDictionary *_Nullable properties))completionHandler; - -@end - #pragma mark - @protocol SAJavaScriptBridgeModuleProtocol @@ -206,4 +187,24 @@ NS_ASSUME_NONNULL_BEGIN @end +@protocol SAVisualizedModuleProtocol + +/// 元素相关属性 +/// @param view 需要采集的 view +- (nullable NSDictionary *)propertiesWithView:(id)view; + +#pragma mark visualProperties + +/// 采集元素自定义属性 +/// @param view 触发事件的元素 +/// @param completionHandler 采集完成回调 +- (void)visualPropertiesWithView:(id)view completionHandler:(void (^)(NSDictionary *_Nullable visualProperties))completionHandler; + +/// 根据配置,采集属性 +/// @param propertyConfigs 自定义属性配置 +/// @param completionHandler 采集完成回调 +- (void)queryVisualPropertiesWithConfigs:(NSArray *)propertyConfigs completionHandler:(void (^)(NSDictionary *_Nullable properties))completionHandler; + +@end + NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Core/SAObject+SAConfigOptions.m b/SensorsAnalyticsSDK/Core/SAObject+SAConfigOptions.m index cca1b5aa..9905a81c 100644 --- a/SensorsAnalyticsSDK/Core/SAObject+SAConfigOptions.m +++ b/SensorsAnalyticsSDK/Core/SAObject+SAConfigOptions.m @@ -25,6 +25,10 @@ #import "SAObject+SAConfigOptions.h" #import "SensorsAnalyticsSDK+Private.h" #import "SALog.h" +#import "SAModuleManager.h" +#if __has_include("SAConfigOptions+Encrypt.h") +#import "SAConfigOptions+Encrypt.h" +#endif @implementation SADatabase (SAConfigOptions) @@ -45,7 +49,7 @@ - (NSUInteger)maxCacheSize { @implementation SAEventFlush (SAConfigOptions) - (BOOL)isDebugMode { - return [[SensorsAnalyticsSDK sdkInstance] debugMode] != SensorsAnalyticsDebugOff; + return SAModuleManager.sharedInstance.debugMode != SensorsAnalyticsDebugOff; } - (NSURL *)serverURL { @@ -57,7 +61,7 @@ - (BOOL)flushBeforeEnterBackground { } - (BOOL)enableEncrypt { -#if TARGET_OS_IOS +#if TARGET_OS_IOS && __has_include("SAConfigOptions+Encrypt.h") return [SensorsAnalyticsSDK sdkInstance].configOptions.enableEncrypt; #else return NO; @@ -77,7 +81,7 @@ - (NSString *)cookie { @implementation SAEventTracker (SAConfigOptions) - (BOOL)isDebugMode { - return [[SensorsAnalyticsSDK sdkInstance] debugMode] != SensorsAnalyticsDebugOff; + return SAModuleManager.sharedInstance.debugMode != SensorsAnalyticsDebugOff; } - (SensorsAnalyticsNetworkType)networkTypePolicy { diff --git a/SensorsAnalyticsSDK/Core/SAReferrerManager.h b/SensorsAnalyticsSDK/Core/SAReferrerManager.h index ddccd868..da216bba 100644 --- a/SensorsAnalyticsSDK/Core/SAReferrerManager.h +++ b/SensorsAnalyticsSDK/Core/SAReferrerManager.h @@ -25,7 +25,6 @@ NS_ASSUME_NONNULL_BEGIN @interface SAReferrerManager : NSObject @property (nonatomic, strong) dispatch_queue_t serialQueue; -@property (nonatomic, assign) BOOL enableReferrerTitle; @property (nonatomic, assign) BOOL isClearReferrer; @property (atomic, copy, readonly) NSDictionary *referrerProperties; diff --git a/SensorsAnalyticsSDK/Core/SAReferrerManager.m b/SensorsAnalyticsSDK/Core/SAReferrerManager.m index b4fc8c93..040640c9 100644 --- a/SensorsAnalyticsSDK/Core/SAReferrerManager.m +++ b/SensorsAnalyticsSDK/Core/SAReferrerManager.m @@ -61,12 +61,9 @@ - (NSDictionary *)propertiesWithURL:(NSString *)currentURL eventProperties:(NSDi self.referrerURL = newProperties[kSAEventPropertyScreenUrl]; self.referrerProperties = newProperties; - if (self.enableReferrerTitle) { - dispatch_async(self.serialQueue, ^{ - [self cacheReferrerTitle:newProperties]; - }); - } - + dispatch_async(self.serialQueue, ^{ + [self cacheReferrerTitle:newProperties]; + }); return newProperties; } diff --git a/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK+Private.h b/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK+Private.h index d3d453c6..9e9a875e 100644 --- a/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK+Private.h +++ b/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK+Private.h @@ -55,12 +55,8 @@ /// @param properties 事件属性 - (void)trackEventObject:(SABaseEventObject *)object properties:(NSDictionary *)properties; -/// 开启可视化模块 -- (void)enableVisualize; - #pragma mark - property @property (nonatomic, strong, readonly) SAConfigOptions *configOptions; -@property (nonatomic, readonly, class) SAConfigOptions *configOptions; @property (nonatomic, strong, readonly) SANetwork *network; @property (nonatomic, strong, readonly) SASuperProperty *superProperty; @property (nonatomic, strong, readonly) dispatch_queue_t serialQueue; diff --git a/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK+Public.h b/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK+Public.h index 599751f7..3d15432e 100644 --- a/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK+Public.h +++ b/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK+Public.h @@ -171,17 +171,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)resetAnonymousId; -/** - * @abstract - * 设置是否显示 debugInfoView,对于 iOS,是 UIAlertView/UIAlertController - * - * @discussion - * 设置是否显示 debugInfoView,默认显示 - * - * @param show 是否显示 - */ -- (void)showDebugInfoView:(BOOL)show API_UNAVAILABLE(macos); - /** @abstract 在初始化 SDK 之后立即调用,替换神策分析默认分配的 *匿名 ID* @@ -332,8 +321,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (NSDictionary *)getLastScreenTrackProperties API_UNAVAILABLE(macos); -- (SensorsAnalyticsDebugMode)debugMode; - /** @abstract * Track App Extension groupIdentifier 中缓存的数据 @@ -453,9 +440,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)itemDeleteWithType:(NSString *)itemType itemId:(NSString *)itemId; - -#pragma mark - VisualizedAutoTrack - /** * 判断是否为符合要求的 openURL @@ -613,30 +597,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)enableLog:(BOOL)enabelLog; -/** - * @abstract - * 设备方向信息采集功能开关 - * - * @discussion - * 根据需要决定是否开启设备方向采集 - * 默认关闭 - * - * @param enable YES/NO - */ -- (void)enableTrackScreenOrientation:(BOOL)enable API_UNAVAILABLE(macos); - -/** - * @abstract - * 位置信息采集功能开关 - * - * @discussion - * 根据需要决定是否开启位置采集 - * 默认关闭 - * - * @param enable YES/NO - */ -- (void)enableTrackGPSLocation:(BOOL)enable API_UNAVAILABLE(macos); - /** * @abstract * 清除 keychain 缓存数据 @@ -649,34 +609,6 @@ NS_ASSUME_NONNULL_BEGIN @end -#pragma mark - Deeplink -@interface SensorsAnalyticsSDK (Deeplink) - -/** -DeepLink 回调函数 -@param callback 请求成功后的回调函数 - params:创建渠道链接时填写的 App 内参数 - succes:deeplink 唤起结果 - appAwakePassedTime:获取渠道信息所用时间 -*/ -- (void)setDeeplinkCallback:(void(^)(NSString *_Nullable params, BOOL success, NSInteger appAwakePassedTime))callback API_UNAVAILABLE(macos); - -/** -触发 $AppDeepLinkLaunch 事件 -@param url 唤起 App 的 DeepLink url -*/ -- (void)trackDeepLinkLaunchWithURL:(NSString *)url API_UNAVAILABLE(macos); - -@end - -#pragma mark - JSCall -@interface SensorsAnalyticsSDK (JSCall) - -- (void)trackFromH5WithEvent:(NSString *)eventInfo; - -- (void)trackFromH5WithEvent:(NSString *)eventInfo enableVerify:(BOOL)enableVerify; -@end - #pragma mark - /** * @class @@ -807,7 +739,7 @@ DeepLink 回调函数 * 两次数据发送的最小时间间隔,单位毫秒 * * @discussion - * 默认值为 15 * 1000 毫秒, 在每次调用 track、trackSignUp 以及 profileSet 等接口的时候, + * 默认值为 15 * 1000 毫秒, 在每次调用 track 和 profileSet 等接口的时候, * 都会检查如下条件,以判断是否向服务器上传数据: * 1. 是否 WIFI/3G/4G 网络 * 2. 是否满足以下数据发送条件之一: @@ -825,7 +757,7 @@ DeepLink 回调函数 * 本地缓存的最大事件数目,当累积日志量达到阈值时发送数据 * * @discussion - * 默认值为 100,在每次调用 track、trackSignUp 以及 profileSet 等接口的时候,都会检查如下条件,以判断是否向服务器上传数据: + * 默认值为 100,在每次调用 track 和 profileSet 等接口的时候,都会检查如下条件,以判断是否向服务器上传数据: * 1. 是否 WIFI/3G/4G 网络 * 2. 是否满足以下数据发送条件之一: * 1) 与上次发送的时间间隔是否大于 flushInterval @@ -835,17 +767,6 @@ DeepLink 回调函数 */ @property (atomic) UInt64 flushBulkSize __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 flushBulkSize"))); -/** - * @proeprty - * - * @abstract - * 当 App 进入后台时,是否执行 flush 将数据发送到 SensrosAnalytics - * - * @discussion - * 默认值为 YES - */ -@property (atomic) BOOL flushBeforeEnterBackground __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 flushBeforeEnterBackground"))); - /** * @abstract * 设置本地缓存最多事件条数 @@ -854,8 +775,7 @@ DeepLink 回调函数 * 默认为 10000 条事件 * */ -@property (nonatomic, getter = getMaxCacheSize) UInt64 maxCacheSize __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 maxCacheSize"))); -- (UInt64)getMaxCacheSize __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 maxCacheSize"))); +@property (nonatomic) UInt64 maxCacheSize __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 maxCacheSize"))); /** * @abstract @@ -868,52 +788,6 @@ DeepLink 回调函数 */ - (void)setFlushNetworkPolicy:(SensorsAnalyticsNetworkType)networkType __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 flushNetworkPolicy"))); -/** - * @abstract - * 根据传入的配置,初始化并返回一个 SensorsAnalyticsSDK 的单例 - * - @param configOptions 参数配置 - @return 返回的单例 - */ -+ (SensorsAnalyticsSDK *)sharedInstanceWithConfig:(nonnull SAConfigOptions *)configOptions __attribute__((deprecated("已过时,请使用 + (void)startWithConfigOptions: 方法进行初始化"))); - -/** - * @abstract - * 根据传入的配置,初始化并返回一个 SensorsAnalyticsSDK 的单例 - * - * @param serverURL 收集事件的 URL - * @param debugMode Sensors Analytics 的 Debug 模式 - * - * @return 返回的单例 - */ -+ (SensorsAnalyticsSDK *)sharedInstanceWithServerURL:(nullable NSString *)serverURL - andDebugMode:(SensorsAnalyticsDebugMode)debugMode __attribute__((deprecated("已过时,请参考 sharedInstanceWithConfig:"))) API_UNAVAILABLE(macos); - -/** - * @abstract - * 根据传入的配置,初始化并返回一个 SensorsAnalyticsSDK 的单例 - * - * @param serverURL 收集事件的 URL - * @param launchOptions launchOptions - * @param debugMode Sensors Analytics 的 Debug 模式 - * - * @return 返回的单例 - */ -+ (SensorsAnalyticsSDK *)sharedInstanceWithServerURL:(nonnull NSString *)serverURL - andLaunchOptions:(NSDictionary * _Nullable)launchOptions - andDebugMode:(SensorsAnalyticsDebugMode)debugMode __attribute__((deprecated("已过时,请参考 sharedInstanceWithConfig:"))) API_UNAVAILABLE(macos); -/** - * @abstract - * 根据传入的配置,初始化并返回一个 SensorsAnalyticsSDK 的单例。 - * 目前 DebugMode 为动态开启,详细请参考说明文档:https://www.sensorsdata.cn/manual/ios_sdk.html - * @param serverURL 收集事件的 URL - * @param launchOptions launchOptions - * - * @return 返回的单例 - */ -+ (SensorsAnalyticsSDK *)sharedInstanceWithServerURL:(nonnull NSString *)serverURL - andLaunchOptions:(NSDictionary * _Nullable)launchOptions __attribute__((deprecated("已过时,请参考 sharedInstanceWithConfig:"))); - /** 设置调试模式 目前 DebugMode 为动态开启,详细请参考说明文档:https://www.sensorsdata.cn/manual/ios_sdk.html @@ -921,64 +795,6 @@ DeepLink 回调函数 */ - (void)setDebugMode:(SensorsAnalyticsDebugMode)debugMode __attribute__((deprecated("已过时,建议动态开启调试模式"))) API_UNAVAILABLE(macos); -/** - * @abstract - * 自动收集 App Crash 日志,该功能默认是关闭的 - */ -- (void)trackAppCrash __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 enableTrackAppCrash"))) API_UNAVAILABLE(macos); - -/** - * @abstract - * 提供一个接口,用来在用户注册的时候,用注册ID来替换用户以前的匿名ID - * - * @discussion - * 这个接口是一个较为复杂的功能,请在使用前先阅读相关说明: http://www.sensorsdata.cn/manual/track_signup.html,并在必要时联系我们的技术支持人员。 - * - * @param newDistinctId 用户完成注册后生成的注册ID - * @param propertyDict event的属性 - */ -- (void)trackSignUp:(NSString *)newDistinctId withProperties:(nullable NSDictionary *)propertyDict __attribute__((deprecated("已过时,请参考login"))); - -/** - * @abstract - * 不带私有属性的trackSignUp,用来在用户注册的时候,用注册ID来替换用户以前的匿名ID - * - * @discussion - * 这个接口是一个较为复杂的功能,请在使用前先阅读相关说明: http://www.sensorsdata.cn/manual/track_signup.html,并在必要时联系我们的技术支持人员。 - * - * @param newDistinctId 用户完成注册后生成的注册ID - */ -- (void)trackSignUp:(NSString *)newDistinctId __attribute__((deprecated("已过时,请参考login"))); - -/** - * @abstract - * 初始化事件的计时器。 - * - * @discussion - * 若需要统计某个事件的持续时间,先在事件开始时调用 trackTimer:"Event" 记录事件开始时间,该方法并不会真正发 - * 送事件;随后在事件结束时,调用 track:"Event" withProperties:properties,SDK 会追踪 "Event" 事件,并自动将事件持续时 - * 间记录在事件属性 "event_duration" 中。 - * - * 默认时间单位为毫秒,若需要以其他时间单位统计时长,请使用 trackTimer:withTimeUnit - * - * 多次调用 trackTimer:"Event" 时,事件 "Event" 的开始时间以最后一次调用时为准。 - * - * @param event event的名称 - */ -- (void)trackTimerBegin:(NSString *)event __attribute__((deprecated("已过时,请参考 trackTimerStart"))); - -/** - * @abstract - * 初始化事件的计时器,允许用户指定计时单位。 - * - * @discussion - * 请参考 trackTimer - * - * @param event event的名称 - * @param timeUnit 计时单位,毫秒/秒/分钟/小时 - */ -- (void)trackTimerBegin:(NSString *)event withTimeUnit:(SensorsAnalyticsTimeUnit)timeUnit __attribute__((deprecated("已过时,请参考 trackTimerStart"))); - /** * @abstract * 初始化事件的计时器。 diff --git a/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.h b/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.h index e3d92da5..d9f2b20a 100755 --- a/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.h +++ b/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.h @@ -24,20 +24,22 @@ #import "SAConfigOptions.h" #import "SAConstants.h" + +//SensorsAnalyticsSDK section #if __has_include("SensorsAnalyticsSDK+SAChannelMatch.h") #import "SensorsAnalyticsSDK+SAChannelMatch.h" #endif -#if __has_include("SensorsAnalyticsSDK+SAAutoTrack.h") -#import "SensorsAnalyticsSDK+SAAutoTrack.h" +#if __has_include("SensorsAnalyticsSDK+DebugMode.h") +#import "SensorsAnalyticsSDK+DebugMode.h" #endif -#if __has_include("SensorsAnalyticsSDK+WKWebView.h") -#import "SensorsAnalyticsSDK+WKWebView.h" +#if __has_include("SensorsAnalyticsSDK+Deeplink.h") +#import "SensorsAnalyticsSDK+Deeplink.h" #endif -#if __has_include("SensorsAnalyticsSDK+WebView.h") -#import "SensorsAnalyticsSDK+WebView.h" +#if __has_include("SensorsAnalyticsSDK+SAAutoTrack.h") +#import "SensorsAnalyticsSDK+SAAutoTrack.h" #endif #if __has_include("SensorsAnalyticsSDK+Visualized.h") @@ -48,6 +50,42 @@ #import "SASecretKey.h" #endif +#if __has_include("SensorsAnalyticsSDK+JavaScriptBridge.h") +#import "SensorsAnalyticsSDK+JavaScriptBridge.h" +#endif + +#if __has_include("SensorsAnalyticsSDK+DeviceOrientation.h") +#import "SensorsAnalyticsSDK+DeviceOrientation.h" +#endif + +#if __has_include("SensorsAnalyticsSDK+Location.h") +#import "SensorsAnalyticsSDK+Location.h" +#endif + + +//configOptions section + +#if __has_include("SAConfigOptions+RemoteConfig.h") +#import "SAConfigOptions+RemoteConfig.h" +#endif + #if __has_include("SAConfigOptions+Encrypt.h") #import "SAConfigOptions+Encrypt.h" #endif + +#if __has_include("SAConfigOptions+AppPush.h") +#import "SAConfigOptions+AppPush.h" +#endif + +#if __has_include("SAConfigOptions+Exception.h") +#import "SAConfigOptions+Exception.h" +#endif + + +#if __has_include("SensorsAnalyticsSDK+WKWebView.h") +#import "SensorsAnalyticsSDK+WKWebView.h" +#endif + +#if __has_include("SensorsAnalyticsSDK+WebView.h") +#import "SensorsAnalyticsSDK+WebView.h" +#endif diff --git a/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.m b/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.m index d39ab0ea..ec3efcd8 100755 --- a/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.m +++ b/SensorsAnalyticsSDK/Core/SensorsAnalyticsSDK.m @@ -40,8 +40,9 @@ #import "SAReferrerManager.h" #import "SAProfileEventObject.h" #import "SAJSONUtil.h" +#import "SAApplication.h" -#define VERSION @"3.1.9" +#define VERSION @"4.0.0" void *SensorsAnalyticsQueueTag = &SensorsAnalyticsQueueTag; @@ -89,16 +90,10 @@ @implementation SensorsAnalyticsSDK #pragma mark - Initialization + (void)startWithConfigOptions:(SAConfigOptions *)configOptions { NSAssert(sensorsdata_is_same_queue(dispatch_get_main_queue()), @"神策 iOS SDK 必须在主线程里进行初始化,否则会引发无法预料的问题(比如丢失 $AppStart 事件)。"); -#if TARGET_OS_IOS - if (configOptions.enableEncrypt) { - NSAssert((configOptions.saveSecretKey && configOptions.loadSecretKey) || - (!configOptions.saveSecretKey && !configOptions.loadSecretKey), @"存储公钥和获取公钥的回调需要全部实现或者全部不实现。"); - } -#endif dispatch_once(&sdkInitializeOnceToken, ^{ - sharedInstance = [[SensorsAnalyticsSDK alloc] initWithConfigOptions:configOptions debugMode:SensorsAnalyticsDebugOff]; - [SAModuleManager startWithConfigOptions:sharedInstance.configOptions debugMode:SensorsAnalyticsDebugOff]; + sharedInstance = [[SensorsAnalyticsSDK alloc] initWithConfigOptions:configOptions]; + [SAModuleManager startWithConfigOptions:sharedInstance.configOptions]; [sharedInstance addAppLifecycleObservers]; }); } @@ -155,10 +150,8 @@ + (void)enableSDK { if (instance.configOptions.enableLog) { [instance enableLog:YES]; } - - // Debug 模块做了特殊处理,未移除,可以使用 Debug 模块获取 DebugMode - SensorsAnalyticsDebugMode mode = SAModuleManager.sharedInstance.debugMode; - [SAModuleManager startWithConfigOptions:instance.configOptions debugMode:mode]; + + [SAModuleManager startWithConfigOptions:instance.configOptions]; // 需要在模块加载完成之后添加监听,如果过早会导致退到后台后,$AppEnd 事件无法立即上报 [instance addAppLifecycleObservers]; @@ -168,20 +161,7 @@ + (void)enableSDK { SALogInfo(@"SensorsAnalyticsSDK enabled"); } -- (instancetype)initWithServerURL:(NSString *)serverURL - andLaunchOptions:(NSDictionary *)launchOptions - andDebugMode:(SensorsAnalyticsDebugMode)debugMode { - @try { - - SAConfigOptions * options = [[SAConfigOptions alloc]initWithServerURL:serverURL launchOptions:launchOptions]; - self = [self initWithConfigOptions:options debugMode:debugMode]; - } @catch(NSException *exception) { - SALogError(@"%@ error: %@", self, exception); - } - return self; -} - -- (instancetype)initWithConfigOptions:(nonnull SAConfigOptions *)configOptions debugMode:(SensorsAnalyticsDebugMode)debugMode { +- (instancetype)initWithConfigOptions:(nonnull SAConfigOptions *)configOptions { @try { self = [super init]; if (self) { @@ -220,8 +200,11 @@ - (instancetype)initWithConfigOptions:(nonnull SAConfigOptions *)configOptions d [self setupSecurityPolicyWithConfigOptions:_configOptions]; [SAReferrerManager sharedInstance].serialQueue = _serialQueue; - [SAReferrerManager sharedInstance].enableReferrerTitle = configOptions.enableReferrerTitle; #endif + //start flush timer for App Extension + if ([SAApplication isAppExtension]) { + [self startFlushTimer]; + } } } @catch(NSException *exception) { @@ -316,10 +299,13 @@ - (void)setServerUrl:(NSString *)serverUrl isRequestRemoteConfig:(BOOL)isRequest } dispatch_async(self.serialQueue, ^{ - // 更新数据接收地址 - [SAModuleManager.sharedInstance updateServerURL:serverUrl]; + if (![self.configOptions.serverURL isEqualToString:serverUrl]) { + self.configOptions.serverURL = serverUrl; + + // 更新数据接收地址 + [SAModuleManager.sharedInstance updateServerURL:serverUrl]; + } - self.configOptions.serverURL = serverUrl; if (isRequestRemoteConfig) { [SAModuleManager.sharedInstance retryRequestRemoteConfigWithForceUpdateFlag:YES]; } @@ -376,10 +362,6 @@ - (void)resetAnonymousId { }); } -- (void)showDebugInfoView:(BOOL)show { - [SAModuleManager.sharedInstance setShowDebugAlertView:show]; -} - - (void)flush { dispatch_async(self.serialQueue, ^{ [self.eventTracker flushAllEventRecords]; @@ -400,6 +382,10 @@ - (void)addAppLifecycleObservers { if (self.configOptions.disableSDK) { return; } + // app extension does not need state observer + if ([SAApplication isAppExtension]) { + return; + } [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appLifecycleStateWillChange:) name:kSAAppLifecycleStateWillChangeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appLifecycleStateDidChange:) name:kSAAppLifecycleStateDidChangeNotification object:nil]; } @@ -452,7 +438,7 @@ - (void)appLifecycleStateDidChange:(NSNotification *)sender { if (newState == SAAppLifecycleStateEnd) { #if TARGET_OS_IOS - UIApplication *application = UIApplication.sharedApplication; + UIApplication *application = [SAApplication sharedApplication]; __block UIBackgroundTaskIdentifier backgroundTaskIdentifier = UIBackgroundTaskInvalid; void (^endBackgroundTask)(void) = ^() { [application endBackgroundTask:backgroundTaskIdentifier]; @@ -499,16 +485,6 @@ - (BOOL)handleSchemeUrl:(NSURL *)url { return [SAModuleManager.sharedInstance handleURL:url]; } -#pragma mark - VisualizedAutoTrack - -// 开启可视化模块 -- (void)enableVisualize { - [SAModuleManager.sharedInstance setEnable:YES forModuleType:SAModuleTypeVisualized]; - - // 开启 WKWebView 和 js 的数据交互 - [SAModuleManager.sharedInstance setEnable:YES forModuleType:SAModuleTypeJavaScriptBridge]; -} - #pragma mark - Item 操作 - (void)itemSetWithType:(NSString *)itemType itemId:(NSString *)itemId properties:(nullable NSDictionary *)propertyDict { NSMutableDictionary *itemDict = [[NSMutableDictionary alloc] init]; @@ -621,11 +597,7 @@ - (void)trackEventObject:(SABaseEventObject *)object properties:(NSDictionary *) [object addLatestUtmProperties:SAModuleManager.sharedInstance.latestUtmProperties]; [object addChannelProperties:[SAModuleManager.sharedInstance channelInfoWithEvent:object.event]]; -#if TARGET_OS_IOS - if (self.configOptions.enableReferrerTitle) { - [object addReferrerTitleProperty:[SAReferrerManager sharedInstance].referrerTitle]; - } -#endif + [object addReferrerTitleProperty:[SAReferrerManager sharedInstance].referrerTitle]; // 5. 添加的自定义属性需要校验 [object addCustomProperties:properties error:&error]; @@ -847,7 +819,7 @@ - (void)startFlushTimer { return; } - if (self.appLifecycle.state != SAAppLifecycleStateStart) { + if (![SAApplication isAppExtension] && self.appLifecycle.state != SAAppLifecycleStateStart) { return; } @@ -984,20 +956,6 @@ - (void)enableLog:(BOOL)enableLog { [self enableLoggers]; } -- (void)enableTrackScreenOrientation:(BOOL)enable { - [SAModuleManager.sharedInstance setEnable:enable forModuleType:SAModuleTypeDeviceOrientation]; -} - -- (void)enableTrackGPSLocation:(BOOL)enableGPSLocation { - if (NSThread.isMainThread) { - [SAModuleManager.sharedInstance setEnable:enableGPSLocation forModuleType:SAModuleTypeLocation]; - } else { - dispatch_async(dispatch_get_main_queue(), ^ { - [SAModuleManager.sharedInstance setEnable:enableGPSLocation forModuleType:SAModuleTypeLocation]; - }); - } -} - - (void)clearKeychainData { [SAKeyChainItemWrapper deletePasswordWithAccount:kSAUdidAccount service:kSAService]; } @@ -1077,25 +1035,6 @@ - (void)appendWebViewUserAgent { [SACommonUtility saveUserAgent:self.userAgent]; } -@end - -#pragma mark - Deeplink -@implementation SensorsAnalyticsSDK (Deeplink) - -- (void)setDeeplinkCallback:(void(^)(NSString *_Nullable params, BOOL success, NSInteger appAwakePassedTime))callback { - SAModuleManager.sharedInstance.linkHandlerCallback = callback; -} - -- (void)trackDeepLinkLaunchWithURL:(NSString *)url { - [SAModuleManager.sharedInstance trackDeepLinkLaunchWithURL:url]; -} - -@end - -#pragma mark - JSCall - -@implementation SensorsAnalyticsSDK (JSCall) - - (void)trackFromH5WithEvent:(NSString *)eventInfo { [self trackFromH5WithEvent:eventInfo enableVerify:NO]; } @@ -1285,7 +1224,6 @@ - (void)trackFromH5WithEventDict:(NSMutableDictionary *)eventDict { @end - #pragma mark - People analytics @implementation SensorsAnalyticsPeople @@ -1352,44 +1290,6 @@ - (void)deleteUser { #pragma mark - Deprecated @implementation SensorsAnalyticsSDK (Deprecated) -+ (SensorsAnalyticsSDK *)sharedInstanceWithConfig:(nonnull SAConfigOptions *)configOptions { - [self startWithConfigOptions:configOptions]; - return sharedInstance; -} - -+ (SensorsAnalyticsSDK *)sharedInstanceWithServerURL:(NSString *)serverURL - andDebugMode:(SensorsAnalyticsDebugMode)debugMode { - return [SensorsAnalyticsSDK sharedInstanceWithServerURL:serverURL - andLaunchOptions:nil andDebugMode:debugMode]; -} - -+ (SensorsAnalyticsSDK *)sharedInstanceWithServerURL:(NSString *)serverURL - andLaunchOptions:(NSDictionary *)launchOptions - andDebugMode:(SensorsAnalyticsDebugMode)debugMode { - NSAssert(sensorsdata_is_same_queue(dispatch_get_main_queue()), @"神策 iOS SDK 必须在主线程里进行初始化,否则会引发无法预料的问题(比如丢失 $AppStart 事件)。"); - dispatch_once(&sdkInitializeOnceToken, ^{ - sharedInstance = [[self alloc] initWithServerURL:serverURL - andLaunchOptions:launchOptions - andDebugMode:debugMode]; - [SAModuleManager startWithConfigOptions:sharedInstance.configOptions debugMode:debugMode]; - [sharedInstance addAppLifecycleObservers]; - }); - return sharedInstance; -} - -+ (SensorsAnalyticsSDK *)sharedInstanceWithServerURL:(nonnull NSString *)serverURL - andLaunchOptions:(NSDictionary * _Nullable)launchOptions { - NSAssert(sensorsdata_is_same_queue(dispatch_get_main_queue()), @"神策 iOS SDK 必须在主线程里进行初始化,否则会引发无法预料的问题(比如丢失 $AppStart 事件)。"); - dispatch_once(&sdkInitializeOnceToken, ^{ - sharedInstance = [[self alloc] initWithServerURL:serverURL - andLaunchOptions:launchOptions - andDebugMode:SensorsAnalyticsDebugOff]; - [SAModuleManager startWithConfigOptions:sharedInstance.configOptions debugMode:SensorsAnalyticsDebugOff]; - [sharedInstance addAppLifecycleObservers]; - }); - return sharedInstance; -} - - (UInt64)flushInterval { @synchronized(self) { return self.configOptions.flushInterval; @@ -1422,24 +1322,6 @@ - (void)setFlushBulkSize:(UInt64)bulkSize { } } -- (BOOL)flushBeforeEnterBackground { - @synchronized(self) { - return self.configOptions.flushBeforeEnterBackground; - } -} - -- (void)setFlushBeforeEnterBackground:(BOOL)flushBeforeEnterBackground { - @synchronized(self) { - self.configOptions.flushBeforeEnterBackground = flushBeforeEnterBackground; - } -} - -- (void)setFlushNetworkPolicy:(SensorsAnalyticsNetworkType)networkType { - @synchronized (self) { - self.configOptions.flushNetworkPolicy = networkType; - } -} - - (void)setMaxCacheSize:(UInt64)maxCacheSize { @synchronized(self) { //防止设置的值太小导致事件丢失 @@ -1448,33 +1330,22 @@ - (void)setMaxCacheSize:(UInt64)maxCacheSize { }; } -- (UInt64)getMaxCacheSize { +- (UInt64)maxCacheSize { @synchronized(self) { return (UInt64)self.configOptions.maxCacheSize; }; } -- (void)trackAppCrash { - _configOptions.enableTrackAppCrash = YES; - // Install uncaught exception handlers first - [SAModuleManager.sharedInstance setEnable:YES forModuleType:SAModuleTypeException]; +- (void)setFlushNetworkPolicy:(SensorsAnalyticsNetworkType)networkType { + @synchronized (self) { + self.configOptions.flushNetworkPolicy = networkType; + } } - (void)setDebugMode:(SensorsAnalyticsDebugMode)debugMode { SAModuleManager.sharedInstance.debugMode = debugMode; } -- (void)trackTimerBegin:(NSString *)event { - [self trackTimerStart:event]; -} - -- (void)trackTimerBegin:(NSString *)event withTimeUnit:(SensorsAnalyticsTimeUnit)timeUnit { - UInt64 currentSysUpTime = [self.class getSystemUpTime]; - dispatch_async(self.serialQueue, ^{ - [self.trackTimer trackTimerStart:event timeUnit:timeUnit currentSysUpTime:currentSysUpTime]; - }); -} - - (void)trackTimer:(NSString *)event { [self trackTimer:event withTimeUnit:SensorsAnalyticsTimeUnitMilliseconds]; } @@ -1486,14 +1357,4 @@ - (void)trackTimer:(NSString *)event withTimeUnit:(SensorsAnalyticsTimeUnit)time }); } -- (void)trackSignUp:(NSString *)newDistinctId withProperties:(NSDictionary *)propertieDict { - [self identify:newDistinctId]; - SASignUpEventObject *object = [[SASignUpEventObject alloc] initWithEventId:kSAEventNameSignUp]; - [self asyncTrackEventObject:object properties:propertieDict]; -} - -- (void)trackSignUp:(NSString *)newDistinctId { - [self trackSignUp:newDistinctId withProperties:nil]; -} - @end diff --git a/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.h b/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.h index fe0f0a86..cd7c0522 100644 --- a/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.h +++ b/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.h @@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN + @interface SAThreadSafeDictionary : NSObject + (SAThreadSafeDictionary *)dictionary; diff --git a/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.m b/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.m index 12d13c01..e09bae18 100644 --- a/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.m +++ b/SensorsAnalyticsSDK/Core/Utils/SAThreadSafeDictionary.m @@ -27,7 +27,7 @@ @interface SAThreadSafeDictionary () @property (nonatomic, strong) NSMutableDictionary *dictionary; -@property (nonatomic, strong) NSLock *lock; +@property (nonatomic, strong) NSRecursiveLock *lock; @end @@ -43,7 +43,7 @@ - (instancetype)init { self = [super init]; if (self) { _dictionary = [NSMutableDictionary dictionary]; - _lock = [[NSLock alloc] init]; + _lock = [[NSRecursiveLock alloc] init]; } return self; } diff --git a/SensorsAnalyticsSDK/DebugMode/SADebugModeManager.h b/SensorsAnalyticsSDK/DebugMode/SADebugModeManager.h index 59352a46..17c2f460 100644 --- a/SensorsAnalyticsSDK/DebugMode/SADebugModeManager.h +++ b/SensorsAnalyticsSDK/DebugMode/SADebugModeManager.h @@ -24,12 +24,19 @@ NS_ASSUME_NONNULL_BEGIN +@interface SAConfigOptions (DebugModePrivate) + +@property (nonatomic, assign) BOOL enableDebugMode; + +@end + @interface SADebugModeManager : NSObject -@property (nonatomic, assign, getter=isEnable) BOOL enable; ++ (instancetype)defaultManager; +@property (nonatomic, assign, getter=isEnable) BOOL enable; +@property (nonatomic, strong) SAConfigOptions *configOptions; @property (nonatomic) SensorsAnalyticsDebugMode debugMode; - @property (nonatomic) BOOL showDebugAlertView; @end diff --git a/SensorsAnalyticsSDK/DebugMode/SADebugModeManager.m b/SensorsAnalyticsSDK/DebugMode/SADebugModeManager.m index 06caf45e..f8b70f23 100644 --- a/SensorsAnalyticsSDK/DebugMode/SADebugModeManager.m +++ b/SensorsAnalyticsSDK/DebugMode/SADebugModeManager.m @@ -30,6 +30,7 @@ #import "SAJSONUtil.h" #import "SANetwork.h" #import "SALog.h" +#import "SAApplication.h" @interface SADebugModeManager () @@ -39,6 +40,15 @@ @interface SADebugModeManager () @implementation SADebugModeManager ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SADebugModeManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SADebugModeManager alloc] init]; + }); + return manager; +} + - (instancetype)init { self = [super init]; if (self) { @@ -48,6 +58,14 @@ - (instancetype)init { return self; } +- (void)setConfigOptions:(SAConfigOptions *)configOptions { + if ([SAApplication isAppExtension]) { + configOptions.enableDebugMode = NO; + } + _configOptions = configOptions; + self.enable = configOptions.enableDebugMode; +} + #pragma mark - SAOpenURLProtocol - (BOOL)canHandleURL:(nonnull NSURL *)url { diff --git a/SensorsAnalyticsSDK/DebugMode/SensorsAnalyticsSDK+DebugMode.h b/SensorsAnalyticsSDK/DebugMode/SensorsAnalyticsSDK+DebugMode.h new file mode 100644 index 00000000..e8f9d72e --- /dev/null +++ b/SensorsAnalyticsSDK/DebugMode/SensorsAnalyticsSDK+DebugMode.h @@ -0,0 +1,42 @@ +// +// SensorsAnalyticsSDK+DebugMode.h +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/11. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#import "SensorsAnalyticsSDK.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SensorsAnalyticsSDK (DebugMode) + +/** + * @abstract + * 设置是否显示 debugInfoView,对于 iOS,是 UIAlertView/UIAlertController + * + * @discussion + * 设置是否显示 debugInfoView,默认显示 + * + * @param show 是否显示 + */ +- (void)showDebugInfoView:(BOOL)show API_UNAVAILABLE(macos); + +- (SensorsAnalyticsDebugMode)debugMode; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/DebugMode/SensorsAnalyticsSDK+DebugMode.m b/SensorsAnalyticsSDK/DebugMode/SensorsAnalyticsSDK+DebugMode.m new file mode 100644 index 00000000..408fe5bf --- /dev/null +++ b/SensorsAnalyticsSDK/DebugMode/SensorsAnalyticsSDK+DebugMode.m @@ -0,0 +1,34 @@ +// +// SensorsAnalyticsSDK+DebugMode.m +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/11. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#if ! __has_feature(objc_arc) +#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag on this file. +#endif + +#import "SensorsAnalyticsSDK+DebugMode.h" +#import "SADebugModeManager.h" + +@implementation SensorsAnalyticsSDK (DebugMode) + +- (void)showDebugInfoView:(BOOL)show { + [[SADebugModeManager defaultManager] setShowDebugAlertView:show]; +} + +@end diff --git a/SensorsAnalyticsSDK/Deeplink/SADeeplinkManager.h b/SensorsAnalyticsSDK/Deeplink/SADeeplinkManager.h index 5a0b3586..977e1c76 100644 --- a/SensorsAnalyticsSDK/Deeplink/SADeeplinkManager.h +++ b/SensorsAnalyticsSDK/Deeplink/SADeeplinkManager.h @@ -28,14 +28,20 @@ NS_ASSUME_NONNULL_BEGIN +@interface SAConfigOptions (DeeplinkPrivate) + +@property (nonatomic, assign) BOOL enableDeeplink; + +@end + typedef void(^SALinkHandlerCallback)(NSString *_Nullable params, BOOL success, NSInteger appAwakePassedTime); @interface SADeeplinkManager : NSObject -@property (nonatomic, assign, getter=isEnable) BOOL enable; ++ (instancetype)defaultManager; +@property (nonatomic, assign, getter=isEnable) BOOL enable; @property (nonatomic, strong) SAConfigOptions *configOptions; - @property (nonatomic, copy) SALinkHandlerCallback linkHandlerCallback; @end diff --git a/SensorsAnalyticsSDK/Deeplink/SADeeplinkManager.m b/SensorsAnalyticsSDK/Deeplink/SADeeplinkManager.m index 6b503b95..43c3791a 100644 --- a/SensorsAnalyticsSDK/Deeplink/SADeeplinkManager.m +++ b/SensorsAnalyticsSDK/Deeplink/SADeeplinkManager.m @@ -30,6 +30,8 @@ #import "SALog.h" #import "SAIdentifier.h" #import "SAJSONUtil.h" +#import "SensorsAnalyticsSDK+Deeplink.h" +#import "SAApplication.h" static NSString *const kSAAppDeeplinkLaunchEvent = @"$AppDeeplinkLaunch"; static NSString *const kSADeeplinkMatchedResultEvent = @"$AppDeeplinkMatchedResult"; @@ -72,6 +74,15 @@ @interface SADeeplinkManager () @implementation SADeeplinkManager ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SADeeplinkManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SADeeplinkManager alloc] init]; + }); + return manager; +} + - (instancetype)init { self = [super init]; if (self) { @@ -83,12 +94,24 @@ - (instancetype)init { } - (void)setConfigOptions:(SAConfigOptions *)configOptions { + if ([SAApplication isAppExtension]) { + configOptions.enableDeeplink = NO; + } _configOptions = configOptions; [self filterValidSourceChannnels:configOptions.sourceChannels]; [self unarchiveSavedDeepLinkInfo:configOptions.enableSaveDeepLinkInfo]; [self handleLaunchOptions:configOptions.launchOptions]; [self acquireColdLaunchDeepLinkInfo]; + self.enable = configOptions.enableDeeplink; +} + +- (void)setEnable:(BOOL)enable { + _enable = enable; + if (!enable) { + self.utms = nil; + self.latestUtms = nil; + } } - (void)filterValidSourceChannnels:(NSArray *)sourceChannels { diff --git a/SensorsAnalyticsSDK/Deeplink/SensorsAnalyticsSDK+Deeplink.h b/SensorsAnalyticsSDK/Deeplink/SensorsAnalyticsSDK+Deeplink.h new file mode 100644 index 00000000..4530b70e --- /dev/null +++ b/SensorsAnalyticsSDK/Deeplink/SensorsAnalyticsSDK+Deeplink.h @@ -0,0 +1,54 @@ +// +// SensorsAnalyticsSDK+Deeplink.h +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/11. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#import "SensorsAnalyticsSDK.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SensorsAnalyticsSDK (Deeplink) + +/** +DeepLink 回调函数 +@param callback 请求成功后的回调函数 + params:创建渠道链接时填写的 App 内参数 + succes:deeplink 唤起结果 + appAwakePassedTime:获取渠道信息所用时间 +*/ +- (void)setDeeplinkCallback:(void(^)(NSString *_Nullable params, BOOL success, NSInteger appAwakePassedTime))callback API_UNAVAILABLE(macos); + +/** +触发 $AppDeepLinkLaunch 事件 +@param url 唤起 App 的 DeepLink url +*/ +- (void)trackDeepLinkLaunchWithURL:(NSString *)url API_UNAVAILABLE(macos); + +@end + +@interface SAConfigOptions (Deeplink) + +/// DeepLink 中解析出来的参数是否需要保存到本地 +@property (nonatomic, assign) BOOL enableSaveDeepLinkInfo API_UNAVAILABLE(macos); + +/// DeepLink 中用户自定义来源渠道属性 key 值,可传多个。 +@property (nonatomic, copy) NSArray *sourceChannels API_UNAVAILABLE(macos); + +@end + +NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Deeplink/SensorsAnalyticsSDK+Deeplink.m b/SensorsAnalyticsSDK/Deeplink/SensorsAnalyticsSDK+Deeplink.m new file mode 100644 index 00000000..5ab6ae12 --- /dev/null +++ b/SensorsAnalyticsSDK/Deeplink/SensorsAnalyticsSDK+Deeplink.m @@ -0,0 +1,38 @@ +// +// SensorsAnalyticsSDK+Deeplink.m +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/11. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#if ! __has_feature(objc_arc) +#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag on this file. +#endif + +#import "SensorsAnalyticsSDK+Deeplink.h" +#import "SADeeplinkManager.h" + +@implementation SensorsAnalyticsSDK (Deeplink) + +- (void)setDeeplinkCallback:(void(^)(NSString *_Nullable params, BOOL success, NSInteger appAwakePassedTime))callback { + [SADeeplinkManager defaultManager].linkHandlerCallback = callback; +} + +- (void)trackDeepLinkLaunchWithURL:(NSString *)url { + [[SADeeplinkManager defaultManager] trackDeepLinkLaunchWithURL:url]; +} + +@end diff --git a/SensorsAnalyticsSDK/DeviceOrientation/SADeviceOrientationManager.h b/SensorsAnalyticsSDK/DeviceOrientation/SADeviceOrientationManager.h index 2daa633c..c98f238e 100644 --- a/SensorsAnalyticsSDK/DeviceOrientation/SADeviceOrientationManager.h +++ b/SensorsAnalyticsSDK/DeviceOrientation/SADeviceOrientationManager.h @@ -23,10 +23,18 @@ NS_ASSUME_NONNULL_BEGIN +@interface SAConfigOptions (DeviceOrientation) + +@property (nonatomic, assign) BOOL enableDeviceOrientation; + +@end + @interface SADeviceOrientationManager : NSObject -@property (nonatomic, assign, getter=isEnable) BOOL enable; ++ (instancetype)defaultManager; +@property (nonatomic, assign, getter=isEnable) BOOL enable; +@property (nonatomic, strong) SAConfigOptions *configOptions; @property (nonatomic, copy, readonly, nullable) NSDictionary *properties; @end diff --git a/SensorsAnalyticsSDK/DeviceOrientation/SADeviceOrientationManager.m b/SensorsAnalyticsSDK/DeviceOrientation/SADeviceOrientationManager.m index d24f7ce2..8b18228a 100644 --- a/SensorsAnalyticsSDK/DeviceOrientation/SADeviceOrientationManager.m +++ b/SensorsAnalyticsSDK/DeviceOrientation/SADeviceOrientationManager.m @@ -34,23 +34,31 @@ @interface SADeviceOrientationManager() @property (nonatomic, strong) CMMotionManager *cmmotionManager; @property (nonatomic, strong) NSOperationQueue *updateQueue; - @property (nonatomic, strong) NSString *deviceOrientation; @end @implementation SADeviceOrientationManager -- (instancetype)init { - if (self = [super init]) { - _cmmotionManager = [[CMMotionManager alloc] init]; - _cmmotionManager.deviceMotionUpdateInterval = kSADefaultDeviceMotionUpdateInterval; - _updateQueue = [[NSOperationQueue alloc] init]; - _updateQueue.name = @"com.sensorsdata.analytics.deviceMotionUpdatesQueue"; ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SADeviceOrientationManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SADeviceOrientationManager alloc] init]; + }); + return manager; +} - [self setupListeners]; +- (void)setup { + if (_cmmotionManager) { + return; } - return self; + _cmmotionManager = [[CMMotionManager alloc] init]; + _cmmotionManager.deviceMotionUpdateInterval = kSADefaultDeviceMotionUpdateInterval; + _updateQueue = [[NSOperationQueue alloc] init]; + _updateQueue.name = @"com.sensorsdata.analytics.deviceMotionUpdatesQueue"; + + [self setupListeners]; } #pragma mark - SAModuleProtocol @@ -59,6 +67,7 @@ - (void)setEnable:(BOOL)enable { _enable = enable; if (enable) { + [self setup]; [self startDeviceMotionUpdates]; } else { self.deviceOrientation = nil; @@ -66,6 +75,11 @@ - (void)setEnable:(BOOL)enable { } } +- (void)setConfigOptions:(SAConfigOptions *)configOptions { + _configOptions = configOptions; + self.enable = configOptions.enableDeviceOrientation; +} + - (NSDictionary *)properties { return self.deviceOrientation ? @{kSAEventPresetPropertyScreenOrientation: self.deviceOrientation} : nil; } diff --git a/SensorsAnalyticsSDK/DeviceOrientation/SensorsAnalyticsSDK+DeviceOrientation.h b/SensorsAnalyticsSDK/DeviceOrientation/SensorsAnalyticsSDK+DeviceOrientation.h new file mode 100644 index 00000000..db574272 --- /dev/null +++ b/SensorsAnalyticsSDK/DeviceOrientation/SensorsAnalyticsSDK+DeviceOrientation.h @@ -0,0 +1,41 @@ +// +// SensorsAnalyticsSDK+DeviceOrientation.h +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/11. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#import "SensorsAnalyticsSDK.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SensorsAnalyticsSDK (DeviceOrientation) + +/** + * @abstract + * 设备方向信息采集功能开关 + * + * @discussion + * 根据需要决定是否开启设备方向采集 + * 默认关闭 + * + * @param enable YES/NO + */ +- (void)enableTrackScreenOrientation:(BOOL)enable API_UNAVAILABLE(macos); + +@end + +NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/DeviceOrientation/SensorsAnalyticsSDK+DeviceOrientation.m b/SensorsAnalyticsSDK/DeviceOrientation/SensorsAnalyticsSDK+DeviceOrientation.m new file mode 100644 index 00000000..b0a49762 --- /dev/null +++ b/SensorsAnalyticsSDK/DeviceOrientation/SensorsAnalyticsSDK+DeviceOrientation.m @@ -0,0 +1,35 @@ +// +// SensorsAnalyticsSDK+DeviceOrientation.m +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/11. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#if ! __has_feature(objc_arc) +#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag on this file. +#endif + +#import "SensorsAnalyticsSDK+DeviceOrientation.h" +#import "SADeviceOrientationManager.h" + +@implementation SensorsAnalyticsSDK (DeviceOrientation) + +- (void)enableTrackScreenOrientation:(BOOL)enable { + [SADeviceOrientationManager defaultManager].enable = enable; + [SADeviceOrientationManager defaultManager].configOptions.enableDeviceOrientation = enable; +} + +@end diff --git a/SensorsAnalyticsSDK/Encrypt/SAConfigOptions+Encrypt.h b/SensorsAnalyticsSDK/Encrypt/SAConfigOptions+Encrypt.h index 86474b58..109cbf91 100644 --- a/SensorsAnalyticsSDK/Encrypt/SAConfigOptions+Encrypt.h +++ b/SensorsAnalyticsSDK/Encrypt/SAConfigOptions+Encrypt.h @@ -25,8 +25,17 @@ NS_ASSUME_NONNULL_BEGIN @interface SAConfigOptions (Encrypt) +/// 是否开启加密 +@property (nonatomic, assign) BOOL enableEncrypt API_UNAVAILABLE(macos); + - (void)registerEncryptor:(id)encryptor API_UNAVAILABLE(macos); +/// 存储公钥的回调。务必保存秘钥所有字段信息 +@property (nonatomic, copy) void (^saveSecretKey)(SASecretKey * _Nonnull secretKey) API_UNAVAILABLE(macos); + +/// 获取公钥的回调。务必回传秘钥所有字段信息 +@property (nonatomic, copy) SASecretKey * _Nonnull (^loadSecretKey)(void) API_UNAVAILABLE(macos); + @end NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Encrypt/SAConfigOptions+Encrypt.m b/SensorsAnalyticsSDK/Encrypt/SAConfigOptions+Encrypt.m index 7dfaca7c..ed6353dc 100644 --- a/SensorsAnalyticsSDK/Encrypt/SAConfigOptions+Encrypt.m +++ b/SensorsAnalyticsSDK/Encrypt/SAConfigOptions+Encrypt.m @@ -27,6 +27,9 @@ @interface SAConfigOptions () @property (atomic, strong, readwrite) NSMutableArray *encryptors; +@property (nonatomic, assign) BOOL enableEncrypt; +@property (nonatomic, copy) void (^saveSecretKey)(SASecretKey * _Nonnull secretKey); +@property (nonatomic, copy) SASecretKey * _Nonnull (^loadSecretKey)(void); @end diff --git a/SensorsAnalyticsSDK/Encrypt/SAEncryptManager.h b/SensorsAnalyticsSDK/Encrypt/SAEncryptManager.h index 91621d20..c5a58b73 100644 --- a/SensorsAnalyticsSDK/Encrypt/SAEncryptManager.h +++ b/SensorsAnalyticsSDK/Encrypt/SAEncryptManager.h @@ -25,8 +25,9 @@ NS_ASSUME_NONNULL_BEGIN @interface SAEncryptManager : NSObject -@property (nonatomic, assign, getter=isEnable) BOOL enable; ++ (instancetype)defaultManager; +@property (nonatomic, assign, getter=isEnable) BOOL enable; @property (nonatomic, strong) SAConfigOptions *configOptions; @end diff --git a/SensorsAnalyticsSDK/Encrypt/SAEncryptManager.m b/SensorsAnalyticsSDK/Encrypt/SAEncryptManager.m index 94e631b9..56281fbc 100644 --- a/SensorsAnalyticsSDK/Encrypt/SAEncryptManager.m +++ b/SensorsAnalyticsSDK/Encrypt/SAEncryptManager.m @@ -62,6 +62,15 @@ @interface SAEncryptManager () @implementation SAEncryptManager ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SAEncryptManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SAEncryptManager alloc] init]; + }); + return manager; +} + #pragma mark - SAModuleProtocol - (void)setEnable:(BOOL)enable { @@ -74,6 +83,9 @@ - (void)setEnable:(BOOL)enable { - (void)setConfigOptions:(SAConfigOptions *)configOptions { _configOptions = configOptions; + if (configOptions.enableEncrypt) { + NSAssert((configOptions.saveSecretKey && configOptions.loadSecretKey) || (!configOptions.saveSecretKey && !configOptions.loadSecretKey), @"存储公钥和获取公钥的回调需要全部实现或者全部不实现。"); + } NSMutableArray *encryptors = [NSMutableArray array]; @@ -84,6 +96,7 @@ - (void)setConfigOptions:(SAConfigOptions *)configOptions { [encryptors addObject:[[SARSAPluginEncryptor alloc] init]]; [encryptors addObjectsFromArray:configOptions.encryptors]; self.encryptors = encryptors; + self.enable = configOptions.enableEncrypt; } #pragma mark - SAOpenURLProtocol diff --git a/SensorsAnalyticsSDK/Exception/SAConfigOptions+Exception.h b/SensorsAnalyticsSDK/Exception/SAConfigOptions+Exception.h new file mode 100644 index 00000000..ff625504 --- /dev/null +++ b/SensorsAnalyticsSDK/Exception/SAConfigOptions+Exception.h @@ -0,0 +1,32 @@ +// +// SAConfigOptions+Exception.h +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/10. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#import "SAConfigOptions.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SAConfigOptions (Exception) + +/// 是否自动收集 App Crash 日志,该功能默认是关闭的 +@property (nonatomic, assign) BOOL enableTrackAppCrash API_UNAVAILABLE(macos); + +@end + +NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Exception/SAExceptionManager.h b/SensorsAnalyticsSDK/Exception/SAExceptionManager.h index 2661c25b..f2f741f1 100644 --- a/SensorsAnalyticsSDK/Exception/SAExceptionManager.h +++ b/SensorsAnalyticsSDK/Exception/SAExceptionManager.h @@ -23,9 +23,12 @@ NS_ASSUME_NONNULL_BEGIN -@interface SAExceptionManager : NSObject +@interface SAExceptionManager : NSObject + ++ (instancetype)defaultManager; @property (nonatomic, assign, getter=isEnable) BOOL enable; +@property (nonatomic, strong) SAConfigOptions *configOptions; @end diff --git a/SensorsAnalyticsSDK/Exception/SAExceptionManager.m b/SensorsAnalyticsSDK/Exception/SAExceptionManager.m index f936a3be..8f14d8ac 100644 --- a/SensorsAnalyticsSDK/Exception/SAExceptionManager.m +++ b/SensorsAnalyticsSDK/Exception/SAExceptionManager.m @@ -28,6 +28,7 @@ #import "SAConstants+Private.h" #import "SAModuleManager.h" #import "SALog.h" +#import "SAConfigOptions+Exception.h" #include #include @@ -49,6 +50,15 @@ @interface SAExceptionManager () @implementation SAExceptionManager ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SAExceptionManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SAExceptionManager alloc] init]; + }); + return manager; +} + - (void)setEnable:(BOOL)enable { _enable = enable; @@ -59,12 +69,13 @@ - (void)setEnable:(BOOL)enable { } } -- (void)dealloc { - free(_prev_signal_handlers); +- (void)setConfigOptions:(SAConfigOptions *)configOptions { + _configOptions = configOptions; + self.enable = configOptions.enableTrackAppCrash; } -+ (instancetype)sharedInstance { - return (SAExceptionManager *)[SAModuleManager.sharedInstance managerForModuleType:SAModuleTypeException]; +- (void)dealloc { + free(_prev_signal_handlers); } - (void)setupExceptionHandler { @@ -100,10 +111,10 @@ static void SASignalHandler(int crashSignal, struct __siginfo *info, void *conte reason:reason userInfo:userInfo]; - [SAExceptionManager.sharedInstance handleUncaughtException:exception]; + [SAExceptionManager.defaultManager handleUncaughtException:exception]; } - struct sigaction prev_action = SAExceptionManager.sharedInstance.prev_signal_handlers[crashSignal]; + struct sigaction prev_action = SAExceptionManager.defaultManager.prev_signal_handlers[crashSignal]; if (prev_action.sa_flags & SA_SIGINFO) { if (prev_action.sa_sigaction) { prev_action.sa_sigaction(crashSignal, info, context); @@ -118,11 +129,11 @@ static void SASignalHandler(int crashSignal, struct __siginfo *info, void *conte static void SAHandleException(NSException *exception) { int32_t exceptionCount = OSAtomicIncrement32(&kSAExceptionCount); if (exceptionCount <= kSAExceptionMaximum) { - [SAExceptionManager.sharedInstance handleUncaughtException:exception]; + [SAExceptionManager.defaultManager handleUncaughtException:exception]; } - if (SAExceptionManager.sharedInstance.defaultExceptionHandler) { - SAExceptionManager.sharedInstance.defaultExceptionHandler(exception); + if (SAExceptionManager.defaultManager.defaultExceptionHandler) { + SAExceptionManager.defaultManager.defaultExceptionHandler(exception); } } @@ -140,6 +151,7 @@ - (void)handleUncaughtException:(NSException *)exception { SAPresetEventObject *object = [[SAPresetEventObject alloc] initWithEventId:kSAEventNameAppCrashed]; [SensorsAnalyticsSDK.sharedInstance asyncTrackEventObject:object properties:properties]; + //TODO: 去除对 SAModuleManager 的引用 //触发页面浏览时长事件 [[SAModuleManager sharedInstance] trackPageLeaveWhenCrashed]; diff --git a/SensorsAnalyticsSDK/Core/JSBridge/SAJavaScriptBridgeManager.h b/SensorsAnalyticsSDK/JSBridge/SAJavaScriptBridgeManager.h similarity index 98% rename from SensorsAnalyticsSDK/Core/JSBridge/SAJavaScriptBridgeManager.h rename to SensorsAnalyticsSDK/JSBridge/SAJavaScriptBridgeManager.h index 4f946fed..2960b68b 100644 --- a/SensorsAnalyticsSDK/Core/JSBridge/SAJavaScriptBridgeManager.h +++ b/SensorsAnalyticsSDK/JSBridge/SAJavaScriptBridgeManager.h @@ -26,12 +26,11 @@ NS_ASSUME_NONNULL_BEGIN @interface SAJavaScriptBridgeManager : NSObject -@property (nonatomic, assign, getter=isEnable) BOOL enable; ++ (instancetype)defaultManager; +@property (nonatomic, assign, getter=isEnable) BOOL enable; @property (nonatomic, strong) SAConfigOptions *configOptions; -+ (instancetype)sharedInstance; - - (void)addScriptMessageHandlerWithWebView:(WKWebView *)webView; @end diff --git a/SensorsAnalyticsSDK/Core/JSBridge/SAJavaScriptBridgeManager.m b/SensorsAnalyticsSDK/JSBridge/SAJavaScriptBridgeManager.m similarity index 95% rename from SensorsAnalyticsSDK/Core/JSBridge/SAJavaScriptBridgeManager.m rename to SensorsAnalyticsSDK/JSBridge/SAJavaScriptBridgeManager.m index ab353842..4f850227 100644 --- a/SensorsAnalyticsSDK/Core/JSBridge/SAJavaScriptBridgeManager.m +++ b/SensorsAnalyticsSDK/JSBridge/SAJavaScriptBridgeManager.m @@ -30,17 +30,18 @@ #import "WKWebView+SABridge.h" #import "SAJSONUtil.h" #import "SASwizzle.h" +#import "SensorsAnalyticsSDK+JavaScriptBridge.h" -@interface SAJavaScriptBridgeManager () - -@end @implementation SAJavaScriptBridgeManager -#pragma mark - Life Cycle - -+ (instancetype)sharedInstance { - return (SAJavaScriptBridgeManager *)[SAModuleManager.sharedInstance managerForModuleType:SAModuleTypeJavaScriptBridge]; ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SAJavaScriptBridgeManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SAJavaScriptBridgeManager alloc] init]; + }); + return manager; } #pragma mark - SAModuleProtocol @@ -52,6 +53,11 @@ - (void)setEnable:(BOOL)enable { } } +- (void)setConfigOptions:(SAConfigOptions *)configOptions { + _configOptions = configOptions; + self.enable = configOptions.enableJavaScriptBridge; +} + #pragma mark - SAJavaScriptBridgeModuleProtocol - (NSString *)javaScriptSource { @@ -111,7 +117,7 @@ - (void)addScriptMessageHandlerWithWebView:(WKWebView *)webView { @try { WKUserContentController *contentController = webView.configuration.userContentController; [contentController removeScriptMessageHandlerForName:SA_SCRIPT_MESSAGE_HANDLER_NAME]; - [contentController addScriptMessageHandler:[SAJavaScriptBridgeManager sharedInstance] name:SA_SCRIPT_MESSAGE_HANDLER_NAME]; + [contentController addScriptMessageHandler:[SAJavaScriptBridgeManager defaultManager] name:SA_SCRIPT_MESSAGE_HANDLER_NAME]; NSString *javaScriptSource = [SAModuleManager.sharedInstance javaScriptSource]; if (javaScriptSource.length == 0) { diff --git a/SensorsAnalyticsSDK/JSBridge/SensorsAnalyticsSDK+JavaScriptBridge.h b/SensorsAnalyticsSDK/JSBridge/SensorsAnalyticsSDK+JavaScriptBridge.h new file mode 100644 index 00000000..284e1cc0 --- /dev/null +++ b/SensorsAnalyticsSDK/JSBridge/SensorsAnalyticsSDK+JavaScriptBridge.h @@ -0,0 +1,40 @@ +// +// SensorsAnalyticsSDK+JavaScriptBridge.h +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/13. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#import "SensorsAnalyticsSDK.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SensorsAnalyticsSDK (JavaScriptBridge) + +- (void)trackFromH5WithEvent:(NSString *)eventInfo; + +- (void)trackFromH5WithEvent:(NSString *)eventInfo enableVerify:(BOOL)enableVerify; + +@end + +@interface SAConfigOptions (JavaScriptBridge) + +/// 是否开启 WKWebView 的 H5 打通功能,该功能默认是关闭的 +@property (nonatomic) BOOL enableJavaScriptBridge; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Core/JSBridge/WKWebView+SABridge.h b/SensorsAnalyticsSDK/JSBridge/WKWebView+SABridge.h similarity index 100% rename from SensorsAnalyticsSDK/Core/JSBridge/WKWebView+SABridge.h rename to SensorsAnalyticsSDK/JSBridge/WKWebView+SABridge.h diff --git a/SensorsAnalyticsSDK/Core/JSBridge/WKWebView+SABridge.m b/SensorsAnalyticsSDK/JSBridge/WKWebView+SABridge.m similarity index 87% rename from SensorsAnalyticsSDK/Core/JSBridge/WKWebView+SABridge.m rename to SensorsAnalyticsSDK/JSBridge/WKWebView+SABridge.m index 5c36a9ff..758497bb 100644 --- a/SensorsAnalyticsSDK/Core/JSBridge/WKWebView+SABridge.m +++ b/SensorsAnalyticsSDK/JSBridge/WKWebView+SABridge.m @@ -28,25 +28,25 @@ @implementation WKWebView (SABridge) - (WKNavigation *)sensorsdata_loadRequest:(NSURLRequest *)request { - [[SAJavaScriptBridgeManager sharedInstance] addScriptMessageHandlerWithWebView:self]; + [[SAJavaScriptBridgeManager defaultManager] addScriptMessageHandlerWithWebView:self]; return [self sensorsdata_loadRequest:request]; } - (WKNavigation *)sensorsdata_loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL { - [[SAJavaScriptBridgeManager sharedInstance] addScriptMessageHandlerWithWebView:self]; + [[SAJavaScriptBridgeManager defaultManager] addScriptMessageHandlerWithWebView:self]; return [self sensorsdata_loadHTMLString:string baseURL:baseURL]; } - (WKNavigation *)sensorsdata_loadFileURL:(NSURL *)URL allowingReadAccessToURL:(NSURL *)readAccessURL { - [[SAJavaScriptBridgeManager sharedInstance] addScriptMessageHandlerWithWebView:self]; + [[SAJavaScriptBridgeManager defaultManager] addScriptMessageHandlerWithWebView:self]; return [self sensorsdata_loadFileURL:URL allowingReadAccessToURL:readAccessURL]; } - (WKNavigation *)sensorsdata_loadData:(NSData *)data MIMEType:(NSString *)MIMEType characterEncodingName:(NSString *)characterEncodingName baseURL:(NSURL *)baseURL { - [[SAJavaScriptBridgeManager sharedInstance] addScriptMessageHandlerWithWebView:self]; + [[SAJavaScriptBridgeManager defaultManager] addScriptMessageHandlerWithWebView:self]; return [self sensorsdata_loadData:data MIMEType:MIMEType characterEncodingName:characterEncodingName baseURL:baseURL]; } diff --git a/SensorsAnalyticsSDK/Location/SALocationManager.h b/SensorsAnalyticsSDK/Location/SALocationManager.h index 5667af07..6ca9abed 100644 --- a/SensorsAnalyticsSDK/Location/SALocationManager.h +++ b/SensorsAnalyticsSDK/Location/SALocationManager.h @@ -25,10 +25,18 @@ NS_ASSUME_NONNULL_BEGIN @interface SALocationManager : NSObject -@property (nonatomic, assign, getter=isEnable) BOOL enable; ++ (instancetype)defaultManager; +@property (nonatomic, assign, getter=isEnable) BOOL enable; +@property (nonatomic, strong) SAConfigOptions *configOptions; @property (nonatomic, copy, readonly, nullable) NSDictionary *properties; @end +@interface SAConfigOptions (Location) + +@property (nonatomic, assign) BOOL enableLocation; + +@end + NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Location/SALocationManager.m b/SensorsAnalyticsSDK/Location/SALocationManager.m index 971a8365..64662e48 100644 --- a/SensorsAnalyticsSDK/Location/SALocationManager.m +++ b/SensorsAnalyticsSDK/Location/SALocationManager.m @@ -43,21 +43,34 @@ @interface SALocationManager() @implementation SALocationManager -- (instancetype)init { - if (self = [super init]) { - //默认设置设置精度为 100 ,也就是 100 米定位一次 ;准确性 kCLLocationAccuracyHundredMeters - _locationManager = [[CLLocationManager alloc] init]; - _locationManager.delegate = self; - _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; - _locationManager.distanceFilter = 100.0; ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SALocationManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SALocationManager alloc] init]; + }); + return manager; +} - _isUpdatingLocation = NO; +- (void)setup { + if (_locationManager) { + return; + } + //默认设置设置精度为 100 ,也就是 100 米定位一次 ;准确性 kCLLocationAccuracyHundredMeters + _locationManager = [[CLLocationManager alloc] init]; + _locationManager.delegate = self; + _locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; + _locationManager.distanceFilter = 100.0; - _coordinate = kCLLocationCoordinate2DInvalid; + _isUpdatingLocation = NO; - [self setupListeners]; - } - return self; + _coordinate = kCLLocationCoordinate2DInvalid; + [self setupListeners]; +} + +- (void)setConfigOptions:(SAConfigOptions *)configOptions { + _configOptions = configOptions; + self.enable = configOptions.enableLocation; } - (void)dealloc { @@ -68,8 +81,8 @@ - (void)dealloc { - (void)setEnable:(BOOL)enable { _enable = enable; - if (enable) { + [self setup]; [self startUpdatingLocation]; } else { [self stopUpdatingLocation]; diff --git a/SensorsAnalyticsSDK/Location/SensorsAnalyticsSDK+Location.h b/SensorsAnalyticsSDK/Location/SensorsAnalyticsSDK+Location.h new file mode 100644 index 00000000..13dfa6ee --- /dev/null +++ b/SensorsAnalyticsSDK/Location/SensorsAnalyticsSDK+Location.h @@ -0,0 +1,41 @@ +// +// SensorsAnalyticsSDK+Location.h +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/11. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#import "SensorsAnalyticsSDK.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SensorsAnalyticsSDK (Location) + +/** + * @abstract + * 位置信息采集功能开关 + * + * @discussion + * 根据需要决定是否开启位置采集 + * 默认关闭 + * + * @param enable YES/NO + */ +- (void)enableTrackGPSLocation:(BOOL)enable API_UNAVAILABLE(macos); + +@end + +NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/Location/SensorsAnalyticsSDK+Location.m b/SensorsAnalyticsSDK/Location/SensorsAnalyticsSDK+Location.m new file mode 100644 index 00000000..70cae5e3 --- /dev/null +++ b/SensorsAnalyticsSDK/Location/SensorsAnalyticsSDK+Location.m @@ -0,0 +1,42 @@ +// +// SensorsAnalyticsSDK+Location.m +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/11. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#if ! __has_feature(objc_arc) +#error This file must be compiled with ARC. Either turn on ARC for the project or use -fobjc-arc flag on this file. +#endif + +#import "SensorsAnalyticsSDK+Location.h" +#import "SALocationManager.h" + +@implementation SensorsAnalyticsSDK (Location) + +- (void)enableTrackGPSLocation:(BOOL)enable { + if (NSThread.isMainThread) { + [SALocationManager defaultManager].enable = enable; + [SALocationManager defaultManager].configOptions.enableLocation = enable; + } else { + dispatch_async(dispatch_get_main_queue(), ^ { + [SALocationManager defaultManager].enable = enable; + [SALocationManager defaultManager].configOptions.enableLocation = enable; + }); + } +} + +@end diff --git a/SensorsAnalyticsSDK/RemoteConfig/SAConfigOptions+RemoteConfig.h b/SensorsAnalyticsSDK/RemoteConfig/SAConfigOptions+RemoteConfig.h new file mode 100644 index 00000000..dd872ab4 --- /dev/null +++ b/SensorsAnalyticsSDK/RemoteConfig/SAConfigOptions+RemoteConfig.h @@ -0,0 +1,42 @@ +// +// SAConfigOptions+RemoteConfig.h +// SensorsAnalyticsSDK +// +// Created by 陈玉国 on 2021/9/10. +// Copyright © 2021 Sensors Data Co., Ltd. All rights reserved. +// +// 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 +// +// http://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. +// + +#import "SAConfigOptions.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SAConfigOptions (RemoteConfig) + +#pragma mark - 请求远程配置策略 +/// 请求远程配置地址,默认从 serverURL 解析 +@property (nonatomic, copy) NSString *remoteConfigURL API_UNAVAILABLE(macos); + +/// 禁用随机时间请求远程配置 +@property (nonatomic, assign) BOOL disableRandomTimeRequestRemoteConfig API_UNAVAILABLE(macos); + +/// 最小间隔时长,单位:小时,默认 24 +@property (nonatomic, assign) NSInteger minRequestHourInterval API_UNAVAILABLE(macos); + +/// 最大间隔时长,单位:小时,默认 48 +@property (nonatomic, assign) NSInteger maxRequestHourInterval API_UNAVAILABLE(macos); + +@end + +NS_ASSUME_NONNULL_END diff --git a/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigCommonOperator.m b/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigCommonOperator.m index d8efe21b..f4541767 100644 --- a/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigCommonOperator.m +++ b/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigCommonOperator.m @@ -27,6 +27,10 @@ #import "SALog.h" #import "SAValidator.h" #import "SAModuleManager.h" +#import "SAConfigOptions+RemoteConfig.h" +#if __has_include("SAConfigOptions+Encrypt.h") +#import "SAConfigOptions+Encrypt.h" +#endif typedef NS_ENUM(NSInteger, SARemoteConfigHandleRandomTimeType) { SARemoteConfigHandleRandomTimeTypeCreate, // 创建分散请求时间 @@ -75,12 +79,14 @@ - (void)tryToRequestRemoteConfig { } // 2. 如果开启加密并且未设置公钥(新用户安装或者从未加密版本升级而来),则请求远程配置获取公钥,同时本地生成随机时间 +#if __has_include("SAConfigOptions+Encrypt.h") if (self.configOptions.enableEncrypt && !SAModuleManager.sharedInstance.hasSecretKey) { [self requestRemoteConfigWithHandleRandomTimeType:SARemoteConfigHandleRandomTimeTypeCreate isForceUpdate:NO]; SALogDebug(@"【remote config】Request remote config because encrypt builder is nil"); return; } - +#endif + // 获取本地保存的随机时间和设备启动时间 NSDictionary *requestTimeConfig = [[NSUserDefaults standardUserDefaults] objectForKey:kRequestRemoteConfigRandomTimeKey]; double randomTime = [[requestTimeConfig objectForKey:kRandomTimeKey] doubleValue]; @@ -174,11 +180,12 @@ - (void)requestRemoteConfigWithDelay:(NSTimeInterval)delay index:(NSUInteger)ind if (success) { if(config != nil) { // 加密 +#if __has_include("SAConfigOptions+Encrypt.h") if (strongSelf.configOptions.enableEncrypt) { NSDictionary *encryptConfig = [strongSelf extractEncryptConfig:config]; [SAModuleManager.sharedInstance handleEncryptWithConfig:encryptConfig]; } - +#endif // 远程配置的请求回调需要在主线程做一些操作(定位和设备方向等) dispatch_async(dispatch_get_main_queue(), ^{ NSDictionary *remoteConfig = [strongSelf extractRemoteConfig:config]; diff --git a/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigManager.h b/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigManager.h index 893f6843..048c1ce8 100644 --- a/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigManager.h +++ b/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigManager.h @@ -25,10 +25,17 @@ NS_ASSUME_NONNULL_BEGIN +@interface SAConfigOptions (RemoteConfigPrivate) + +@property (nonatomic, assign) BOOL enableRemoteConfig; + +@end + @interface SARemoteConfigManager : NSObject -@property (nonatomic, assign, getter=isEnable) BOOL enable; ++ (instancetype)defaultManager; +@property (nonatomic, assign, getter=isEnable) BOOL enable; @property (nonatomic, strong) SAConfigOptions *configOptions; @end diff --git a/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigManager.m b/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigManager.m index 20664720..8f7be57d 100644 --- a/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigManager.m +++ b/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigManager.m @@ -27,6 +27,8 @@ #import "SensorsAnalyticsSDK+Private.h" #import "SAModuleManager.h" #import "SALog.h" +#import "SAConfigOptions+RemoteConfig.h" +#import "SAApplication.h" @interface SARemoteConfigManager () @@ -36,6 +38,23 @@ @interface SARemoteConfigManager () @implementation SARemoteConfigManager ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SARemoteConfigManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SARemoteConfigManager alloc] init]; + }); + return manager; +} + +- (void)setConfigOptions:(SAConfigOptions *)configOptions { + if ([SAApplication isAppExtension]) { + configOptions.enableRemoteConfig = NO; + } + _configOptions = configOptions; + self.enable = configOptions.enableRemoteConfig; +} + - (instancetype)init { self = [super init]; if (self) { diff --git a/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigOperator.m b/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigOperator.m index 795faa14..af613e91 100644 --- a/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigOperator.m +++ b/SensorsAnalyticsSDK/RemoteConfig/SARemoteConfigOperator.m @@ -31,6 +31,11 @@ #import "SAModuleManager.h" #import "SARemoteConfigEventObject.h" #import "SensorsAnalyticsSDK+Private.h" +#import "SAConfigOptions+RemoteConfig.h" + +#if __has_include("SAConfigOptions+Encrypt.h") +#import "SAConfigOptions+Encrypt.h" +#endif @interface SARemoteConfigOperator () @@ -151,10 +156,11 @@ - (BOOL)isLibVersionUnchanged { } - (BOOL)shouldAddVersionOnEnableEncrypt { +#if __has_include("SAConfigOptions+Encrypt.h") if (!self.configOptions.enableEncrypt) { return YES; } - +#endif return SAModuleManager.sharedInstance.hasSecretKey; } diff --git a/SensorsAnalyticsSDK/Visualized/Config/SAVisualPropertiesConfig.m b/SensorsAnalyticsSDK/Visualized/Config/SAVisualPropertiesConfig.m index 65a6b3fa..af996780 100644 --- a/SensorsAnalyticsSDK/Visualized/Config/SAVisualPropertiesConfig.m +++ b/SensorsAnalyticsSDK/Visualized/Config/SAVisualPropertiesConfig.m @@ -279,7 +279,7 @@ - (instancetype)initWithDictionary:(NSDictionary *)eventsDic { [properties addObject:config]; } } - _properties = properties.count > 0 ? [properties copy]: nil;; + _properties = properties.count > 0 ? [properties copy]: nil; _webProperties = webProperties.count > 0 ? [webProperties copy]: nil; } } diff --git a/SensorsAnalyticsSDK/Visualized/Config/SAVisualPropertiesConfigSources.m b/SensorsAnalyticsSDK/Visualized/Config/SAVisualPropertiesConfigSources.m index ab6351b6..d0fad18b 100644 --- a/SensorsAnalyticsSDK/Visualized/Config/SAVisualPropertiesConfigSources.m +++ b/SensorsAnalyticsSDK/Visualized/Config/SAVisualPropertiesConfigSources.m @@ -87,6 +87,19 @@ - (void)setupConfigWithDictionary:(NSDictionary *)configDic disableConfig:(BOOL) [self updateConfigStatus]; } +// 刷新配置 +- (void)reloadConfig { + // 更新最新缓存,并清除本地配置 + [self cleanConfig]; + + NSString *logMessage = [SAVisualizedLogger buildLoggerMessageWithTitle:@"获取配置" message:@"重设 serverURL,并清除配置缓存"]; + SALogDebug(@"%@", logMessage); + + [self updateConfigStatus]; + + [self requestConfigWithTimes:kSARequestConfigMaxTimes]; +} + /// 更新配置结果状态 - (void)updateConfigStatus { if ([self.delegate respondsToSelector:@selector(configChangedWithValid:)]) { @@ -121,15 +134,6 @@ - (void)requestConfigWithTimes:(NSInteger)times { }]; } -- (void)reloadConfig { - // 更新最新缓存,并清除本地配置 - [self cleanConfig]; - - NSString *logMessage = [SAVisualizedLogger buildLoggerMessageWithTitle:@"获取配置" message:@"重设 serverURL,并清除配置缓存"]; - SALogDebug(@"%@", logMessage); - [self requestConfigWithTimes:1]; -} - - (void)requestConfigWithCompletionHandler:(SAVisualPropertiesConfigCompletionHandler)completionHandler { if (![SAReachability sharedInstance].reachable) { diff --git a/SensorsAnalyticsSDK/Visualized/ElementPath/UIViewController+SAElementPath.m b/SensorsAnalyticsSDK/Visualized/ElementPath/UIViewController+SAElementPath.m index ef78b98e..7ee2dfcb 100644 --- a/SensorsAnalyticsSDK/Visualized/ElementPath/UIViewController+SAElementPath.m +++ b/SensorsAnalyticsSDK/Visualized/ElementPath/UIViewController+SAElementPath.m @@ -50,8 +50,7 @@ - (NSArray *)sensorsdata_subElements { if (childViewControllers.count > 0 && ![self isKindOfClass:UIAlertController.class]) { // UIAlertController 如果添加 TextField 也会嵌套 childViewController,直接返回 .view 即可 - - UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow; + UIWindow *keyWindow = UIApplication.sharedApplication.keyWindow; subElements = [NSMutableArray arrayWithArray:self.view.subviews]; // 是否包含全屏视图 __block BOOL isContainFullScreen = NO; @@ -89,7 +88,7 @@ - (NSArray *)sensorsdata_subElements { - (void)sensorsdata_visualize_viewDidAppear:(BOOL)animated { [self sensorsdata_visualize_viewDidAppear:animated]; - if (SAAutoTrackManager.sharedInstance.configOptions.enableAutoTrackChildViewScreen || + if ([SAVisualizedManager defaultManager].configOptions.enableAutoTrackChildViewScreen || !self.parentViewController || [self.parentViewController isKindOfClass:[UITabBarController class]] || [self.parentViewController isKindOfClass:[UINavigationController class]] || @@ -100,12 +99,12 @@ - (void)sensorsdata_visualize_viewDidAppear:(BOOL)animated { // 跳转进入 RN 自定义页面,需更新节点的页面名称 if ([SAVisualizedUtils isRNCustomViewController:self]) { - [SAVisualizedManager.sharedInstance.visualPropertiesTracker enterRNViewController:self]; + [SAVisualizedManager.defaultManager.visualPropertiesTracker enterRNViewController:self]; } } - (void)sensorsdata_readyEnterViewController { - if (![[SAAutoTrackManager sharedInstance].appViewScreenTracker shouldTrackViewController:self]) { + if (![[SAAutoTrackManager defaultManager].appViewScreenTracker shouldTrackViewController:self]) { return; } // 保存最后一次页面浏览所在的 controller,用于可视化全埋点定义页面浏览 diff --git a/SensorsAnalyticsSDK/Visualized/SAApplicationStateSerializer.m b/SensorsAnalyticsSDK/Visualized/SAApplicationStateSerializer.m index f166c515..8a3f487f 100644 --- a/SensorsAnalyticsSDK/Visualized/SAApplicationStateSerializer.m +++ b/SensorsAnalyticsSDK/Visualized/SAApplicationStateSerializer.m @@ -51,12 +51,11 @@ - (instancetype)initWithConfiguration:(SAObjectSerializerConfig *)configuration // 所有 window 截图合成 - (void)screenshotImageForAllWindowWithCompletionHandler:(void (^)(UIImage *))completionHandler { CGFloat scale = [UIScreen mainScreen].scale; - // 获取所有可见的 window 截图 NSMutableArray *allActiveWindows = [NSMutableArray array]; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, *)) { - for (UIWindowScene *windowScene in [UIApplication sharedApplication].connectedScenes) { + for (UIWindowScene *windowScene in UIApplication.sharedApplication.connectedScenes) { if (windowScene.activationState == UISceneActivationStateForegroundActive) { [allActiveWindows addObjectsFromArray:windowScene.windows]; } @@ -64,7 +63,7 @@ - (void)screenshotImageForAllWindowWithCompletionHandler:(void (^)(UIImage *))co } #endif if (allActiveWindows.count == 0) { - [allActiveWindows addObjectsFromArray:[UIApplication sharedApplication].windows]; + [allActiveWindows addObjectsFromArray:UIApplication.sharedApplication.windows]; } NSMutableArray *validWindows = [NSMutableArray array]; diff --git a/SensorsAnalyticsSDK/Visualized/SAVisualizedAbstractMessage.m b/SensorsAnalyticsSDK/Visualized/SAVisualizedAbstractMessage.m index 7aced2d1..3f7a547c 100644 --- a/SensorsAnalyticsSDK/Visualized/SAVisualizedAbstractMessage.m +++ b/SensorsAnalyticsSDK/Visualized/SAVisualizedAbstractMessage.m @@ -142,6 +142,10 @@ - (NSData *)JSONDataWithFeatureCode:(NSString *)featureCode { } jsonObject[@"app_autotrack"] = autotrackOptions; + // 自定义属性开关状态 + jsonObject[@"app_enablevisualizedproperties"] = @(SensorsAnalyticsSDK.sharedInstance.configOptions.enableVisualizedProperties); + + // 添加前端弹框信息 if (serializerManager.alertInfos.count > 0) { jsonObject[@"app_alert_infos"] = [serializerManager.alertInfos copy]; @@ -158,7 +162,7 @@ - (NSData *)JSONDataWithFeatureCode:(NSString *)featureCode { // SDK 版本号 jsonObject[@"lib_version"] = SensorsAnalyticsSDK.sharedInstance.libVersion; // 可视化全埋点配置版本号 - jsonObject[@"config_version"] = [SAVisualizedManager sharedInstance].configSources.configVersion; + jsonObject[@"config_version"] = [SAVisualizedManager defaultManager].configSources.configVersion; if (_payload.count == 0) { return [SAJSONUtil dataWithJSONObject:jsonObject]; diff --git a/SensorsAnalyticsSDK/Visualized/SAVisualizedAutoTrackObjectSerializer.m b/SensorsAnalyticsSDK/Visualized/SAVisualizedAutoTrackObjectSerializer.m index fcfdedcf..54f812b2 100644 --- a/SensorsAnalyticsSDK/Visualized/SAVisualizedAutoTrackObjectSerializer.m +++ b/SensorsAnalyticsSDK/Visualized/SAVisualizedAutoTrackObjectSerializer.m @@ -258,7 +258,7 @@ - (void)addNotWKWebViewAlertInfo { alertInfo[@"message"] = @"此页面不是 WKWebView,iOS App 内嵌 H5 可视化全埋点,只支持 WKWebView"; alertInfo[@"link_text"] = @"配置文档"; alertInfo[@"link_url"] = @"https://manual.sensorsdata.cn/sa/latest/enable_visualized_autotrack-7548675.html"; - if ([SAVisualizedManager sharedInstance].visualizedType == SensorsAnalyticsVisualizedTypeHeatMap) { + if ([SAVisualizedManager defaultManager].visualizedType == SensorsAnalyticsVisualizedTypeHeatMap) { alertInfo[@"title"] = @"当前页面无法进行点击分析"; alertInfo[@"message"] = @"此页面包含 UIWebView,iOS App 内嵌 H5 点击分析,只支持 WKWebView"; alertInfo[@"link_url"] = @"https://manual.sensorsdata.cn/sa/latest/app-16286049.html"; @@ -345,7 +345,7 @@ - (void)checkJSSDKIntegrationWithWebView:(WKWebView *)webView { alertInfo[@"message"] = @"此页面未集成 Web JS SDK 或者 Web JS SDK 版本过低,请集成最新版 Web JS SDK"; alertInfo[@"link_text"] = @"配置文档"; alertInfo[@"link_url"] = @"https://manual.sensorsdata.cn/sa/latest/tech_sdk_client_web_use-7548173.html"; - if ([SAVisualizedManager sharedInstance].visualizedType == SensorsAnalyticsVisualizedTypeHeatMap) { + if ([SAVisualizedManager defaultManager].visualizedType == SensorsAnalyticsVisualizedTypeHeatMap) { alertInfo[@"title"] = @"当前页面无法进行点击分析"; } NSMutableDictionary *alertInfoMessage = [@{ @"callType": @"app_alert", @"data": @[alertInfo] } mutableCopy]; diff --git a/SensorsAnalyticsSDK/Visualized/SAVisualizedConnection.m b/SensorsAnalyticsSDK/Visualized/SAVisualizedConnection.m index b3227fb9..b64bbc0d 100644 --- a/SensorsAnalyticsSDK/Visualized/SAVisualizedConnection.m +++ b/SensorsAnalyticsSDK/Visualized/SAVisualizedConnection.m @@ -138,10 +138,10 @@ - (void)close { [[SAVisualizedObjectSerializerManager sharedInstance] cleanVisualizedWebPageInfoCache]; // 关闭埋点校验 - [SAVisualizedManager.sharedInstance enableEventCheck:NO]; + [SAVisualizedManager.defaultManager enableEventCheck:NO]; // 关闭诊断信息收集 - [SAVisualizedManager.sharedInstance.visualPropertiesTracker enableCollectDebugLog:NO]; + [SAVisualizedManager.defaultManager.visualPropertiesTracker enableCollectDebugLog:NO]; } - (BOOL)isVisualizedConnecting { @@ -188,10 +188,11 @@ - (void)sendMessage:(id)message { /// 解析调试信息 - (void)analysisDebugMessage:(NSDictionary *)message { - if (message.count == 0) { + // 关闭自定义属性也不再处理调试信息 + if (message.count == 0 || !SAVisualizedManager.defaultManager.configOptions.enableVisualizedProperties) { return; } - + // 解析可视化全埋点配置 NSDictionary *configDic = message[@"visualized_sdk_config"]; // 是否关闭自定义属性 @@ -199,18 +200,18 @@ - (void)analysisDebugMessage:(NSDictionary *)message { if (disableConfig) { NSString *logMessage = [SAVisualizedLogger buildLoggerMessageWithTitle:@"开关控制" message:@"轮询接口返回,运维配置,关闭自定义属性"]; SALogDebug(@"%@", logMessage); - - [SAVisualizedManager.sharedInstance.configSources setupConfigWithDictionary:nil disableConfig:YES]; + + [SAVisualizedManager.defaultManager.configSources setupConfigWithDictionary:nil disableConfig:YES]; } else if (configDic.count > 0) { NSString *logMessage = [SAVisualizedLogger buildLoggerMessageWithTitle:@"获取配置" message:@"轮询接口更新可视化全埋点配置,%@", configDic]; SALogInfo(@"%@", logMessage); - - [SAVisualizedManager.sharedInstance.configSources setupConfigWithDictionary:configDic disableConfig:NO]; + + [SAVisualizedManager.defaultManager.configSources setupConfigWithDictionary:configDic disableConfig:NO]; } - + // 前端页面进入 &debug=1 调试模式 BOOL isDebug = [message[@"visualized_debug_mode_enabled"] boolValue]; - [SAVisualizedManager.sharedInstance.visualPropertiesTracker enableCollectDebugLog:isDebug]; + [SAVisualizedManager.defaultManager.visualPropertiesTracker enableCollectDebugLog:isDebug]; } diff --git a/SensorsAnalyticsSDK/Visualized/SAVisualizedManager.h b/SensorsAnalyticsSDK/Visualized/SAVisualizedManager.h index ed358f14..d383bf59 100644 --- a/SensorsAnalyticsSDK/Visualized/SAVisualizedManager.h +++ b/SensorsAnalyticsSDK/Visualized/SAVisualizedManager.h @@ -34,10 +34,9 @@ NS_ASSUME_NONNULL_BEGIN @interface SAVisualizedManager : NSObject -@property (class,nonatomic, strong, readonly)SAVisualizedManager *sharedInstance; ++ (instancetype)defaultManager; @property (nonatomic, assign, getter=isEnable) BOOL enable; - @property (nonatomic, strong) SAConfigOptions *configOptions; /// 自定义属性采集 diff --git a/SensorsAnalyticsSDK/Visualized/SAVisualizedManager.m b/SensorsAnalyticsSDK/Visualized/SAVisualizedManager.m index a470023d..2d55d15a 100644 --- a/SensorsAnalyticsSDK/Visualized/SAVisualizedManager.m +++ b/SensorsAnalyticsSDK/Visualized/SAVisualizedManager.m @@ -56,17 +56,19 @@ @interface SAVisualizedManager() /// 埋点校验 @property (nonatomic, strong, readwrite) SAVisualizedEventCheck *eventCheck; + @end @implementation SAVisualizedManager -+ (SAVisualizedManager *)sharedInstance { - id manager = [[SAModuleManager sharedInstance] managerForModuleType:SAModuleTypeVisualized]; - if (manager.isEnable) { - return (SAVisualizedManager *)manager; - } - return nil; ++ (instancetype)defaultManager { + static dispatch_once_t onceToken; + static SAVisualizedManager *manager = nil; + dispatch_once(&onceToken, ^{ + manager = [[SAVisualizedManager alloc] init]; + }); + return manager; } #pragma mark initialize @@ -106,6 +108,7 @@ - (void)setEnable:(BOOL)enable { if (!enable) { self.configSources = nil; self.visualPropertiesTracker = nil; + [self.visualizedConnection close]; return; } @@ -118,19 +121,33 @@ - (void)setEnable:(BOOL)enable { } }); - if (!self.configSources && self.configOptions.enableVisualizedAutoTrack) { - // 只要开启可视化,默认获取远程配置 + // 未开启自定义属性 + if (!self.configOptions.enableVisualizedProperties) { + SALogDebug(@"Current App does not support visualizedProperties"); + return; + } + + if (!self.configSources) { + // 获取自定义属性配置 self.configSources = [[SAVisualPropertiesConfigSources alloc] initWithDelegate:self]; [self.configSources loadConfig]; } } +- (void)setConfigOptions:(SAConfigOptions *)configOptions { + _configOptions = configOptions; + + // 由于自定义属性依赖于可视化全埋点,所以只要开启自定义属性,默认打开可视化全埋点相关功能 + // 可视化全埋点或点击分析开启 + self.enable = configOptions.enableHeatMap || configOptions.enableVisualizedAutoTrack || configOptions.enableVisualizedProperties; +} + -(void)updateServerURL:(NSString *)serverURL { - if (![SAValidator isValidString:serverURL] || ![self.configOptions.serverURL isEqualToString:serverURL]) { + if (![SAValidator isValidString:serverURL]) { return; } // 刷新自定义属性配置 - [self.configSources loadConfig]; + [self.configSources reloadConfig]; } #pragma mark - @@ -144,8 +161,8 @@ - (NSString *)javaScriptSource { NSString *jsVisualizedMode = [SAJavaScriptBridgeBuilder buildVisualBridgeWithVisualizedMode:YES]; [javaScriptSource appendString:jsVisualizedMode]; } - - if (!self.configSources.isValid || self.configSources.originalResponse.count == 0) { + + if (!self.configOptions.enableVisualizedProperties || !self.configSources.isValid || self.configSources.originalResponse.count == 0) { return javaScriptSource; } @@ -205,7 +222,7 @@ - (BOOL)handleURL:(NSURL *)url { return YES; } if (featureCode && postURLStr && self.isEnable) { - [SAVisualizedManager.sharedInstance showOpenAlertWithURL:url featureCode:featureCode postURL:postURLStr]; + [SAVisualizedManager.defaultManager showOpenAlertWithURL:url featureCode:featureCode postURL:postURLStr]; return YES; } //feature_code url 参数错误 @@ -333,7 +350,7 @@ - (void)visualPropertiesWithView:(UIView *)view completionHandler:(void (^)(NSDi } - (void)queryVisualPropertiesWithConfigs:(NSArray *)propertyConfigs completionHandler:(void (^)(NSDictionary * _Nullable))completionHandler { - if (!self.visualPropertiesTracker) { + if (propertyConfigs.count == 0 || !self.visualPropertiesTracker) { return completionHandler(nil); } diff --git a/SensorsAnalyticsSDK/Visualized/SAVisualizedObjectSerializerManager.m b/SensorsAnalyticsSDK/Visualized/SAVisualizedObjectSerializerManager.m index b321a299..4008a4fe 100644 --- a/SensorsAnalyticsSDK/Visualized/SAVisualizedObjectSerializerManager.m +++ b/SensorsAnalyticsSDK/Visualized/SAVisualizedObjectSerializerManager.m @@ -114,16 +114,16 @@ - (void)saveVisualizedWebPageInfoWithWebView:(WKWebView *)webview webPageInfo:(N NSString *callType = pageInfo[@"callType"]; if ([callType isEqualToString:@"visualized_track"]) { // 页面元素信息 - + [self saveWebElementInfoWithData:pageInfo webView:webview]; } else if ([callType isEqualToString:@"app_alert"]) { // 弹框提示信息 - + [self saveWebAlertInfoWithData:pageInfo webView:webview]; - + } else if ([callType isEqualToString:@"page_info"]) { // h5 页面信息 [self saveWebPageInfoWithData:pageInfo webView:webview]; } - + // 刷新数据 [self refreshPayloadHashWithData:pageInfo]; } @@ -202,7 +202,7 @@ - (void)saveWebAlertInfoWithData:(NSDictionary *)pageInfo webView:(WKWebView *)w } // 区分点击分析和可视化全埋点,针对 JS 发送的弹框信息,截取标题替换处理 - if ([SAVisualizedManager sharedInstance].visualizedType == SensorsAnalyticsVisualizedTypeHeatMap) { + if ([SAVisualizedManager defaultManager].visualizedType == SensorsAnalyticsVisualizedTypeHeatMap) { NSMutableArray * alertNewDatas = [NSMutableArray array]; for (NSDictionary *alertDic in alertDatas) { NSMutableDictionary * alertNewDic = [NSMutableDictionary dictionaryWithDictionary:alertDic]; @@ -352,3 +352,4 @@ - (void)refreshPayloadHashWithData:(id)obj { } @end + diff --git a/SensorsAnalyticsSDK/Visualized/SAVisualizedSnapshotMessage.m b/SensorsAnalyticsSDK/Visualized/SAVisualizedSnapshotMessage.m index fcc243e2..65f6dc5c 100644 --- a/SensorsAnalyticsSDK/Visualized/SAVisualizedSnapshotMessage.m +++ b/SensorsAnalyticsSDK/Visualized/SAVisualizedSnapshotMessage.m @@ -70,12 +70,12 @@ - (NSOperation *)responseCommandWithConnection:(SAVisualizedConnection *)connect dispatch_async(dispatch_get_main_queue(), ^{ [serializer screenshotImageForAllWindowWithCompletionHandler:^(UIImage *image) { // 添加待校验事件 - snapshotMessage.debugEvents = SAVisualizedManager.sharedInstance.eventCheck.eventCheckResult; + snapshotMessage.debugEvents = SAVisualizedManager.defaultManager.eventCheck.eventCheckResult; // 清除事件缓存 - [SAVisualizedManager.sharedInstance.eventCheck cleanEventCheckResult]; + [SAVisualizedManager.defaultManager.eventCheck cleanEventCheckResult]; // 添加诊断信息 - snapshotMessage.logInfos = SAVisualizedManager.sharedInstance.visualPropertiesTracker.logInfos; + snapshotMessage.logInfos = SAVisualizedManager.defaultManager.visualPropertiesTracker.logInfos; // 最后构建截图,并设置 imageHash snapshotMessage.screenshot = image; diff --git a/SensorsAnalyticsSDK/Visualized/SAVisualizedUtils.m b/SensorsAnalyticsSDK/Visualized/SAVisualizedUtils.m index 8da343f8..d8784c4c 100644 --- a/SensorsAnalyticsSDK/Visualized/SAVisualizedUtils.m +++ b/SensorsAnalyticsSDK/Visualized/SAVisualizedUtils.m @@ -404,7 +404,7 @@ + (BOOL)isSupportCallJSWithWebView:(WKWebView *)webview { @implementation SAVisualizedUtils (ViewPath) + (BOOL)isIgnoredViewPathForViewController:(UIViewController *)viewController { - BOOL isEnableVisualized = [[SAVisualizedManager sharedInstance] isVisualizeWithViewController:viewController]; + BOOL isEnableVisualized = [[SAVisualizedManager defaultManager] isVisualizeWithViewController:viewController]; return !isEnableVisualized; } diff --git a/SensorsAnalyticsSDK/Visualized/SensorsAnalyticsSDK+Visualized.h b/SensorsAnalyticsSDK/Visualized/SensorsAnalyticsSDK+Visualized.h index 7ad55298..550bce5a 100644 --- a/SensorsAnalyticsSDK/Visualized/SensorsAnalyticsSDK+Visualized.h +++ b/SensorsAnalyticsSDK/Visualized/SensorsAnalyticsSDK+Visualized.h @@ -73,27 +73,20 @@ NS_ASSUME_NONNULL_BEGIN */ - (BOOL)isHeatMapViewController:(UIViewController *)viewController; +@end -/** - * 开启 可视化全埋点 分析,默认不开启, - * $AppClick 事件将会采集控件的 viewPath。 - */ -- (void)enableVisualizedAutoTrack __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 enableVisualizedAutoTrack"))); +@interface SAConfigOptions (Visualized) -/** - 开启 HeatMap,$AppClick 事件将会采集控件的 viewPath - */ -- (void)enableHeatMap __attribute__((deprecated("已过时,请参考 SAConfigOptions 类的 enableHeatMap"))); +/// 开启点击图 +@property (nonatomic, assign) BOOL enableHeatMap API_UNAVAILABLE(macos); -/** - * @abstract - * 神策 SDK 会处理 点击图,可视化全埋点url - * @discussion - * 目前处理 heatmap,visualized - * @param url 点击图的 url - * @return YES/NO - */ -- (BOOL)handleHeatMapUrl:(NSURL *)url __attribute__((deprecated("已过时,请参考 handleSchemeUrl:"))); +/// 开启可视化全埋点 +@property (nonatomic, assign) BOOL enableVisualizedAutoTrack API_UNAVAILABLE(macos); + +/// 开启可视化全埋点自定义属性 +/// +/// 开启后,SDK 会默认开启可视化全埋点功能 +@property (nonatomic, assign) BOOL enableVisualizedProperties API_UNAVAILABLE(macos); @end diff --git a/SensorsAnalyticsSDK/Visualized/SensorsAnalyticsSDK+Visualized.m b/SensorsAnalyticsSDK/Visualized/SensorsAnalyticsSDK+Visualized.m index 302f37b8..7377393b 100644 --- a/SensorsAnalyticsSDK/Visualized/SensorsAnalyticsSDK+Visualized.m +++ b/SensorsAnalyticsSDK/Visualized/SensorsAnalyticsSDK+Visualized.m @@ -25,26 +25,20 @@ #import "SensorsAnalyticsSDK+Visualized.h" #import "SensorsAnalyticsSDK+Private.h" #import "SAVisualizedManager.h" -#import "SAModuleManager.h" @implementation SensorsAnalyticsSDK (Visualized) #pragma mark - VisualizedAutoTrack - (BOOL)isVisualizedAutoTrackEnabled { - return self.configOptions.enableVisualizedAutoTrack; + return self.configOptions.enableVisualizedAutoTrack || self.configOptions.enableVisualizedProperties; } - (void)addVisualizedAutoTrackViewControllers:(NSArray *)controllers { - [[SAVisualizedManager sharedInstance] addVisualizeWithViewControllers:controllers]; + [[SAVisualizedManager defaultManager] addVisualizeWithViewControllers:controllers]; } - (BOOL)isVisualizedAutoTrackViewController:(UIViewController *)viewController { - return [[SAVisualizedManager sharedInstance] isVisualizeWithViewController:viewController]; -} - -- (void)enableVisualizedAutoTrack { - self.configOptions.enableVisualizedAutoTrack = YES; - [self enableVisualize]; + return [[SAVisualizedManager defaultManager] isVisualizeWithViewController:viewController]; } #pragma mark - HeatMap @@ -53,20 +47,11 @@ - (BOOL)isHeatMapEnabled { } - (void)addHeatMapViewControllers:(NSArray *)controllers { - [[SAVisualizedManager sharedInstance] addVisualizeWithViewControllers:controllers]; + [[SAVisualizedManager defaultManager] addVisualizeWithViewControllers:controllers]; } - (BOOL)isHeatMapViewController:(UIViewController *)viewController { - return [[SAVisualizedManager sharedInstance] isVisualizeWithViewController:viewController]; -} - -- (void)enableHeatMap { - self.configOptions.enableHeatMap = YES; - [self enableVisualize]; -} - -- (BOOL)handleHeatMapUrl:(NSURL *)URL { - return [SAModuleManager.sharedInstance handleURL:URL]; + return [[SAVisualizedManager defaultManager] isVisualizeWithViewController:viewController]; } @end diff --git a/SensorsAnalyticsSDK/Visualized/VisualProperties/ViewNode/UIView+SAVisualProperties.m b/SensorsAnalyticsSDK/Visualized/VisualProperties/ViewNode/UIView+SAVisualProperties.m index fe5ae8c2..dc774229 100644 --- a/SensorsAnalyticsSDK/Visualized/VisualProperties/ViewNode/UIView+SAVisualProperties.m +++ b/SensorsAnalyticsSDK/Visualized/VisualProperties/ViewNode/UIView+SAVisualProperties.m @@ -33,19 +33,19 @@ @implementation UIView (SAVisualProperties) - (void)sensorsdata_visualize_didMoveToSuperview { [self sensorsdata_visualize_didMoveToSuperview]; - [SAVisualizedManager.sharedInstance.visualPropertiesTracker didMoveToSuperviewWithView:self]; + [SAVisualizedManager.defaultManager.visualPropertiesTracker didMoveToSuperviewWithView:self]; } - (void)sensorsdata_visualize_didMoveToWindow { [self sensorsdata_visualize_didMoveToWindow]; - [SAVisualizedManager.sharedInstance.visualPropertiesTracker didMoveToWindowWithView:self]; + [SAVisualizedManager.defaultManager.visualPropertiesTracker didMoveToWindowWithView:self]; } - (void)sensorsdata_visualize_didAddSubview:(UIView *)subview { [self sensorsdata_visualize_didAddSubview:subview]; - [SAVisualizedManager.sharedInstance.visualPropertiesTracker didAddSubview:subview]; + [SAVisualizedManager.defaultManager.visualPropertiesTracker didAddSubview:subview]; } - (void)sensorsdata_visualize_bringSubviewToFront:(UIView *)view { @@ -78,7 +78,7 @@ - (void)setSensorsdata_viewNode:(SAViewNode *)sensorsdata_viewNode { - (SAViewNode *)sensorsdata_viewNode { // 自定义属性被关闭,就不再操作 viewNode - if (!SAVisualizedManager.sharedInstance.visualPropertiesTracker) { + if (!SAVisualizedManager.defaultManager.visualPropertiesTracker) { return nil; } return objc_getAssociatedObject(self, kSAViewNodePropertyName); @@ -131,7 +131,7 @@ @implementation UIWindow(SAVisualProperties) - (void)sensorsdata_visualize_becomeKeyWindow { [self sensorsdata_visualize_becomeKeyWindow]; - [SAVisualizedManager.sharedInstance.visualPropertiesTracker becomeKeyWindow:self]; + [SAVisualizedManager.defaultManager.visualPropertiesTracker becomeKeyWindow:self]; } @end @@ -146,7 +146,7 @@ - (void)sensorsdata_visualize_setSelectedItem:(UITabBarItem *)selectedItem { if (!isSwitchTab) { return; } - if (!SAVisualizedManager.sharedInstance.visualPropertiesTracker) { + if (!SAVisualizedManager.defaultManager.visualPropertiesTracker) { return; } @@ -156,7 +156,7 @@ - (void)sensorsdata_visualize_setSelectedItem:(UITabBarItem *)selectedItem { // 只需更新切换 item 对应 node 页面名称即可 if ([node isKindOfClass:SATabBarButtonNode.class] && [node.elementPosition isEqualToString:itemIndex]) { // 共用自定义属性查询队列,从而保证更新页面信息后,再进行属性元素遍历 - dispatch_async(SAVisualizedManager.sharedInstance.visualPropertiesTracker.serialQueue, ^{ + dispatch_async(SAVisualizedManager.defaultManager.visualPropertiesTracker.serialQueue, ^{ [node refreshSubNodeScreenName]; }); } diff --git a/SensorsAnalyticsTests/AutoTrack/SAAutoTrackUtilsTest.m b/SensorsAnalyticsTests/AutoTrack/SAAutoTrackUtilsTest.m index 6a9c88eb..f7aa22d7 100644 --- a/SensorsAnalyticsTests/AutoTrack/SAAutoTrackUtilsTest.m +++ b/SensorsAnalyticsTests/AutoTrack/SAAutoTrackUtilsTest.m @@ -61,7 +61,6 @@ - (void)setUp { SAConfigOptions *options = [[SAConfigOptions alloc] initWithServerURL:@"" launchOptions:nil]; options.autoTrackEventType = SensorsAnalyticsEventTypeAppStart | SensorsAnalyticsEventTypeAppEnd | SensorsAnalyticsEventTypeAppClick | SensorsAnalyticsEventTypeAppViewScreen; [SensorsAnalyticsSDK startWithConfigOptions:options]; - [[SensorsAnalyticsSDK sharedInstance] enableHeatMap]; } - (void)tearDown { diff --git a/SensorsAnalyticsTests/SensorsAnalyticsTests.m b/SensorsAnalyticsTests/SensorsAnalyticsTests.m index 00323a7e..cbaffd00 100644 --- a/SensorsAnalyticsTests/SensorsAnalyticsTests.m +++ b/SensorsAnalyticsTests/SensorsAnalyticsTests.m @@ -74,21 +74,6 @@ - (void)testMultiThreadInitializedSDK { }]; } -/** - trackAppCrash 接口在支持 configOptions 初始化开始过期 - 但是该接口内未设置 enableTrackAppCrash 导致该接口不能正常开启崩溃采集 - - v1.11.14 修改 trackAppCrash 实现,增加 enableTrackAppCrash 设置 -*/ -- (void)testTrackAppCrashCanNotTrackCrash { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - [self.sensorsAnalytics trackAppCrash]; -#pragma clang diagnostic pop - - XCTAssertTrue(self.sensorsAnalytics.configOptions.enableTrackAppCrash); -} - /** 多次调用初始化方法会生成多个实例,不是一个单例对象,v1.11.7 修复 */