简单的 JS 与 原生交互实现上传图片的需求

2,962 阅读2分钟

前文

近期由于公司业务发展的需求,个人从 iOS开发 转为 半 iOS 半前端😂。 没人带,只能自学,自学的坏处在于,有很多坑是要自己摔进去,再爬出来。好处在于印象深刻

需求

将一个报修界面(类似于反馈)改版,并将新版界面的实现由原生迁移到H5。如下图

img

现在的需求是,点击加号图片:

  • 调用系统拍照或者相册,然后将图片交给H5显示;
  • 并在H5接收到时,进行阿里云 OSS 直传;

实现

1、调用系统拍照或者相册,然后将图片交给H5显示

已知的方法有两种:

  1. 使用<input>标签,使用H5直接调用(在iOS上可以调用,但在Android上无法调用,Pass)
  2. 使用 JSBridge 进行 js 与原生交互。

现在的问题是选择一个兼容三端的JSBridge库(虽然原生都有方法进行交互,使用封装好的,更符合实际)。

恰好前段时间在掘金看到 DSBridge,学习了一下,所以这次就直接拿过来用了。

DSBridge 的使用,这里就不介绍了,可以直接点击👆的链接查看。

大致代码如下:

#JSAPI

// js 调用原生
- (NSString *)chooseImageFromMobile:(NSString *) msg {
  // 使用block回调,通知Controller
  if (self.chooseImage) {
    self.chooseImage();
  }
  return [msg stringByAppendingString:@"[ syn call]"];
}

- (NSString *)showRepairPendding:(NSString *) msg {
  [SVProgressHUD showWithStatus:@"正在处理中..."];
  return [msg stringByAppendingString:@"[ syn call]"];
}

// 服务端返回请求错误时, js调用原生
- (NSString *)showRepairError:(NSString *) msg {
  [SVProgressHUD showImage:nil status:msg];
  return [msg stringByAppendingString:@"[ syn call]"];
}

// 服务端返回报修成功时, js调用原生
- (NSString *)showRepairSuccess:(NSString *) msg {
  [SVProgressHUD dismiss];
  return [msg stringByAppendingString:@"[ syn call]"];
}
# ViewController


- (void)viewDidLoad {
    [super viewDidLoad];
  @weakify(self)
  self.repairApi.chooseImage = ^(){
    @strongify(self)
    [self changeHeader];
  };
    
}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
    @weakify(self);
  [picker dismissViewControllerAnimated:YES completion:^{
    @strongify(self)
    UIImage *icon = info[UIImagePickerControllerOriginalImage];
    NSData *imgData = UIImageJPEGRepresentation(icon,0.1);
    NSString *data = [imgData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    // 将data拼接成 img src 能识别的标志。
    NSString *source = [NSString stringWithFormat:@"data:image/png;base64,%@", data];
    [self.webView callHandler:@"addPicture" arguments:@[source] completionHandler:^(id  _Nullable value) {
      NSLog(@"%@",value);
    }];
  }];
}

接下来只要在 js 中调用 OC 中的方法就可以了


// 注册	addPicture 方法,接受从 OC 传过来的参数
dsBridge.register("addPicture", function(data) {
		// TODO
		// 从服务端获取直传 accessid 和 hosturl 等参数
	  return data;
});
        

总结

这个需求的核心就是 JS 与 原生之间的交互,只要找对下手方向,那么剩下就是码代码了。

顺便贴下自己的博客