美文网首页
吐槽极光iOS产品bug,认证与推送一起使用,认证的JVTele

吐槽极光iOS产品bug,认证与推送一起使用,认证的JVTele

作者: 三刀不留Ethan刀奈特 | 来源:发表于2020-06-08 10:34 被阅读0次

        标题写得有点长,好让BAIDU愚蠢的SEO能找到。zzzzzz

        最近图方便app迭代加入了极光的认证登录,百度一圈没找到解决方法,现在踩坑完毕了叶总要留下点什么。这个好东西呢,本身是个好东西,但是既然你是收费的好歹写好文档严格控制控制代码质量,而不是让开发者自己去踩坑,像我这种搬运工还要花力气整理呢,碰上懒一点的解决完自己的问题也就算了。结果一大帮像我这样的人还要花费时间修轮子。估计也没谁像我这样一半时间coding一半时间写经验的了呵呵。

        由于版本不一样可能有所不同,不知道别人会不会修复修复,但求后人有参考,一切不写版本号的教程都是耍流氓。

    $cat Podfile.lock查看pod库的版本。JPush(3.2.1)和JVerification(2.6.3)都使用了JCore(2.2.5)

        两个模块整合前最好单独分别测试是否能通能用,以排除因为账号、证书、Bundleid等配置问题导致的错误。反正我两个模块都分开单独测试了。

        当你乖乖按照极光官网那过时的教程加上一点百度coding完毕后。

    ···objectivec

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    ......

    [self registJpush:application :launchOptions];

    [self Jverify];

    }

    -(void)Jverify{

        JVAuthConfig *config = [[JVAuthConfig alloc] init];

        config.appKey = appKey;

        [JVERIFICATIONService setDebug:YES];

        [JVERIFICATIONService setupWithConfig:config];

    }

    -(void)registJpush:(UIApplication *)application :(NSDictionary *)launchOptions{

        if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {

            JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];

            entity.types = UNAuthorizationOptionAlert|UNAuthorizationOptionBadge|UNAuthorizationOptionSound;

            [JPUSHService registerForRemoteNotificationConfig:entity delegate:self];

        }else if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {

            //可以添加自定义categories

            [JPUSHService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound |UIUserNotificationTypeAlert) categories:nil];

        }else {

            //categories 必须为nil

            [JPUSHService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert) categories:nil];

        }

        //初始换JPush

        [JPUSHService setupWithOption:launchOptions appKey:appKey

                              channel:channel

                    apsForProduction:isProduction

                advertisingIdentifier:nil];  // 这里是没有advertisingIdentifier的情况,有的话,大家在自行添加

        //添加监听通知

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkDidLogin:) name:kJPFNetworkDidLoginNotification object:nil];

        //注册远端消息通知获取device token

        [application registerForRemoteNotifications];

    }

    ···

    然后在业务控制器中加入官方提供的demo抠出来的代码,因为是没有教程告诉你怎么调用的。

    ···objectivec

    -(void)configJVerify{

        [JVERIFICATIONService getAuthorizationWithController:self hide:NO completion:^(NSDictionary *result) {

            NSString *token = result[@"loginToken"];

            NSInteger code = [result[@"code"] integerValue];

            if(token){

                dispatch_async(dispatch_get_main_queue(), ^{

                    [self verifyLoginToken:token];//得到token调用登录接口

                });

            }else if (code == 6004){

            }else if(code != 6002){

                [self mbShowToast:KLString(@"无效token")];

            }

        }];

    }

    ···

    锵!赶紧commond+r跑起来。然而什么都没有发生,继续对比了官方提供的demo,有个JVTelecomViewConreoller,翻烂都没在库里找到,应该是打包成framework了。不过还是能找到配置它的地方,把这些臭臭长长的UI代码复制到我们的业务控制器viewDidLoad初始化就行了,把图片改成自己想要的,比较随便。

        再commond+r,页面还是没有按照demo那样显示出来。命名我单独测试的时候是没问题的,一切正常,把推送部分的代码注释掉也正常。为什么加上极光推送就不行了,那一定是两个模块公共部分的代码冲突了,说的就是JCore,首先推送和认证都分别初始化,推送的初始化先执行,极光服务器先收到JPush的业务请求,但这时候,我业务控制器已经调用的极光认证部分的方法getAuthorizationWithController,两个模块又是使用同一个JCore同一个appKey,那么很大可能是因为异步的原因,在JCore未接收到服务器返回的token的时候,认证模块已经访问了一个空的token,getAuthorizationWithController方法就很自然地返回了空。这个token业务是抽象的,我也不知道具体是什么,又看不到源码。我也不知道毕竟我是猜的。

        根据这个猜想,我将认证的注册部分(在AppDelegate)和调用部分(业务控制器)分别开辟了5秒和10秒的延时线程执行:

    ···objectivec

    //AppDelegate

    __block ViewController *weakSelf = self;dispatch_time_tdelayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0* NSEC_PER_SEC));dispatch_after(delayTime, dispatch_get_main_queue(), ^{ [weakSelf Jverify];});

    //业务控制器
    __block ViewController *weakSelf = self;dispatch_time_tdelayTime =

    dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0*

    NSEC_PER_SEC));dispatch_after(delayTime, dispatch_get_main_queue(), ^{ 

      [weakSelf configJVerify];});

    ···

        完美!可以打开,证明确实是异步问题,而这个问题官网是没有任何说明的。

        既然知道了问题所在,就再修修边幅吧,我发现JPush注册完deviceToken之后是有这个通知回调的:kJPFNetworkDidLoginNotification。盲猜是注册完毕推送后的回调。于是在业务控制器注册了观察者,当收到kJPFNetworkDidLoginNotification时再去调用getAuthorizationWithController方法,确保认证模块的业务是在推送注册执行完后再执行的,修改代码如下:

    ···objectivec

    - (void)viewDidLoad {

        [super viewDidLoad];

        ............

        [self JVerifyCustomUI];

        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];

        [center addObserver:self selector:@selector(configJVerify) name:kJPFNetworkDidLoginNotification object:nil];

    }

    ···

        这里还特别说明一下getAuthorizationWithController这个方法,同样极光也是没有任何文档提及过,好歹说明下返回参数,继续盲猜。  

         在执行到configJVerify这方法的同时,弹出了“无效token”的提示。并且打了断点证明这个completion比方法的第一行都要早执行。

        差不多搞定了,只是最后有点困惑,就再琢磨一下,说不定能帮到用需要的人。查了一下这次completion块返回的code值,是6004。

        这就印证了我的之前的想法。因为这个推送初始化完成后通过通知调用的,因为共用了JCore,JCore队列执行了所有的completion。那么只可能第一次的completion是推送模块通过JCore执行的,第二次的completion是认证模块通过JCore执行的。调用就调用吧,反正没崩溃,写个else if(code == 6004){}把这个过滤掉就行了。这也让我加深了对block的了解,block的可否调用,跟谁去声明它是没有必然联系的。

        最后还是希望极光把这个隐藏的bug改过来,毕竟也是很浪费时间的,还有完善一下那咸丰年写的文档。

    相关文章

      网友评论

          本文标题:吐槽极光iOS产品bug,认证与推送一起使用,认证的JVTele

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