iOS 给AppDelegate瘦身

2018-07-28  本文已影响0人  东风不起尘

项目中经常要用到第三方的SDK每次都要在AppDelegate中注册APPKEY 接受回调等 这样就使本来很简洁的AppDelegate中的代码越来越多 那么问题来了 怎样把这些第三方的代码提到其他的地方使用啊?

runtime是一个好东西 给AppDelegate写个分类(AppDelegate+TimingChat) 在分类中替换原来的方法。

本人项目中是这样写的 如下:

#import "AppDelegate+TimingChat.h"

#import <objc/runtime.h>

#import "TimingCustomAttachmentDecoder.h"

#import "TimingCellLayoutConfig.h"

#define APPKEY          @""

#define APNSCERNAME    @""

//这个暂时不需要

#define PKCERNAME      @""

@implementation AppDelegate (TimingChat)

+(void)load {

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        Class class = [self class];

        swizzleMethod(class, @selector(application:didFinishLaunchingWithOptions:), @selector(aop_application:didFinishLaunchingWithOptions:));

        swizzleMethod(class, @selector(applicationDidEnterBackground:), @selector(aop_applicationDidEnterBackground:));

        swizzleMethod(class, @selector(applicationWillEnterForeground:), @selector(aop_applicationWillEnterForeground:));

  swizzleMethod(class, @selector(applicationDidBecomeActive:), @selector(aop_applicationDidBecomeActive:));

swizzleMethod(class, @selector(applicationWillTerminate:), @selector(aop_applicationWillTerminate:));

        swizzleMethod(class, @selector(application:didRegisterForRemoteNotificationsWithDeviceToken:), @selector(aop_application:didRegisterForRemoteNotificationsWithDeviceToken:));

        swizzleMethod(class, @selector(handleNotification:), @selector(aop_handleNotification:));

    });

}

static inline void swizzleMethod(Class class, SEL originalSelector, SEL swizzledSelector) {

    Method originalMethod = class_getInstanceMethod(class, originalSelector);

    Method swizzledMethod = class_getInstanceMethod(class, 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)aop_application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSLog(@"分类launchOptions");

    [self aop_application:application didFinishLaunchingWithOptions:launchOptions];

    NIMServerSetting *setting  = [[NIMServerSetting alloc] init];

//#ifdef DEBUG

//    setting.httpsEnabled = NO;

//#endif

    setting.httpsEnabled = NO;

 [[NIMSDK sharedSDK] setServerSetting:setting];   

[[NIMSDK sharedSDK] registerWithAppID:APPKEY cerName:APNSCERNAME];

   [[TNIMNotificationCenter sharedCenter] start];

    //自定义消息布局

    [[NIMKit sharedKit] registerLayoutConfig:[TimingCellLayoutConfig new]];

    //自定义消息对象序列化

    [NIMCustomObject registerCustomDecoder:[[TimingCustomAttachmentDecoder alloc]init]];

    //存云端历史

    NIMMessageSetting *messageSetting = [[NIMMessageSetting alloc] init];

    messageSetting.historyEnabled = YES;

    [[NIMSDK sharedSDK].loginManager addDelegate:self];

    [self registerAPNs];

    return YES;

}

#pragma mark - 退出登陆

-(void)setupLogout{

    [[[NIMSDK sharedSDK] loginManager] logout:^(NSError *error) {

        if (error == nil){

            NSLog(@"云信退出登陆");

        }

    }];

}

#pragma mark -多端登陆问题 踢下线

-(void)onKick:(NIMKickReason)code clientType:(NIMLoginClientType)clientType{

    [self setupLogout];

    [self postNotification:KL_NOTIFICATION_ACCOUNT_LOGIN_OTHER];

}

#pragma mark -自动登陆的回调

-(void)onLogin:(NIMLoginStep)step{

    switch (step) {

        case NIMLoginStepLinking:{//链接服务器

          NSLog(@"链接服务器");

        }

            break;

        case NIMLoginStepLinkOK:{//连接服务器成功

            NSLog(@"连接服务器成功");

        }

            break;

        case NIMLoginStepLinkFailed:{//连接服务器失败

            NSLog(@"连接服务器失败");

        }

            break;

        case NIMLoginStepLogining:{//登陆中

            NSLog(@"登陆中");

        }

            break;

        case NIMLoginStepLoginOK:{//登陆成功

            NSLog(@"登陆成功");

        }

            break;

        case NIMLoginStepLoginFailed:{//登陆失败

            NSLog(@"登陆失败");

            [[[TAlertView alloc] initWithErrorMsg:@"自动--登陆失败"] showStatusWithDuration:1.5];

            }

            break;

        case NIMLoginStepLoseConnection:{//链接断开

                NSLog(@"链接断开");

            }

            break;

        default:

            break;

    }

}

