美文网首页
创建一个隐式的控制器, 解决无法给客服发消息的bug

创建一个隐式的控制器, 解决无法给客服发消息的bug

作者: 小冰山口 | 来源:发表于2023-11-18 13:02 被阅读0次

不得不吐槽一下网易七鱼SDK的设计

给客服发消息的会话, 和控制器, 竟然没有分开
你见过拿一个viewController去发起会话的吗? 讲道理, 我是没有见过的
好的, 那你今天就见到了!

/**
 *  获取客服聊天ViewController,非单例,每次调用新建会话页面
 *
 *  @return 会话ViewController
 *  @discussion 为保证功能完整性,必须嵌入至UINavigationController中使用;保证全局仅有一个VC实例,退出后可正常释放
 */
- (QYSessionViewController *)sessionViewController;

这是七鱼的代码文档
发消息一定要创建会话, 这可以理解. 但会话和控制器其实是两个概念
会话可以理解为一个模型, 用模型去处理调用发消息的接口, 可以做到很好的解耦
而控制器, 尤其是iOS的控制器, 其实是一个view的容器, 相当于, 你在view层去调用网络请求的接口, 是可以这么做, 但是, 耦合性就非常高了. 这样你调用接口必须创建控制器, 并且控制器要处于控制器栈中.

现在产品有一个需求, 就是用户现在处于商品的退款界面, 我这时候就想给客服发一条要退款商品的信息. 七鱼iOS端的做法是, 你必须拉起sessionViewController界面, 才可以调用发消息的接口

 QYSDK.shared().sessionViewController().sendText("test")

直接这样写是不行的. 因为此时sessionViewController并没有在栈中, 意思是: 其实真正的会话并没有创建成功, 那发送消息肯定就不行了. 会提示

错误提示

这就很坑, 我想给客服发消息就不能隐式地发了, 就必须创建一个控制器, 还必须push或者present出来. 还不能停留时间太短, 还要等真正的会话(虽然我也不知道是怎么创建出来的)创建出来才能发消息

此时, 我采取了以下的方法:

        if let productDict = dict["productDetail"] as? Dictionary<String, Any>,
           let product = JSONDeserializer<CustomServiceProduct>.deserializeFrom(dict: productDict)
        {
            let commodityInfo = QYCommodityInfo()
            commodityInfo.show = product.show
            commodityInfo.cardType = product.cardType
            commodityInfo.title = product.title
            commodityInfo.desc = product.desc
            commodityInfo.note = product.note
            commodityInfo.pictureUrlString = product.picture
            commodityInfo.urlString = product.url
            commodityInfo.actionText = product.actionText
            commodityInfo.goodsId = product.goodsId
            commodityInfo.goodsCId = product.goodsCId
            commodityInfo.orderId = product.orderId
            commodityInfo.actionTextColor = UIColor.cp_text()
            // TODO: - 这里的逻辑很奇葩, 这个会话是和控制器耦连的, 所以控制器如果没有push或者present出来, 会话是无法真正连接的
            // TODO: - 所以思路就是创建会话, 并present出来, 但用户感知不到, 给客服发消息, 然后dissmiss掉会话
            // 创建一个与客服的回话
            let session = QYSDK.shared().sessionViewController()
            // 文档上说要包在nav中使用, 那就勉强包一下吧
            // 不知道包含了什么骚操作
            // 创建一个空的控制器, 他的view在屏幕之外, 就是不让用户看到
            let vc = UIViewController()
            vc.view.frame = CGRectMake(0, UIScreen.main.bounds.size.height + 100, 1, 1)
            // 然后把这个控制器的view, 添加在当前控制器的view上
            view.addSubview(vc.view)
            guard let session = session else { return }
            let nav = UINavigationController(rootViewController: session)
            // 设置模态的类型, 如果按照默认, 会有动画效果, 就会被看出来
            nav.modalPresentationStyle = .overCurrentContext
            // 空的控制器, 将nav模态出来
            vc.present(nav, animated: false) {
                // 模态出来之后, 延时1.5秒操作, 这里的时间无法把控, 之前设置过1s, 但是, 仍有可能会话没有连接成功
                DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.5) {
                    // 延时1.5s后, 会话连接成功(其实也不一定)后, 发送消息给客服
                    session.sendCommodityInfo(commodityInfo)
                    // 然后再过0.25秒, 将会话控制器dismiss掉, 全程不让用户感知
                    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.25) {
                        session.dismiss(animated: false)
                    }
                }
            }
        }

我创建了一个viewsize{1,1}的控制器, 并且y值为屏幕高度下面100的位置, 这样就可以保证这个view其实是不在用户的视野内的. 然后用这个控制器去present出来奇葩的sessionViewController, 这还没完, 不知道里面有什么异步操作, 我延时一秒后, 竟然还有一定的概率真实的会话没有创建成功, 所以延迟1.5秒, 虽然这不是什么好的操作, 但目前也只能这么玩了. 测试了一段时间, 是可以在用户无法感知的情况下, 去发送给客服消息的.

相关文章

  • JavaScript数组总结

    有哪些创建数组的方法? js创建数组有以下三种方法: 隐式创建 直接实例化 创建数组并给数组元素赋值 创建一个长度...

  • 其他快速开启线程的方法

    创建线程后自动启动线程 隐式创建并启动线程 ● 上述2种创建线程方式的优缺点● 优点:简单快捷● 缺点:无法对线程...

  • 报bug的礼仪(8)

    一个bug的闭环除了包括创建bug和解决bug,还应该包括关闭bug。关闭bug有哪些注意事项呢? 最重要的,要看...

  • CSS Grid Auto

    关键词:隐式轨道 / 隐式网格 / 自动布局算法 隐式网格 隐式网格是指当网格项目确认在显式网格之外时所创建的网格...

  • TP3.2.3标签判断变量等于0

    不确定算不算BUG.问题已解决.问题描述:控制器中给模板赋值变量. 页面上的select元素,根据refund_s...

  • iOS视频播放

    控制器播放 1、创建AVPlayer2、创建视频播放视图的控制器3、将创建的AVPlayer赋值给控制器自带的pl...

  • 微信严重bug

    微信无法解封,无法发消息,无法付款,无人解决此类问题

  • Chapter 21《Implicit Conversions

    隐式转换和隐式参数 如果使用别人的代码库,无法进行修改,Scala进行扩展的方法是隐式转换和隐式参数。允许省略掉冗...

  • RN无法找到模块的声明文件

    记问题:无法找到模块"XXX"的声明文件。"XXX.js"隐式拥有"any"类型。 解决方案: 即可。

  • selenium显示等待和隐式等待的区别

    selenium显示等待和隐式等待的区别1、隐式等待隐式等待,就是在创建driver时,设置全局元素等待超时时间。...

网友评论

      本文标题:创建一个隐式的控制器, 解决无法给客服发消息的bug

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