##背景
仕事でFlutterを触る機会があり、自分の備忘録として残しておきたいと思います。
今回はSwiftのImagePickerControllerをFlutter側から呼び出す手順になります。
##内容
サンプルとしてファイルを作成します。
flutter create -i swift my_app
作成したフォルダを開くと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側にも設定をします。
@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側にメッセージを送ります。
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側で受け取ります。
あとはネイティブ側で自分で作成したメソッドを呼び出せば完了です。
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ファイルにカメラの許可する設定もお忘れなく。。。
以上です。