weex ios 集成
參閱:Weex學習與實踐:iOS原理篇
swift集成weex
首先將weexsdk集成到項目中,同OC
將weex的WeexSDK.framework導入
將main.js導入項目中。main.js在weex的WeexSDK.framework中
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/m
和 WXSwiftTestModule.swift
文件巩掺, 在新建Swift文件的時候會提示
選擇 Create Bridging Header
, 因為我們要在swift中訪問Objective-C
的一些類,正是通過這個header暴露OC的類給Swift,header格式為 yourTarget-Bridging-Header.h
页畦,我這里創(chuàng)建完header文件名稱為:WeexDemo-Bridging-Header.h
WXSwiftTestModule.h/m 中實現(xiàn)
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 中實現(xiàn)
- 擴展 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("http://") {
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 已經算是開發(fā)完成
注意點如下:
- 需要遵循WXModuleProtocol協(xié)議州胳;
- 需要合成(synthesize)weexInstance屬性;
- 使用WX_EXPORT_METHOD來暴露API逸月;
- 使用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:@"http://"]) {
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.創(chuàng)建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時填寫的字符串一致力穗。