首先將weexsdk集成到項目中
將weex的WeexSDK.framework導入
將main.js導入項目中。main.js在weex的WeexSDK.framework中
1涮毫、初始化weex和調(diào)用
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中
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層面能夠調(diào)用Native的一些功能,比如通過JS代碼讓Native打開一個特定的url间校。這時候,我們可以自定義一個模塊向JS層面暴露API:
因為module 暴露method是通過 Objective-C 宏來做的页慷,調(diào)用的時候是通過反射憔足,所以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.m 中
#import <Foundation/Foundation.h>
#import <WeexSDK/WeexSDK.h>
@interface WXEventModule : NSObject <WXModuleProtocol>
@end
WXSwiftTestModule.m 中
WeexDemo-Swift.h 這個文件需要編譯一下才可以搜索到,具體的路徑
#import "WXEventModule.h"
#import "SwiftWeexSample-Bridging-Header.h"
@implementation WXEventModule
@synthesize weexInstance;
WX_EXPORT_METHOD(@selector(openURL:))
@end
擴展 OC的類 WXSwiftTestModule ,增加了一個方法,這個方法就是我們要暴露出來他匪,在js中可以調(diào)到的
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)
}
}
如果需要調(diào)用oc的類菇存,需要在SwiftWeexSample-Bridging-Header 中暴露。
至此這個Swift的簡單的module 已經(jīng)算是開發(fā)完成
注意點如下:
需要遵循WXModuleProtocol協(xié)議邦蜜;
需要合成(synthesize)weexInstance屬性依鸥;
使用WX_EXPORT_METHOD來暴露API;
使用WXModuleCallback進行回調(diào)悼沈;
2贱迟、module 使用
1、在注冊weex時絮供,注冊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文件中
#import <Foundation/Foundation.h>
#import <WeexSDK/WeexSDK.h>
@interface WXImgLoaderDefaultImpl : NSObject<WXImgLoaderProtocol, WXModuleProtocol>
@end
.m文件中
#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的內(nèi)置標簽不足以滿足要求時,我們可以自定義Native組件塘揣,然后暴露給.we文件使用包雀。
比如我們可以定義一個WXButton,繼承自WXComponent亲铡,
1.創(chuàng)建UI組件WXButton才写,繼承自WXComponent
WXButton.h中
#import <WeexSDK/WeexSDK.h>
@interface WXButton : WXComponent
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) UIButton *innerButton;
@end
在WXButton.m中
#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赞草,通過這些屬性,我們可以在組件生命周期中修改組件的樣式吆鹤,比如上面已經(jīng)設置了按鈕的title厨疙。
2、然后將其注冊進Weex SDK:
// register component
WXSDKEngine.registerComponent("weex-button", with: NSClassFromString("WXButton"))
3疑务、在we文件中調(diào)用按鈕標簽
<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時填寫的字符串一致沾凄。
如有疑問,可以留言咨詢知允,關注撒蟀!最終會完成一套完整的OC&&Swift集成Weex最全講解文檔。包括內(nèi)部實現(xiàn)N赂搿1M汀!