首先将weexsdk集成到项目中
将weex的WeexSDK.framework导入
image.png
将main.js导入项目中。main.js在weex的WeexSDK.framework中
image.png
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中
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文件的时候会提示
image.png
选择 Create Bridging Header , 因为我们要在swift中访问Objective-C的一些类,正是通过这个header暴露OC的类给Swift,header格式为 yourTarget-Bridging-Header.h ,我这里创建完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中可以调到的
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 已经算是开发完成
注意点如下:
需要遵循WXModuleProtocol协议;
需要合成(synthesize)weexInstance属性;
使用WX_EXPORT_METHOD来暴露API;
使用WXModuleCallback进行回调;
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:@"//"]) {
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中
#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,通过这些属性,我们可以在组件生命周期中修改组件的样式,比如上面已经设置了按钮的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时填写的字符串一致。
如有疑问,可以留言咨询,关注!最终会完成一套完整的OC&&Swift集成Weex最全讲解文档。包括内部实现!!!
网友评论