Swift 中的 weex

weex ios 集成
参阅:Weex学习与实践:iOS原理篇

swift集成weex

首先将weexsdk集成到项目中,同OC

将weex的WeexSDK.framework导入

屏幕快照 2016-11-14 下午5.20.51.png

将main.js导入项目中。main.js在weex的WeexSDK.framework中

屏幕快照 2016-11-14 下午5.21.00.png

swift 使用weex

1、初始化weex和调用

import WeexSDK
AppDelegate.Swift中

 WXAppConfiguration.setAppGroup("SwiftWeexSample")
        WXAppConfiguration.setAppName("SwiftWeexSample")
        WXAppConfiguration.setAppVersion("1.0.0")
        
        WXLog.setLogLevel(WXLogLevel.All)
        
     
        
        //init WeexSDK
        WXSDKEngine.initSDKEnviroment()

ViewController.Swift中

//
//  ViewController.swift
//  SwiftWeexSample
//
//  Created by zifan.zx on 6/18/16.
//  Copyright © 2016 com.taobao.weex. All rights reserved.
//

import UIKit
import WeexSDK

class ViewController: UIViewController {
    var instance:WXSDKInstance?;
    var weexView = UIView()
    var weexHeight:CGFloat?;
    var top:CGFloat?;
    var url:NSURL?;
    
    override func viewDidLoad() {
        super.viewDidLoad()
        if !self.navigationController!.navigationBar.hidden {
            top = CGRectGetMaxY(self.navigationController!.navigationBar.frame);
        } else {
            top = CGRectGetMaxY(UIApplication.sharedApplication().statusBarFrame)
        }
        weexHeight = self.view.frame.size.height - top!;
        render()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    deinit {
        if instance != nil {
            instance!.destroyInstance()
        }
    }
    
    func render(){
        if instance != nil {
            instance!.destroyInstance()
        }
        instance = WXSDKInstance();
        instance!.viewController = self
        let width = self.view.frame.size.width
        
        instance!.frame = CGRectMake(self.view.frame.size.width-width, top!, width, weexHeight!)
        weak var weakSelf:ViewController? = self
        instance!.onCreate = {
            (view:UIView!)-> Void in
            weakSelf!.weexView.removeFromSuperview()
            weakSelf!.weexView = view;
            weakSelf!.view.addSubview(self.weexView)
            UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, weakSelf!.weexView)
        }
        instance!.onFailed = {
            (error:NSError!)-> Void in
            
            print("faild at error: %@", error)
        }
        
        instance!.renderFinish = {
            (view:UIView!)-> Void in
            print("render finish")
        }
        instance!.updateFinish = {
            (view:UIView!)-> Void in
            print("update finish")
        }
        
        instance!.renderWithURL(url, options: ["bundleUrl":String.init(format: "file://%@/bundlejs/", NSBundle.mainBundle().bundlePath)], data: nil)
    }


}

2、module 扩展,自定义模块

有些时候我们希望JS层面能够调用Native的一些功能,比如通过JS代码让Native打开一个特定的url。这时候,我们可以自定义一个模块向JS层面暴露API:

因为module 暴露method是通过 Objective-C 宏来做的,调用的时候是通过反射,所以Swift扩展module通过extension Objective-C的类,以下操作,可以直接在weex 的iOS playground中进行

1、拓展module

新建WXSwiftTestModule.h/mWXSwiftTestModule.swift 文件, 在新建Swift文件的时候会提示

nuQVVjj.jpg!web.jpg

选择 Create Bridging Header , 因为我们要在swift中访问Objective-C的一些类,正是通过这个header暴露OC的类给Swift,header格式为 yourTarget-Bridging-Header.h ,我这里创建完header文件名称为:WeexDemo-Bridging-Header.h

WXSwiftTestModule.h/m 中实现

WXSwiftTestModule.m 中

