暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

TestFlight流程优化

ChangbaDev 2018-09-17
1179

项目背景:

长久以来,iOS的灰度一直用的越狱渠道(不用审核,不用审核,不用审核),好处有了,那么问题是什么呢→(没人啊,一周才能上100的安装量啊,然后基本上只能帮我们看看有没有启动就crash,感觉这个如果发现了有点打脸)。于是乎,在@大胖 同学的建议帮助下,开始研究TestFlight及其流程优化。

TestFlight简介:

苹果官方提供给开发者,邀请内测用户的载体(最多邀请10000人)。

TestFlight优化前的完整流程:

TestFlight优化历程:

从上图可以看出几个痛点: 

(1) 需要和至少1w个用户沟通,并记录用户的邮箱。 

(2) 如果需要不同人群(聊天活跃高的、 录音活跃高的、 活动活跃高的等),那么(1)的沟通成本就会成倍数增加 

(3) 用户操作步骤多:提供邮箱、读取邮件且记录邀请码、App Store下载TestFlight、TestFlight输入邀请码下载唱吧 

(4) 用户理解要求高,TestFlight面向用户的使用步骤为纯英文,用户无法轻松操作。

既然找到了痛点,那这些就是要优化的地方,所以我们是这样设计的:

(1)针对痛点1和2,首先我们要做的是干掉通过用户收集邮箱的步骤,也就是说我们自己来维护1W个邮箱。这个事情开始困扰了我一段时间,也分别尝试了几个方式: 

• 发动同学们一起注册:当前几乎所有的邮箱注册都需要绑定手机号,且最多不超过5个,也就是说,我们需要至少2000个同学(pass); 

• 搭建邮箱服务器:时间成本+维护服务器稳定性(pass); 

• 某宝shopping1W个:便宜的找不到,贵的买不起(pass); 

• @大马 同学偶然提过xx+N@gmail.com 相当于xx@gmail.com,瞬间起飞,匹配TestFlight测试员的格式{email, xx, aa},马上生成了ss+1@gmail.com,xx+1,aa+1 到 ss+10000@gmail.com , xx+10000,aa+10000 ,共10000个邮箱,愉快的下发测试邀请,果然可以收到N封邀请邮件 {perfect}

But,一个坑完了另一个坑又来了,随着接收到的邀请邮件到100封左右,数量就不增加了,于是通过重新下发,换新的邮箱等得出了结论:同一个邮箱“每天”“最多”收到100封左右的邀请邮件。

所以最终的方案是:维护100+邮箱(辛苦团队同学们注册!),每一版TestFlight灰度,分别生成100*100个测试员(简单的循环追加写文件)。

(2)针对痛点3和4,分两步走,第一步:python脚本解析1W封邀请邮件,获取邀请链接。

这里我是用.INI文件{以节(section)和键(key)构成的配置文件}作为存储host、邮箱等数据容器(读取配置文件的方法这里就不介绍了)。

[host]

sina_pophost = pop.sina.com

sohu_pophost = pop3.sohu.com

qq_pophost = pop.qq.com

aliyun_pophost = pop3.aliyun.com

[aliyun]

zzb@aliyun.com = XXXX

zzb@aliyun.com = XXXX

zzb@aliyun.com = XXXX

zzb@aliyun.com = XXXX

主体是通过基于python的poplib模块的POP3类来实现邮件的收取,话不多说,直接上代码: 首先两种登录模式,一种是SSL协议登录,一种是非SSL协议登录。

def login_with_ssl(self, host, username, password):

    server = poplib.POP3_SSL(host)

    print "username is %s status is %s " % (username, server.getwelcome())

    server.user(username)

    server.pass_(password)

    return server

def login(self, host, username, password):

    server = poplib.POP3(host)

    print "\n username is %s status is %s " % (username, server.getwelcome())

    server.user(username)

    server.pass_(password)

    return server

然后获取邮件根实例,方便获取邮件的各种信息

def get_msgs(self, server, index):

    """

    :param server:

    :param index: email_index

    :return:

    """

    res_status, lines, msgsize = server.retr(index)

    msg_content = '\r\n'.join(lines)

    msgs = Parser().parsestr(msg_content)

    return msgs

再然后是关键的获取邮件信息,并拿到邀请链接。为了拿到邀请链接,先看下邮件的构成,如图

通过开发者工具,我们可以找到{ 标签a的 href 属性}就是我们需要的邀请链接,那么ok,开始撸代码: 

