写给 iOS 程序员的 Weex 教程(2):打造自己的 iOS host 应用

2017/1/12 22:10 下午 posted in  iOS comments

官方 Playground 应用只适合学习的时候用一用,真正需要开发应用的时候,还是打造自己的 iOS 应用,方便扩展。

建议在上一篇的工程里新建一个 iOS 目录,把 iOS 工程放在这。这样可以统一管理,之后要支持 Android,Web 都可以新建相应的目录,不相互影响。

引入 SDK

我们将使用 CocoaPods 来集成 WeexSDK。如果现在还不会用这个的,可以反省一下了。顺便引入 Weex 的调试工具 WXDevtool。

# 这是我司维护的一个 CocoaPods 镜像源
source 'git://git.coding.net/fannheyward/CocoaPodsSpecs.git'

target 'hello' do
  pod 'WeexSDK'
  pod 'WXDevtool', :configurations => ['Debug'] #只在 debug 时引入
end

我们为 WXDevtool 增加了 configurations 选项,限制只有测试环境有。大家可以根据自己的需要修改。

配置调试工具 WXDevtool 和 SDK

安装完后,打开 AppDelegate 文件。配置很简单,代码如下。
记住,文档说了,WXDevtool 必须先于 WeexSDK 的初始化。

#import <WeexSDK/WeexSDK.h>
#ifdef DEBUG
#import <TBWXDevTool/WXDevTool.h>
#endif

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
#ifdef DEBUG
    //use weex-devtool to start debug server and paste debug url here
    [WXDevTool launchDevToolDebugWithUrl:@"ws://127.0.0.1:8088/debugProxy/native"];
#endif
    //business configuration
    [WXAppConfiguration setAppName:@"hello"];
    //init sdk enviroment
    [WXSDKEngine initSDKEnviroment];
    
    return YES;
}

Weex 界面的 view controller

WeexSDK 自带了一个 WXBaseViewController 用来展示界面(没有暴露出来),只是这个 WXBaseViewController 不支持实时刷新界面调试,而且也不方便自定义。所以我们来是创建一个自己的 view controller。这个建议直接从官方 playground 工程里抄过来,然后再根据自己的需要修改,原因有二:

  1. 官方探过坑。比如现在 WeexSDK 还不支持 HTTP cache;
  2. view controller需要做一些适配的工作,比如转发 viewDidAppearviewDidDisappear 事件,支持实时刷新等。

代码就不贴了。文后会有 demo。
改完后,需要实现一下 WXNavigationProtocol 协议才能利用上刚才写的 view controller。这个协议是用来实现界面跳转的。像 <a> 标签的点击事件 和 navigator 的 push 和 pop 事件,最后都会转发给这个协议的对象。
实现方式也很简单,从 WeexSDK 里把默认实现复制一份出来,改一下生成 view controller 的方法就好。

image handler

WeexSDK 默认没有实现图片加载,需要自己实现 WXImgLoaderProtocol 协议。这个对象会很有用,之后加载本地图片也会需要它。
现在我们先实现最简单的版本, 网络加载图片用 SDWebImage 这个库:

#import <SDWebImage/SDWebImageManager.h>

@implementation ImageHandler

- (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)options completed:(void (^)(UIImage *, NSError *, BOOL))completedBlock
{
    if (![self isValidString:url]) {
        return nil;
    }
    
    if ([url hasPrefix:@"//"]) {
        url = [@"http:" stringByAppendingString:url];
    }
    
    SDWebImageManager *mgr = [SDWebImageManager sharedManager];

    id op = [mgr downloadImageWithURL:[NSURL URLWithString:url]
                              options:SDWebImageRetryFailed
                             progress:nil
                            completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
                                if (completedBlock) {
                                    completedBlock(image, error, finished);
                                }
                            }];
    return (id<WXImageOperationProtocol>)op;
}

- (BOOL)isValidString:(NSString *)str
{
    if (str && [str isKindOfClass:[NSString class]] && [str length] > 0) {
        return YES;
    }
    
    return NO;
}

@end

然后就是把刚才实现的两个的对象注册到 WXSDKEngine

    [WXSDKEngine registerHandler:[ImageHandler new] withProtocol:@protocol(WXImgLoaderProtocol)];
    [WXSDKEngine registerHandler:[NavigationHandler new] withProtocol:@protocol(WXNavigationProtocol)];

debug view controller

到此,基本已经完成了。不过,我们还需要一个 view controller 用来 debug。为什么呢?因为当你调试多页应用,启动 debugger 的时候,页面不能正常刷新,会变白。不确定这是不是一个 bug。而且,如果debug 启动时的问题,是没有时间立即开启 debugger。所以我们需要先启动进入一个 viewController,然后开启 debugger,然后再进入我们的 Weex 页面,进行开发调试。
当然,发布的时候是可以直接进入 Weex 页面。
这个 debug view controller 很简单,只需要有一个按钮,点击跳转到我们的 Weex 页面就行。具体代码我就不贴了,看文末 demo。

到此,一个基本的 iOS host 应用打造完了,虽然没有什么功能。别担心,后面可以轻松扩展。

优化编辑器:SublimeText 插件推荐

如果你选择 SublimeText 来开发的话,推荐几个插件,默认情况下,对 JavaScript 的补全很差:

  1. Package Control, SublimeText 的插件管理器;
  2. SublimeCodeIntel,JavaScript 的自动补全;
  3. All Autocomplete,SublimeText 只根据当前文件内容自动补全,这个可以从所有打开的文件来补全;

好了,本篇的内容都完了。下一篇讲界面布局并做一个简单应用

demo下载