#pragma mark -手动登陆

-(void)loginManual{

    NSLog(@"手动登陆");

    [SharedApiClient neteaseimCreateUserGetTokenWithUserID:^(NSURLSessionDataTask *task, KLApiResponse *aResponse, NSError *anError) {

     NSLog(@"createUserGetToken=====:%@",aResponse.data);

        if (aResponse.success) {

            NSString *token = aResponse.data[@"token"];

            NSString *account = aResponse.data[@"accid"];

            SharedData.user.token = token;

            SharedData.user.account = account;

            [[[NIMSDK sharedSDK] loginManager] login:account

                                              token:token

                                          completion:^(NSError *error) {

                            if (!error){

                                NSLog(@"手动登陆----云信登陆成功。。。。。。。。。。");

                                //覆盖更新的用户要调用云信的修改用户资料

                                [[NIMSDK sharedSDK].userManager updateMyUserInfo:@{@(NIMUserInfoUpdateTagNick):SharedData.user.nickname,@(NIMUserInfoUpdateTagAvatar):SharedData.user.avatar,@(NIMUserInfoUpdateTagExt):SharedData.user.categoryAlias} completion:nil];

                                //将群的通知关闭

                                NSArray *array = [SharedCache allTeamInfo];

                                for (TTeamChannelInfoModel *teamInfo in array) {

                                    [[NIMSDK sharedSDK].teamManager updateNotifyState:NIMTeamNotifyStateNone inTeam:teamInfo.teamID completion:nil];

                                }

                                }else{

                                NSString *toast = [NSString stringWithFormat:@"登录失败 code:%ld",error.code];

                                NSLog(@"toast====%@",toast);

                                [[[TAlertView alloc] initWithErrorMsg:toast] showStatusWithDuration:1.5];

                    }

            }];

        }

    }];

}

#pragma mark - 登陆

- (void)setupLogin

{

    if (!SharedData.user.token) {

        [self loginManual];

    }else{

        NSLog(@"开始自动登陆");

        NIMAutoLoginData *loginData = [[NIMAutoLoginData alloc] init];

        loginData.account = SharedData.user.account;

        loginData.token = SharedData.user.token;

        NSLog(@"SharedData.user.account====%@",SharedData.user.account);

        NSLog(@"SharedData.user.token====%@",SharedData.user.token);

        [[[NIMSDK sharedSDK] loginManager] autoLogin:loginData];

    }

}

#pragma mark - 客户端注册 APNS,并在获取到 APNS Token 时将值传给 SDK

- (void)registerAPNs

{

    if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerForRemoteNotifications)]){

        UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;

        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];

        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];

        [[UIApplication sharedApplication] registerForRemoteNotifications];

    }else{

        UIRemoteNotificationType types = UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge;

        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];

//        UNAuthorizationOptions typeax = UNAuthorizationOptionBadge | UNAuthorizationOptionSound |UNAuthorizationOptionAlert;

//

//        [[UIApplication sharedApplication] registerForRemoteNotifications];

    }

}

-(void)aop_applicationDidEnterBackground:(UIApplication *)application{

    [self aop_applicationDidEnterBackground:application];

    NSLog(@"分类 applicationDidEnterBackground");

}

-(void)aop_applicationWillEnterForeground:(UIApplication *)application{

    [self aop_applicationWillEnterForeground:application];

    NSLog(@"分类 applicationWillEnterForeground");

}

-(void)aop_applicationDidBecomeActive:(UIApplication *)application{

    [self aop_applicationDidBecomeActive:application];

    NSLog(@"分类 applicationDidBecomeActive");

}

-(void)aop_applicationWillTerminate:(UIApplication *)application{

    [self aop_applicationWillTerminate:application];

    NSLog(@"分类 applicationWillTerminate");

}

#pragma mark - 获取到 APNS Token 时将值传给 SDK

-(void)aop_application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{

    [self aop_application:app didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];

//    NSLog(@"分类----deviceToken======%@",deviceToken);

[[NIMSDK sharedSDK] updateApnsToken:deviceToken];

}

@end

runtime的方法交换是个好东西(也是魔鬼)

细心的读者应该注意到了下面的方法中调用了 [self aop_applicationDidEnterBackground:application]; 会产生死循环调用的问题吗?其实没有死循环 他会调用原来的方法applicationDidEnterBackground: 在调用aop_applicationDidEnterBackground:替换的方法 这样就不会影响原来的applicationDidEnterBackground:方法里面的调用内容

-(void)aop_applicationDidEnterBackground:(UIApplication *)application{

    [self aop_applicationDidEnterBackground:application];

    NSLog(@"分类 applicationDidEnterBackground");

}

这样就可以给AppDelegate瘦身了  其他的第三方可以这样写


上一篇下一篇

猜你喜欢

热点阅读