OC调用设备功能扩展(无UI界面,UI界面纯原生的,固定不变的)
非事件型功能--当业务需要某种信息或者需要终端执行某项指令,直接通过接口调用终端代码即可。
使用方法:创建类只需要继承自简单的NSObject类即可
XWPhotoModule.h
@interface XWPhotoModule : NSObject
@end
XWPhotoModule.m
/// 将当前类注册,前端会对当前类进行实例对象指派。可以自定义,也可以不填
/// HIPPY_EXPORT_MODULE(PhotoModule)或者HIPPY_EXPORT_MODULE()(默认当前类名)
HIPPY_EXPORT_MODULE(PhotoModule)
// 无回调
HIPPY_EXPORT_METHOD(choosePhoto) {
NSLog(@"响应操作");
}
// 无回调带参
HIPPY_EXPORT_METHOD(choosePhoto:(NSString *)photoString) {
NSLog(@"%@", photoString);
NSLog(@"响应操作");
}
// 有回调
HIPPY_EXPORT_METHOD(updatePhotoString:(NSString *)photoString
resolver:(HippyPromiseResolveBlock)resolve
rejecter:(__unused HippyPromiseRejectBlock)reject) {
NSLog(@"%@", photoString);
resolve(@{@"result" : @"你谁啊?"});
}
事件型功能--业务需要终端监听某个事件。当事件触发时,终端通知前端。
使用方法:创建类继承HippyEventObserverModule类
XWPhotoModule.h
#import
#import "HippyEventObserverModule.h"
@interface XWPhotoModule : HippyEventObserverModule
@end
XWPhotoModule.m
HIPPY_EXPORT_MODULE(PhotoModule)
// 无回调
HIPPY_EXPORT_METHOD(choosePhoto) {
NSLog(@"响应操作");
}
// 在需要向前端发消息的方法中调用 [self sendEvent:@"photo" params:@{@"key": @"value"}]; 第一个参数为事件名,前端终端事件名必须一致。 第二个参数为事件信息,`NSDictionary`类型。
- (void)eventOccur {
// 事件发生,通知前端
[self sendEvent:@"photo" params:@{@"key": @"value"}];
}
JS调用终端能力
callNative/callNativeWithPromise
调用终端模块的方法,callNative 一般用于无返回的模块方法调用,callNativeWithPromise 一般用于有返回的模块方法调用,它会返回一个带着结果的 Promise。
methods: {
clickView() {
// 无回调(类名,方法)- (void)choosePhoto;
Vue.Native.callNative('PhotoModule', 'choosePhoto');
// 无回调带参(类名,方法,参数)- (void)choosePhoto:(NSString *)photo;
Vue.Native.callNative('PhotoModule', 'choosePhoto', '小李');
// 回调
Vue.Native.callNativeWithPromise('PhotoModule', 'updatePhotoString', '小李').then(resolve => {
console.log(resolve);
/// async 和await回调
this.updatePhotoString();
});
},
/// async 和await回调
async updatePhotoString() {
const resolve = await Vue.Native.callNativeWithPromise('PhotoModule', 'updatePhotoString', '小李');
console.log(resolve);
},
},
调用终端事件,终端通过[self sendEvent:@"photo" params:@{@"key": @"value"}];发送事件,前端需要监听事件发送来做出响应
methods: {
// 监听事件返回值,输出结果
listener(rsp) {
console.log(rsp);
console.log(rsp.key);
},
},
// 页面加载完成调用
mounted() {
// 将入口文件中 setApp() 时保存的 Vue 实例取出来。
const app = getApp();
// 通过 app 监听 rotate 事件,并通过 this.listener 在事件发生时触发回调。
app.$on('photo', this.listener);
},
当前组件不需要使用的时候,一定要销毁
// 销毁、释放
beforeDestroy() {
// 取消 mounted 里监听的自定义事件
app.$off('photo', this.listener);
},
以下是关于调用相机相册的完整例子
XWPhotoModule.h
#import
#import "HippyEventObserverModule.h"
NS_ASSUME_NONNULL_BEGIN
@interface XWPhotoModule : HippyEventObserverModule
@end
NS_ASSUME_NONNULL_END
XWPhotoModule.m
#import "XWPhotoModule.h"
#import "HippyUtils.h"
static NSString *xwPhotoEvent = @"photo";
@implementation XWPhotoModule
// hippy_export_module
HIPPY_EXPORT_MODULE(PhotoModule)
// hippy_export_method
HIPPY_EXPORT_METHOD(choosePhoto) {
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
UIAlertAction *snapAction = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self snapImage];
}];
UIAlertAction *albumAction = [UIAlertAction actionWithTitle:@"从手机相册选择" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self localAlbum];
}];
[actionSheet addAction:cancelAction];
[actionSheet addAction:snapAction];
[actionSheet addAction:albumAction];
[HippyPresentedViewController() presentViewController:actionSheet animated:YES completion:nil];
}
/// 拍照
- (void)snapImage {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
__block UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
ipc.delegate = self;
ipc.navigationBar.barTintColor = [UIColor whiteColor];
ipc.navigationBar.tintColor = [UIColor whiteColor];
ipc.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor whiteColor]};
[HippyPresentedViewController() presentViewController:ipc animated:YES completion:^{
ipc = nil;
}];
} else {
NSLog(@"模拟器无法打开照相机");
}
}
/// 从手机相册选择
- (void)localAlbum {
__block UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.view.backgroundColor = [UIColor whiteColor];
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
picker.delegate = self;
picker.navigationBar.barTintColor = [UIColor whiteColor];
picker.navigationBar.tintColor = [UIColor blackColor];
picker.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor blackColor]};
[HippyPresentedViewController() presentViewController:picker animated:YES completion:^{
picker = nil;
}];
}
//当用户取消选择的时候,调用该方法
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:^{}];
}
/// 用户确认了选择了照片调取这个方法
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissViewControllerAnimated:YES completion:^{
UIImage *selectedImage = info[UIImagePickerControllerOriginalImage];
NSData *imgData = UIImageJPEGRepresentation(selectedImage, 0.4);
NSString *imageStr = @"";
if (imgData) {
imageStr = @"test";
}
// 事件发生,通知前端
[self sendEvent:xwPhotoEvent params:@{@"result": imageStr}];
}];
}
@end
JS的app.vue代码