IOS通过注入实现推送功能

在工作中发现,有些app本身没有实现推送功能。

而我们在没有源码的情况下,想给这些app发送推送消息。

这个时候,我们就需要通过注入来给App实现相关功能。

 

网上很多注入都是通过Tweak实现的。 我这里通过纯手写的方式实现推送注入。

 

1,首先我们需要hook住AppDelegate内的推送相关方法。

示例代码:

+(void)load{
    Class oriMethodClass1 = NSClassFromString(@"AppDelegate");

    swizzleMethod(oriMethodClass,[self class], @selector(application:didFinishLaunchingWithOptions:), @selector(sw_application:didFinishLaunchingWithOptions:));
    
    swizzleMethod(oriMethodClass,[self class], @selector(userNotificationCenter:willPresentNotification:withCompletionHandler:), @selector(sw_userNotificationCenter:willPresentNotification:withCompletionHandler:));

    swizzleMethod(oriMethodClass,[self class], @selector(application:didFailToRegisterForRemoteNotificationsWithError:), @selector(sw_application:didFailToRegisterForRemoteNotificationsWithError:));
    
    swizzleMethod(oriMethodClass,[self class], @selector(application:didRegisterForRemoteNotificationsWithDeviceToken:), @selector(sw_application:didRegisterForRemoteNotificationsWithDeviceToken:));

}


void swizzleMethod(Class class,Class class1, SEL originalSelector,SEL swizzledSelector)
{
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class1, swizzledSelector);
    BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
    if (didAddMethod)
    {
        class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
    }else{
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

然后在自己的类里面实现相关的函数:

- (BOOL)sw_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
            //iOS10特有
            UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
            // 必须写代理,不然无法监听通知的接收与点击
            center.delegate = self;
            [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
                if (granted) {
                    // 点击允许
                    NSLog(@"apns注册成功");
                    [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
                        NSLog(@"%@", settings);
                    }];
                } else {
                    // 点击不允许
                    NSLog(@"apns注册失败");
                }
            }];
        }else if ([[UIDevice currentDevice].systemVersion floatValue] >8.0){
            //iOS8 - iOS10
            [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge categories:nil]];
            
        }else if ([[UIDevice currentDevice].systemVersion floatValue] < 8.0) {
            //iOS8系统以下
            [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
        }
        // 注册获得device Token
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    return YES;
}

- (void)sw_application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{

    NSMutableString *deviceTokenString = [NSMutableString string];



}

// 注册deviceToken失败

- (void)sw_application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{


NSLog(@"error -- %@",error);

}
- (void)sw_userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{

// 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置

completionHandler(UNNotificationPresentationOptionBadge|

UNNotificationPresentationOptionSound|

UNNotificationPresentationOptionAlert);

}

这样,我们打包一个dylib 注入到应用就能给应用实现推送功能了。

但是,你会发现一个问题。有的App 他的delegate名称并不叫AppDelegate。这样我们就无法hook到相关方法。

别着急。

我们可以通过hook UIApplication 的 setDelegate来获得当前delegate的类名:

示例如下:

Class oriMethodClass1 = NSClassFromString(@"UIApplication");
    swizzleMethod(oriMethodClass1,oriMethodClass1, @selector(setDelegate:), @selector(TY_setDelegate:));

通过delegate.class 即可获得类名。这样就能实现一个通用的推送注入包。

 

以上,如有问题可联系我。 欢迎指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值