def get_identifying_code_url(self, msgs, user_email):

"""

:param msgs: Message对象结构的根实例

:param user_email:

:return:

"""

if msgs.is_multipart():

    # get_payload()返回list,包含所有的子对象:

    parts = msgs.get_payload()

    for n, part in enumerate(parts):

        self.get_identifying_code_url(msgs=part, user_email=user_email)

else:

    content_type = msgs.get_content_type()

    if content_type == 'text/html':

        # 纯文本或HTML内容:

        content = msgs.get_payload(decode=True)

        # 获取文档对象

        soup = BeautifulSoup(content, "html.parser")

        # 获取tag==a的Tag

        tag = soup.a

        # 获取tag中的href属性, 也就是我们需要的url

        if tag:

            url = tag["href"]

            url = replace(url, old="https", new="itms-beta")

            c = open('url%s.txt ' % self.today_time, 'a')

            c.write(user_email + "--" + url + "\n")

            c.close()

        else:

            url = "error! tag is None"

            self.write_failure_file(text=url, username=user_email)

    elif content_type == 'text/plain':

            pass

    else:

            pass

见code可以看到,直接通过BeautifulSoup实例获取标签a,然后获取href属性,这里大家注意下,我们不只是获取了邀请链接,而是把https换成了items-beta,这个replace会在后面介绍。 

说到这基本上处理邮件获取url的脚本就ok了,剩下的遍历邮箱,拿到对应版本的TestFlight链接,区分唱吧或火星(不同的业务线)等逻辑,通过邮件的'From', 'To', 'Subject', "Date"特征来区分,这里就不上code了。

接着回到前面的https替换成items-beta话题上,大家或许注意到,解决痛点3和4我们的第一步是获取邀请链接,而不是邀请码,这是为什么呢,这也就是我们解决痛点3和4的第二步,用户可从唱吧客户端直接内跳至TestFlight,而不是我们再次和用户沟通并转交验证码。

items-betaTestFlightURL Scheme,而URL Scheme是苹果提供的一个可以让app相互之间可以跳转的协议。

这样我们就提供了一个邀请弹窗,用户通过点击立即体验按钮,向服务器申请测试资格,服务器下发我们从邮件中读取的邀请链接,客户端收到后直接跳转至App Store TestFlight or 唱吧安装界面,如图:

到此,我们设计的第一版优化就完成了,看下新的流程图 

如图,完全干掉了和用户沟通的成本,同时可以筛选当前灰度重要功能活跃度高的用户测试。相对于用户,只需要从唱吧内点击一个按钮,就可以跳转至App Store下载TestFlight,然后安装唱吧(如果已安装过TestFlight,则直接安装唱吧)。

当我们快快乐乐的上线,脸一黑。。。发现给4000个用户下发了2000个邀请链接,一天带来的安装量只有80多个,于是重新分析我们优化后的流程,发现了几个会带来损失的点: 

1)由于怕打扰用户,体验弹窗只会弹出一次,在用户跳转安装TestFlight或者唱吧的过程中,一旦用户关闭该弹窗,则客户端内就不会再有入口暴露给用户;

2)对用户安装的吸引力小

根据损失点,我们重新调整了策略,在用户点击立即体验的同时,下发notice,给予这些用户体验常驻入口;然后针对所有体验用户,随机抽取部分用户给予一个月会员奖励。就这样,随着新策略上线,同等用户群体1小时内,安装量变成了400+,持续发现概率crash20+(此刻应该有掌声)。 最终的优化流程: 

每当你认为要搞定了,八成又要踩坑了,上线几天后,零星收到用户反馈无法正常支付,经过google后,发现TestFlight的支付全部走沙盒,所以非测试AppleId均会支付失败,这都是我们后面要解决的问题。 

当然,在踩坑的过程中,我们也get到一些点:某个版本,TestFlight苹果审核过后,提交相同app版本不同build版本,会马上审核过,会马上审核过,会马上审核过,所以为了节省审核时间,我们可以预先提审一个稳定版本(占坑),然后等灰度开始,持续不断地提审该版本。

总结:

整个优化过程就是找坑→填坑→踩坑→续填的过程,每一步都有收获。从用户的角度发现问题,从开发者的角度解决问题,再从用户的角度验证问题。PS 欢迎小伙伴们与我们沟通对TestFlight流程优化的见解,欢迎加入唱吧测试小分队。


文章转载自ChangbaDev,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论