提供 iOS 用的 FunctionChannel 的实现。
示例
本仓库的 Example 目录提供了一个简单示例项目,使用 FunctionChannel 实现 WKWebView(HTML) 和原生代码(Objective-c) 之间的 RPC 调用。
- Objective-c: ViewController.m, MyClassObjc.m, MyClassObjc.h
- HTML: index.html, script.js, data-channel.js, function-channel.js
要构建和运行示例,请先运行 pod install
。
cd Example
pod install
open Example.xcworkspace
配置
Podspec
abstract_target 'defaults' do
pod 'CBBFunctionChannel', '2.0.5'
end
用法
step 1: CBBFunctionChannel的准备工作
使用CBBDataChannel实例指定,以生成CBBFunctionChannel。
CBBFunctionChannel* functionChannel = [[CBBFunctionChannel alloc] initWithDataChannel:dataChannel];
step 2: 定义可以从远程执行的方法的类
需要定义为从远程端可以执行的方法的协议,继承自 CBBRemoteExport
。以下是一个示例,在名为 MyClassObjc
的类中定义了可以从远程端执行的 foo
(同步)和 fooA
(异步)方法。
(摘录)
// プロトコル
@protocol MyClassObjcExport <CBBRemoteExport>
- (NSString*)foo:(id)arg1:(id)arg2:(id)arg3;
- (CBBAsyncResult*)fooA:(id)arg1:(id)arg2:(id)arg3;
@end
// インタフェース定義
@interface MyClassObjc : NSObject <MyClassObjcExport>
@end
// 実装
@implementation MyClassObjc
-(NSString*)foo:(id)arg1 :(id)arg2 :(id)arg3 {
return [[NSString alloc]initWithFormat:@"%@+%@+%@",arg1,arg2,arg3];
}
-(CBBAsyncResult*)fooA:(id)arg1 :(id)arg2 :(id)arg3 {
return [CBBAsyncResult create:^(void (^ _Nonnull done)(id _Nonnull)) {
usleep(3000 * 1000);
done([[NSString alloc]initWithFormat:@"%@+%@+%@",arg1,arg2,arg3]);
}];
}
@end
异步方法应按以下方式实现。
- 将返回值类型设置为
CBBAsyncResult*
。 - 在该方法中返回
CBBAsyncResult#create
的返回值,并在回调中实现处理。 - 处理正常完成时,调用
done
并返回返回值。
(方法第二参数及以后关键字传递时的注意事项)
在Objective-c中,可以将关键字传递给方法的第二参数及以后(省略也可以)。但是,如果传递了关键字,那么远程调用时指定的方法名是将方法名末尾添加了首字母大写的 名称。
例如,
-(void)fooWithArg1:(id)a arg2:(id)b;
该方法在远程调用时指定的方法名是
fooWithArg1Arg2
。(方法参数类型注意事项)
- 方法参数类型原则上必须是
id
类型。- 但是,对于
NSString*
,可以保持原样指定。
step 3: 绑定准备好的类的实例
通过 CBBFunctionChannel#bindWithInstanceId
将 step 2 中准备的类的实例注册,使得可以从远程端调用方法(绑定额外状态)。
[functionChannel bindWithInstanceId:@"MyClassObjc" instance:[[MyClassObjc alloc]init]];
使用
CBBFunctionChannel#unbindWithInstanceId
可以取消绑定额外状态。
步骤 4:执行远程方法
可以通过代码FunctionChannel#invokeWithInstanceId
来执行远程对象上已绑定的bind
方法。
[_functionChannel invokeWithInstanceId:@"MyClassJS" method:@"foo" arguments:@[@"One", @(2), @"3"] callback:^(NSError * _Nullable error, id _Nullable result) {
// 実行に失敗した場合: error にエラー情報が格納される
// 実行に成功した場合: error が nil になり, result に戻り値が格納される
}];
步骤 5:销毁
可以使用FunctionChannel#destroy
来进行销毁。
[functionChannel destroy];
即使销毁了FunctionChannel,也不会执行下层次(DataChannel, DataBus)的销毁操作。
许可
- 源代码、文档:[MIT](LICENSE)
- 图片文件:[CC BY 2.1 JP](https://creativecommons.org/licenses/by/2.1/jp/)