├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example ├── .gitignore ├── .metadata ├── README.md ├── analysis_options.yaml ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── example │ │ │ │ │ └── example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Podfile.lock │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ ├── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ │ └── LaunchImage.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ └── README.md │ │ ├── Base.lproj │ │ │ ├── LaunchScreen.storyboard │ │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h │ └── RunnerTests │ │ └── RunnerTests.swift ├── lib │ └── main.dart ├── macos │ ├── .gitignore │ ├── Flutter │ │ ├── Flutter-Debug.xcconfig │ │ ├── Flutter-Release.xcconfig │ │ └── GeneratedPluginRegistrant.swift │ ├── Podfile │ ├── Podfile.lock │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Contents.json │ │ │ │ ├── app_icon_1024.png │ │ │ │ ├── app_icon_128.png │ │ │ │ ├── app_icon_16.png │ │ │ │ ├── app_icon_256.png │ │ │ │ ├── app_icon_32.png │ │ │ │ ├── app_icon_512.png │ │ │ │ └── app_icon_64.png │ │ ├── Base.lproj │ │ │ └── MainMenu.xib │ │ ├── Configs │ │ │ ├── AppInfo.xcconfig │ │ │ ├── Debug.xcconfig │ │ │ ├── Release.xcconfig │ │ │ └── Warnings.xcconfig │ │ ├── DebugProfile.entitlements │ │ ├── Info.plist │ │ ├── MainFlutterWindow.swift │ │ └── Release.entitlements │ └── RunnerTests │ │ └── RunnerTests.swift └── pubspec.yaml ├── lib ├── cast.dart ├── cast_channel │ ├── cast_channel.idl │ ├── cast_channel.pb.dart │ ├── cast_channel.pbenum.dart │ ├── cast_channel.pbjson.dart │ ├── cast_channel.pbserver.dart │ └── cast_channel.proto ├── device.dart ├── discovery_service.dart ├── session.dart ├── session_manager.dart └── socket.dart ├── pubspec.lock └── pubspec.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/app.flx 64 | **/ios/Flutter/app.zip 65 | **/ios/Flutter/flutter_assets/ 66 | **/ios/Flutter/flutter_export_environment.sh 67 | **/ios/ServiceDefinitions.json 68 | **/ios/Runner/GeneratedPluginRegistrant.* 69 | 70 | # Exceptions to above rules. 71 | !**/ios/**/default.mode1v3 72 | !**/ios/**/default.mode2v3 73 | !**/ios/**/default.pbxuser 74 | !**/ios/**/default.perspectivev3 75 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 76 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: f7a6a7906be96d2288f5d63a5a54c515a6e987fe 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [2.1.0] 2 | 3 | * Remove upper version limit for `bonsoir` 4 | 5 | ## [2.0.0] 6 | 7 | * Upgrade dependency `bonsoir` to 3.0.0 8 | * Upgrade to Dart 3 9 | 10 | ## [1.1.1] 11 | 12 | * Upgrade dependency `bonsoir` 13 | 14 | ## [1.1.0] 15 | 16 | * Replace dependency `multicast_dns` (not working on iOS) by `bonsoir` 17 | 18 | ## [1.0.0] 19 | 20 | * Migrate to null safety 21 | * Replace dependency `mdns_plugin` (doesn't support null safety) by `multicast_dns` 22 | 23 | ## [0.3.0] 24 | 25 | * Add the possibility to use your own requestId 26 | 27 | ## [0.2.0] 28 | 29 | * Improve service discovery #1 30 | 31 | ## [0.1.1] 32 | 33 | * Add `kNamespaceMedia` to `CastSession` 34 | 35 | ## [0.1.0] 36 | 37 | * First release 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Jonathan VUKOVICH 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Pub Likes](https://img.shields.io/pub/likes/cast)](https://pub.dev/packages/cast) 2 | [![Pub Popularity](https://img.shields.io/pub/popularity/cast)](https://pub.dev/packages/cast) 3 | [![Pub Points](https://img.shields.io/pub/points/cast)](https://pub.dev/packages/cast) 4 | 5 | # cast 6 | 7 | Dart package to discover and connect with Chromecast devices 8 | 9 | ## Installation 10 | 11 | Add this to your package's pubspec.yaml file: 12 | 13 | ``` 14 | dependencies: 15 | cast: ^2.1.0 16 | ``` 17 | 18 | ### iOS 19 | 20 | Required iOS 13 minimum. 21 | Since iOS 14 a few more steps are required https://developers.google.com/cast/docs/ios_sender/ios_permissions_changes 22 | 23 | In `ios/Runner/Info.plist` add: 24 | 25 | ```xml 26 | NSBonjourServices 27 | 28 | _googlecast._tcp 29 | _YOUR_APP_ID._googlecast._tcp 30 | 31 | 32 | NSLocalNetworkUsageDescription 33 | ${PRODUCT_NAME} uses the local network to discover Cast-enabled devices on your WiFi 34 | network. 35 | ``` 36 | 37 | ## Usage 38 | 39 | List devices: 40 | 41 | ``` 42 | Widget build(BuildContext context) { 43 | return FutureBuilder>( 44 | future: CastDiscoveryService().search(), 45 | builder: (context, snapshot) { 46 | if (snapshot.hasError) { 47 | return Center( 48 | child: Text( 49 | 'Error: ${snapshot.error.toString()}', 50 | ), 51 | ); 52 | } else if (!snapshot.hasData) { 53 | return Center( 54 | child: CircularProgressIndicator(), 55 | ); 56 | } 57 | 58 | if (snapshot.data!.isEmpty) { 59 | return Column( 60 | children: [ 61 | Center( 62 | child: Text( 63 | 'No Chromecast founded', 64 | ), 65 | ), 66 | ], 67 | ); 68 | } 69 | 70 | return Column( 71 | children: snapshot.data!.map((device) { 72 | return ListTile( 73 | title: Text(device.name), 74 | onTap: () { 75 | _connectToYourApp(context, device); 76 | }, 77 | ); 78 | }).toList(), 79 | ); 80 | }, 81 | ); 82 | } 83 | ``` 84 | 85 | Connect to device: 86 | 87 | ``` 88 | Future _connect(BuildContext context, CastDevice object) async { 89 | final session = await CastSessionManager().startSession(object); 90 | 91 | session.stateStream.listen((state) { 92 | if (state == CastSessionState.connected) { 93 | _sendMessage(session); 94 | } 95 | }); 96 | 97 | session.messageStream.listen((message) { 98 | print('receive message: $message'); 99 | }); 100 | 101 | session.sendMessage(CastSession.kNamespaceReceiver, { 102 | 'type': 'LAUNCH', 103 | 'appId': 'YouTube', // set the appId of your app here 104 | }); 105 | } 106 | ``` 107 | 108 | `CastSessionManager` is used to keep track of all sessions. 109 | 110 | Send message: 111 | 112 | ``` 113 | void _sendMessage(CastSession session) { 114 | session.sendMessage('urn:x-cast:namespace-of-the-app', { 115 | 'type': 'sample', 116 | }); 117 | } 118 | ``` 119 | 120 | Except for the launch message, you should wait until the session have a connected state before sending message. 121 | 122 | ## Note 123 | 124 | Some informations about the protocol used https://docs.rs/crate/gcast/0.1.5/source/PROTOCOL.md 125 | 126 | $ pub global activate protoc_plugin 127 | $ export PATH="$PATH":"$HOME/.pub-cache/bin" 128 | $ protoc -I=./lib/cast_channel --dart_out=./lib/cast_channel ./lib/cast_channel/cast_channel.proto --plugin "pub run protoc_plugin" 129 | 130 | ## Author 131 | 132 | - [Jonathan VUKOVICH](https://github.com/johnvuko) 133 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:pedantic/analysis_options.yaml 2 | 3 | analyzer: 4 | exclude: 5 | - lib/cast_channel/* 6 | 7 | # https://dart-lang.github.io/linter/lints/ 8 | linter: 9 | rules: 10 | # Error Rules 11 | avoid_empty_else: true 12 | avoid_relative_lib_imports: true 13 | avoid_returning_null_for_future: true 14 | avoid_slow_async_io: true 15 | avoid_types_as_parameter_names: true 16 | control_flow_in_finally: true 17 | empty_statements: true 18 | no_adjacent_strings_in_list: true 19 | no_duplicate_case_values: true 20 | prefer_void_to_null: true 21 | unnecessary_statements: true 22 | unrelated_type_equality_checks: true 23 | # Style Rules 24 | always_declare_return_types: true 25 | annotate_overrides: true 26 | avoid_field_initializers_in_const_classes: true 27 | avoid_renaming_method_parameters: true 28 | avoid_void_async: true 29 | directives_ordering: true 30 | unnecessary_await_in_return: true 31 | sort_pub_dependencies: true 32 | omit_local_variable_types: false -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | pubspec.lock 2 | 3 | # Miscellaneous 4 | *.class 5 | *.log 6 | *.pyc 7 | *.swp 8 | .DS_Store 9 | .atom/ 10 | .buildlog/ 11 | .history 12 | .svn/ 13 | 14 | # IntelliJ related 15 | *.iml 16 | *.ipr 17 | *.iws 18 | .idea/ 19 | 20 | # The .vscode folder contains launch configuration and tasks you configure in 21 | # VS Code which you may wish to be included in version control, so this line 22 | # is commented out by default. 23 | #.vscode/ 24 | 25 | # Flutter/Dart/Pub related 26 | **/doc/api/ 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Symbolication related 39 | app.*.symbols 40 | 41 | # Obfuscation related 42 | app.*.map.json 43 | 44 | # Exceptions to above rules. 45 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 46 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "d211f42860350d914a5ad8102f9ec32764dc6d06" 8 | channel: "stable" 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 17 | base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 18 | - platform: android 19 | create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 20 | base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 21 | - platform: ios 22 | create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 23 | base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06 24 | 25 | # User provided section 26 | 27 | # List of Local paths (relative to this file) that should be 28 | # ignored by the migrate tool. 29 | # 30 | # Files that are not part of the templates will be ignored by default. 31 | unmanaged_files: 32 | - 'lib/main.dart' 33 | - 'ios/Runner.xcodeproj/project.pbxproj' 34 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | linter: 13 | # The lint rules applied to this project can be customized in the 14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml` 15 | # included above or to enable additional rules. A list of all available lints 16 | # and their documentation is published at https://dart.dev/lints. 17 | # 18 | # Instead of disabling a lint rule for the entire project in the 19 | # section below, it can also be suppressed for a single line of code 20 | # or a specific dart file by using the `// ignore: name_of_lint` and 21 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file 22 | # producing the lint. 23 | rules: 24 | # avoid_print: false # Uncomment to disable the `avoid_print` rule 25 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule 26 | 27 | # Additional information about this file can be found at 28 | # https://dart.dev/guides/language/analysis-options 29 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | id "dev.flutter.flutter-gradle-plugin" 5 | } 6 | 7 | def localProperties = new Properties() 8 | def localPropertiesFile = rootProject.file('local.properties') 9 | if (localPropertiesFile.exists()) { 10 | localPropertiesFile.withReader('UTF-8') { reader -> 11 | localProperties.load(reader) 12 | } 13 | } 14 | 15 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 16 | if (flutterVersionCode == null) { 17 | flutterVersionCode = '1' 18 | } 19 | 20 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 21 | if (flutterVersionName == null) { 22 | flutterVersionName = '1.0' 23 | } 24 | 25 | android { 26 | namespace "com.example.example" 27 | compileSdkVersion flutter.compileSdkVersion 28 | ndkVersion flutter.ndkVersion 29 | 30 | compileOptions { 31 | sourceCompatibility JavaVersion.VERSION_1_8 32 | targetCompatibility JavaVersion.VERSION_1_8 33 | } 34 | 35 | kotlinOptions { 36 | jvmTarget = '1.8' 37 | } 38 | 39 | sourceSets { 40 | main.java.srcDirs += 'src/main/kotlin' 41 | } 42 | 43 | defaultConfig { 44 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 45 | applicationId "com.example.example" 46 | // You can update the following values to match your application needs. 47 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. 48 | minSdkVersion flutter.minSdkVersion 49 | targetSdkVersion flutter.targetSdkVersion 50 | versionCode flutterVersionCode.toInteger() 51 | versionName flutterVersionName 52 | } 53 | 54 | buildTypes { 55 | release { 56 | // TODO: Add your own signing config for the release build. 57 | // Signing with the debug keys for now, so `flutter run --release` works. 58 | signingConfig signingConfigs.debug 59 | } 60 | } 61 | } 62 | 63 | flutter { 64 | source '../..' 65 | } 66 | 67 | dependencies {} 68 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 14 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/example/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.7.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.3.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | tasks.register("clean", Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip 6 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | } 9 | settings.ext.flutterSdkPath = flutterSdkPath() 10 | 11 | includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") 12 | 13 | plugins { 14 | id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false 15 | } 16 | } 17 | 18 | include ":app" 19 | 20 | apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle" 21 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 11.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '13.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | target 'RunnerTests' do 36 | inherit! :search_paths 37 | end 38 | end 39 | 40 | post_install do |installer| 41 | installer.pods_project.targets.each do |target| 42 | flutter_additional_ios_build_settings(target) 43 | target.build_configurations.each do |config| 44 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - bonsoir_darwin (4.0.0): 3 | - Flutter 4 | - FlutterMacOS 5 | - connectivity_plus (0.0.1): 6 | - Flutter 7 | - ReachabilitySwift 8 | - Flutter (1.0.0) 9 | - ReachabilitySwift (5.0.0) 10 | 11 | DEPENDENCIES: 12 | - bonsoir_darwin (from `.symlinks/plugins/bonsoir_darwin/darwin`) 13 | - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) 14 | - Flutter (from `Flutter`) 15 | 16 | SPEC REPOS: 17 | trunk: 18 | - ReachabilitySwift 19 | 20 | EXTERNAL SOURCES: 21 | bonsoir_darwin: 22 | :path: ".symlinks/plugins/bonsoir_darwin/darwin" 23 | connectivity_plus: 24 | :path: ".symlinks/plugins/connectivity_plus/ios" 25 | Flutter: 26 | :path: Flutter 27 | 28 | SPEC CHECKSUMS: 29 | bonsoir_darwin: 7da594ad87e24a387874c49496ff39ffcc9645d9 30 | connectivity_plus: 07c49e96d7fc92bc9920617b83238c4d178b446a 31 | Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 32 | ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 33 | 34 | PODFILE CHECKSUM: 0a7d5b7d0e53420cb0284f7b2f171f93843b94d2 35 | 36 | COCOAPODS: 1.13.0 37 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 09B6BC8F2F7867700B958D2B /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12958BFFDE470C0AEC5E0B1E /* Pods_Runner.framework */; }; 11 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 12 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; 13 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 15 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 16 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 17 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 18 | A810307DE42D40D35B78DE2E /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 708F7ADE0882B87BE0D434A4 /* Pods_RunnerTests.framework */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = 97C146E61CF9000F007C117D /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = 97C146ED1CF9000F007C117D; 27 | remoteInfo = Runner; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXCopyFilesBuildPhase section */ 32 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 33 | isa = PBXCopyFilesBuildPhase; 34 | buildActionMask = 2147483647; 35 | dstPath = ""; 36 | dstSubfolderSpec = 10; 37 | files = ( 38 | ); 39 | name = "Embed Frameworks"; 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXCopyFilesBuildPhase section */ 43 | 44 | /* Begin PBXFileReference section */ 45 | 12958BFFDE470C0AEC5E0B1E /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 47 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 48 | 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 49 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 51 | 4C86D9E5688B3273EB596676 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 52 | 520B5728D30A78FF10C5C581 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 53 | 708F7ADE0882B87BE0D434A4 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 55 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 56 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 57 | 7BAF53CF980267C69056A753 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 58 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 59 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 60 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 62 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 63 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 64 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 65 | A029B89B6D3A3D8C66220CFC /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 66 | D370CB05C2D13808BC0CF3CD /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 67 | F9F67F142F6C554E58A265B5 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 68 | /* End PBXFileReference section */ 69 | 70 | /* Begin PBXFrameworksBuildPhase section */ 71 | 16F217B6AE411E6D553CE435 /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | A810307DE42D40D35B78DE2E /* Pods_RunnerTests.framework in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | 09B6BC8F2F7867700B958D2B /* Pods_Runner.framework in Frameworks */, 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | /* End PBXFrameworksBuildPhase section */ 88 | 89 | /* Begin PBXGroup section */ 90 | 1A9B8FBFDA47B66D566D6F96 /* Pods */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 7BAF53CF980267C69056A753 /* Pods-Runner.debug.xcconfig */, 94 | D370CB05C2D13808BC0CF3CD /* Pods-Runner.release.xcconfig */, 95 | 520B5728D30A78FF10C5C581 /* Pods-Runner.profile.xcconfig */, 96 | A029B89B6D3A3D8C66220CFC /* Pods-RunnerTests.debug.xcconfig */, 97 | 4C86D9E5688B3273EB596676 /* Pods-RunnerTests.release.xcconfig */, 98 | F9F67F142F6C554E58A265B5 /* Pods-RunnerTests.profile.xcconfig */, 99 | ); 100 | path = Pods; 101 | sourceTree = ""; 102 | }; 103 | 331C8082294A63A400263BE5 /* RunnerTests */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | 331C807B294A618700263BE5 /* RunnerTests.swift */, 107 | ); 108 | path = RunnerTests; 109 | sourceTree = ""; 110 | }; 111 | 9740EEB11CF90186004384FC /* Flutter */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 115 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 116 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 117 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 118 | ); 119 | name = Flutter; 120 | sourceTree = ""; 121 | }; 122 | 97C146E51CF9000F007C117D = { 123 | isa = PBXGroup; 124 | children = ( 125 | 9740EEB11CF90186004384FC /* Flutter */, 126 | 97C146F01CF9000F007C117D /* Runner */, 127 | 97C146EF1CF9000F007C117D /* Products */, 128 | 331C8082294A63A400263BE5 /* RunnerTests */, 129 | 1A9B8FBFDA47B66D566D6F96 /* Pods */, 130 | C8DACBEC770D48D47EB425F0 /* Frameworks */, 131 | ); 132 | sourceTree = ""; 133 | }; 134 | 97C146EF1CF9000F007C117D /* Products */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 97C146EE1CF9000F007C117D /* Runner.app */, 138 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */, 139 | ); 140 | name = Products; 141 | sourceTree = ""; 142 | }; 143 | 97C146F01CF9000F007C117D /* Runner */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 147 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 148 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 149 | 97C147021CF9000F007C117D /* Info.plist */, 150 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 151 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 152 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 153 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 154 | ); 155 | path = Runner; 156 | sourceTree = ""; 157 | }; 158 | C8DACBEC770D48D47EB425F0 /* Frameworks */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 12958BFFDE470C0AEC5E0B1E /* Pods_Runner.framework */, 162 | 708F7ADE0882B87BE0D434A4 /* Pods_RunnerTests.framework */, 163 | ); 164 | name = Frameworks; 165 | sourceTree = ""; 166 | }; 167 | /* End PBXGroup section */ 168 | 169 | /* Begin PBXNativeTarget section */ 170 | 331C8080294A63A400263BE5 /* RunnerTests */ = { 171 | isa = PBXNativeTarget; 172 | buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; 173 | buildPhases = ( 174 | F1609B17994B047C26D5B58B /* [CP] Check Pods Manifest.lock */, 175 | 331C807D294A63A400263BE5 /* Sources */, 176 | 331C807F294A63A400263BE5 /* Resources */, 177 | 16F217B6AE411E6D553CE435 /* Frameworks */, 178 | ); 179 | buildRules = ( 180 | ); 181 | dependencies = ( 182 | 331C8086294A63A400263BE5 /* PBXTargetDependency */, 183 | ); 184 | name = RunnerTests; 185 | productName = RunnerTests; 186 | productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; 187 | productType = "com.apple.product-type.bundle.unit-test"; 188 | }; 189 | 97C146ED1CF9000F007C117D /* Runner */ = { 190 | isa = PBXNativeTarget; 191 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 192 | buildPhases = ( 193 | 2D31493C31CD9CF3DDFF5C8B /* [CP] Check Pods Manifest.lock */, 194 | 9740EEB61CF901F6004384FC /* Run Script */, 195 | 97C146EA1CF9000F007C117D /* Sources */, 196 | 97C146EB1CF9000F007C117D /* Frameworks */, 197 | 97C146EC1CF9000F007C117D /* Resources */, 198 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 199 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 200 | DCEC3F3D803DB0413ACC8F94 /* [CP] Embed Pods Frameworks */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | ); 206 | name = Runner; 207 | productName = Runner; 208 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 209 | productType = "com.apple.product-type.application"; 210 | }; 211 | /* End PBXNativeTarget section */ 212 | 213 | /* Begin PBXProject section */ 214 | 97C146E61CF9000F007C117D /* Project object */ = { 215 | isa = PBXProject; 216 | attributes = { 217 | BuildIndependentTargetsInParallel = YES; 218 | LastUpgradeCheck = 1430; 219 | ORGANIZATIONNAME = ""; 220 | TargetAttributes = { 221 | 331C8080294A63A400263BE5 = { 222 | CreatedOnToolsVersion = 14.0; 223 | TestTargetID = 97C146ED1CF9000F007C117D; 224 | }; 225 | 97C146ED1CF9000F007C117D = { 226 | CreatedOnToolsVersion = 7.3.1; 227 | LastSwiftMigration = 1100; 228 | }; 229 | }; 230 | }; 231 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 232 | compatibilityVersion = "Xcode 9.3"; 233 | developmentRegion = en; 234 | hasScannedForEncodings = 0; 235 | knownRegions = ( 236 | en, 237 | Base, 238 | ); 239 | mainGroup = 97C146E51CF9000F007C117D; 240 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 241 | projectDirPath = ""; 242 | projectRoot = ""; 243 | targets = ( 244 | 97C146ED1CF9000F007C117D /* Runner */, 245 | 331C8080294A63A400263BE5 /* RunnerTests */, 246 | ); 247 | }; 248 | /* End PBXProject section */ 249 | 250 | /* Begin PBXResourcesBuildPhase section */ 251 | 331C807F294A63A400263BE5 /* Resources */ = { 252 | isa = PBXResourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | 97C146EC1CF9000F007C117D /* Resources */ = { 259 | isa = PBXResourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 263 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 264 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 265 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | }; 269 | /* End PBXResourcesBuildPhase section */ 270 | 271 | /* Begin PBXShellScriptBuildPhase section */ 272 | 2D31493C31CD9CF3DDFF5C8B /* [CP] Check Pods Manifest.lock */ = { 273 | isa = PBXShellScriptBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | ); 277 | inputFileListPaths = ( 278 | ); 279 | inputPaths = ( 280 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 281 | "${PODS_ROOT}/Manifest.lock", 282 | ); 283 | name = "[CP] Check Pods Manifest.lock"; 284 | outputFileListPaths = ( 285 | ); 286 | outputPaths = ( 287 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 288 | ); 289 | runOnlyForDeploymentPostprocessing = 0; 290 | shellPath = /bin/sh; 291 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 292 | showEnvVarsInLog = 0; 293 | }; 294 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 295 | isa = PBXShellScriptBuildPhase; 296 | alwaysOutOfDate = 1; 297 | buildActionMask = 2147483647; 298 | files = ( 299 | ); 300 | inputPaths = ( 301 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 302 | ); 303 | name = "Thin Binary"; 304 | outputPaths = ( 305 | ); 306 | runOnlyForDeploymentPostprocessing = 0; 307 | shellPath = /bin/sh; 308 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 309 | }; 310 | 9740EEB61CF901F6004384FC /* Run Script */ = { 311 | isa = PBXShellScriptBuildPhase; 312 | alwaysOutOfDate = 1; 313 | buildActionMask = 2147483647; 314 | files = ( 315 | ); 316 | inputPaths = ( 317 | ); 318 | name = "Run Script"; 319 | outputPaths = ( 320 | ); 321 | runOnlyForDeploymentPostprocessing = 0; 322 | shellPath = /bin/sh; 323 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 324 | }; 325 | DCEC3F3D803DB0413ACC8F94 /* [CP] Embed Pods Frameworks */ = { 326 | isa = PBXShellScriptBuildPhase; 327 | buildActionMask = 2147483647; 328 | files = ( 329 | ); 330 | inputFileListPaths = ( 331 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 332 | ); 333 | name = "[CP] Embed Pods Frameworks"; 334 | outputFileListPaths = ( 335 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | shellPath = /bin/sh; 339 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 340 | showEnvVarsInLog = 0; 341 | }; 342 | F1609B17994B047C26D5B58B /* [CP] Check Pods Manifest.lock */ = { 343 | isa = PBXShellScriptBuildPhase; 344 | buildActionMask = 2147483647; 345 | files = ( 346 | ); 347 | inputFileListPaths = ( 348 | ); 349 | inputPaths = ( 350 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 351 | "${PODS_ROOT}/Manifest.lock", 352 | ); 353 | name = "[CP] Check Pods Manifest.lock"; 354 | outputFileListPaths = ( 355 | ); 356 | outputPaths = ( 357 | "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", 358 | ); 359 | runOnlyForDeploymentPostprocessing = 0; 360 | shellPath = /bin/sh; 361 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 362 | showEnvVarsInLog = 0; 363 | }; 364 | /* End PBXShellScriptBuildPhase section */ 365 | 366 | /* Begin PBXSourcesBuildPhase section */ 367 | 331C807D294A63A400263BE5 /* Sources */ = { 368 | isa = PBXSourcesBuildPhase; 369 | buildActionMask = 2147483647; 370 | files = ( 371 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, 372 | ); 373 | runOnlyForDeploymentPostprocessing = 0; 374 | }; 375 | 97C146EA1CF9000F007C117D /* Sources */ = { 376 | isa = PBXSourcesBuildPhase; 377 | buildActionMask = 2147483647; 378 | files = ( 379 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 380 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 381 | ); 382 | runOnlyForDeploymentPostprocessing = 0; 383 | }; 384 | /* End PBXSourcesBuildPhase section */ 385 | 386 | /* Begin PBXTargetDependency section */ 387 | 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { 388 | isa = PBXTargetDependency; 389 | target = 97C146ED1CF9000F007C117D /* Runner */; 390 | targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; 391 | }; 392 | /* End PBXTargetDependency section */ 393 | 394 | /* Begin PBXVariantGroup section */ 395 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 396 | isa = PBXVariantGroup; 397 | children = ( 398 | 97C146FB1CF9000F007C117D /* Base */, 399 | ); 400 | name = Main.storyboard; 401 | sourceTree = ""; 402 | }; 403 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 404 | isa = PBXVariantGroup; 405 | children = ( 406 | 97C147001CF9000F007C117D /* Base */, 407 | ); 408 | name = LaunchScreen.storyboard; 409 | sourceTree = ""; 410 | }; 411 | /* End PBXVariantGroup section */ 412 | 413 | /* Begin XCBuildConfiguration section */ 414 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 415 | isa = XCBuildConfiguration; 416 | buildSettings = { 417 | ALWAYS_SEARCH_USER_PATHS = NO; 418 | CLANG_ANALYZER_NONNULL = YES; 419 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 420 | CLANG_CXX_LIBRARY = "libc++"; 421 | CLANG_ENABLE_MODULES = YES; 422 | CLANG_ENABLE_OBJC_ARC = YES; 423 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 424 | CLANG_WARN_BOOL_CONVERSION = YES; 425 | CLANG_WARN_COMMA = YES; 426 | CLANG_WARN_CONSTANT_CONVERSION = YES; 427 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 428 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 429 | CLANG_WARN_EMPTY_BODY = YES; 430 | CLANG_WARN_ENUM_CONVERSION = YES; 431 | CLANG_WARN_INFINITE_RECURSION = YES; 432 | CLANG_WARN_INT_CONVERSION = YES; 433 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 434 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 435 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 436 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 437 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 438 | CLANG_WARN_STRICT_PROTOTYPES = YES; 439 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 440 | CLANG_WARN_UNREACHABLE_CODE = YES; 441 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 442 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 443 | COPY_PHASE_STRIP = NO; 444 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 445 | ENABLE_NS_ASSERTIONS = NO; 446 | ENABLE_STRICT_OBJC_MSGSEND = YES; 447 | GCC_C_LANGUAGE_STANDARD = gnu99; 448 | GCC_NO_COMMON_BLOCKS = YES; 449 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 450 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 451 | GCC_WARN_UNDECLARED_SELECTOR = YES; 452 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 453 | GCC_WARN_UNUSED_FUNCTION = YES; 454 | GCC_WARN_UNUSED_VARIABLE = YES; 455 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 456 | MTL_ENABLE_DEBUG_INFO = NO; 457 | SDKROOT = iphoneos; 458 | SUPPORTED_PLATFORMS = iphoneos; 459 | TARGETED_DEVICE_FAMILY = "1,2"; 460 | VALIDATE_PRODUCT = YES; 461 | }; 462 | name = Profile; 463 | }; 464 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 465 | isa = XCBuildConfiguration; 466 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 467 | buildSettings = { 468 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 469 | CLANG_ENABLE_MODULES = YES; 470 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 471 | ENABLE_BITCODE = NO; 472 | INFOPLIST_FILE = Runner/Info.plist; 473 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 474 | LD_RUNPATH_SEARCH_PATHS = ( 475 | "$(inherited)", 476 | "@executable_path/Frameworks", 477 | ); 478 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 479 | PRODUCT_NAME = "$(TARGET_NAME)"; 480 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 481 | SWIFT_VERSION = 5.0; 482 | VERSIONING_SYSTEM = "apple-generic"; 483 | }; 484 | name = Profile; 485 | }; 486 | 331C8088294A63A400263BE5 /* Debug */ = { 487 | isa = XCBuildConfiguration; 488 | baseConfigurationReference = A029B89B6D3A3D8C66220CFC /* Pods-RunnerTests.debug.xcconfig */; 489 | buildSettings = { 490 | BUNDLE_LOADER = "$(TEST_HOST)"; 491 | CODE_SIGN_STYLE = Automatic; 492 | CURRENT_PROJECT_VERSION = 1; 493 | GENERATE_INFOPLIST_FILE = YES; 494 | MARKETING_VERSION = 1.0; 495 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; 496 | PRODUCT_NAME = "$(TARGET_NAME)"; 497 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 498 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 499 | SWIFT_VERSION = 5.0; 500 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 501 | }; 502 | name = Debug; 503 | }; 504 | 331C8089294A63A400263BE5 /* Release */ = { 505 | isa = XCBuildConfiguration; 506 | baseConfigurationReference = 4C86D9E5688B3273EB596676 /* Pods-RunnerTests.release.xcconfig */; 507 | buildSettings = { 508 | BUNDLE_LOADER = "$(TEST_HOST)"; 509 | CODE_SIGN_STYLE = Automatic; 510 | CURRENT_PROJECT_VERSION = 1; 511 | GENERATE_INFOPLIST_FILE = YES; 512 | MARKETING_VERSION = 1.0; 513 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; 514 | PRODUCT_NAME = "$(TARGET_NAME)"; 515 | SWIFT_VERSION = 5.0; 516 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 517 | }; 518 | name = Release; 519 | }; 520 | 331C808A294A63A400263BE5 /* Profile */ = { 521 | isa = XCBuildConfiguration; 522 | baseConfigurationReference = F9F67F142F6C554E58A265B5 /* Pods-RunnerTests.profile.xcconfig */; 523 | buildSettings = { 524 | BUNDLE_LOADER = "$(TEST_HOST)"; 525 | CODE_SIGN_STYLE = Automatic; 526 | CURRENT_PROJECT_VERSION = 1; 527 | GENERATE_INFOPLIST_FILE = YES; 528 | MARKETING_VERSION = 1.0; 529 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example.RunnerTests; 530 | PRODUCT_NAME = "$(TARGET_NAME)"; 531 | SWIFT_VERSION = 5.0; 532 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; 533 | }; 534 | name = Profile; 535 | }; 536 | 97C147031CF9000F007C117D /* Debug */ = { 537 | isa = XCBuildConfiguration; 538 | buildSettings = { 539 | ALWAYS_SEARCH_USER_PATHS = NO; 540 | CLANG_ANALYZER_NONNULL = YES; 541 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 542 | CLANG_CXX_LIBRARY = "libc++"; 543 | CLANG_ENABLE_MODULES = YES; 544 | CLANG_ENABLE_OBJC_ARC = YES; 545 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 546 | CLANG_WARN_BOOL_CONVERSION = YES; 547 | CLANG_WARN_COMMA = YES; 548 | CLANG_WARN_CONSTANT_CONVERSION = YES; 549 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 550 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 551 | CLANG_WARN_EMPTY_BODY = YES; 552 | CLANG_WARN_ENUM_CONVERSION = YES; 553 | CLANG_WARN_INFINITE_RECURSION = YES; 554 | CLANG_WARN_INT_CONVERSION = YES; 555 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 556 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 557 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 558 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 559 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 560 | CLANG_WARN_STRICT_PROTOTYPES = YES; 561 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 562 | CLANG_WARN_UNREACHABLE_CODE = YES; 563 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 564 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 565 | COPY_PHASE_STRIP = NO; 566 | DEBUG_INFORMATION_FORMAT = dwarf; 567 | ENABLE_STRICT_OBJC_MSGSEND = YES; 568 | ENABLE_TESTABILITY = YES; 569 | GCC_C_LANGUAGE_STANDARD = gnu99; 570 | GCC_DYNAMIC_NO_PIC = NO; 571 | GCC_NO_COMMON_BLOCKS = YES; 572 | GCC_OPTIMIZATION_LEVEL = 0; 573 | GCC_PREPROCESSOR_DEFINITIONS = ( 574 | "DEBUG=1", 575 | "$(inherited)", 576 | ); 577 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 578 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 579 | GCC_WARN_UNDECLARED_SELECTOR = YES; 580 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 581 | GCC_WARN_UNUSED_FUNCTION = YES; 582 | GCC_WARN_UNUSED_VARIABLE = YES; 583 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 584 | MTL_ENABLE_DEBUG_INFO = YES; 585 | ONLY_ACTIVE_ARCH = YES; 586 | SDKROOT = iphoneos; 587 | TARGETED_DEVICE_FAMILY = "1,2"; 588 | }; 589 | name = Debug; 590 | }; 591 | 97C147041CF9000F007C117D /* Release */ = { 592 | isa = XCBuildConfiguration; 593 | buildSettings = { 594 | ALWAYS_SEARCH_USER_PATHS = NO; 595 | CLANG_ANALYZER_NONNULL = YES; 596 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 597 | CLANG_CXX_LIBRARY = "libc++"; 598 | CLANG_ENABLE_MODULES = YES; 599 | CLANG_ENABLE_OBJC_ARC = YES; 600 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 601 | CLANG_WARN_BOOL_CONVERSION = YES; 602 | CLANG_WARN_COMMA = YES; 603 | CLANG_WARN_CONSTANT_CONVERSION = YES; 604 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 605 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 606 | CLANG_WARN_EMPTY_BODY = YES; 607 | CLANG_WARN_ENUM_CONVERSION = YES; 608 | CLANG_WARN_INFINITE_RECURSION = YES; 609 | CLANG_WARN_INT_CONVERSION = YES; 610 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 611 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 612 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 613 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 614 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 615 | CLANG_WARN_STRICT_PROTOTYPES = YES; 616 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 617 | CLANG_WARN_UNREACHABLE_CODE = YES; 618 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 619 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 620 | COPY_PHASE_STRIP = NO; 621 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 622 | ENABLE_NS_ASSERTIONS = NO; 623 | ENABLE_STRICT_OBJC_MSGSEND = YES; 624 | GCC_C_LANGUAGE_STANDARD = gnu99; 625 | GCC_NO_COMMON_BLOCKS = YES; 626 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 627 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 628 | GCC_WARN_UNDECLARED_SELECTOR = YES; 629 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 630 | GCC_WARN_UNUSED_FUNCTION = YES; 631 | GCC_WARN_UNUSED_VARIABLE = YES; 632 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 633 | MTL_ENABLE_DEBUG_INFO = NO; 634 | SDKROOT = iphoneos; 635 | SUPPORTED_PLATFORMS = iphoneos; 636 | SWIFT_COMPILATION_MODE = wholemodule; 637 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 638 | TARGETED_DEVICE_FAMILY = "1,2"; 639 | VALIDATE_PRODUCT = YES; 640 | }; 641 | name = Release; 642 | }; 643 | 97C147061CF9000F007C117D /* Debug */ = { 644 | isa = XCBuildConfiguration; 645 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 646 | buildSettings = { 647 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 648 | CLANG_ENABLE_MODULES = YES; 649 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 650 | ENABLE_BITCODE = NO; 651 | INFOPLIST_FILE = Runner/Info.plist; 652 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 653 | LD_RUNPATH_SEARCH_PATHS = ( 654 | "$(inherited)", 655 | "@executable_path/Frameworks", 656 | ); 657 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 658 | PRODUCT_NAME = "$(TARGET_NAME)"; 659 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 660 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 661 | SWIFT_VERSION = 5.0; 662 | VERSIONING_SYSTEM = "apple-generic"; 663 | }; 664 | name = Debug; 665 | }; 666 | 97C147071CF9000F007C117D /* Release */ = { 667 | isa = XCBuildConfiguration; 668 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 669 | buildSettings = { 670 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 671 | CLANG_ENABLE_MODULES = YES; 672 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 673 | ENABLE_BITCODE = NO; 674 | INFOPLIST_FILE = Runner/Info.plist; 675 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 676 | LD_RUNPATH_SEARCH_PATHS = ( 677 | "$(inherited)", 678 | "@executable_path/Frameworks", 679 | ); 680 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example; 681 | PRODUCT_NAME = "$(TARGET_NAME)"; 682 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 683 | SWIFT_VERSION = 5.0; 684 | VERSIONING_SYSTEM = "apple-generic"; 685 | }; 686 | name = Release; 687 | }; 688 | /* End XCBuildConfiguration section */ 689 | 690 | /* Begin XCConfigurationList section */ 691 | 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { 692 | isa = XCConfigurationList; 693 | buildConfigurations = ( 694 | 331C8088294A63A400263BE5 /* Debug */, 695 | 331C8089294A63A400263BE5 /* Release */, 696 | 331C808A294A63A400263BE5 /* Profile */, 697 | ); 698 | defaultConfigurationIsVisible = 0; 699 | defaultConfigurationName = Release; 700 | }; 701 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 702 | isa = XCConfigurationList; 703 | buildConfigurations = ( 704 | 97C147031CF9000F007C117D /* Debug */, 705 | 97C147041CF9000F007C117D /* Release */, 706 | 249021D3217E4FDB00AE95B9 /* Profile */, 707 | ); 708 | defaultConfigurationIsVisible = 0; 709 | defaultConfigurationName = Release; 710 | }; 711 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 712 | isa = XCConfigurationList; 713 | buildConfigurations = ( 714 | 97C147061CF9000F007C117D /* Debug */, 715 | 97C147071CF9000F007C117D /* Release */, 716 | 249021D4217E4FDB00AE95B9 /* Profile */, 717 | ); 718 | defaultConfigurationIsVisible = 0; 719 | defaultConfigurationName = Release; 720 | }; 721 | /* End XCConfigurationList section */ 722 | }; 723 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 724 | } 725 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | UIApplicationSupportsIndirectInputEvents 47 | 48 | NSBonjourServices 49 | 50 | _googlecast._tcp 51 | _YOUR_APP_ID._googlecast._tcp 52 | 53 | 54 | NSLocalNetworkUsageDescription 55 | ${PRODUCT_NAME} uses the local network to discover Cast-enabled devices on your WiFi 56 | network. 57 | 58 | 59 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:cast/cast.dart'; 3 | 4 | void main() { 5 | runApp(MyApp()); 6 | } 7 | 8 | class MyApp extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | title: 'Cast Demo', 13 | theme: ThemeData( 14 | primarySwatch: Colors.blue, 15 | visualDensity: VisualDensity.adaptivePlatformDensity, 16 | ), 17 | home: Scaffold( 18 | appBar: AppBar(), 19 | body: MyHomePage(), 20 | ), 21 | ); 22 | } 23 | } 24 | 25 | class MyHomePage extends StatefulWidget { 26 | @override 27 | _MyHomePageState createState() => _MyHomePageState(); 28 | } 29 | 30 | class _MyHomePageState extends State { 31 | Future>? _future; 32 | 33 | @override 34 | void initState() { 35 | super.initState(); 36 | _startSearch(); 37 | } 38 | 39 | @override 40 | Widget build(BuildContext context) { 41 | return FutureBuilder>( 42 | future: _future, 43 | builder: (context, snapshot) { 44 | if (snapshot.hasError) { 45 | return Center( 46 | child: Text( 47 | 'Error: ${snapshot.error.toString()}', 48 | ), 49 | ); 50 | } else if (!snapshot.hasData) { 51 | return Center( 52 | child: CircularProgressIndicator(), 53 | ); 54 | } 55 | 56 | if (snapshot.data!.isEmpty) { 57 | return Column( 58 | children: [ 59 | Center( 60 | child: Text( 61 | 'No Chromecast founded', 62 | ), 63 | ), 64 | ], 65 | ); 66 | } 67 | 68 | return Column( 69 | children: snapshot.data!.map((device) { 70 | return ListTile( 71 | title: Text(device.name), 72 | onTap: () { 73 | // _connectToYourApp(context, device); 74 | _connectAndPlayMedia(context, device); 75 | }, 76 | ); 77 | }).toList(), 78 | ); 79 | }, 80 | ); 81 | } 82 | 83 | void _startSearch() { 84 | _future = CastDiscoveryService().search(); 85 | } 86 | 87 | Future _connectToYourApp(BuildContext context, CastDevice object) async { 88 | final session = await CastSessionManager().startSession(object); 89 | 90 | session.stateStream.listen((state) { 91 | if (state == CastSessionState.connected) { 92 | final snackBar = SnackBar(content: Text('Connected')); 93 | ScaffoldMessenger.of(context).showSnackBar(snackBar); 94 | 95 | _sendMessageToYourApp(session); 96 | } 97 | }); 98 | 99 | session.messageStream.listen((message) { 100 | print('receive message: $message'); 101 | }); 102 | 103 | session.sendMessage(CastSession.kNamespaceReceiver, { 104 | 'type': 'LAUNCH', 105 | 'appId': 'Youtube', // set the appId of your app here 106 | }); 107 | } 108 | 109 | void _sendMessageToYourApp(CastSession session) { 110 | print('_sendMessageToYourApp'); 111 | 112 | session.sendMessage('urn:x-cast:namespace-of-the-app', { 113 | 'type': 'sample', 114 | }); 115 | } 116 | 117 | Future _connectAndPlayMedia(BuildContext context, CastDevice object) async { 118 | final session = await CastSessionManager().startSession(object); 119 | 120 | session.stateStream.listen((state) { 121 | if (state == CastSessionState.connected) { 122 | final snackBar = SnackBar(content: Text('Connected')); 123 | ScaffoldMessenger.of(context).showSnackBar(snackBar); 124 | } 125 | }); 126 | 127 | var index = 0; 128 | 129 | session.messageStream.listen((message) { 130 | index += 1; 131 | 132 | print('receive message: $message'); 133 | 134 | if (index == 2) { 135 | Future.delayed(Duration(seconds: 5)).then((x) { 136 | _sendMessagePlayVideo(session); 137 | }); 138 | } 139 | }); 140 | 141 | session.sendMessage(CastSession.kNamespaceReceiver, { 142 | 'type': 'LAUNCH', 143 | 'appId': 'CC1AD845', // set the appId of your app here 144 | }); 145 | } 146 | 147 | void _sendMessagePlayVideo(CastSession session) { 148 | print('_sendMessagePlayVideo'); 149 | 150 | var message = { 151 | // Here you can plug an URL to any mp4, webm, mp3 or jpg file with the proper contentType. 152 | 'contentId': 'http://commondatastorage.googleapis.com/gtv-videos-bucket/big_buck_bunny_1080p.mp4', 153 | 'contentType': 'video/mp4', 154 | 'streamType': 'BUFFERED', // or LIVE 155 | 156 | // Title and cover displayed while buffering 157 | 'metadata': { 158 | 'type': 0, 159 | 'metadataType': 0, 160 | 'title': "Big Buck Bunny", 161 | 'images': [ 162 | {'url': 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg'} 163 | ] 164 | } 165 | }; 166 | 167 | session.sendMessage(CastSession.kNamespaceMedia, { 168 | 'type': 'LOAD', 169 | 'autoPlay': true, 170 | 'currentTime': 0, 171 | 'media': message, 172 | }); 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import bonsoir_darwin 9 | import connectivity_plus 10 | 11 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 12 | SwiftBonsoirPlugin.register(with: registry.registrar(forPlugin: "SwiftBonsoirPlugin")) 13 | ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) 14 | } 15 | -------------------------------------------------------------------------------- /example/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.15' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | target 'RunnerTests' do 35 | inherit! :search_paths 36 | end 37 | end 38 | 39 | post_install do |installer| 40 | installer.pods_project.targets.each do |target| 41 | flutter_additional_macos_build_settings(target) 42 | target.build_configurations.each do |config| 43 | config.build_settings['MACOSX_DEPLOYMENT_TARGET'] = '10.15' 44 | end 45 | end 46 | end 47 | -------------------------------------------------------------------------------- /example/macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - bonsoir_darwin (3.0.0): 3 | - Flutter 4 | - FlutterMacOS 5 | - connectivity_plus (0.0.1): 6 | - FlutterMacOS 7 | - ReachabilitySwift 8 | - FlutterMacOS (1.0.0) 9 | - ReachabilitySwift (5.0.0) 10 | 11 | DEPENDENCIES: 12 | - bonsoir_darwin (from `Flutter/ephemeral/.symlinks/plugins/bonsoir_darwin/darwin`) 13 | - connectivity_plus (from `Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos`) 14 | - FlutterMacOS (from `Flutter/ephemeral`) 15 | 16 | SPEC REPOS: 17 | trunk: 18 | - ReachabilitySwift 19 | 20 | EXTERNAL SOURCES: 21 | bonsoir_darwin: 22 | :path: Flutter/ephemeral/.symlinks/plugins/bonsoir_darwin/darwin 23 | connectivity_plus: 24 | :path: Flutter/ephemeral/.symlinks/plugins/connectivity_plus/macos 25 | FlutterMacOS: 26 | :path: Flutter/ephemeral 27 | 28 | SPEC CHECKSUMS: 29 | bonsoir_darwin: 127bdc632fdc154ae2f277a4d5c86a6212bc75be 30 | connectivity_plus: 18d3c32514c886e046de60e9c13895109866c747 31 | FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 32 | ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 33 | 34 | PODFILE CHECKSUM: 4062a5d7621e35b4f677b9e411c2714a4f99d4c2 35 | 36 | COCOAPODS: 1.13.0 37 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnvuko/flutter_cast/69aa2fffcbcfc91bff15fab55b14502f9dbaf94c/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /example/macos/Runner/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2023 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.network.server 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | NSBonjourServices 32 | 33 | _googlecast._tcp 34 | _YOUR_APP_ID._googlecast._tcp 35 | 36 | 37 | NSLocalNetworkUsageDescription 38 | ${PRODUCT_NAME} uses the local network to discover Cast-enabled devices on your WiFi 39 | network. 40 | 41 | 42 | -------------------------------------------------------------------------------- /example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/macos/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import FlutterMacOS 2 | import Cocoa 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: cast_example 2 | description: Example projet for cast 3 | version: 1.0.0+1 4 | 5 | environment: 6 | sdk: '>=3.1.3 <4.0.0' 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | cast: 12 | path: ../ 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | 18 | flutter: 19 | uses-material-design: true 20 | -------------------------------------------------------------------------------- /lib/cast.dart: -------------------------------------------------------------------------------- 1 | library cast; 2 | 3 | export 'device.dart'; 4 | export 'discovery_service.dart'; 5 | export 'session.dart'; 6 | export 'session_manager.dart'; 7 | export 'socket.dart'; 8 | -------------------------------------------------------------------------------- /lib/cast_channel/cast_channel.idl: -------------------------------------------------------------------------------- 1 | // Source https://github.com/chromium/chromium/blob/master/extensions/common/api/cast_channel.idl 2 | // Should be use to generate cast_channel.dart 3 | 4 | // Copyright 2014 The Chromium Authors. All rights reserved. 5 | // Use of this source code is governed by a BSD-style license that can be 6 | // found in the LICENSE file. 7 | 8 | // API for communicating with a Google Cast device over an authenticated 9 | // channel. 10 | namespace cast.channel { 11 | // The state of the channel. 12 | enum ReadyState { 13 | // The channel is connecting. 14 | connecting, 15 | // The channel is open and available for messaging. 16 | open, 17 | // The channel is closing. 18 | closing, 19 | // The channel is closed. 20 | closed 21 | }; 22 | 23 | // Error conditions that the channel may encounter. All error conditions 24 | // are terminal. When an error condition is encountered the API will: 25 | // (1) Transition the channel to readyState == 'closed'. 26 | // (2) Set ChannelInfo.lastError to the error condition. 27 | // (3) Fire an onError event with the error condition. 28 | // (4) Fire an onClose event. 29 | enum ChannelError { 30 | // cast.channel.send() was called when ChannelInfo.readyState != 'open'. 31 | channel_not_open, 32 | // Authentication was requested and the receiver could not be 33 | // authenticated (invalid signature, invalid handhake, TLS error, etc.) 34 | authentication_error, 35 | // A new channel could not be created for reasons unrelated to 36 | // authentication (e.g., there is already an open channel to the same URL). 37 | connect_error, 38 | // There was an error writing or reading from the underlying socket. 39 | socket_error, 40 | // A transport level occurred (like an unparseable message). 41 | transport_error, 42 | // The client attempted to send an unsupported message type through the 43 | // channel. 44 | invalid_message, 45 | // An invalid channel id was passed. 46 | invalid_channel_id, 47 | // The connection could not be established before timing out. 48 | connect_timeout, 49 | // The receiving end became unresponsive. 50 | ping_timeout, 51 | // Unspecified error. 52 | unknown 53 | }; 54 | 55 | // Authentication methods that may be required to connect to a Cast receiver. 56 | enum ChannelAuthType { 57 | // SSL over TCP with challenge and receiver signature verification. 58 | ssl_verified 59 | }; 60 | 61 | // Describes the information needed to connect to a Cast receiver. 62 | // This replaces the prior use of cast:// and casts:// URLs. 63 | dictionary ConnectInfo { 64 | // The IPV4 address of the Cast receiver, e.g. '198.1.0.2'. 65 | // TODO(mfoltz): Investigate whether IPV6 addresses "just work." 66 | DOMString ipAddress; 67 | 68 | // The port number to connect to, 0-65535. 69 | long port; 70 | 71 | // The amount of time to wait in milliseconds before stopping the 72 | // connection process. Timeouts are disabled if the value is zero. 73 | // The default timeout is 8000ms. 74 | long? timeout; 75 | 76 | // The authentication method required for the channel. 77 | ChannelAuthType auth; 78 | 79 | // ------------------------------------------------------------------------ 80 | // Both pingInterval and livenessTimeout must be set to enable keep-alive 81 | // handling. 82 | 83 | // The amount of time to wait in milliseconds before sending pings 84 | // to idle channels. 85 | long? pingInterval; 86 | 87 | // The maximum amount of idle time allowed before a channel is closed. 88 | long? livenessTimeout; 89 | 90 | // If set, CastDeviceCapability bitmask values describing capability of the 91 | // cast device. 92 | long? capabilities; 93 | }; 94 | 95 | // Describes the state of a channel to a Cast receiver. 96 | dictionary ChannelInfo { 97 | // Id for the channel. 98 | long channelId; 99 | 100 | // Connection information that was used to establish the channel to the 101 | // receiver. 102 | ConnectInfo connectInfo; 103 | 104 | // The current state of the channel. 105 | ReadyState readyState; 106 | 107 | // If set, the last error condition encountered by the channel. 108 | ChannelError? errorState; 109 | 110 | // If true, keep-alive messages are handled automatically by the channel. 111 | boolean keepAlive; 112 | 113 | // Whether the channel is audio only as identified by the device 114 | // certificate during channel authentication. 115 | boolean audioOnly; 116 | }; 117 | 118 | // Describes a message sent or received over the channel. Currently only 119 | // string messages are supported, although ArrayBuffer and Blob types may be 120 | // supported in the future. 121 | dictionary MessageInfo { 122 | // The message namespace. A namespace is a URN of the form 123 | // urn:cast-x: that is used to interpret and route Cast messages. 124 | DOMString namespace_; 125 | 126 | // source and destination ids identify the origin and destination of the 127 | // message. They are used to route messages between endpoints that share a 128 | // device-to-device channel. 129 | // 130 | // For messages between applications: 131 | // - The sender application id is a unique identifier generated on behalf 132 | // of the sender application. 133 | // - The receiver id is always the the session id for the application. 134 | // 135 | // For messages to or from the sender or receiver platform, the special ids 136 | // 'sender-0' and 'receiver-0' can be used. 137 | // 138 | // For messages intended for all endpoints using a given channel, the 139 | // wildcard destination_id '*' can be used. 140 | DOMString sourceId; 141 | DOMString destinationId; 142 | 143 | // The content of the message. Must be either a string or an ArrayBuffer. 144 | any data; 145 | }; 146 | 147 | // Describes a terminal error encountered by the channel with details of the 148 | // error that caused the channel to be closed. One or more of the optional 149 | // fields may be set with specific error codes from the underlying 150 | // implementation. 151 | dictionary ErrorInfo { 152 | // The type of error encountered by the channel. 153 | ChannelError errorState; 154 | 155 | // The event that was occurring when the error happened. Values are defined 156 | // in the enum EventType in logging.proto. 157 | long? eventType; 158 | 159 | // An error encountered when processing the authentication handshake. 160 | // Values are defined in the enum ChallengeReplyErrorType in logging.proto. 161 | long? challengeReplyErrorType; 162 | 163 | // A return value from the underlying net:: socket libraries. Values are 164 | // defined in net/base/net_error_list.h. 165 | long? netReturnValue; 166 | 167 | // An error code returned by NSS. Values are defined in secerr.h. 168 | long? nssErrorCode; 169 | }; 170 | 171 | // Callback holding the result of a channel operation. 172 | callback ChannelInfoCallback = void (ChannelInfo result); 173 | 174 | interface Functions { 175 | // Opens a new channel to the Cast receiver specified by connectInfo. Only 176 | // one channel may be connected to same receiver from the same extension at 177 | // a time. If the open request is successful, the callback will be invoked 178 | // with a ChannelInfo with readyState == 'connecting'. If unsuccessful, the 179 | // callback will be invoked with a ChannelInfo with channel.readyState == 180 | // 'closed', channel.errorState will be set to the error condition, and 181 | // onError will be fired with error details. 182 | static void open(ConnectInfo connectInfo, 183 | ChannelInfoCallback callback); 184 | 185 | // Sends a message on the channel and invokes callback with the resulting 186 | // channel status. The channel must be in readyState == 'open'. If 187 | // unsuccessful, channel.readyState will be set to 'closed', 188 | // channel.errorState will be set to the error condition, and onError will 189 | // be fired with error details. 190 | static void send(ChannelInfo channel, 191 | MessageInfo message, 192 | ChannelInfoCallback callback); 193 | 194 | // Requests that the channel be closed and invokes callback with the 195 | // resulting channel status. The channel must be in readyState == 'open' or 196 | // 'connecting'. If successful, onClose will be fired with readyState == 197 | // 'closed'. If unsuccessful, channel.readyState will be set to 'closed', 198 | // and channel.errorState will be set to the error condition. 199 | static void close(ChannelInfo channel, 200 | ChannelInfoCallback callback); 201 | }; 202 | 203 | // Events on the channel. 204 | interface Events { 205 | // Fired when a message is received on an open channel. 206 | static void onMessage(ChannelInfo channel, 207 | MessageInfo message); 208 | 209 | // Fired when an error occurs as a result of a channel operation or a 210 | // network event. |error| contains details of the error. 211 | static void onError(ChannelInfo channel, ErrorInfo error); 212 | }; 213 | }; -------------------------------------------------------------------------------- /lib/cast_channel/cast_channel.pb.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: cast_channel.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields 7 | 8 | import 'dart:core' as $core; 9 | 10 | import 'package:protobuf/protobuf.dart' as $pb; 11 | 12 | import 'cast_channel.pbenum.dart'; 13 | 14 | export 'cast_channel.pbenum.dart'; 15 | 16 | class CastMessage extends $pb.GeneratedMessage { 17 | static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'CastMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'extensions.api.cast_channel'), createEmptyInstance: create) 18 | ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'protocolVersion', $pb.PbFieldType.QE, defaultOrMaker: CastMessage_ProtocolVersion.CASTV2_1_0, valueOf: CastMessage_ProtocolVersion.valueOf, enumValues: CastMessage_ProtocolVersion.values) 19 | ..aQS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sourceId') 20 | ..aQS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'destinationId') 21 | ..aQS(4, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'namespace') 22 | ..e(5, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'payloadType', $pb.PbFieldType.QE, defaultOrMaker: CastMessage_PayloadType.STRING, valueOf: CastMessage_PayloadType.valueOf, enumValues: CastMessage_PayloadType.values) 23 | ..aOS(6, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'payloadUtf8') 24 | ..a<$core.List<$core.int>>(7, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'payloadBinary', $pb.PbFieldType.OY) 25 | ; 26 | 27 | CastMessage._() : super(); 28 | factory CastMessage({ 29 | CastMessage_ProtocolVersion? protocolVersion, 30 | $core.String? sourceId, 31 | $core.String? destinationId, 32 | $core.String? namespace, 33 | CastMessage_PayloadType? payloadType, 34 | $core.String? payloadUtf8, 35 | $core.List<$core.int>? payloadBinary, 36 | }) { 37 | final _result = create(); 38 | if (protocolVersion != null) { 39 | _result.protocolVersion = protocolVersion; 40 | } 41 | if (sourceId != null) { 42 | _result.sourceId = sourceId; 43 | } 44 | if (destinationId != null) { 45 | _result.destinationId = destinationId; 46 | } 47 | if (namespace != null) { 48 | _result.namespace = namespace; 49 | } 50 | if (payloadType != null) { 51 | _result.payloadType = payloadType; 52 | } 53 | if (payloadUtf8 != null) { 54 | _result.payloadUtf8 = payloadUtf8; 55 | } 56 | if (payloadBinary != null) { 57 | _result.payloadBinary = payloadBinary; 58 | } 59 | return _result; 60 | } 61 | factory CastMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); 62 | factory CastMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); 63 | @$core.Deprecated( 64 | 'Using this can add significant overhead to your binary. ' 65 | 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 66 | 'Will be removed in next major version') 67 | CastMessage clone() => CastMessage()..mergeFromMessage(this); 68 | @$core.Deprecated( 69 | 'Using this can add significant overhead to your binary. ' 70 | 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 71 | 'Will be removed in next major version') 72 | CastMessage copyWith(void Function(CastMessage) updates) => super.copyWith((message) => updates(message as CastMessage)) as CastMessage; // ignore: deprecated_member_use 73 | $pb.BuilderInfo get info_ => _i; 74 | @$core.pragma('dart2js:noInline') 75 | static CastMessage create() => CastMessage._(); 76 | CastMessage createEmptyInstance() => create(); 77 | static $pb.PbList createRepeated() => $pb.PbList(); 78 | @$core.pragma('dart2js:noInline') 79 | static CastMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); 80 | static CastMessage? _defaultInstance; 81 | 82 | @$pb.TagNumber(1) 83 | CastMessage_ProtocolVersion get protocolVersion => $_getN(0); 84 | @$pb.TagNumber(1) 85 | set protocolVersion(CastMessage_ProtocolVersion v) { setField(1, v); } 86 | @$pb.TagNumber(1) 87 | $core.bool hasProtocolVersion() => $_has(0); 88 | @$pb.TagNumber(1) 89 | void clearProtocolVersion() => clearField(1); 90 | 91 | @$pb.TagNumber(2) 92 | $core.String get sourceId => $_getSZ(1); 93 | @$pb.TagNumber(2) 94 | set sourceId($core.String v) { $_setString(1, v); } 95 | @$pb.TagNumber(2) 96 | $core.bool hasSourceId() => $_has(1); 97 | @$pb.TagNumber(2) 98 | void clearSourceId() => clearField(2); 99 | 100 | @$pb.TagNumber(3) 101 | $core.String get destinationId => $_getSZ(2); 102 | @$pb.TagNumber(3) 103 | set destinationId($core.String v) { $_setString(2, v); } 104 | @$pb.TagNumber(3) 105 | $core.bool hasDestinationId() => $_has(2); 106 | @$pb.TagNumber(3) 107 | void clearDestinationId() => clearField(3); 108 | 109 | @$pb.TagNumber(4) 110 | $core.String get namespace => $_getSZ(3); 111 | @$pb.TagNumber(4) 112 | set namespace($core.String v) { $_setString(3, v); } 113 | @$pb.TagNumber(4) 114 | $core.bool hasNamespace() => $_has(3); 115 | @$pb.TagNumber(4) 116 | void clearNamespace() => clearField(4); 117 | 118 | @$pb.TagNumber(5) 119 | CastMessage_PayloadType get payloadType => $_getN(4); 120 | @$pb.TagNumber(5) 121 | set payloadType(CastMessage_PayloadType v) { setField(5, v); } 122 | @$pb.TagNumber(5) 123 | $core.bool hasPayloadType() => $_has(4); 124 | @$pb.TagNumber(5) 125 | void clearPayloadType() => clearField(5); 126 | 127 | @$pb.TagNumber(6) 128 | $core.String get payloadUtf8 => $_getSZ(5); 129 | @$pb.TagNumber(6) 130 | set payloadUtf8($core.String v) { $_setString(5, v); } 131 | @$pb.TagNumber(6) 132 | $core.bool hasPayloadUtf8() => $_has(5); 133 | @$pb.TagNumber(6) 134 | void clearPayloadUtf8() => clearField(6); 135 | 136 | @$pb.TagNumber(7) 137 | $core.List<$core.int> get payloadBinary => $_getN(6); 138 | @$pb.TagNumber(7) 139 | set payloadBinary($core.List<$core.int> v) { $_setBytes(6, v); } 140 | @$pb.TagNumber(7) 141 | $core.bool hasPayloadBinary() => $_has(6); 142 | @$pb.TagNumber(7) 143 | void clearPayloadBinary() => clearField(7); 144 | } 145 | 146 | class AuthChallenge extends $pb.GeneratedMessage { 147 | static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AuthChallenge', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'extensions.api.cast_channel'), createEmptyInstance: create) 148 | ..hasRequiredFields = false 149 | ; 150 | 151 | AuthChallenge._() : super(); 152 | factory AuthChallenge() => create(); 153 | factory AuthChallenge.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); 154 | factory AuthChallenge.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); 155 | @$core.Deprecated( 156 | 'Using this can add significant overhead to your binary. ' 157 | 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 158 | 'Will be removed in next major version') 159 | AuthChallenge clone() => AuthChallenge()..mergeFromMessage(this); 160 | @$core.Deprecated( 161 | 'Using this can add significant overhead to your binary. ' 162 | 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 163 | 'Will be removed in next major version') 164 | AuthChallenge copyWith(void Function(AuthChallenge) updates) => super.copyWith((message) => updates(message as AuthChallenge)) as AuthChallenge; // ignore: deprecated_member_use 165 | $pb.BuilderInfo get info_ => _i; 166 | @$core.pragma('dart2js:noInline') 167 | static AuthChallenge create() => AuthChallenge._(); 168 | AuthChallenge createEmptyInstance() => create(); 169 | static $pb.PbList createRepeated() => $pb.PbList(); 170 | @$core.pragma('dart2js:noInline') 171 | static AuthChallenge getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); 172 | static AuthChallenge? _defaultInstance; 173 | } 174 | 175 | class AuthResponse extends $pb.GeneratedMessage { 176 | static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AuthResponse', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'extensions.api.cast_channel'), createEmptyInstance: create) 177 | ..a<$core.List<$core.int>>(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'signature', $pb.PbFieldType.QY) 178 | ..a<$core.List<$core.int>>(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'clientAuthCertificate', $pb.PbFieldType.QY) 179 | ..p<$core.List<$core.int>>(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'clientCa', $pb.PbFieldType.PY) 180 | ; 181 | 182 | AuthResponse._() : super(); 183 | factory AuthResponse({ 184 | $core.List<$core.int>? signature, 185 | $core.List<$core.int>? clientAuthCertificate, 186 | $core.Iterable<$core.List<$core.int>>? clientCa, 187 | }) { 188 | final _result = create(); 189 | if (signature != null) { 190 | _result.signature = signature; 191 | } 192 | if (clientAuthCertificate != null) { 193 | _result.clientAuthCertificate = clientAuthCertificate; 194 | } 195 | if (clientCa != null) { 196 | _result.clientCa.addAll(clientCa); 197 | } 198 | return _result; 199 | } 200 | factory AuthResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); 201 | factory AuthResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); 202 | @$core.Deprecated( 203 | 'Using this can add significant overhead to your binary. ' 204 | 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 205 | 'Will be removed in next major version') 206 | AuthResponse clone() => AuthResponse()..mergeFromMessage(this); 207 | @$core.Deprecated( 208 | 'Using this can add significant overhead to your binary. ' 209 | 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 210 | 'Will be removed in next major version') 211 | AuthResponse copyWith(void Function(AuthResponse) updates) => super.copyWith((message) => updates(message as AuthResponse)) as AuthResponse; // ignore: deprecated_member_use 212 | $pb.BuilderInfo get info_ => _i; 213 | @$core.pragma('dart2js:noInline') 214 | static AuthResponse create() => AuthResponse._(); 215 | AuthResponse createEmptyInstance() => create(); 216 | static $pb.PbList createRepeated() => $pb.PbList(); 217 | @$core.pragma('dart2js:noInline') 218 | static AuthResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); 219 | static AuthResponse? _defaultInstance; 220 | 221 | @$pb.TagNumber(1) 222 | $core.List<$core.int> get signature => $_getN(0); 223 | @$pb.TagNumber(1) 224 | set signature($core.List<$core.int> v) { $_setBytes(0, v); } 225 | @$pb.TagNumber(1) 226 | $core.bool hasSignature() => $_has(0); 227 | @$pb.TagNumber(1) 228 | void clearSignature() => clearField(1); 229 | 230 | @$pb.TagNumber(2) 231 | $core.List<$core.int> get clientAuthCertificate => $_getN(1); 232 | @$pb.TagNumber(2) 233 | set clientAuthCertificate($core.List<$core.int> v) { $_setBytes(1, v); } 234 | @$pb.TagNumber(2) 235 | $core.bool hasClientAuthCertificate() => $_has(1); 236 | @$pb.TagNumber(2) 237 | void clearClientAuthCertificate() => clearField(2); 238 | 239 | @$pb.TagNumber(3) 240 | $core.List<$core.List<$core.int>> get clientCa => $_getList(2); 241 | } 242 | 243 | class AuthError extends $pb.GeneratedMessage { 244 | static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'AuthError', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'extensions.api.cast_channel'), createEmptyInstance: create) 245 | ..e(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'errorType', $pb.PbFieldType.QE, defaultOrMaker: AuthError_ErrorType.INTERNAL_ERROR, valueOf: AuthError_ErrorType.valueOf, enumValues: AuthError_ErrorType.values) 246 | ; 247 | 248 | AuthError._() : super(); 249 | factory AuthError({ 250 | AuthError_ErrorType? errorType, 251 | }) { 252 | final _result = create(); 253 | if (errorType != null) { 254 | _result.errorType = errorType; 255 | } 256 | return _result; 257 | } 258 | factory AuthError.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); 259 | factory AuthError.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); 260 | @$core.Deprecated( 261 | 'Using this can add significant overhead to your binary. ' 262 | 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 263 | 'Will be removed in next major version') 264 | AuthError clone() => AuthError()..mergeFromMessage(this); 265 | @$core.Deprecated( 266 | 'Using this can add significant overhead to your binary. ' 267 | 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 268 | 'Will be removed in next major version') 269 | AuthError copyWith(void Function(AuthError) updates) => super.copyWith((message) => updates(message as AuthError)) as AuthError; // ignore: deprecated_member_use 270 | $pb.BuilderInfo get info_ => _i; 271 | @$core.pragma('dart2js:noInline') 272 | static AuthError create() => AuthError._(); 273 | AuthError createEmptyInstance() => create(); 274 | static $pb.PbList createRepeated() => $pb.PbList(); 275 | @$core.pragma('dart2js:noInline') 276 | static AuthError getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); 277 | static AuthError? _defaultInstance; 278 | 279 | @$pb.TagNumber(1) 280 | AuthError_ErrorType get errorType => $_getN(0); 281 | @$pb.TagNumber(1) 282 | set errorType(AuthError_ErrorType v) { setField(1, v); } 283 | @$pb.TagNumber(1) 284 | $core.bool hasErrorType() => $_has(0); 285 | @$pb.TagNumber(1) 286 | void clearErrorType() => clearField(1); 287 | } 288 | 289 | class DeviceAuthMessage extends $pb.GeneratedMessage { 290 | static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'DeviceAuthMessage', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'extensions.api.cast_channel'), createEmptyInstance: create) 291 | ..aOM(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'challenge', subBuilder: AuthChallenge.create) 292 | ..aOM(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'response', subBuilder: AuthResponse.create) 293 | ..aOM(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'error', subBuilder: AuthError.create) 294 | ; 295 | 296 | DeviceAuthMessage._() : super(); 297 | factory DeviceAuthMessage({ 298 | AuthChallenge? challenge, 299 | AuthResponse? response, 300 | AuthError? error, 301 | }) { 302 | final _result = create(); 303 | if (challenge != null) { 304 | _result.challenge = challenge; 305 | } 306 | if (response != null) { 307 | _result.response = response; 308 | } 309 | if (error != null) { 310 | _result.error = error; 311 | } 312 | return _result; 313 | } 314 | factory DeviceAuthMessage.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); 315 | factory DeviceAuthMessage.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); 316 | @$core.Deprecated( 317 | 'Using this can add significant overhead to your binary. ' 318 | 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' 319 | 'Will be removed in next major version') 320 | DeviceAuthMessage clone() => DeviceAuthMessage()..mergeFromMessage(this); 321 | @$core.Deprecated( 322 | 'Using this can add significant overhead to your binary. ' 323 | 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' 324 | 'Will be removed in next major version') 325 | DeviceAuthMessage copyWith(void Function(DeviceAuthMessage) updates) => super.copyWith((message) => updates(message as DeviceAuthMessage)) as DeviceAuthMessage; // ignore: deprecated_member_use 326 | $pb.BuilderInfo get info_ => _i; 327 | @$core.pragma('dart2js:noInline') 328 | static DeviceAuthMessage create() => DeviceAuthMessage._(); 329 | DeviceAuthMessage createEmptyInstance() => create(); 330 | static $pb.PbList createRepeated() => $pb.PbList(); 331 | @$core.pragma('dart2js:noInline') 332 | static DeviceAuthMessage getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); 333 | static DeviceAuthMessage? _defaultInstance; 334 | 335 | @$pb.TagNumber(1) 336 | AuthChallenge get challenge => $_getN(0); 337 | @$pb.TagNumber(1) 338 | set challenge(AuthChallenge v) { setField(1, v); } 339 | @$pb.TagNumber(1) 340 | $core.bool hasChallenge() => $_has(0); 341 | @$pb.TagNumber(1) 342 | void clearChallenge() => clearField(1); 343 | @$pb.TagNumber(1) 344 | AuthChallenge ensureChallenge() => $_ensure(0); 345 | 346 | @$pb.TagNumber(2) 347 | AuthResponse get response => $_getN(1); 348 | @$pb.TagNumber(2) 349 | set response(AuthResponse v) { setField(2, v); } 350 | @$pb.TagNumber(2) 351 | $core.bool hasResponse() => $_has(1); 352 | @$pb.TagNumber(2) 353 | void clearResponse() => clearField(2); 354 | @$pb.TagNumber(2) 355 | AuthResponse ensureResponse() => $_ensure(1); 356 | 357 | @$pb.TagNumber(3) 358 | AuthError get error => $_getN(2); 359 | @$pb.TagNumber(3) 360 | set error(AuthError v) { setField(3, v); } 361 | @$pb.TagNumber(3) 362 | $core.bool hasError() => $_has(2); 363 | @$pb.TagNumber(3) 364 | void clearError() => clearField(3); 365 | @$pb.TagNumber(3) 366 | AuthError ensureError() => $_ensure(2); 367 | } 368 | 369 | -------------------------------------------------------------------------------- /lib/cast_channel/cast_channel.pbenum.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: cast_channel.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields 7 | 8 | // ignore_for_file: UNDEFINED_SHOWN_NAME 9 | import 'dart:core' as $core; 10 | import 'package:protobuf/protobuf.dart' as $pb; 11 | 12 | class CastMessage_ProtocolVersion extends $pb.ProtobufEnum { 13 | static const CastMessage_ProtocolVersion CASTV2_1_0 = CastMessage_ProtocolVersion._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'CASTV2_1_0'); 14 | 15 | static const $core.List values = [ 16 | CASTV2_1_0, 17 | ]; 18 | 19 | static final $core.Map<$core.int, CastMessage_ProtocolVersion> _byValue = $pb.ProtobufEnum.initByValue(values); 20 | static CastMessage_ProtocolVersion? valueOf($core.int value) => _byValue[value]; 21 | 22 | const CastMessage_ProtocolVersion._($core.int v, $core.String n) : super(v, n); 23 | } 24 | 25 | class CastMessage_PayloadType extends $pb.ProtobufEnum { 26 | static const CastMessage_PayloadType STRING = CastMessage_PayloadType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'STRING'); 27 | static const CastMessage_PayloadType BINARY = CastMessage_PayloadType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'BINARY'); 28 | 29 | static const $core.List values = [ 30 | STRING, 31 | BINARY, 32 | ]; 33 | 34 | static final $core.Map<$core.int, CastMessage_PayloadType> _byValue = $pb.ProtobufEnum.initByValue(values); 35 | static CastMessage_PayloadType? valueOf($core.int value) => _byValue[value]; 36 | 37 | const CastMessage_PayloadType._($core.int v, $core.String n) : super(v, n); 38 | } 39 | 40 | class AuthError_ErrorType extends $pb.ProtobufEnum { 41 | static const AuthError_ErrorType INTERNAL_ERROR = AuthError_ErrorType._(0, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'INTERNAL_ERROR'); 42 | static const AuthError_ErrorType NO_TLS = AuthError_ErrorType._(1, const $core.bool.fromEnvironment('protobuf.omit_enum_names') ? '' : 'NO_TLS'); 43 | 44 | static const $core.List values = [ 45 | INTERNAL_ERROR, 46 | NO_TLS, 47 | ]; 48 | 49 | static final $core.Map<$core.int, AuthError_ErrorType> _byValue = $pb.ProtobufEnum.initByValue(values); 50 | static AuthError_ErrorType? valueOf($core.int value) => _byValue[value]; 51 | 52 | const AuthError_ErrorType._($core.int v, $core.String n) : super(v, n); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /lib/cast_channel/cast_channel.pbjson.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: cast_channel.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package 7 | 8 | import 'dart:core' as $core; 9 | import 'dart:convert' as $convert; 10 | import 'dart:typed_data' as $typed_data; 11 | @$core.Deprecated('Use castMessageDescriptor instead') 12 | const CastMessage$json = const { 13 | '1': 'CastMessage', 14 | '2': const [ 15 | const {'1': 'protocol_version', '3': 1, '4': 2, '5': 14, '6': '.extensions.api.cast_channel.CastMessage.ProtocolVersion', '10': 'protocolVersion'}, 16 | const {'1': 'source_id', '3': 2, '4': 2, '5': 9, '10': 'sourceId'}, 17 | const {'1': 'destination_id', '3': 3, '4': 2, '5': 9, '10': 'destinationId'}, 18 | const {'1': 'namespace', '3': 4, '4': 2, '5': 9, '10': 'namespace'}, 19 | const {'1': 'payload_type', '3': 5, '4': 2, '5': 14, '6': '.extensions.api.cast_channel.CastMessage.PayloadType', '10': 'payloadType'}, 20 | const {'1': 'payload_utf8', '3': 6, '4': 1, '5': 9, '10': 'payloadUtf8'}, 21 | const {'1': 'payload_binary', '3': 7, '4': 1, '5': 12, '10': 'payloadBinary'}, 22 | ], 23 | '4': const [CastMessage_ProtocolVersion$json, CastMessage_PayloadType$json], 24 | }; 25 | 26 | @$core.Deprecated('Use castMessageDescriptor instead') 27 | const CastMessage_ProtocolVersion$json = const { 28 | '1': 'ProtocolVersion', 29 | '2': const [ 30 | const {'1': 'CASTV2_1_0', '2': 0}, 31 | ], 32 | }; 33 | 34 | @$core.Deprecated('Use castMessageDescriptor instead') 35 | const CastMessage_PayloadType$json = const { 36 | '1': 'PayloadType', 37 | '2': const [ 38 | const {'1': 'STRING', '2': 0}, 39 | const {'1': 'BINARY', '2': 1}, 40 | ], 41 | }; 42 | 43 | /// Descriptor for `CastMessage`. Decode as a `google.protobuf.DescriptorProto`. 44 | final $typed_data.Uint8List castMessageDescriptor = $convert.base64Decode('CgtDYXN0TWVzc2FnZRJjChBwcm90b2NvbF92ZXJzaW9uGAEgAigOMjguZXh0ZW5zaW9ucy5hcGkuY2FzdF9jaGFubmVsLkNhc3RNZXNzYWdlLlByb3RvY29sVmVyc2lvblIPcHJvdG9jb2xWZXJzaW9uEhsKCXNvdXJjZV9pZBgCIAIoCVIIc291cmNlSWQSJQoOZGVzdGluYXRpb25faWQYAyACKAlSDWRlc3RpbmF0aW9uSWQSHAoJbmFtZXNwYWNlGAQgAigJUgluYW1lc3BhY2USVwoMcGF5bG9hZF90eXBlGAUgAigOMjQuZXh0ZW5zaW9ucy5hcGkuY2FzdF9jaGFubmVsLkNhc3RNZXNzYWdlLlBheWxvYWRUeXBlUgtwYXlsb2FkVHlwZRIhCgxwYXlsb2FkX3V0ZjgYBiABKAlSC3BheWxvYWRVdGY4EiUKDnBheWxvYWRfYmluYXJ5GAcgASgMUg1wYXlsb2FkQmluYXJ5IiEKD1Byb3RvY29sVmVyc2lvbhIOCgpDQVNUVjJfMV8wEAAiJQoLUGF5bG9hZFR5cGUSCgoGU1RSSU5HEAASCgoGQklOQVJZEAE='); 45 | @$core.Deprecated('Use authChallengeDescriptor instead') 46 | const AuthChallenge$json = const { 47 | '1': 'AuthChallenge', 48 | }; 49 | 50 | /// Descriptor for `AuthChallenge`. Decode as a `google.protobuf.DescriptorProto`. 51 | final $typed_data.Uint8List authChallengeDescriptor = $convert.base64Decode('Cg1BdXRoQ2hhbGxlbmdl'); 52 | @$core.Deprecated('Use authResponseDescriptor instead') 53 | const AuthResponse$json = const { 54 | '1': 'AuthResponse', 55 | '2': const [ 56 | const {'1': 'signature', '3': 1, '4': 2, '5': 12, '10': 'signature'}, 57 | const {'1': 'client_auth_certificate', '3': 2, '4': 2, '5': 12, '10': 'clientAuthCertificate'}, 58 | const {'1': 'client_ca', '3': 3, '4': 3, '5': 12, '10': 'clientCa'}, 59 | ], 60 | }; 61 | 62 | /// Descriptor for `AuthResponse`. Decode as a `google.protobuf.DescriptorProto`. 63 | final $typed_data.Uint8List authResponseDescriptor = $convert.base64Decode('CgxBdXRoUmVzcG9uc2USHAoJc2lnbmF0dXJlGAEgAigMUglzaWduYXR1cmUSNgoXY2xpZW50X2F1dGhfY2VydGlmaWNhdGUYAiACKAxSFWNsaWVudEF1dGhDZXJ0aWZpY2F0ZRIbCgljbGllbnRfY2EYAyADKAxSCGNsaWVudENh'); 64 | @$core.Deprecated('Use authErrorDescriptor instead') 65 | const AuthError$json = const { 66 | '1': 'AuthError', 67 | '2': const [ 68 | const {'1': 'error_type', '3': 1, '4': 2, '5': 14, '6': '.extensions.api.cast_channel.AuthError.ErrorType', '10': 'errorType'}, 69 | ], 70 | '4': const [AuthError_ErrorType$json], 71 | }; 72 | 73 | @$core.Deprecated('Use authErrorDescriptor instead') 74 | const AuthError_ErrorType$json = const { 75 | '1': 'ErrorType', 76 | '2': const [ 77 | const {'1': 'INTERNAL_ERROR', '2': 0}, 78 | const {'1': 'NO_TLS', '2': 1}, 79 | ], 80 | }; 81 | 82 | /// Descriptor for `AuthError`. Decode as a `google.protobuf.DescriptorProto`. 83 | final $typed_data.Uint8List authErrorDescriptor = $convert.base64Decode('CglBdXRoRXJyb3ISTwoKZXJyb3JfdHlwZRgBIAIoDjIwLmV4dGVuc2lvbnMuYXBpLmNhc3RfY2hhbm5lbC5BdXRoRXJyb3IuRXJyb3JUeXBlUgllcnJvclR5cGUiKwoJRXJyb3JUeXBlEhIKDklOVEVSTkFMX0VSUk9SEAASCgoGTk9fVExTEAE='); 84 | @$core.Deprecated('Use deviceAuthMessageDescriptor instead') 85 | const DeviceAuthMessage$json = const { 86 | '1': 'DeviceAuthMessage', 87 | '2': const [ 88 | const {'1': 'challenge', '3': 1, '4': 1, '5': 11, '6': '.extensions.api.cast_channel.AuthChallenge', '10': 'challenge'}, 89 | const {'1': 'response', '3': 2, '4': 1, '5': 11, '6': '.extensions.api.cast_channel.AuthResponse', '10': 'response'}, 90 | const {'1': 'error', '3': 3, '4': 1, '5': 11, '6': '.extensions.api.cast_channel.AuthError', '10': 'error'}, 91 | ], 92 | }; 93 | 94 | /// Descriptor for `DeviceAuthMessage`. Decode as a `google.protobuf.DescriptorProto`. 95 | final $typed_data.Uint8List deviceAuthMessageDescriptor = $convert.base64Decode('ChFEZXZpY2VBdXRoTWVzc2FnZRJICgljaGFsbGVuZ2UYASABKAsyKi5leHRlbnNpb25zLmFwaS5jYXN0X2NoYW5uZWwuQXV0aENoYWxsZW5nZVIJY2hhbGxlbmdlEkUKCHJlc3BvbnNlGAIgASgLMikuZXh0ZW5zaW9ucy5hcGkuY2FzdF9jaGFubmVsLkF1dGhSZXNwb25zZVIIcmVzcG9uc2USPAoFZXJyb3IYAyABKAsyJi5leHRlbnNpb25zLmFwaS5jYXN0X2NoYW5uZWwuQXV0aEVycm9yUgVlcnJvcg=='); 96 | -------------------------------------------------------------------------------- /lib/cast_channel/cast_channel.pbserver.dart: -------------------------------------------------------------------------------- 1 | /// 2 | // Generated code. Do not modify. 3 | // source: cast_channel.proto 4 | // 5 | // @dart = 2.12 6 | // ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields,deprecated_member_use_from_same_package 7 | 8 | export 'cast_channel.pb.dart'; 9 | 10 | -------------------------------------------------------------------------------- /lib/cast_channel/cast_channel.proto: -------------------------------------------------------------------------------- 1 | // Source https://github.com/terrabythia/dart_chromecast/blob/master/lib/proto/cast_channel.proto 2 | // Used to generate cast_channel*.dart 3 | 4 | // Copyright 2013 The Chromium Authors. All rights reserved. 5 | // Use of this source code is governed by a BSD-style license that can be 6 | // found in the LICENSE file. 7 | 8 | syntax = "proto2"; 9 | 10 | option optimize_for = LITE_RUNTIME; 11 | 12 | package extensions.api.cast_channel; 13 | 14 | message CastMessage { 15 | // Always pass a version of the protocol for future compatibility 16 | // requirements. 17 | enum ProtocolVersion { 18 | CASTV2_1_0 = 0; 19 | } 20 | required ProtocolVersion protocol_version = 1; 21 | 22 | // source and destination ids identify the origin and destination of the 23 | // message. They are used to route messages between endpoints that share a 24 | // device-to-device channel. 25 | // 26 | // For messages between applications: 27 | // - The sender application id is a unique identifier generated on behalf of 28 | // the sender application. 29 | // - The receiver id is always the the session id for the application. 30 | // 31 | // For messages to or from the sender or receiver platform, the special ids 32 | // 'sender-0' and 'receiver-0' can be used. 33 | // 34 | // For messages intended for all endpoints using a given channel, the 35 | // wildcard destination_id '*' can be used. 36 | required string source_id = 2; 37 | required string destination_id = 3; 38 | 39 | // This is the core multiplexing key. All messages are sent on a namespace 40 | // and endpoints sharing a channel listen on one or more namespaces. The 41 | // namespace defines the protocol and semantics of the message. 42 | required string namespace = 4; 43 | 44 | // Encoding and payload info follows. 45 | 46 | // What type of data do we have in this message. 47 | enum PayloadType { 48 | STRING = 0; 49 | BINARY = 1; 50 | } 51 | required PayloadType payload_type = 5; 52 | 53 | // Depending on payload_type, exactly one of the following optional fields 54 | // will always be set. 55 | optional string payload_utf8 = 6; 56 | optional bytes payload_binary = 7; 57 | } 58 | 59 | // Messages for authentication protocol between a sender and a receiver. 60 | message AuthChallenge { 61 | } 62 | 63 | message AuthResponse { 64 | required bytes signature = 1; 65 | required bytes client_auth_certificate = 2; 66 | repeated bytes client_ca = 3; 67 | } 68 | 69 | message AuthError { 70 | enum ErrorType { 71 | INTERNAL_ERROR = 0; 72 | NO_TLS = 1; // The underlying connection is not TLS 73 | } 74 | required ErrorType error_type = 1; 75 | } 76 | 77 | message DeviceAuthMessage { 78 | // Request fields 79 | optional AuthChallenge challenge = 1; 80 | // Response fields 81 | optional AuthResponse response = 2; 82 | optional AuthError error = 3; 83 | } -------------------------------------------------------------------------------- /lib/device.dart: -------------------------------------------------------------------------------- 1 | class CastDevice { 2 | /// unique across network 3 | final String serviceName; 4 | 5 | /// friendly name 6 | final String name; 7 | final String host; 8 | final int port; 9 | 10 | final Map extras; 11 | 12 | const CastDevice({ 13 | required this.serviceName, 14 | required this.name, 15 | required this.host, 16 | required this.port, 17 | this.extras = const {}, 18 | }); 19 | 20 | @override 21 | bool operator ==(Object other) => identical(this, other) || (other is CastDevice && runtimeType == other.runtimeType && other.serviceName == serviceName); 22 | 23 | @override 24 | int get hashCode => serviceName.hashCode; 25 | } 26 | -------------------------------------------------------------------------------- /lib/discovery_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:bonsoir/bonsoir.dart'; 4 | 5 | import 'device.dart'; 6 | 7 | const _domain = '_googlecast._tcp'; 8 | 9 | class CastDiscoveryService { 10 | static final CastDiscoveryService _instance = CastDiscoveryService._(); 11 | CastDiscoveryService._(); 12 | 13 | factory CastDiscoveryService() { 14 | return _instance; 15 | } 16 | 17 | Future> search({Duration timeout = const Duration(seconds: 5)}) async { 18 | final results = []; 19 | 20 | final discovery = BonsoirDiscovery(type: _domain); 21 | await discovery.ready; 22 | 23 | discovery.eventStream!.listen((event) { 24 | if (event.type == BonsoirDiscoveryEventType.discoveryServiceFound) { 25 | event.service?.resolve(discovery.serviceResolver); 26 | } else if (event.type == BonsoirDiscoveryEventType.discoveryServiceResolved) { 27 | if (event.service == null || event.service?.attributes == null) { 28 | return; 29 | } 30 | 31 | final port = event.service?.port; 32 | final host = event.service?.toJson()['service.ip'] ?? event.service?.toJson()['service.host']; 33 | 34 | String name = [ 35 | event.service?.attributes?['md'], 36 | event.service?.attributes?['fn'], 37 | ].whereType().join(' - '); 38 | if (name.isEmpty) { 39 | name = event.service!.name; 40 | } 41 | 42 | if (port == null || host == null) { 43 | return; 44 | } 45 | 46 | results.add( 47 | CastDevice( 48 | serviceName: event.service!.name, 49 | name: name, 50 | port: port, 51 | host: host, 52 | extras: event.service!.attributes ?? {}, 53 | ), 54 | ); 55 | } 56 | }, onError: (error) { 57 | print('[CastDiscoveryService] error ${error.runtimeType} - $error'); 58 | }); 59 | 60 | await discovery.start(); 61 | await Future.delayed(timeout); 62 | await discovery.stop(); 63 | 64 | return results.toSet().toList(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lib/session.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'device.dart'; 4 | import 'socket.dart'; 5 | 6 | enum CastSessionState { 7 | connecting, 8 | connected, 9 | closed, 10 | } 11 | 12 | class CastSession { 13 | static const kNamespaceConnection = 'urn:x-cast:com.google.cast.tp.connection'; 14 | static const kNamespaceHeartbeat = 'urn:x-cast:com.google.cast.tp.heartbeat'; 15 | static const kNamespaceReceiver = 'urn:x-cast:com.google.cast.receiver'; 16 | static const kNamespaceDeviceauth = 'urn:x-cast:com.google.cast.tp.deviceauth'; 17 | static const kNamespaceMedia = 'urn:x-cast:com.google.cast.media'; 18 | 19 | final String sessionId; 20 | CastSocket get socket => _socket; 21 | CastSessionState get state => _state; 22 | 23 | Stream get stateStream => _stateController.stream; 24 | Stream> get messageStream => _messageController.stream; 25 | 26 | final CastSocket _socket; 27 | CastSessionState _state = CastSessionState.connecting; 28 | String? _transportId; 29 | 30 | final _stateController = StreamController.broadcast(); 31 | final _messageController = StreamController>.broadcast(); 32 | 33 | CastSession._(this.sessionId, this._socket); 34 | 35 | static Future connect(String sessionId, CastDevice device, [Duration? timeout]) async { 36 | final _socket = await CastSocket.connect( 37 | device.host, 38 | device.port, 39 | timeout, 40 | ); 41 | 42 | final session = CastSession._(sessionId, _socket); 43 | 44 | session._startListening(); 45 | 46 | session.sendMessage(kNamespaceConnection, { 47 | 'type': 'CONNECT', 48 | }); 49 | 50 | return session; 51 | } 52 | 53 | Future close() async { 54 | if (!_messageController.isClosed) { 55 | sendMessage(kNamespaceConnection, { 56 | 'type': 'CLOSE', 57 | }); 58 | try { 59 | await _socket.flush(); 60 | } catch (_error) {} 61 | } 62 | 63 | return _socket.close(); 64 | } 65 | 66 | void _startListening() { 67 | _socket.stream.listen((message) { 68 | // happen 69 | if (_messageController.isClosed) { 70 | return; 71 | } 72 | 73 | if (message.namespace == kNamespaceHeartbeat && message.payload['type'] == 'PING') { 74 | sendMessage(kNamespaceHeartbeat, { 75 | 'type': 'PONG', 76 | }); 77 | } else if (message.namespace == kNamespaceConnection && message.payload['type'] == 'CLOSE') { 78 | close(); 79 | } else if (message.namespace == kNamespaceReceiver && message.payload['type'] == 'RECEIVER_STATUS') { 80 | _handleReceiverStatus(message.payload); 81 | _messageController.add(message.payload); 82 | } else { 83 | _messageController.add(message.payload); 84 | } 85 | }, onError: (error) { 86 | _messageController.addError(error); 87 | }, onDone: () { 88 | _messageController.close(); 89 | 90 | _state = CastSessionState.closed; 91 | _stateController.add(_state); 92 | _stateController.close(); 93 | }, cancelOnError: false); 94 | } 95 | 96 | void _handleReceiverStatus(Map payload) { 97 | if (_transportId != null) { 98 | return; 99 | } 100 | 101 | if (payload['status']?.containsKey('applications') == true) { 102 | _transportId = payload['status']['applications'][0]['transportId']; 103 | 104 | // reconnect with new _transportId 105 | sendMessage(kNamespaceConnection, { 106 | 'type': 'CONNECT', 107 | }); 108 | 109 | _state = CastSessionState.connected; 110 | _stateController.add(_state); 111 | } 112 | } 113 | 114 | void sendMessage(String namespace, Map payload) { 115 | _socket.sendMessage( 116 | namespace, 117 | sessionId, 118 | _transportId ?? 'receiver-0', 119 | payload, 120 | ); 121 | } 122 | 123 | Future flush() { 124 | return _socket.flush(); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /lib/session_manager.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | 3 | import 'package:cast/device.dart'; 4 | import 'package:cast/session.dart'; 5 | 6 | class CastSessionManager { 7 | static final CastSessionManager _instance = CastSessionManager._(); 8 | CastSessionManager._(); 9 | 10 | factory CastSessionManager() { 11 | return _instance; 12 | } 13 | 14 | final sessions = []; 15 | 16 | Future startSession(CastDevice device, [Duration? timeout]) async { 17 | String sessionId = 'client-${Random().nextInt(99999)}'; 18 | 19 | while (sessions.contains((x) => x.sessionId == sessionId)) { 20 | sessionId = 'client-${Random().nextInt(99999)}'; 21 | } 22 | 23 | final session = await CastSession.connect(sessionId, device, timeout); 24 | 25 | sessions.add(session); 26 | 27 | return session; 28 | } 29 | 30 | Future endSession(String sessionId) async { 31 | // cast required to avoid adding `collection` dependency 32 | // https://github.com/dart-lang/sdk/issues/42947 33 | final session = sessions.cast().firstWhere((x) => x?.sessionId == sessionId, orElse: () => null); 34 | if (session == null) { 35 | return; 36 | } 37 | 38 | sessions.removeWhere((x) => x.sessionId == sessionId); 39 | return session.close(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/socket.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | import 'dart:io'; 4 | import 'dart:typed_data'; 5 | 6 | import 'cast_channel/cast_channel.pb.dart'; 7 | 8 | class CastSocketMessage { 9 | final String namespace; 10 | final Map payload; 11 | 12 | const CastSocketMessage(this.namespace, this.payload); 13 | } 14 | 15 | class CastSocket { 16 | Stream get stream => _controller.stream; 17 | 18 | final SecureSocket _socket; 19 | int _requestId = 0; 20 | final _controller = StreamController.broadcast(); 21 | 22 | CastSocket._(this._socket); 23 | 24 | static Future connect(String host, int port, [Duration? timeout]) async { 25 | timeout ??= Duration(seconds: 10); 26 | 27 | final _socket = await SecureSocket.connect( 28 | host, 29 | port, 30 | onBadCertificate: (X509Certificate certificate) => true, // chromecast use self-signed certificate 31 | timeout: timeout, 32 | ); 33 | 34 | final socket = CastSocket._(_socket); 35 | socket._startListening(); 36 | 37 | return socket; 38 | } 39 | 40 | void _startListening() { 41 | _socket.listen((event) { 42 | // happen 43 | if (_controller.isClosed) { 44 | return; 45 | } 46 | 47 | List slice = event.getRange(4, event.length).toList(); 48 | CastMessage message = CastMessage.fromBuffer(slice); 49 | 50 | Map payload = jsonDecode(message.payloadUtf8); 51 | _controller.add(CastSocketMessage(message.namespace, payload)); 52 | }, onError: (error) { 53 | _controller.addError(error); 54 | }, onDone: () { 55 | _controller.close(); 56 | }, cancelOnError: false); 57 | } 58 | 59 | Future close() { 60 | return _socket.close(); 61 | } 62 | 63 | void sendMessage(String namespace, String sourceId, String destinationId, Map payload) { 64 | if (payload['requestId'] == null) { 65 | payload['requestId'] = _requestId; 66 | _requestId += 1; 67 | } 68 | 69 | CastMessage castMessage = CastMessage(); 70 | castMessage.protocolVersion = CastMessage_ProtocolVersion.CASTV2_1_0; 71 | castMessage.sourceId = sourceId; 72 | castMessage.destinationId = destinationId; 73 | castMessage.namespace = namespace; 74 | castMessage.payloadType = CastMessage_PayloadType.STRING; 75 | castMessage.payloadUtf8 = jsonEncode(payload); 76 | 77 | Uint8List bytes = castMessage.writeToBuffer(); 78 | Uint32List headers = Uint32List.fromList(_writeUInt32BE(List.filled(4, 0), bytes.lengthInBytes)); 79 | Uint32List data = Uint32List.fromList(headers.toList()..addAll(bytes.toList())); 80 | 81 | _socket.add(data); 82 | } 83 | 84 | Future flush() { 85 | return _socket.flush(); 86 | } 87 | 88 | static final Function _writeUInt32BE = (target, value) { 89 | target[0] = ((value & 0xffffffff) >> 24); 90 | target[1] = ((value & 0xffffffff) >> 16); 91 | target[2] = ((value & 0xffffffff) >> 8); 92 | target[3] = ((value & 0xffffffff) & 0xff); 93 | return target; 94 | }; 95 | } 96 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | args: 5 | dependency: transitive 6 | description: 7 | name: args 8 | sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.4.2" 12 | bonsoir: 13 | dependency: "direct main" 14 | description: 15 | name: bonsoir 16 | sha256: "800d77c0581fff06cc43ef2b7723dfe5ee9b899ab0fdf80fb1c7b8829a5deb5c" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "3.0.0+1" 20 | bonsoir_android: 21 | dependency: transitive 22 | description: 23 | name: bonsoir_android 24 | sha256: "7207c36fd7e0f3c7c2d8cf353f02bd640d96e2387d575837f8ac051c9cbf4aa7" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "3.0.0+1" 28 | bonsoir_darwin: 29 | dependency: transitive 30 | description: 31 | name: bonsoir_darwin 32 | sha256: "7211042c85da2d6efa80c0976bbd9568f2b63624097779847548ed4530675ade" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "3.0.0" 36 | bonsoir_platform_interface: 37 | dependency: transitive 38 | description: 39 | name: bonsoir_platform_interface 40 | sha256: "64d57cd52bd477b4891e9b9d419e6408da171ed9e0efc8aa716e7e343d5d93ad" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "3.0.0" 44 | characters: 45 | dependency: transitive 46 | description: 47 | name: characters 48 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.3.0" 52 | collection: 53 | dependency: transitive 54 | description: 55 | name: collection 56 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "1.18.0" 60 | connectivity_plus: 61 | dependency: transitive 62 | description: 63 | name: connectivity_plus 64 | sha256: "77a180d6938f78ca7d2382d2240eb626c0f6a735d0bfdce227d8ffb80f95c48b" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "4.0.2" 68 | connectivity_plus_platform_interface: 69 | dependency: transitive 70 | description: 71 | name: connectivity_plus_platform_interface 72 | sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "1.2.4" 76 | dbus: 77 | dependency: transitive 78 | description: 79 | name: dbus 80 | sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "0.7.8" 84 | ffi: 85 | dependency: transitive 86 | description: 87 | name: ffi 88 | sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "2.1.0" 92 | fixnum: 93 | dependency: transitive 94 | description: 95 | name: fixnum 96 | sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "1.1.0" 100 | flutter: 101 | dependency: "direct main" 102 | description: flutter 103 | source: sdk 104 | version: "0.0.0" 105 | flutter_web_plugins: 106 | dependency: transitive 107 | description: flutter 108 | source: sdk 109 | version: "0.0.0" 110 | js: 111 | dependency: transitive 112 | description: 113 | name: js 114 | sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 115 | url: "https://pub.dev" 116 | source: hosted 117 | version: "0.6.7" 118 | material_color_utilities: 119 | dependency: transitive 120 | description: 121 | name: material_color_utilities 122 | sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" 123 | url: "https://pub.dev" 124 | source: hosted 125 | version: "0.8.0" 126 | meta: 127 | dependency: transitive 128 | description: 129 | name: meta 130 | sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" 131 | url: "https://pub.dev" 132 | source: hosted 133 | version: "1.12.0" 134 | nm: 135 | dependency: transitive 136 | description: 137 | name: nm 138 | sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" 139 | url: "https://pub.dev" 140 | source: hosted 141 | version: "0.5.0" 142 | path: 143 | dependency: transitive 144 | description: 145 | name: path 146 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" 147 | url: "https://pub.dev" 148 | source: hosted 149 | version: "1.8.3" 150 | pedantic: 151 | dependency: "direct dev" 152 | description: 153 | name: pedantic 154 | sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" 155 | url: "https://pub.dev" 156 | source: hosted 157 | version: "1.11.1" 158 | petitparser: 159 | dependency: transitive 160 | description: 161 | name: petitparser 162 | sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 163 | url: "https://pub.dev" 164 | source: hosted 165 | version: "5.4.0" 166 | plugin_platform_interface: 167 | dependency: transitive 168 | description: 169 | name: plugin_platform_interface 170 | sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d 171 | url: "https://pub.dev" 172 | source: hosted 173 | version: "2.1.6" 174 | protobuf: 175 | dependency: "direct main" 176 | description: 177 | name: protobuf 178 | sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" 179 | url: "https://pub.dev" 180 | source: hosted 181 | version: "3.1.0" 182 | protoc_plugin: 183 | dependency: "direct dev" 184 | description: 185 | name: protoc_plugin 186 | sha256: fb0554851c9eca30bd18405fbbfe81e39166d4a2f0e5b770606fd69da3da0b2f 187 | url: "https://pub.dev" 188 | source: hosted 189 | version: "21.1.2" 190 | sky_engine: 191 | dependency: transitive 192 | description: flutter 193 | source: sdk 194 | version: "0.0.99" 195 | vector_math: 196 | dependency: transitive 197 | description: 198 | name: vector_math 199 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 200 | url: "https://pub.dev" 201 | source: hosted 202 | version: "2.1.4" 203 | xml: 204 | dependency: transitive 205 | description: 206 | name: xml 207 | sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" 208 | url: "https://pub.dev" 209 | source: hosted 210 | version: "6.3.0" 211 | sdks: 212 | dart: ">=3.3.0-0 <4.0.0" 213 | flutter: ">=3.7.0" 214 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: cast 2 | description: Dart package to discover and connect with Chromecast devices 3 | version: 2.1.0 4 | homepage: https://github.com/johnvuko/flutter_cast 5 | 6 | environment: 7 | sdk: '>=3.1.3 <4.0.0' 8 | 9 | dependencies: 10 | bonsoir: '>=3.0.0' 11 | flutter: 12 | sdk: flutter 13 | protobuf: ^3.1.0 14 | 15 | dev_dependencies: 16 | pedantic: ^1.11.1 17 | protoc_plugin: ^21.1.2 18 | --------------------------------------------------------------------------------