A modification of the Flutter engine + test application to demonstrate that Flutter applications run on Apple TV
This project (and Liberty Global repositories referred to) are for testing purposes only!
Flutter and the related logo are trademarks of Google LLC We are not endorsed by or affiliated with Google LLC.
- Engine:
- Use
iostarget to compiletvostarget- It is possible to create a new
tvostarget, but this would have impact and more files would need to be changed and therefore require more effort to maintain Apple TV support in the engine- This can be done by modifiying the makefiles in the different projects
- See 'real_tvos_target' branch (not finished!)
- Instead of using
iosSDK,tvosSDK is used
- It is possible to create a new
- Disable/replace code not supported by
tvosSDK - Added support for Apple TV remote
- Swipe
- Based on gesture recognizer & game controller
- Created new channel to forward movement to application
- Application translates movement to left, right, up & down
- Handling this in the application allows the application to optimize the speed etc per screen / use-case
- Remote keys:
- Menu, play-pause, … are mapped to key codes
- Menu key is mapped to “popRoute” function, but could be mapped to ‘back’ key
- Keyboard input:
- 1.26: Support for ios keyboard and no modifications needed.
- In flutter 1.15/1.19/1.22 a subset of keys is mapped to "macos" and "Android" key codes
- Swipe
- Repositories modified
- https://github.com/flutter/buildroot --> https://github.com/LibertyGlobal/flutter-tvos-buildroot
- https://github.com/flutter/engine --> https://github.com/LibertyGlobal/flutter-tvos-engine
- https://dart.googlesource.com/sdk --> https://github.com/LibertyGlobal/flutter-tvos-dart
- https://skia.googlesource.com/skia --> https://github.com/LibertyGlobal/flutter-tvos-skia
- https://github.com/google/perfetto --> https://github.com/LibertyGlobal/flutter-tvos-perfetto
- Tested flutter engines:
- 1.15, 1.19-candidate-4, 1.22-candidate.13, 1.26.0-17.6-pre, 2.0.4, 2.10.3, 3.3.10, 3.10.6, 3.13.8, 3.16.2, 3.27.4
- Use
- Framework
- No modifications in "flutter" tool (/framework)
- Platform
tvosnot supported,iostarget cannot be used because without modifications it would the use wrong SDK(ios) to compile the application
- Application
- Changes compared to
iosapplication setup:- Modified main storyboard
- Icon set for tvos
- Custom script to compile application which replaces
code_backend.shin the “build phases” step. This script is based on scripts from the engine test application which only use tools from the engine. The normal script cannot be used because it used the standard “flutter” tool which does not supporttvos.
- Copy generated resources from real
iosapp target. The test app target actually overwrites theiosbuild to use the resources. - Change targets for application and pods to ‘tvos’ and set minimum OS version to 12.0
- Changes compared to
- Not all pods will compile.
iostarget is used and some API's are not supported bytvos. E.g. WebView - No debugging capabilities
- No Apple TV look and feel widgets, no integration of virtual keyboard (it is possible to create native view in the app for this), ...
- Resource monitoring is not supported by tvos (using flutter tools)
- When a debug version is installed on a simulator or Apple TV device, then the app will not load when selected on screen. It will only load from the xcode debugger. This is not an issue for release builds. This has most likely to do with the fact that the app is trying to connect to 127.0.0.1 which is not started because the flutter tools are not used.
- 3.27.4: minimum tvOS 13.0
- older versions: minimum tvOS 12.0
- Disabled fork commands etc. in
process_macos.cc- This should not be needed and only be compiled for host
- dart-lang/sdk#39918 (comment)
- Disabled fatal error in
kernel_translation_helper.cc, still to be investigated what the root cause is
-
Host compilation (macos) fails on system with 16Gb memory, no issues on 32Gb mac
- Added
--no-ltoflag, see flutter/flutter#57207
- Added
-
Based on instructions here: https://github.com/flutter/flutter/wiki/Setting-up-the-Engine-development-environment)
-
Create empty directory called
enginefor you local copy of the repository andcdinto it. (some tools assume this folder name!) -
Create a
.gclientfile in engine directory with the following contents:solutions = [ { "managed": False, "name": "src/flutter", "url": "[email protected]:LibertyGlobal/[email protected]", "custom_deps": {}, "deps_file": "DEPS", "safesync_url": "", }, ] -
Run
gclient syncinenginedirectory -
See flutter wiki for Java SKD and 'ant' dependencies
-
Install "flutter" version
3.27.4(https://flutter.dev/docs/get-started/install/macos)
- The script will build 5 targets for TVOS in the src/out folder:
- ios_debug_unopt, ios_debug_sim_unopt, ios_release, host_debug_unopt and host_release release
- Note: Fectching all repositories and compiling the engine for Apple TV (all targets) requires at leaste
29Gbof free diskspace! - Run in
/engine/src/scriptsh ninja_build.sh(located in script folder, see ninja_build.sh)- Add paramter
cleanfor a full rebuild. - Note: The
--no-ltoflag can be removed on host systems with minimum 32Gb
- Add paramter
- Based on: https://github.com/flutter/flutter/wiki/Compiling-the-engine. The problem with the order described on this wiki is that the generated files for the host point to the ios/tvos sdk instead of macos
- 1st build real ios target to make sure the resources(images, fonts, ...) are generated by the flutter tools and can be used for tvos
- Open
ios/Runner.xcworkspaceand set signing team and bundle identifier - Run command:
flutter build ios
- Open
- Note: the application will regardless of the target, always be compiled to
/build/ios/Release-iphoneos. The main reasone for this is that the resouces generated by the normal ios build are located here and are re-used.- This means that if any of the resource will change, added or removed that normal ios build must be done first. In order to do this, the step below must be un done first!
- Rename tvos folder to ios
- Flutter tools assume the folder name is
ios. Flutter pub get will fail if the folder has a different name! - Run command:
sh scripts/switch_target.sh tvos - (to switch back to ios:
sh scripts/switch_target.sh ios)
- Flutter tools assume the folder name is
- Run command:
flutter pub get - Go to
iosfolder - Install/get cocoa pods
- Run command:
pod install - Pods target is automatically corrected from ios to tvos in
podfilepost_install step
- Run command:
- Set path to local compiled flutter engine in
FLUTTER_LOCAL_ENGINE(src folder) enviroment variable - Copy flutter framework to pods
- Run command:
sh ../scripts/copy_framework.sh debug_sim - Copies debug simulator version. The correct version (debug, sim, release/archive) will be copied during app compilation
- Unfortunately this is a manual step, because the pods are compiled first as a dependency by xcode and there is no hook in the xcode build process before this to automatically copy the right frame work to be used based on the selected target
- Run command:
- Open in ios folder
Runner.xcworkspace- In settings, set signing team and bundle identifier
- Set path to local compiled flutter engine in
FLUTTER_LOCAL_ENGINE(src folder) - e.g.
FLUTTER_LOCAL_ENGINE = <your local path to flutter engine>/engine/src - alternatively run:
sed -i '' "s#FLUTTER_LOCAL_ENGINE[[:space:]]=[[:space:]].*;#FLUTTER_LOCAL_ENGINE = \"${FLUTTER_LOCAL_ENGINE}\";#g" Runner.xcodeproj/project.pbxproj
- Build app for device debug, simulator or archive (see switching target below)
- Accessibility (only supported from 3.27.4 onwards)
- Voice over:
- Only navigation mode is supported
- Only tested our applications, might not work for all use cases
- Only widgets Application must include "semantics" classes, these must be focusable and the focused one must have the is focused flag set!
- Note: this is not specific for tvOS and is also required for Android TV
- See "accessibility_bridge.mm"
- Limitations / known issues:
- "Explorer" mode is not working and behaves as "navigation" mode
- "item chooser" mode is not working properly
- Navigation focus rectangle is sometimes flashing a few times when the element is focused
- Navigation focus rectangle is sometimes not visible (also seen in system UI)
- Voice over:
-
Engine
- 3.3.10: in case compilation of
libpng.pngread.ofails. Replacesrc/third_party/libpng/pngread.cwith file pngread.c from patches folder- this only happens with newer compilers/SDK's
-
../../third_party/libpng/pngread.c:3455:26: error: variable 'row' set but not used [-Werror,-Wunused-but-set-variable] `png_bytep row = png_voidcast(png_bytep, display->first_row);
- 3.3.10: in case compilation of
-
Application
- If compilation fails because of this reason:
Showing Recent Messages Ignoring file /Users/../tvos-demo/ios/Flutter/Flutter.framework/Flutter, building for tvOS Simulator-x86\_64 but attempting to link with file built for tvOS-arm64 Undefined symbol: _OBJC_CLASS_$_FlutterError Undefined symbol: _OBJC_CLASS_$_FlutterMethodChannel Undefined symbol: _FlutterMethodNotImplemented
- When switching between targetes (simulator <=> debug/release), then the correct framework must be copied / updated
- This can be solved by copy the correct version of the framework to the flutter folder
sh scripts/copy_framework.sh <target> <path to local flutter engine>- Targets:
debug,debug_sim,release
- Switching between targets: simulator(debug), debug (on Actual AppleTV device) & Release/archive
- First "Clean build folder" in Xcode
- Copy to be used framework (See above)
- Build / Archive
- Distribution / Validation in Organizer fails
- Check if both
ios_deployment_target&MinimumOSVersionin the engine and app match. Both must be13.0!- The
info.plistfile is copied from the engine to theflutter.frameworkfolder and contains13.0
- The
- Check if both
- If compilation fails because of this reason:
Jürgen Wölke, Prikshit Chahar, Andrei Lesnitsky
v2.0.4: Aleksandr Denisov, Oleksandr Prokhorenko, Maksim Nazaruk, Andrei Kulbeda
v2.10.3: Aleksandr Denisov, Maksim Nazaruk, Andrei Kulbeda
v3.3.10: Aleksandr Denisov, Andrei Kulbeda, Jürgen Wölke
v3.10.6: Eldar Pikunov, Jürgen Wölke
v3.13.8: not on GitHub
v3.16.2: not on GitHub
v3.27.4: Neelam Bansal, Nidhim Mathew, Satnam Singh, Jürgen Wölke
