hmhv

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

2020-02-09

以下の方法はFlutter 1.17以上では動かなくなりました。

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 { 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; _MyTodayPageState createState() => _MyTodayPageState(); } class _MyTodayPageState extends State<MyTodayPage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } 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
('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. 参考