/**
 * Created by Weex.
 * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
 *
 * This source code is licensed under the Apache Licence 2.0.
 * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
 */

#import <Foundation/Foundation.h>
#import <WeexSDK/WeexSDK.h>

@interface WXEventModule : NSObject <WXModuleProtocol>

@end

WXSwiftTestModule.m 中

WeexDemo-Swift.h 这个文件需要编译一下才可以搜索到,具体的路径

/**
 * Created by Weex.
 * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
 *
 * This source code is licensed under the Apache Licence 2.0.
 * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
 */

#import "WXEventModule.h"
#import "SwiftWeexSample-Bridging-Header.h"
@implementation WXEventModule

@synthesize weexInstance;

WX_EXPORT_METHOD(@selector(openURL:))

@end


Swift 中实现

  • 扩展 OC的类 WXSwiftTestModule ,增加了一个方法,这个方法就是我们要暴露出来,在js中可以调到的
//
//  WXEventModule.swift
//  SwiftWeexSample
//
//  Created by zifan.zx on 24/09/2016.
//  Copyright © 2016 com.taobao.weex. All rights reserved.
//

import Foundation

public extension WXEventModule {
    public func openURL(url:String) {
        var newUrl:String = url;
        if url.hasPrefix("//") {
            newUrl = String.init(format: "http://%@", url);
        }else if !url.hasPrefix("http") {
            //relative path
            newUrl = (NSURL.init(string: url, relativeToURL: weexInstance.scriptURL)!.absoluteString)!
        }
        let controller:ViewController = ViewController()
        controller.url = NSURL.init(string: newUrl)
        weexInstance.viewController.navigationController?.pushViewController(controller, animated:true)
    }
}

如果需要调用oc的类,需要在SwiftWeexSample-Bridging-Header 中暴露。

至此这个Swift的简单的module 已经算是开发完成

注意点如下:

  1. 需要遵循WXModuleProtocol协议;
  2. 需要合成(synthesize)weexInstance属性;
  3. 使用WX_EXPORT_METHOD来暴露API;
  4. 使用WXModuleCallback进行回调;
2、module 使用

1、在注册weex时,注册module

// register event module
        WXSDKEngine.registerModule("event", withClass: NSClassFromString("WXEventModule"))

2、we 文件中使用

<template>
    <text>Swift Module</text>
</template>
<script>
    require('weex-components');
    Module.exports = {

        data:{

        },
        ready: function(){
            var  swifter =  require('@weex-module/swifter');
            swifter.openURL('http://baidu.com');

        };
    }

</script>

3、下载图片

weex中没有直接下载图片的方法,所以需要进行以下操作。
在项目中,导入SDWebImage
新建WXImgLoaderDefaultImpl.h/m文件,在.h文件中

/**
 * Created by Weex.
 * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
 *
 * This source code is licensed under the Apache Licence 2.0.
 * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
 */

#import <Foundation/Foundation.h>
#import <WeexSDK/WeexSDK.h>

@interface WXImgLoaderDefaultImpl : NSObject<WXImgLoaderProtocol, WXModuleProtocol>
@end

.m文件中

/**
 * Created by Weex.
 * Copyright (c) 2016, Alibaba, Inc. All rights reserved.
 *
 * This source code is licensed under the Apache Licence 2.0.
 * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree.
 */

#import "WXImgLoaderDefaultImpl.h"
#import "SDWebImageManager.h"

#define MIN_IMAGE_WIDTH 36
#define MIN_IMAGE_HEIGHT 36

#if OS_OBJECT_USE_OBJC
#undef  WXDispatchQueueRelease
#undef  WXDispatchQueueSetterSementics
#define WXDispatchQueueRelease(q)
#define WXDispatchQueueSetterSementics strong
#else
#undef  WXDispatchQueueRelease
#undef  WXDispatchQueueSetterSementics
#define WXDispatchQueueRelease(q) (dispatch_release(q))
#define WXDispatchQueueSetterSementics assign
#endif

