加一个弹窗要多久

最近正在使用shareSDK,为应用提供分享的功能。本来已经做的差不多了,一测试才发现少了一项需求:如果对应分享平台本地没有安装应用,则弹窗提示用户是否安装,并跳转到对应的安装界面。

那么问题来了,加一个带跳转功能的弹窗要多久?

加一个弹窗我们需要什么功能

也许在产品的眼中,弹窗就是几句话的事,画个对话框写几句话就完成。但是,要完整地把这个功能整理出来,我们要做的不仅仅是表面上看到的东西。我们可以先按照简单的流程看看具体需要增加哪些功能。

  • 首先,我们需要判断是否需要弹窗。

  • 我们需要有一个对话框,对话框需要显示提示语,显示一个取消按钮和一个确认按钮。

  • 提示语需要提示“未安装某某应用,请安装”。

  • 点击确认按钮需要跳转到应用的安装界面。

如此看来,我们需要完成的功能似乎很简单,就这么四个。接下来,我们逐个功能看看我们都需要做什么。

分解功能

总结以上的四个功能,分别是判断安装、显示提示框、提示框文案、安装跳转。

判断本地应用安装

如果我们点击QQ的图标,那么我就需要判断设备上是否安装了QQ应用。但是,如何判断QQ应用是否已经安装?从腾讯的API文档里我们看到(其实是从客服那里了解到)腾讯的SDK提供了判断是否安装QQ应用的接口。同样的道理,我们也可以拿到微信、微博等不同平台是否已经在本地安装的接口。这样就可以简单地判断本地是否安装了对应的应用,并根据结果执行对应的功能。

显示提示框

大部分的移动设备显示提示框都是十分简单的,比如iOS设备直接用UIAlertView就可以显示提示框,并设置提示框的内容以及定制提示框的按钮,包括取消按钮和确定按钮,并对不同的按钮执行不同的操作。一般取消按钮不需要执行任何操作,弹窗自动会消失。而确认按钮则会执行跳转安装的功能。

提示框文案

如何显示提示框文案?这么一个简单的需求,却隐含了很复杂的要求。因为提示语里面包括了某某应用,那么,对于不同应用的提示,显然要显示不同应用的名称。那么,如果是英文环境,应该显示什么?微信、新浪微博、腾讯微博都需要显示不同的名称。当然,因为我们知道每个平台不同的类型,根据不同的平台显示不同的名称还是可以实现的。

安装跳转

系统提供了根据安装路径跳转到安装界面的方法。同样地,从API文档里(还是问了客服)得知,每个平台也提供了它们各自应用的安装路径。通过平台类型的判断,我们可以获取不同的路径并跳转到对应的安装界面。

我们还需要做什么

到这里,也许你认为我们的工作就结束了。很显然,如果只是这样,那么我们和搬运工有什么区别?不对!我们和码农有什么区别?不对!我们和程序猿有什么区别!

为了让我们的后续工作更容易开展,装装逼什么的,我们也得用上那么个设计模式。美其名曰可扩展。

哪里不对呢?

也许你已经看出来了,无论是本地应用是否安装的判断,或者提示文案里应用名称的显示,还是安装跳转路径的获取,都需要根据不同平台的类型来判断。如果是一股脑地写代码,那么到处都是switchif...else。也许应付目前几个平台没什么大问题,但这些都是坏代码的味道,下次维护代码的时候连你都懒得想怎么重构就直接往里面堆代码了。

怎么做

这里不想探讨如何思考出好的方案。这里我直接给出了我的方案。

面向对象

把每一个类型的平台都看成一个对象,因为每一个平台都需要知道自己是否已经在本地安装、需要提供自己安装的路径,以及需要知道自己的名称,所以对于每一个对象,也都需要以上三个方法供开发者调用。

于是,我们写了一个BaseComponent的类,并基于这个父 类继承了QQComponentWechatComponent等子类。BaseComponent有三个方法,分别是isInstalledgetInstallationUrlgetComponentName。以上的三个功能都可以通过这三个方法来实现。

此外还有一个跳转安装的功能,即通过安装路径跳转到安装界面。因为这个过程对于每个平台都是相似的,所以我们只需要在BaseComponent里统一提供一个installComponent的方法并只在父类实现就可以了。

面向接口

为了装装逼,我们必须搞一个接口,而且现在看来这个接口的意义并不是特别大。

我们把上面的四个方法写到一个ComponentInterface的接口里,并让BaseComponent实现这个接口。这样,BaseComponent一出生就自带四个技能,随便加下点就可以用了。

面向接口的好处是很多,这里也不展开讨论,只有你在实践中多使用面向接口编程、多以面向接口的方式思考,才能慢慢挖掘它的潜力。

工厂模式

对于分享的结果,如果它要知道具体要调用哪一个平台的流程,那代码会再次回到原始时代,又是一堆if...else。所以,我们可以搬一个设计模式再次出来装装逼。

如果分享失败,我们会拿到分享平台的类型,根据类型我们可以得到某个平台组件,并判断它是否安装以及安装跳转等。我们可以把“根据类型判断获取平台组件”这个过程封装起来,得到一个ComponentFactory类,只要告诉这个类某个平台类型,就能得到这个平台的组件。得益于上面我们做的接口,我们可以直接返回一个接口,而无需返回具体的类。

所以,ComponentFactory有一个静态方法+ (ComponentInterface)getComponentFromType:(Type)type(虽然这样写有点奇葩,但是将就一下啦)。通过这个方法,传递类型我们就可以获得平台组件接口,并拿这个接口的实例来判断平台是否安装以及跳转安装等。

总结

从一个产品经理的角度出发,可能会问,为什么要做的这么麻烦?

是的,我们完全可以通过一堆if...else语句的堆砌就把代码写好,而且只需要写一个文件。而现在,不仅使用了工厂模式、新增接口和不同的类继承,还一次性提交了十几二十个文件。写这么多,只为了后面更加容易扩展,代码更加容易阅读,为了自己,也为了别人。

以上就是做一个弹窗在技术层面的解决。但是,真实的流程并不只是出于技术层面,还有很多需要和产品人员沟通、需要和shareSDK的客服沟通,以及需要和各个平台的客服沟通,这些才是最无聊、最耗时、而且最无效率甚至没有结果的。

我们能做的,就是在代码上尽量提前优化。沟通的事,随缘吧~