iOS开发技巧iOS开源&高仿项目精选iOS开发

从【简书】iOS客户端,来谈谈Hybrid方案细节设计

2017-08-06  本文已影响6566人  halohily

作为一位 iOS 开发人员,你应该已经敏感地发现,自己的工作涉及内容已经不止于 Native 的部分,因为 Hybrid App 和 ReactNative 等技术方案已经不仅仅是概念,越来越多的公司开始着手自己的 Hybrid 方案以及 ReactNative 本地化工作。

一、引言

介绍相关概念的优秀文章已经有许多,方案的实现原理你也应该已经或多或少有了一些理解。不了解也没有关系,在这篇文章里,我将用简书 iOS 客户端的有关特性,来探索一下 Hybrid 方案的技术细节。文章的目的是抛砖引玉,用一个具体的项目,大家很熟悉的简书客户端,来帮助大家认识 Hybrid 方案,然后亲自实现它

从现在开始,不再着眼于某一个 feature ,你需要站在一个客户端架构师的角度来看待问题。

二、我们用到的简书客户端特性

1.界面构成分析
2.界面特性分析

三、我们需要的储备知识

1.Hybrid相关
2.UIWebview的相关特性

四、相关特性的模仿实现

对于上文中提到的相关特性,我写了一个demo,对它们进行了简要的模仿实现。当然简书官方的实现会考虑到方方面面,而我的demo仅是从Hybrid架构的思想出发,盼能够抛砖引玉。
这是demo中对该页面的模仿实现:

demo页面
1.页面初始化

在demo中,使用一条web页面的URL来初始化VC:- (instancetype)initWithURL:(NSURL *)URL;这条URL对应文章的链接。
顶部导航栏和底部工具栏都是系统原生的UINavigationBarUIToolBar,按钮素材使用阿里巴巴的iconfont字体。

2.点击作者头像进入个人主页

关于这个特性的实现,如果按照 Hybrid 架构的思想,属于 Web 页面调用原生方法,进入一个原生的VC。点击头像,JS脚本执行相关代码,调用原生方法暴露出来的接口,执行原生方法。
我在这里用一种简要的方法实现:原生代码利用之前提到的代理方法,在用户点击头像后,拦截该URL,分析URL为头像部分,直接执行原生方法跳转到个人主页VC。
通过分析简书文章页面的网页源代码,我发现用户头像对应的URL中的Query部分,有一个参数为utm_medium=note-author-link。据此,在- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType代理方法中加以判断,若是头像链接,则跳转到个人主页VC。下面是相关代码:

NSURL *destinationURL = request.URL;
    NSString *URLQuery = destinationURL.query;
//    简书点击文章中头像时跳转至原生页面。此处利用头像链接中的一个参数作判断
    if ([URLQuery containsString:@"utm_medium=note-author-link"])
    {
        NSLog(@"我跳转到个人主页啦");
        AvatorViewController *avatorVC = [[AvatorViewController alloc] init];
        [self.navigationController pushViewController:avatorVC animated:YES];
        return NO;
    }

最后返回NO是因为若是头像链接,该web页面是不需要做跳转操作的。

这里顺便讲一个小tips:如果想要在Mac端查看移动端的网页源代码,那么你只需要在Safari中输入该页面,并且在开发选项下的用户代理中,选择iOS系统下的Safari作为代理,这时再使用源代码查看,看到的就是移动端的网页源代码了。

3.点击评论按钮,页面滑动到评论区域

这个特性的实现方式和上面类似,点击评论按钮,原生代码构建一条JS语句,交由- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;方法进行执行,由web页面执行滑动操作。代码如下:

- (void)scrollToCommentField
{
    [self stringByEvaluatingJavaScriptFromString:@"scrollTo(0,20500)"];
}

这里的JS语句非常简单,由于笔者的前端知识还有所欠缺,没有想到可以精确滑动到评论区域的JS语句,所以简要实现,点到为止。

4.原生组件写评论,web页面更新

这里首先需要贴一下文章页面的网页源代码:

<!-- 评论列表 -->
  <div data-vcomp="comments-list" data-lazy="3">
    <script type="application/json">
      {"likedNote":true,"commentable":true,"publicCommentsCount":3,"noteId":2491941,"likesCount":43}
    </script>
  </div>

可以看到,页面的评论内容是异步加载的。所以这个功能的实现,我
认为比较合理的逻辑是原生组件向服务器提交一条新的评论,收到成功回调之后,原生组件和web页面进行交互,执行更新并加载评论列表的JS代码,从而看到自己发的新评论。

5.内外站页面的区分

这里和点击头像的实现方法类似,通过拦截链接的URL,区分内部链接和第三方链接,从而在开始加载的时候采用不同的加载界面,或者对于第三方链接单独开启一个第三方VC。
demo中关于第三方链接的关闭按钮的显示逻辑,做出了相应的处理。

五、demo中的不足

看到这里大家应该就会发现,对于提到Hybrid我们就会想到的Bridge、Router等模块,我并没有做明显的限定。这样也是为了方便大家用一种更接近以往原生代码编写的思维,来理解Hybrid模式。
同时,demo中较多涉及了原生代码对web页面做出的沟通操作。而没有JS代码对原生代码的调用,这是因为一来站在一个简书客户端的用户和iOS开发的角度,对于JS端执行的操作,有些力不能及,这本是和你共同工作的前端伙伴的任务,二来对于一篇帮助大家入门Hybrid的文章来说,从这个单方面的交互来入手,管中窥豹,已是足够。

六、一些感悟

其实,写了这么多,我觉得收获到一些感悟是最重要的,下面的要讲的,可能是我觉得更为重要的思想性的东西。

1.未来的趋势之一,便是大前端团队进行客户端开发。
2.在Hybrid模式下,如何进行产品技术方案的取舍

七、文章的demo

对于文章内容,我写了一个demo,这是demo地址

为了便于理解,我为代码写了详尽的注释。
如果觉得它对你有帮助,不妨在github上为我点一个star~非常感谢!

上一篇 下一篇

猜你喜欢

热点阅读