hmhv

flutterでiosのtoday-extensionを作って見る

2020-02-09

1. Flutterプロジェクトを新規作成

2. ビルドして確認

AndroidStudioでビルドして確認

Xcodeでビルドして確認

ios/Runner.xcworkspaceを開いて

3. Today Extenstionを作成

  • テンプレートからToday Extenstion選択して作成

  • today Targetに App.framework , Flutter.framework を追加

4. Today Extenstionの修正

  • MainInterface.storyboardから不要なラベルを削除
  • Flutter frameworkをimport
  • FlutterEngineをつくる
  • FlutterViewControllerをTodayViewControllerに追加
TodayViewController.swift
import Flutter

class TodayViewController: UIViewController, NCWidgetProviding {

lazy var flutterEngine = FlutterEngine(name: "TodayViewController")

override func viewDidLoad() {
super.viewDidLoad()
flutterEngine.run()
addFlutterVC()
}

func addFlutterVC() {
let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
flutterViewController.view.translatesAutoresizingMaskIntoConstraints = false
addChild(flutterViewController)
view.addSubview(flutterViewController.view)

flutterViewController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
flutterViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
flutterViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
flutterViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true

flutterViewController.didMove(toParent: self)
}
}

5. ナビゲーションバーを削除

  • DartクラスでToday Extenstion用のTodayAppを作成
     (基本MYAppのままでappBarのみ削除)
today_app.dart
import 'package:flutter/material.dart';

class TodayApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyTodayPage(title: 'Flutter Demo Home Page'),
);
}
}

class MyTodayPage extends StatefulWidget {
MyTodayPage({Key key, this.title}) : super(key: key);
final String title;

@override
_MyTodayPageState createState() => _MyTodayPageState();
}

class _MyTodayPageState extends State<MyTodayPage> {
int _counter = 0;

void _incrementCounter() {
setState(() {
_counter++;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
  • Today Extenstion用のエントリーポイントを作成
main.dart
@pragma('vm:entry-point')
void mainForTodayExtension() => runApp(TodayApp());
  • Today Extenstion用のエントリーポイントを利用
TodayViewController.swift
override func viewDidLoad() {
super.viewDidLoad()
flutterEngine.run(withEntrypoint: "mainForTodayExtension", libraryURI: nil)
addFlutterVC()
}

6. Today Extenstionの高さ変更可能に

TodayViewController.swift
override func viewDidLoad() {
super.viewDidLoad()

extensionContext?.widgetLargestAvailableDisplayMode = NCWidgetDisplayMode.expanded

flutterEngine.run(withEntrypoint: "mainForTodayExtension", libraryURI: nil)
addFlutterVC()
}

func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
if (activeDisplayMode == NCWidgetDisplayMode.compact) {
self.preferredContentSize = maxSize;
} else {
self.preferredContentSize = CGSize(width: 0, height: 200);
}
}

7. Today Extenstionのタイトル修正

全ソースコードはこちらに
https://github.com/hmhv/flutter_today_extension_example

8. 参考