美文网首页
Hippy的OC和vue.js交互实现调取相机相册demo

Hippy的OC和vue.js交互实现调取相机相册demo

作者: 这小子 | 来源:发表于2020-01-19 17:13 被阅读0次

    OC调用设备功能扩展(无UI界面,UI界面纯原生的,固定不变的)

    非事件型功能--当业务需要某种信息或者需要终端执行某项指令,直接通过接口调用终端代码即可。
    使用方法:创建类只需要继承自简单的NSObject类即可

    XWPhotoModule.h

    @interface XWPhotoModule : NSObject <HippyBridgeModule>
    
    @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 <UIKit/UIKit.h>
    #import "HippyEventObserverModule.h"
    
    @interface XWPhotoModule : HippyEventObserverModule <HippyBridgeModule>
    
    @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 <UIKit/UIKit.h>
    #import "HippyEventObserverModule.h"
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface XWPhotoModule : HippyEventObserverModule <HippyBridgeModule, UINavigationControllerDelegate, UIImagePickerControllerDelegate>
    
    @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<NSString *,id> *)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代码

    <template>
      <div class="button-demo">
        <label>按钮和状态绑定:</label>
        <button v-bind:class="{ 'is-active': isClicked, 'is-pressing': isPressing }"
          class="button-demo-1"
          @click="clickView"
          <span v-if="isClicked" class="button-text">视图已经被点击了,再点一下恢复</span>
          <span v-else class="button-text">视图尚未点击</span>
        </button>
      </div>
    </template>
    
    <script>
    import Vue from 'vue';
    import { getApp } from './util';
    
    const XW_CAMERA = 'photo';
    
    export default {
      methods: {
        clickView() {
    
         Vue.Native.callNative('PhotoModule', 'choosePhoto');
        },
       
        // 监听
        uploadImage(rsp) {
          console.log(rsp);
          console.log(rsp.result);
        },
      },
    
      // 页面加载完成调用
      mounted() {
        // 将入口文件中 setApp() 时保存的 Vue 实例取出来。
        const app = getApp();
        // 通过 app 监听 rotate 事件,并通过 this.listener 在事件发生时触发回调。
        /// 相册 相机
        app.$on(XW_CAMERA, this.uploadImage);
      },
      
      data() {
        return {
          isClicked: false,
          isPressing: false,
        };
      },
      // 销毁、释放
      beforeDestroy() {
          // 取消 mounted 里监听的自定义事件
          app.$off(XW_CAMERA, this.uploadImage);
        },
    };
    </script>
    
    <style scope>
      .button-demo {
        display: flex;
        align-items: center;
        flex-direction: column;
      }
      .button-demo-1 {
        height: 64px;
        width: 240px;
        border-style: solid;
        border-color: #40b883;
        border-width: 2px;
        border-radius: 10px;
        align-items: center;
      }
      .button-demo-1 .button-text {
        line-height: 56px;
        text-align: center;
      }
      .button-demo-1-image {
        width: 216px;
        height: 58px;
      }
      .button-demo-1.is-active {
        color: white;
        background-color: red;
      }
      .button-demo-1.is-pressing {
        color: white;
        background-color: blue;
      }
    </style>
    
    

    相关文章

      网友评论

          本文标题:Hippy的OC和vue.js交互实现调取相机相册demo

          本文链接:https://www.haomeiwen.com/subject/avirzctx.html