@interface WXImgLoaderDefaultImpl()

@property (WXDispatchQueueSetterSementics, nonatomic) dispatch_queue_t ioQueue;

@end

@implementation WXImgLoaderDefaultImpl

#pragma mark -
#pragma mark WXImgLoaderProtocol

- (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)userInfo completed:(void(^)(UIImage *image,  NSError *error, BOOL finished))completedBlock
{
    if ([url hasPrefix:@"//"]) {
        url = [@"http:" stringByAppendingString:url];
    }
    return (id<WXImageOperationProtocol>)[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:url] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
        
    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
        if (completedBlock) {
            completedBlock(image, error, finished);
        }
    }];
}

@end

然后再注册weex时,注册handler

// register handler
        WXSDKEngine.registerHandler(WXImgLoaderDefaultImpl(), withProtocol:NSProtocolFromString("WXImgLoaderProtocol"))

4、自定义UI组件

如果Weex的内置标签不足以满足要求时,我们可以自定义Native组件,然后暴露给.we文件使用。

比如我们可以定义一个WXButton,继承自WXComponent

1.创建UI组件WXButton,继承自WXComponent

WXButton.h中

//
//  WXButton.h
//  LSWeexSwiftDemo
//
//  Created by John_LS on 2016/11/15.
//  Copyright © 2016年 John_LS. All rights reserved.
//

#import <WeexSDK/WeexSDK.h>

@interface WXButton : WXComponent
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) UIButton *innerButton;
@end

在WXButton.m中

//
//  WXButton.m
//  LSWeexSwiftDemo
//
//  Created by John_LS on 2016/11/15.
//  Copyright © 2016年 John_LS. All rights reserved.
//

#import "WXButton.h"

@implementation WXButton
-(instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance{
    self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
    if (self) {
        self.title = [WXConvert NSString:attributes[@"title"]];
    }
    return self;
}
-(void)viewDidLoad{
    [super viewDidLoad];
    self.innerButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    self.innerButton.frame = self.view.bounds;
    [self.view addSubview:self.innerButton];
    [self.innerButton setTitle:self.title forState:UIControlStateNormal];
    [self.innerButton addTarget:self action:@selector(onButtonClick:)
               forControlEvents:UIControlEventTouchUpInside];
}
-(void)onButtonClick:(UIButton*)btn{
    NSLog(@"按钮被onButtonClick击了");
}
@end

其中,在

-(instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance{
    self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
    if (self) {
        self.title = [WXConvert NSString:attributes[@"title"]];
    }
    return self;
}

方法中可以获得we文件标签里面的属性,如title,通过这些属性,我们可以在组件生命周期中修改组件的样式,比如上面已经设置了按钮的title。

2、然后将其注册进Weex SDK:
  // register component
        WXSDKEngine.registerComponent("weex-button", with: NSClassFromString("WXButton"))
3、在we文件中调用按钮标签
<template> 
     <div>  
       <image class="thumbnail" src="http://image.coolapk.com/apk_logo/2015/0817/257251_1439790718_385.png"></image>  
         <text class="title" onclick="onClickTitle">Hello Weex</text> 
         <weex-button class="button" title="hello button"  ></weex-button>
      </div>
</template>
          
<style> 
     .title { color: red; } 
     .thumbnail { width: 100; height: 100; }
     .button { color: blue; width: 100; height: 100;}
</style>
<script>  
    module.exports = { 
       methods: {    
         onClickTitle: function (e) {    
             console.log(e);       
              alert('title clicked.'); 
            }   
        }  
     }
</script>

注:we文件中按钮的标签要与注册weexSDK时填写的字符串一致。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,252评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,886评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,814评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,869评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,888评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,475评论 1 312
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,010评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,924评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,469评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,552评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,680评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,362评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,037评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,519评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,621评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,099评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,691评论 2 361

推荐阅读更多精彩内容