美文网首页
iOS 给AppDelegate瘦身

iOS 给AppDelegate瘦身

作者: 东风不起尘 | 来源:发表于2018-07-28 11: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瘦身了  其他的第三方可以这样写


    相关文章

      网友评论

          本文标题:iOS 给AppDelegate瘦身

          本文链接:https://www.haomeiwen.com/subject/nyfomftx.html