Flutter 与 iOS 通信,获取相册图片

1,266 阅读2分钟

演示

基本思路:

  • Flutter 端发起请求(得到回传的数据后,展示图片),iOS 端响应请求 (打开相册,选择图片后,回传数据)
Step 1:将 Flutter module 集成到 iOS 项目
  • 创建 iOS 项目,语言选择 Swift、Object-C 都可以

  • 创建一个 Flutter module:flutter create --template module my_flutter`

  • 使用 CocoaPods ,集成 Flutter SDK。在 Podfile 中添加以下代码:

     flutter_application_path = '../my_flutter' #注意文件路径 
    
     load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
     
     target 'MyApp' do
     install_all_flutter_pods(flutter_application_path)
     end
    

    文档地址:将 Flutter module 集成到 iOS 项目

Step 2: main.dart 中的关键代码:
class _MyHomePageState extends State<MyHomePage> {
  // name(imageChannel) 必须与 iOS 端的一致
  MethodChannel _methodChannel = MethodChannel('imageChannel');
  // Widget
  Image _image;
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Container(
            width: 300,
            height: 300,
            color: Colors.purple[200],
            child: _image,
          ),
          RaisedButton(
              onPressed: () {
              // 发送请求,传递方法名
        _methodChannel.invokeMethod('selectImage').then((value) {
        	// 获取到 回传的二进制数据,生成 Image
                  _image = Image.memory(value);
                  // 重新渲染,
                  setState(() {});
                });
              },
              child: Text('选择图片')),
        ],
      ),
    ));
  }
}
Step 3:iOS 端关键代码
  • 注意点:
    • 2 端的 methodChannelWithName 中的name必须一致
    • 不能直接将 UIImage 回传到 Flutter(不支持的数据格式)
#import "ViewController.h"
#import <Flutter/Flutter.h>

typedef void(^blockType)(NSData *);
@interface ViewController ()<UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@property(nonatomic,strong) FlutterMethodChannel *methodChannel;
@property(nonatomic,strong) FlutterViewController *flutterViewController;
@property(nonatomic,strong) blockType result;

@end

@implementation ViewController

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    //1. 创建 FlutterViewController
    self.flutterViewController = (FlutterViewController *)[segue destinationViewController];
    //2. 创建 methodChannel
    self.methodChannel = [FlutterMethodChannel methodChannelWithName:@"imageChannel" binaryMessenger:self.flutterViewController.binaryMessenger];
    //3. 响应 Flutter 端发的请求,并回传数据
    __weak typeof(self) weakSelf = self;
    [self.methodChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
            // 1.判断 方法名是否相等
        if([call.method isEqualToString:@"selectImage"]){
            // 2.调用 打开相册方法
            [weakSelf presentImagePickerController];
            // 3.block 赋值
            weakSelf.result = result;
        }
    }];
}

-(void)presentImagePickerController{
        // 1.判断 是否能打开
        if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) return;
        // 2.创建 相册控制器
        UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
        // 3.设置 相册类型(所有)
        imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        // 4.设置 代理
        imagePickerController.delegate = self;
        // 5. modal 相册控制器
        [self presentViewController:imagePickerController animated:YES completion:nil];
}

#pragma mark -- <UIImagePickerControllerDelegate>--
// 获取图片后的操作
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    //1.销毁 相册控制器
    [picker dismissViewControllerAnimated:YES completion:^{
        // 2. 选中的图片
        UIImage *image = info[UIImagePickerControllerOriginalImage];
        // 3. 图片转 NSData
        NSData *data = UIImagePNGRepresentation(image);
        // 4. 回传 二进制数据
        self.result(data);
    }];  
}
@end

代码地址