190 lines
7.6 KiB
Mathematica
190 lines
7.6 KiB
Mathematica
|
|
//
|
||
|
|
// TDAutoPushPlugin.m
|
||
|
|
// TDAutoPushPlugin.m
|
||
|
|
// Pods
|
||
|
|
//
|
||
|
|
// Created by 廖德生 on 2024/08/26.
|
||
|
|
//
|
||
|
|
|
||
|
|
#import "TDAutoPushPlugin.h"
|
||
|
|
#import <objc/runtime.h>
|
||
|
|
#import <UIKit/UIKit.h>
|
||
|
|
|
||
|
|
#if __has_include(<ThinkingDataCore/ThinkingDataCore.h>)
|
||
|
|
#import <ThinkingDataCore/ThinkingDataCore.h>
|
||
|
|
#else
|
||
|
|
#import "ThinkingDataCore.h"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
static BOOL _logOn = YES;
|
||
|
|
static NSString * _fcm_token = nil;
|
||
|
|
static NSString * _apns_token = nil;
|
||
|
|
static NSString * _jpush_token = nil;
|
||
|
|
static NSString * const TD_FCM_TOKEN = @"fcm_token";
|
||
|
|
static NSString * const TD_APNS_TOKEN = @"apns_token";
|
||
|
|
static NSString * const TD_JPUSH_TOKEN = @"jiguang_id";
|
||
|
|
static NSMutableSet<NSString *> * _pushAppIds;
|
||
|
|
|
||
|
|
@interface TDAutoPushPlugin ()
|
||
|
|
|
||
|
|
@end
|
||
|
|
|
||
|
|
@implementation TDAutoPushPlugin
|
||
|
|
|
||
|
|
+ (void)load {
|
||
|
|
static dispatch_once_t onceToken;
|
||
|
|
dispatch_once(&onceToken, ^{
|
||
|
|
[TDAutoPushPlugin monitorFIRMessagingToken];
|
||
|
|
[TDAutoPushPlugin monitorJPUSHServiceToken];
|
||
|
|
[TDAutoPushPlugin registerAnalyticsListener];
|
||
|
|
[TDAutoPushPlugin registerAppLifeCycleListener];
|
||
|
|
_pushAppIds = [NSMutableSet set];
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (void)enableLog:(BOOL)enable {
|
||
|
|
_logOn = enable;
|
||
|
|
}
|
||
|
|
|
||
|
|
void (*td_fcm_imp_original)(id, SEL, id);
|
||
|
|
void td_fcm_imp_final(id self, SEL _cmd, id token) {
|
||
|
|
[TDAutoPushPlugin printLog:@"FCM token: %@", token];
|
||
|
|
_fcm_token = token;
|
||
|
|
for (NSString *appId in _pushAppIds) {
|
||
|
|
[TDAutoPushPlugin tdUserSetValue:token forKey:TD_FCM_TOKEN appid:appId];
|
||
|
|
}
|
||
|
|
if(td_fcm_imp_original) {
|
||
|
|
td_fcm_imp_original(self, _cmd, token);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (void)monitorFIRMessagingToken {
|
||
|
|
Class desClass_FIRMessaging = objc_getClass("FIRMessaging");
|
||
|
|
bool ret = NO;
|
||
|
|
ret = class_addMethod(desClass_FIRMessaging, NSSelectorFromString(@"td_updateDefaultFCMToken:"), (IMP)(td_fcm_imp_final), "v@:@");
|
||
|
|
if (ret) {
|
||
|
|
Method method_original = class_getInstanceMethod(desClass_FIRMessaging, NSSelectorFromString(@"updateDefaultFCMToken:"));
|
||
|
|
Method method_final = class_getInstanceMethod(desClass_FIRMessaging, NSSelectorFromString(@"td_updateDefaultFCMToken:"));
|
||
|
|
td_fcm_imp_original = (void(*)(id, SEL, id))method_getImplementation(method_original);
|
||
|
|
method_exchangeImplementations(method_original, method_final);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (void)monitorJPUSHServiceToken {
|
||
|
|
Class desClass = NSClassFromString(@"JPUSHService");
|
||
|
|
void(^_handler)(int resCode, NSString *registrationID) = ^(int resCode, NSString *registrationID) {
|
||
|
|
[TDAutoPushPlugin printLog:@"JPush registrationID: %@, resCode: %d", registrationID, resCode];
|
||
|
|
_jpush_token = registrationID;
|
||
|
|
for (NSString *appId in _pushAppIds) {
|
||
|
|
[TDAutoPushPlugin tdUserSetValue:registrationID forKey:TD_JPUSH_TOKEN appid:appId];
|
||
|
|
}
|
||
|
|
};
|
||
|
|
SEL _sel = NSSelectorFromString(@"registrationIDCompletionHandler:");
|
||
|
|
if ([desClass respondsToSelector:_sel]) {
|
||
|
|
#pragma clang diagnostic push
|
||
|
|
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
|
||
|
|
[desClass performSelector:_sel withObject:_handler];
|
||
|
|
#pragma clang diagnostic pop
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (void)tdUserSetValue:(NSString *)value forKey:(NSString *)key appid:(NSString *)appId {
|
||
|
|
if (value != nil && value.length > 0) {
|
||
|
|
if ([[TDMediator sharedInstance] tdAnalyticsGetEnableAutoPushWithAppId: appId]) {
|
||
|
|
[[TDMediator sharedInstance] tdAnalyticsUserSetProperties:@{key: value} appId:appId];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (void)registerAnalyticsListener {
|
||
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushTokenNotification:) name:kAnalyticsNotificationNameInit object:nil];
|
||
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushTokenNotification:) name:kAnalyticsNotificationNameLogin object:nil];
|
||
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pushTokenNotification:) name:kAnalyticsNotificationNameSetDistinctId object:nil];
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (void)pushTokenNotification:(NSNotification *)notification {
|
||
|
|
NSDictionary *userInfo = notification.userInfo;
|
||
|
|
NSString *appId = userInfo[kAnalyticsNotificationParamsAppId];
|
||
|
|
if (_fcm_token.length) {
|
||
|
|
[TDAutoPushPlugin tdUserSetValue:_fcm_token forKey:TD_FCM_TOKEN appid:appId];
|
||
|
|
} else {
|
||
|
|
[_pushAppIds addObject:appId];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (_jpush_token.length) {
|
||
|
|
[TDAutoPushPlugin tdUserSetValue:_jpush_token forKey:TD_JPUSH_TOKEN appid:appId];
|
||
|
|
} else {
|
||
|
|
[_pushAppIds addObject:appId];
|
||
|
|
}
|
||
|
|
|
||
|
|
if (_apns_token.length) {
|
||
|
|
[TDAutoPushPlugin tdUserSetValue:_apns_token forKey:TD_APNS_TOKEN appid:appId];
|
||
|
|
} else {
|
||
|
|
[_pushAppIds addObject:appId];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (void)registerAppLifeCycleListener {
|
||
|
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||
|
|
selector:@selector(td_applicationDidFinishLaunching:)
|
||
|
|
name:UIApplicationDidFinishLaunchingNotification
|
||
|
|
object:nil];
|
||
|
|
}
|
||
|
|
|
||
|
|
static void (*original_didRegisterForRemoteNotificationsWithDeviceToken)(id, SEL, UIApplication *, NSData *);
|
||
|
|
+ (void)td_applicationDidFinishLaunching:(NSNotification *)notification {
|
||
|
|
Class delegateClass = [UIApplication sharedApplication].delegate.class;
|
||
|
|
|
||
|
|
SEL originalSelector = @selector(application:didRegisterForRemoteNotificationsWithDeviceToken:);
|
||
|
|
SEL swizzledSelector = @selector(td_application:didRegisterForRemoteNotificationsWithDeviceToken:);
|
||
|
|
|
||
|
|
Method originalMethod = class_getInstanceMethod(delegateClass, originalSelector);
|
||
|
|
// 保存原有方法的实现
|
||
|
|
original_didRegisterForRemoteNotificationsWithDeviceToken = (void (*)(id, SEL, UIApplication *, NSData *))method_getImplementation(originalMethod);
|
||
|
|
|
||
|
|
Method swizzledMethod = class_getClassMethod([self class], swizzledSelector);
|
||
|
|
method_exchangeImplementations(originalMethod, swizzledMethod);
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (void)td_application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
|
||
|
|
NSString *tokenStr = [TDAutoPushPlugin formatDeviceTokenToHexStr:deviceToken];
|
||
|
|
[TDAutoPushPlugin printLog:@"apns token: %@", tokenStr];
|
||
|
|
_apns_token = tokenStr;
|
||
|
|
for (NSString *appId in _pushAppIds) {
|
||
|
|
[TDAutoPushPlugin tdUserSetValue:tokenStr forKey:TD_APNS_TOKEN appid:appId];
|
||
|
|
}
|
||
|
|
original_didRegisterForRemoteNotificationsWithDeviceToken(self, _cmd, application, deviceToken);
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (NSString *)formatDeviceTokenToHexStr:(NSData *)deviceToken {
|
||
|
|
NSString *tokenStr;
|
||
|
|
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 13.0) {
|
||
|
|
const unsigned *tokenBytes = [deviceToken bytes];
|
||
|
|
tokenStr = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
|
||
|
|
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
|
||
|
|
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
|
||
|
|
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
|
||
|
|
} else {
|
||
|
|
tokenStr = [[deviceToken description] stringByReplacingOccurrencesOfString:@"<" withString:@""];
|
||
|
|
tokenStr = [tokenStr stringByReplacingOccurrencesOfString:@">" withString:@""];
|
||
|
|
tokenStr = [tokenStr stringByReplacingOccurrencesOfString:@" " withString:@""];
|
||
|
|
}
|
||
|
|
return tokenStr;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ (void)printLog:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2) {
|
||
|
|
if (_logOn == YES) {
|
||
|
|
if (format) {
|
||
|
|
va_list args;
|
||
|
|
va_start(args, format);
|
||
|
|
NSString *output = [[NSString alloc] initWithFormat:format arguments:args];
|
||
|
|
va_end(args);
|
||
|
|
|
||
|
|
NSString *prefix = @"TDAutoPushPlugin";
|
||
|
|
[TDOSLog logMessage:output prefix:prefix type:TDLogTypeInfo asynchronous:YES];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@end
|