20
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

FlutterからSwiftのネイティブコードを呼び出す。

Posted at

##背景
仕事でFlutterを触る機会があり、自分の備忘録として残しておきたいと思います。
今回はSwiftのImagePickerControllerをFlutter側から呼び出す手順になります。

##内容
サンプルとしてファイルを作成します。

flutter create -i swift my_app

作成したフォルダを開くとlib/main.dartがあるので開きます。
以下は、かなり省略していますが、全体のイメージです。

lib/main.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class _MyHomePageState extends State<MyHomePage> {
  static const platform = const MethodChannel('test_camera');

  Future<void> _getCamera() async {
    String cameraLevel;
    try {
      await platform.invokeMethod('getCamera');
    } on PlatformException catch (e) {
      cameraLevel = "Failed to get camera";
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Camera List!',
            ),
            RaisedButton(
            child: Text('Get Camera'),
            onPressed: _getCamera,
            ),
          ],
        ),
      ),
    );
  }
}

まずは、SwiftとFlutterを結ぶためのチャンネルを作成します。
チャンネルを作成することでやり取りを可能にします。

static const platform = const MethodChannel('test_camera');

Swift側にも設定をします。

ios/Runner/AppDelegate.swift
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?

  ) -> Bool {
    let controller :FlutterViewController = window?.rootViewController as! FlutterViewController
    let cameraChannel = FlutterMethodChannel(name: "test_camera",
                                             binaryMessenger: controller.binaryMessenger)
    
}

チャンネルを繋げたら次にSwift側のメソッドを呼び出すための準備をします。
以下のRaisedButtonを押すと、_getCamera()メソッドが呼ばれます。
_getCameraの**await platform.invokeMethod('getCamera');**でSwift側にメッセージを送ります。

lib/main.dart
Future<void> _getCamera() async {
    String cameraLevel;
    try {
     //Swiftにメッセージ 'getCamera'を送る
      await platform.invokeMethod('getCamera');
    } on PlatformException catch (e) {
      cameraLevel = "Failed to get camera";
    }
  }


@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: <Widget>[
            Text(
              'Camera List!',
            ),
            RaisedButton(
            child: Text('Get Camera'),
            onPressed: _getCamera,
            ),
          ],
        ),
      ),
    );
  }

_getCameraメソッドで送ったメッセージをSwift側で受け取ります。
あとはネイティブ側で自分で作成したメソッドを呼び出せば完了です。

ios/Runner/AppDelegate.swift
 cameraChannel.setMethodCallHandler({
      (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
        switch call.method {
        case "getCamera":
          self.receiveCamera(result: result,controller: controller)
        default:
          result(FlutterMethodNotImplemented)
          return
        }
    })

 func receiveCamera(result: FlutterResult,controller: FlutterViewController) {
        let pickerController = UIImagePickerController()
        pickerController.sourceType = .camera
        
        controller.present(pickerController,animated: true,completion: nil)
    }

殴り書きで見にくいとは思いますが、ご了承ください。
flutter側からネイティブコードを呼び出す記事が少なかったので、共有させていただきます。
誰かの役に立てたら光栄です。

ちなみにInfo.plistファイルにカメラの許可する設定もお忘れなく。。。
スクリーンショット 2019-10-29 22.52.30.png

以上です。

20
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?