├── analysis_options.yaml ├── screenshot-1.png ├── screenshot-2.png ├── lib ├── src │ ├── utils │ │ └── settings.dart │ └── pages │ │ ├── index.dart │ │ └── call.dart └── main.dart ├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ ├── Flutter.podspec │ └── AppFrameworkInfo.plist ├── Runner │ ├── AppDelegate.h │ ├── Runner-Bridging-Header.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── 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-1024x1024@1x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── File.swift │ ├── main.m │ ├── AppDelegate.m │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Podfile ├── android ├── gradle.properties ├── app │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── 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 │ │ │ │ └── styles.xml │ │ │ └── drawable │ │ │ │ └── launch_background.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── agoraflutterquickstart │ │ │ │ └── MainActivity.java │ │ │ └── AndroidManifest.xml │ └── build.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .project ├── settings.gradle └── build.gradle ├── LICENSE ├── test └── widget_test.dart ├── pubspec.yaml ├── README.zh.md ├── .gitignore └── README.md /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:pedantic/analysis_options.yaml 2 | -------------------------------------------------------------------------------- /screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/screenshot-1.png -------------------------------------------------------------------------------- /screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/screenshot-2.png -------------------------------------------------------------------------------- /lib/src/utils/settings.dart: -------------------------------------------------------------------------------- 1 | /// Define App ID and Token 2 | const appId = 'Your_App_ID'; 3 | const token = 'Your_Token'; 4 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/File.swift: -------------------------------------------------------------------------------- 1 | // 2 | // File.swift 3 | // Runner 4 | // 5 | // Created by LXH on 2020/7/21. 6 | // Copyright © 2020 The Chromium Authors. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AgoraIO-Community/Agora-Flutter-Quickstart/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/example/agoraflutterquickstart/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.agoraflutterquickstart; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import './src/pages/index.dart'; 4 | 5 | void main() => runApp(MyApp()); 6 | 7 | class MyApp extends StatelessWidget { 8 | // This widget is the root of your application. 9 | @override 10 | Widget build(BuildContext context) { 11 | return MaterialApp( 12 | title: 'Flutter Demo', 13 | theme: ThemeData( 14 | primarySwatch: Colors.blue, 15 | ), 16 | home: IndexPage(), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | android 4 | Project android created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.3.1' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /ios/Flutter/Flutter.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: This podspec is NOT to be published. It is only used as a local source! 3 | # This is a generated file; do not edit or check into version control. 4 | # 5 | 6 | Pod::Spec.new do |s| 7 | s.name = 'Flutter' 8 | s.version = '1.0.0' 9 | s.summary = 'High-performance, high-fidelity mobile apps.' 10 | s.homepage = 'https://flutter.io' 11 | s.license = { :type => 'MIT' } 12 | s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } 13 | s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } 14 | s.ios.deployment_target = '9.0' 15 | # Framework linking is handled by Flutter tooling, not CocoaPods. 16 | # Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs. 17 | s.vendored_frameworks = 'path/to/nothing' 18 | end 19 | -------------------------------------------------------------------------------- /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 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Qianze Zhang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:agora_flutter_quickstart/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.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 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | target.build_configurations.each do |config| 41 | config.build_settings['ONLY_ACTIVE_ARCH'] = 'YES' 42 | config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "i386" 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | agora_flutter_quickstart 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | NSCameraUsageDescription 28 | The app tries to use your camera 29 | NSMicrophoneUsageDescription 30 | The app tries to use your microphone 31 | UILaunchStoryboardName 32 | LaunchScreen 33 | UIMainStoryboardFile 34 | Main 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | UIViewControllerBasedStatusBarAppearance 49 | 50 | io.flutter.embedded_views_preview 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 15 | 19 | 26 | 30 | 33 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.example.agoraflutterquickstart" 37 | minSdkVersion 16 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 42 | 43 | // Use code below for production build 44 | // For debug mode you need to comment above lines of code 45 | // Issue with 'libflutter.so' 46 | ndk { 47 | abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86' 48 | } 49 | 50 | multiDexEnabled true 51 | } 52 | 53 | buildTypes { 54 | release { 55 | // TODO: Add your own signing config for the release build. 56 | // Signing with the debug keys for now, so `flutter run --release` works. 57 | signingConfig signingConfigs.debug 58 | } 59 | } 60 | } 61 | 62 | flutter { 63 | source '../..' 64 | } 65 | 66 | dependencies { 67 | testImplementation 'junit:junit:4.12' 68 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 69 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' 70 | 71 | implementation 'com.android.support:multidex:1.0.3' 72 | } 73 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: agora_flutter_quickstart 2 | description: A new Flutter project. 3 | 4 | # The following defines the version and build number for your application. 5 | # A version number is three numbers separated by dots, like 1.2.43 6 | # followed by an optional build number separated by a +. 7 | # Both the version and the builder number may be overridden in flutter 8 | # build by specifying --build-name and --build-number, respectively. 9 | # Read more about versioning at semver.org. 10 | version: 1.0.0+1 11 | 12 | environment: 13 | sdk: '>=2.12.0 <3.0.0' 14 | 15 | dependencies: 16 | flutter: 17 | sdk: flutter 18 | 19 | # The following adds the Cupertino Icons font to your application. 20 | # Use with the CupertinoIcons class for iOS style icons. 21 | cupertino_icons: ^1.0.3 22 | agora_rtc_engine: ^5.3.0 23 | permission_handler: ^8.1.1 24 | 25 | dev_dependencies: 26 | flutter_test: 27 | sdk: flutter 28 | 29 | # For information on the generic Dart part of this file, see the 30 | # following page: https://www.dartlang.org/tools/pub/pubspec 31 | 32 | # The following section is specific to Flutter. 33 | flutter: 34 | # The following line ensures that the Material Icons font is 35 | # included with your application, so that you can use the icons in 36 | # the material Icons class. 37 | uses-material-design: true 38 | # To add assets to your application, add an assets section, like this: 39 | # assets: 40 | # - images/a_dot_burr.jpeg 41 | # - images/a_dot_ham.jpeg 42 | # An image asset can refer to one or more resolution-specific "variants", see 43 | # https://flutter.io/assets-and-images/#resolution-aware. 44 | # For details regarding adding assets from package dependencies, see 45 | # https://flutter.io/assets-and-images/#from-packages 46 | # To add custom fonts to your application, add a fonts section here, 47 | # in this "flutter" section. Each entry in this list should have a 48 | # "family" key with the font family name, and a "fonts" key with a 49 | # list giving the asset and other descriptors for the font. For 50 | # example: 51 | # fonts: 52 | # - family: Schyler 53 | # fonts: 54 | # - asset: fonts/Schyler-Regular.ttf 55 | # - asset: fonts/Schyler-Italic.ttf 56 | # style: italic 57 | # - family: Trajan Pro 58 | # fonts: 59 | # - asset: fonts/TrajanPro.ttf 60 | # - asset: fonts/TrajanPro_Bold.ttf 61 | # weight: 700 62 | # 63 | # For details regarding fonts from package dependencies, 64 | # see https://flutter.io/custom-fonts/#from-packages 65 | -------------------------------------------------------------------------------- /README.zh.md: -------------------------------------------------------------------------------- 1 | # Agora Flutter 快速入门 2 | 3 | _Other languages: [English](README.md)_ 4 | 5 | 本教程介绍如何使用[Flutter](https://flutter.io/)创建 Agora 帐户并使用 Agora 构建示例应用程序。 6 | 7 | ## 准备工作 8 | 9 | - Agora.io [开发者帐户](https://dashboard.agora.io/signin/) 10 | - [Flutter](https://flutter.io/) 1.0.0 11 | 12 | ## 快速开始 13 | 14 | 这个示例向您展示如何使用 Agora Flutter SDK 构建一个简单的视频通话应用程序。它向您展示了如何: 15 | 16 | - 加入/离开频道 17 | - 静音/取消静音 18 | - 切换摄像头 19 | - 布局多个视频视图 20 | 21 | ![screenshot-1](screenshot-1.png) 22 | ![screenshot-2](screenshot-2.png) 23 | 24 | ### 创建一个帐户并获取一个 App ID 25 | 26 | 要构建和运行示例应用程序,请首先获取 Agora App ID: 27 | 28 | 1. 在[agora.io](https://dashboard.agora.io/signin/)创建开发人员帐户。完成注册过程后,您将被重定向到仪表板页面。 29 | 2. 在左侧的仪表板树中导航到**项目** > **项目列表**。 30 | 3. 将从仪表板获取的 App ID 复制到文本文件中。您将在启动应用程序时用到它。 31 | 32 | ### 更新并运行示例应用程序 33 | 34 | 打开[settings.dart](lib/src/utils/settings.dart)文件并添加 App ID。 35 | 36 | ```dart 37 |   const APP_ID =""; 38 | ``` 39 | 40 | 在项目目录中运行`packages get`命令: 41 | 42 | ```shell 43 |   #install dependencies 44 |   flutter packages get 45 | ``` 46 | 47 | 构建完成后,执行`run`命令启动应用程序。 48 | 49 | ```shell 50 |   #start app 51 |   flutter run 52 | ``` 53 | 54 | #### 我们建议您在开发期间按照 flutter 官方引导推荐,使用 IDE(包括但不限于 VS Code)来控制整体构建过程 55 | 56 | 有关如何设置 IDE 的详细信息,请参阅[此处](https://flutter.io/docs/get-started/editor?tab=vscode) 57 | 58 | ## 错误处理 59 | 60 | ### iOS 内存泄漏 61 | 62 | 如果你的 flutter channel 是 stable, `PlatformView` 会导致内存泄漏, 你可以运行 `flutter channel beta` 63 | 64 | [你可以参考这条 pull request](https://github.com/flutter/engine/pull/14326) 65 | 66 | ### Android 黑屏 67 | 68 | `提示:请确保你所有的配置都正确,但是仍然是黑屏` 69 | 70 | 如果你的 MainActivity 继承 `io.flutter.embedding.android.FlutterActivity`,并且你重写了 `configureFlutterEngine` 方法 71 | 72 | 请不要忘记添加 `super.configureFlutterEngine(flutterEngine)` 73 | 74 | 请不要添加 `GeneratedPluginRegistrant.registerWith(flutterEngine)`, 插件现在会自动注册 75 | 76 | [你可以参考官方文档](https://flutter.dev/docs/development/packages-and-plugins/plugin-api-migration) 77 | 78 | ### Android Release 模式闪退 79 | 80 | 这个是代码混淆导致的,因为 flutter 默认设置了`android.enableR8=true` 81 | 82 | 在你的**app/proguard-rules.pro**文件中添加下面这行代码,以避免代码混淆: 83 | 84 | ```proguard 85 | -keep class io.agora.**{*;} 86 | ``` 87 | 88 | ## 附录 89 | 90 | - 开发者中心[API 文档](https://docs.agora.io/en/) 91 | - 如果发现了示例代码的 bug, 欢迎提交 [issue](https://github.com/AgoraIO/Agora-Interactive-Broadcasting-Live-Streaming-Web/issues) 92 | - [Flutter lab:编写你的第一个 Flutter 应用程序](https://flutter.io/docs/get-started/codelab) 93 | - [Flutter cookbook](https://flutter.io/docs/cookbook) 94 | - [Flutter 在线文档](https://flutter.io/docs),提供有关移动开发的教程,示例,指南以及完整的 API 参考。 95 | 96 | ## License 97 | 98 | MIT 99 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .svn/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # Visual Studio Code related 20 | .vscode/ 21 | 22 | # Flutter repo-specific 23 | /bin/cache/ 24 | /bin/mingit/ 25 | /dev/benchmarks/mega_gallery/ 26 | /dev/bots/.recipe_deps 27 | /dev/bots/android_tools/ 28 | /dev/docs/doc/ 29 | /dev/docs/flutter.docs.zip 30 | /dev/docs/lib/ 31 | /dev/docs/pubspec.yaml 32 | /packages/flutter/coverage/ 33 | version 34 | 35 | # Flutter/Dart/Pub related 36 | **/doc/api/ 37 | .dart_tool/ 38 | .flutter-plugins 39 | .packages 40 | .pub-cache/ 41 | .pub/ 42 | build/ 43 | flutter_*.png 44 | linked_*.ds 45 | unlinked.ds 46 | unlinked_spec.ds 47 | .flutter-plugins-dependencies 48 | 49 | # Android related 50 | **/android/**/gradle-wrapper.jar 51 | **/android/.gradle 52 | **/android/captures/ 53 | **/android/gradlew 54 | **/android/gradlew.bat 55 | **/android/local.properties 56 | **/android/**/GeneratedPluginRegistrant.java 57 | **/android/key.properties 58 | *.jks 59 | 60 | # iOS/XCode related 61 | **/ios/**/*.mode1v3 62 | **/ios/**/*.mode2v3 63 | **/ios/**/*.moved-aside 64 | **/ios/**/*.pbxuser 65 | **/ios/**/*.perspectivev3 66 | **/ios/**/*sync/ 67 | **/ios/**/.sconsign.dblite 68 | **/ios/**/.tags* 69 | **/ios/**/.vagrant/ 70 | **/ios/**/DerivedData/ 71 | **/ios/**/Icon? 72 | **/ios/**/Pods/ 73 | **/ios/**/.symlinks/ 74 | **/ios/**/profile 75 | **/ios/**/xcuserdata 76 | **/ios/.generated/ 77 | **/ios/Flutter/App.framework 78 | **/ios/Flutter/Flutter.framework 79 | **/ios/Flutter/Generated.xcconfig 80 | **/ios/Flutter/app.flx 81 | **/ios/Flutter/app.zip 82 | **/ios/Flutter/flutter_assets/ 83 | **/ios/ServiceDefinitions.json 84 | **/ios/Runner/GeneratedPluginRegistrant.* 85 | 86 | # Exceptions to above rules. 87 | !**/ios/**/default.mode1v3 88 | !**/ios/**/default.mode2v3 89 | !**/ios/**/default.pbxuser 90 | !**/ios/**/default.perspectivev3 91 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packagesandroid/app/.* 92 | *.*~ 93 | 94 | # Android related 95 | **/android/**/gradle-wrapper.jar 96 | **/android/.gradle 97 | **/android/captures/ 98 | **/android/gradlew 99 | **/android/gradlew.bat 100 | **/android/local.properties 101 | **/android/**/GeneratedPluginRegistrant.java 102 | **/android/key.properties 103 | *.jks 104 | 105 | # iOS/XCode related 106 | **/ios/**/*.mode1v3 107 | **/ios/**/*.mode2v3 108 | **/ios/**/*.moved-aside 109 | **/ios/**/*.pbxuser 110 | **/ios/**/*.perspectivev3 111 | **/ios/**/*sync/ 112 | **/ios/**/.sconsign.dblite 113 | **/ios/**/.tags* 114 | **/ios/**/.vagrant/ 115 | **/ios/**/DerivedData/ 116 | **/ios/**/Icon? 117 | **/ios/**/Pods/ 118 | **/ios/**/.symlinks/ 119 | **/ios/**/profile 120 | **/ios/**/xcuserdata 121 | **/ios/.generated/ 122 | **/ios/Flutter/App.framework 123 | **/ios/Flutter/Flutter.framework 124 | **/ios/Flutter/Generated.xcconfig 125 | **/ios/Flutter/app.flx 126 | **/ios/Flutter/app.zip 127 | **/ios/Flutter/flutter_assets/ 128 | **/ios/Flutter/flutter_export_environment.sh 129 | **/ios/ServiceDefinitions.json 130 | **/ios/Runner/GeneratedPluginRegistrant.* 131 | android/gradle/wrapper/gradle-wrapper.properties 132 | 133 | android/.settings/org.eclipse.buildship.core.prefs 134 | android/app/.classpath 135 | android/app/.project 136 | android/app/.settings/ -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Agora Flutter Quickstart 2 | 3 | This tutorial describes how to create an Agora account and build a sample app with Agora using [Flutter](https://flutter.io/). 4 | 5 | ## Other Languages: 6 | 7 | [简体中文](README.zh.md)_ 8 | 9 | ## Prerequisites 10 | 11 | - Agora.io [Developer Account](https://dashboard.agora.io/signin/) 12 | - [Flutter](https://flutter.io/) 1.0.0 13 | 14 | ## Quick Start 15 | 16 | This repository shows you how to use Agora Flutter SDK to build a simple video call app. It demonstrates you how to: 17 | 18 | - Join / leave a channel 19 | - Mute / unmute audio 20 | - Switch camera views 21 | - Layout multiple video views 22 | 23 | ![Screenshot-1](screenshot-1.png) 24 | ![Screenshot-2](screenshot-2.png) 25 | 26 | ### Create an Account and Obtain an App ID 27 | 28 | To build and run the sample application, first obtain an app ID: 29 | 30 | 1. Create a developer account at [agora.io](https://dashboard.agora.io/signin/). Once you finish the sign-up process, you are redirected to the dashboard. 31 | 2. Navigate in the dashboard tree on the left to **Projects** > **Project List**. 32 | 3. Copy the app ID that you obtain from the dashboard into a text file. You will use this when you launch the app. 33 | 34 | ### Update and Run the Sample Application 35 | 36 | Open the [settings.dart](lib/src/utils/settings.dart) file and add the app ID. 37 | 38 | ```dart 39 | const APP_ID = ""; 40 | ``` 41 | 42 | Run the `packages get` command in your project directory: 43 | 44 | ```bash 45 | # install dependencies 46 | flutter pub get 47 | ``` 48 | 49 | Once the build is complete, run the `run` command to start the app. 50 | 51 | ```bash 52 | # start app 53 | flutter run 54 | ``` 55 | 56 | #### We recommend you to use IDE to control overall build process during development 57 | 58 | Details about how to set up the IDE please take a look at [here](https://flutter.io/docs/get-started/editor?tab=vscode) 59 | 60 | ## Error handling 61 | 62 | ### iOS memory leak 63 | 64 | if your flutter channel is stable, `PlatformView` will cause memory leak, you can run `flutter channel beta` 65 | 66 | [you can refer to this pull request](https://github.com/flutter/engine/pull/14326) 67 | 68 | ### Android Black screen 69 | 70 | `Tips: please make sure your all configurations are correct, but still black screen` 71 | 72 | if your MainActivity extends `io.flutter.embedding.android.FlutterActivity` and override the `configureFlutterEngine` function 73 | 74 | please don't forget add `super.configureFlutterEngine(flutterEngine)` 75 | 76 | please don't add `GeneratedPluginRegistrant.registerWith(flutterEngine)`, plugins will be registered auto now 77 | 78 | [you can refer to official documents](https://flutter.dev/docs/development/packages-and-plugins/plugin-api-migration) 79 | 80 | ### Android Release crash 81 | 82 | it causes by code obfuscation because of flutter set `android.enableR8=true` by the default 83 | 84 | Add the following line in the **app/proguard-rules.pro** file to prevent code obfuscation: 85 | 86 | ```proguard 87 | -keep class io.agora.**{*;} 88 | ``` 89 | 90 | ## Reporting an issue 91 | 92 | Please ensure you provide following information when you report an issue, 93 | 94 | ### Environment 95 | 96 | #### Flutter Doctor 97 | 98 | run `flutter doctor` and copy the log output. 99 | 100 | #### Agora SDK Logs 101 | 102 | Insert below code 103 | 104 | ```dart 105 | AgoraRtcEngine.setParameters("{\"rtc.log_filter\": 65535}"); 106 | ``` 107 | 108 | to `call.dart` 109 | The eventual outcome would look like this, 110 | 111 | ```dart 112 | ... 113 | _initAgoraRtcEngine(); 114 | _addAgoraEventHandlers(); 115 | AgoraRtcEngine.enableWebSdkInteroperability(true); 116 | AgoraRtcEngine.setParameters('{\"che.video.lowBitRateStreamParameter\":{\"width\":320,\"height\":180,\"frameRate\":15,\"bitRate\":140}}'); 117 | AgoraRtcEngine.setParameters("{\"rtc.log_filter\": 65535}"); 118 | AgoraRtcEngine.joinChannel(null, widget.channelName, null, 0); 119 | ... 120 | ``` 121 | 122 | and then start the app. Our sdk log will print directly to console in this case. 123 | 124 | ## Resources 125 | 126 | - Complete [API documentation](https://docs.agora.io/en/) at the Developer Center 127 | - [File bugs about this sample](https://github.com/AgoraIO-Community/Agora-Flutter-Quickstart/issues) 128 | - [Flutter lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab) 129 | - [Flutter cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook) 130 | - [Flutter online documentation](https://flutter.io/docs), which offers tutorials, samples, guidance on mobile development, and a full API reference. 131 | 132 | ## Credit 133 | 134 | https://pub.dartlang.org/packages/permission_handler 135 | 136 | ## License 137 | 138 | This software is under the MIT License (MIT). 139 | -------------------------------------------------------------------------------- /lib/src/pages/index.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:agora_rtc_engine/rtc_engine.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:permission_handler/permission_handler.dart'; 6 | 7 | import './call.dart'; 8 | 9 | class IndexPage extends StatefulWidget { 10 | @override 11 | State createState() => IndexState(); 12 | } 13 | 14 | class IndexState extends State { 15 | /// create a channelController to retrieve text value 16 | final _channelController = TextEditingController(); 17 | 18 | /// if channel textField is validated to have error 19 | bool _validateError = false; 20 | 21 | ClientRole? _role = ClientRole.Broadcaster; 22 | 23 | @override 24 | void dispose() { 25 | // dispose input controller 26 | _channelController.dispose(); 27 | super.dispose(); 28 | } 29 | 30 | @override 31 | Widget build(BuildContext context) { 32 | return Scaffold( 33 | appBar: AppBar( 34 | title: Text('Agora Flutter QuickStart'), 35 | ), 36 | body: Center( 37 | child: Container( 38 | padding: const EdgeInsets.symmetric(horizontal: 20), 39 | height: 400, 40 | child: Column( 41 | children: [ 42 | Row( 43 | children: [ 44 | Expanded( 45 | child: TextField( 46 | controller: _channelController, 47 | decoration: InputDecoration( 48 | errorText: 49 | _validateError ? 'Channel name is mandatory' : null, 50 | border: UnderlineInputBorder( 51 | borderSide: BorderSide(width: 1), 52 | ), 53 | hintText: 'Channel name', 54 | ), 55 | ), 56 | ) 57 | ], 58 | ), 59 | Column( 60 | children: [ 61 | ListTile( 62 | title: Text(ClientRole.Broadcaster.toString()), 63 | leading: Radio( 64 | value: ClientRole.Broadcaster, 65 | groupValue: _role, 66 | onChanged: (ClientRole? value) { 67 | setState(() { 68 | _role = value; 69 | }); 70 | }, 71 | ), 72 | ), 73 | ListTile( 74 | title: Text(ClientRole.Audience.toString()), 75 | leading: Radio( 76 | value: ClientRole.Audience, 77 | groupValue: _role, 78 | onChanged: (ClientRole? value) { 79 | setState(() { 80 | _role = value; 81 | }); 82 | }, 83 | ), 84 | ) 85 | ], 86 | ), 87 | Padding( 88 | padding: const EdgeInsets.symmetric(vertical: 20), 89 | child: Row( 90 | children: [ 91 | Expanded( 92 | child: ElevatedButton( 93 | onPressed: onJoin, 94 | child: Text('Join'), 95 | style: ButtonStyle( 96 | backgroundColor: 97 | MaterialStateProperty.all(Colors.blueAccent), 98 | foregroundColor: 99 | MaterialStateProperty.all(Colors.white)), 100 | ), 101 | ), 102 | // Expanded( 103 | // child: RaisedButton( 104 | // onPressed: onJoin, 105 | // child: Text('Join'), 106 | // color: Colors.blueAccent, 107 | // textColor: Colors.white, 108 | // ), 109 | // ) 110 | ], 111 | ), 112 | ) 113 | ], 114 | ), 115 | ), 116 | ), 117 | ); 118 | } 119 | 120 | Future onJoin() async { 121 | // update input validation 122 | setState(() { 123 | _channelController.text.isEmpty 124 | ? _validateError = true 125 | : _validateError = false; 126 | }); 127 | if (_channelController.text.isNotEmpty) { 128 | // await for camera and mic permissions before pushing video page 129 | await _handleCameraAndMic(Permission.camera); 130 | await _handleCameraAndMic(Permission.microphone); 131 | // push video page with given channel name 132 | await Navigator.push( 133 | context, 134 | MaterialPageRoute( 135 | builder: (context) => CallPage( 136 | channelName: _channelController.text, 137 | role: _role, 138 | ), 139 | ), 140 | ); 141 | } 142 | } 143 | 144 | Future _handleCameraAndMic(Permission permission) async { 145 | final status = await permission.request(); 146 | print(status); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /lib/src/pages/call.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:agora_rtc_engine/rtc_engine.dart'; 4 | import 'package:agora_rtc_engine/rtc_local_view.dart' as RtcLocalView; 5 | import 'package:agora_rtc_engine/rtc_remote_view.dart' as RtcRemoteView; 6 | import 'package:flutter/material.dart'; 7 | 8 | import '../utils/settings.dart'; 9 | 10 | class CallPage extends StatefulWidget { 11 | /// non-modifiable channel name of the page 12 | final String? channelName; 13 | 14 | /// non-modifiable client role of the page 15 | final ClientRole? role; 16 | 17 | /// Creates a call page with given channel name. 18 | const CallPage({Key? key, this.channelName, this.role}) : super(key: key); 19 | 20 | @override 21 | _CallPageState createState() => _CallPageState(); 22 | } 23 | 24 | class _CallPageState extends State { 25 | final _users = []; 26 | final _infoStrings = []; 27 | bool muted = false; 28 | late RtcEngine _engine; 29 | 30 | @override 31 | void dispose() { 32 | // clear users 33 | _users.clear(); 34 | _dispose(); 35 | super.dispose(); 36 | } 37 | 38 | Future _dispose() async { 39 | // destroy sdk 40 | await _engine.leaveChannel(); 41 | await _engine.destroy(); 42 | } 43 | 44 | @override 45 | void initState() { 46 | super.initState(); 47 | // initialize agora sdk 48 | initialize(); 49 | } 50 | 51 | Future initialize() async { 52 | if (appId.isEmpty) { 53 | setState(() { 54 | _infoStrings.add( 55 | 'APP_ID missing, please provide your APP_ID in settings.dart', 56 | ); 57 | _infoStrings.add('Agora Engine is not starting'); 58 | }); 59 | return; 60 | } 61 | 62 | await _initAgoraRtcEngine(); 63 | _addAgoraEventHandlers(); 64 | VideoEncoderConfiguration configuration = VideoEncoderConfiguration(); 65 | configuration.dimensions = VideoDimensions(width: 1920, height: 1080); 66 | await _engine.setVideoEncoderConfiguration(configuration); 67 | await _engine.joinChannel(token, widget.channelName!, null, 0); 68 | } 69 | 70 | /// Create agora sdk instance and initialize 71 | Future _initAgoraRtcEngine() async { 72 | _engine = await RtcEngine.create(appId); 73 | await _engine.enableVideo(); 74 | await _engine.setChannelProfile(ChannelProfile.LiveBroadcasting); 75 | await _engine.setClientRole(widget.role!); 76 | } 77 | 78 | /// Add agora event handlers 79 | void _addAgoraEventHandlers() { 80 | _engine.setEventHandler(RtcEngineEventHandler(error: (code) { 81 | setState(() { 82 | final info = 'onError: $code'; 83 | _infoStrings.add(info); 84 | }); 85 | }, joinChannelSuccess: (channel, uid, elapsed) { 86 | setState(() { 87 | final info = 'onJoinChannel: $channel, uid: $uid'; 88 | _infoStrings.add(info); 89 | }); 90 | }, leaveChannel: (stats) { 91 | setState(() { 92 | _infoStrings.add('onLeaveChannel'); 93 | _users.clear(); 94 | }); 95 | }, userJoined: (uid, elapsed) { 96 | setState(() { 97 | final info = 'userJoined: $uid'; 98 | _infoStrings.add(info); 99 | _users.add(uid); 100 | }); 101 | }, userOffline: (uid, elapsed) { 102 | setState(() { 103 | final info = 'userOffline: $uid'; 104 | _infoStrings.add(info); 105 | _users.remove(uid); 106 | }); 107 | }, firstRemoteVideoFrame: (uid, width, height, elapsed) { 108 | setState(() { 109 | final info = 'firstRemoteVideo: $uid ${width}x $height'; 110 | _infoStrings.add(info); 111 | }); 112 | })); 113 | } 114 | 115 | /// Helper function to get list of native views 116 | List _getRenderViews() { 117 | final List list = []; 118 | if (widget.role == ClientRole.Broadcaster) { 119 | list.add(RtcLocalView.SurfaceView()); 120 | } 121 | _users.forEach((int uid) => list.add( 122 | RtcRemoteView.SurfaceView(channelId: widget.channelName!, uid: uid))); 123 | return list; 124 | } 125 | 126 | /// Video view wrapper 127 | Widget _videoView(view) { 128 | return Expanded(child: Container(child: view)); 129 | } 130 | 131 | /// Video view row wrapper 132 | Widget _expandedVideoRow(List views) { 133 | final wrappedViews = views.map(_videoView).toList(); 134 | return Expanded( 135 | child: Row( 136 | children: wrappedViews, 137 | ), 138 | ); 139 | } 140 | 141 | /// Video layout wrapper 142 | Widget _viewRows() { 143 | final views = _getRenderViews(); 144 | switch (views.length) { 145 | case 1: 146 | return Container( 147 | child: Column( 148 | children: [_videoView(views[0])], 149 | )); 150 | case 2: 151 | return Container( 152 | child: Column( 153 | children: [ 154 | _expandedVideoRow([views[0]]), 155 | _expandedVideoRow([views[1]]) 156 | ], 157 | )); 158 | case 3: 159 | return Container( 160 | child: Column( 161 | children: [ 162 | _expandedVideoRow(views.sublist(0, 2)), 163 | _expandedVideoRow(views.sublist(2, 3)) 164 | ], 165 | )); 166 | case 4: 167 | return Container( 168 | child: Column( 169 | children: [ 170 | _expandedVideoRow(views.sublist(0, 2)), 171 | _expandedVideoRow(views.sublist(2, 4)) 172 | ], 173 | )); 174 | default: 175 | } 176 | return Container(); 177 | } 178 | 179 | /// Toolbar layout 180 | Widget _toolbar() { 181 | if (widget.role == ClientRole.Audience) return Container(); 182 | return Container( 183 | alignment: Alignment.bottomCenter, 184 | padding: const EdgeInsets.symmetric(vertical: 48), 185 | child: Row( 186 | mainAxisAlignment: MainAxisAlignment.center, 187 | children: [ 188 | RawMaterialButton( 189 | onPressed: _onToggleMute, 190 | child: Icon( 191 | muted ? Icons.mic_off : Icons.mic, 192 | color: muted ? Colors.white : Colors.blueAccent, 193 | size: 20.0, 194 | ), 195 | shape: CircleBorder(), 196 | elevation: 2.0, 197 | fillColor: muted ? Colors.blueAccent : Colors.white, 198 | padding: const EdgeInsets.all(12.0), 199 | ), 200 | RawMaterialButton( 201 | onPressed: () => _onCallEnd(context), 202 | child: Icon( 203 | Icons.call_end, 204 | color: Colors.white, 205 | size: 35.0, 206 | ), 207 | shape: CircleBorder(), 208 | elevation: 2.0, 209 | fillColor: Colors.redAccent, 210 | padding: const EdgeInsets.all(15.0), 211 | ), 212 | RawMaterialButton( 213 | onPressed: _onSwitchCamera, 214 | child: Icon( 215 | Icons.switch_camera, 216 | color: Colors.blueAccent, 217 | size: 20.0, 218 | ), 219 | shape: CircleBorder(), 220 | elevation: 2.0, 221 | fillColor: Colors.white, 222 | padding: const EdgeInsets.all(12.0), 223 | ) 224 | ], 225 | ), 226 | ); 227 | } 228 | 229 | /// Info panel to show logs 230 | Widget _panel() { 231 | return Container( 232 | padding: const EdgeInsets.symmetric(vertical: 48), 233 | alignment: Alignment.bottomCenter, 234 | child: FractionallySizedBox( 235 | heightFactor: 0.5, 236 | child: Container( 237 | padding: const EdgeInsets.symmetric(vertical: 48), 238 | child: ListView.builder( 239 | reverse: true, 240 | itemCount: _infoStrings.length, 241 | itemBuilder: (BuildContext context, int index) { 242 | if (_infoStrings.isEmpty) { 243 | return Text( 244 | "null"); // return type can't be null, a widget was required 245 | } 246 | return Padding( 247 | padding: const EdgeInsets.symmetric( 248 | vertical: 3, 249 | horizontal: 10, 250 | ), 251 | child: Row( 252 | mainAxisSize: MainAxisSize.min, 253 | children: [ 254 | Flexible( 255 | child: Container( 256 | padding: const EdgeInsets.symmetric( 257 | vertical: 2, 258 | horizontal: 5, 259 | ), 260 | decoration: BoxDecoration( 261 | color: Colors.yellowAccent, 262 | borderRadius: BorderRadius.circular(5), 263 | ), 264 | child: Text( 265 | _infoStrings[index], 266 | style: TextStyle(color: Colors.blueGrey), 267 | ), 268 | ), 269 | ) 270 | ], 271 | ), 272 | ); 273 | }, 274 | ), 275 | ), 276 | ), 277 | ); 278 | } 279 | 280 | void _onCallEnd(BuildContext context) { 281 | Navigator.pop(context); 282 | } 283 | 284 | void _onToggleMute() { 285 | setState(() { 286 | muted = !muted; 287 | }); 288 | _engine.muteLocalAudioStream(muted); 289 | } 290 | 291 | void _onSwitchCamera() { 292 | _engine.switchCamera(); 293 | } 294 | 295 | @override 296 | Widget build(BuildContext context) { 297 | return Scaffold( 298 | appBar: AppBar( 299 | title: Text('Agora Flutter QuickStart'), 300 | ), 301 | backgroundColor: Colors.black, 302 | body: Center( 303 | child: Stack( 304 | children: [ 305 | _viewRows(), 306 | _panel(), 307 | _toolbar(), 308 | ], 309 | ), 310 | ), 311 | ); 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 09C461CDA333E8A9229BCE94 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD307999238EDC85FE091077 /* Pods_Runner.framework */; }; 11 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 14 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 15 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 16 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 17 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 18 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 19 | F530E89124C697BE005ABA96 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = F530E89024C697BE005ABA96 /* File.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXCopyFilesBuildPhase section */ 23 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 24 | isa = PBXCopyFilesBuildPhase; 25 | buildActionMask = 2147483647; 26 | dstPath = ""; 27 | dstSubfolderSpec = 10; 28 | files = ( 29 | ); 30 | name = "Embed Frameworks"; 31 | runOnlyForDeploymentPostprocessing = 0; 32 | }; 33 | /* End PBXCopyFilesBuildPhase section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 37 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 38 | 20A90719B9DCA448196FFB39 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 39 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 41 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 42 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 43 | 95D5DB38E733BAC3BC39DE10 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 44 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 45 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 46 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 48 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 49 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 50 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 51 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | D2F1DDE08D43173089B977E4 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 53 | DD307999238EDC85FE091077 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | F530E88F24C697BE005ABA96 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 55 | F530E89024C697BE005ABA96 /* File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = ""; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | 09C461CDA333E8A9229BCE94 /* Pods_Runner.framework in Frameworks */, 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | /* End PBXFrameworksBuildPhase section */ 68 | 69 | /* Begin PBXGroup section */ 70 | 9740EEB11CF90186004384FC /* Flutter */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 74 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 75 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 76 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 77 | ); 78 | name = Flutter; 79 | sourceTree = ""; 80 | }; 81 | 97C146E51CF9000F007C117D = { 82 | isa = PBXGroup; 83 | children = ( 84 | 9740EEB11CF90186004384FC /* Flutter */, 85 | 97C146F01CF9000F007C117D /* Runner */, 86 | 97C146EF1CF9000F007C117D /* Products */, 87 | B1F363491EB667712DC3160E /* Pods */, 88 | E20598027883B3EFE670E4EB /* Frameworks */, 89 | ); 90 | sourceTree = ""; 91 | }; 92 | 97C146EF1CF9000F007C117D /* Products */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 97C146EE1CF9000F007C117D /* Runner.app */, 96 | ); 97 | name = Products; 98 | sourceTree = ""; 99 | }; 100 | 97C146F01CF9000F007C117D /* Runner */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 104 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 105 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 106 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 107 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 108 | 97C147021CF9000F007C117D /* Info.plist */, 109 | 97C146F11CF9000F007C117D /* Supporting Files */, 110 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 111 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 112 | F530E89024C697BE005ABA96 /* File.swift */, 113 | F530E88F24C697BE005ABA96 /* Runner-Bridging-Header.h */, 114 | ); 115 | path = Runner; 116 | sourceTree = ""; 117 | }; 118 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 97C146F21CF9000F007C117D /* main.m */, 122 | ); 123 | name = "Supporting Files"; 124 | sourceTree = ""; 125 | }; 126 | B1F363491EB667712DC3160E /* Pods */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 20A90719B9DCA448196FFB39 /* Pods-Runner.debug.xcconfig */, 130 | D2F1DDE08D43173089B977E4 /* Pods-Runner.release.xcconfig */, 131 | 95D5DB38E733BAC3BC39DE10 /* Pods-Runner.profile.xcconfig */, 132 | ); 133 | name = Pods; 134 | sourceTree = ""; 135 | }; 136 | E20598027883B3EFE670E4EB /* Frameworks */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | DD307999238EDC85FE091077 /* Pods_Runner.framework */, 140 | ); 141 | name = Frameworks; 142 | sourceTree = ""; 143 | }; 144 | /* End PBXGroup section */ 145 | 146 | /* Begin PBXNativeTarget section */ 147 | 97C146ED1CF9000F007C117D /* Runner */ = { 148 | isa = PBXNativeTarget; 149 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 150 | buildPhases = ( 151 | 1A076E56C3029D30462D7162 /* [CP] Check Pods Manifest.lock */, 152 | 9740EEB61CF901F6004384FC /* Run Script */, 153 | 97C146EA1CF9000F007C117D /* Sources */, 154 | 97C146EB1CF9000F007C117D /* Frameworks */, 155 | 97C146EC1CF9000F007C117D /* Resources */, 156 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 157 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 158 | EF6FAA7416F5035E3CDB11B9 /* [CP] Embed Pods Frameworks */, 159 | ); 160 | buildRules = ( 161 | ); 162 | dependencies = ( 163 | ); 164 | name = Runner; 165 | productName = Runner; 166 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 167 | productType = "com.apple.product-type.application"; 168 | }; 169 | /* End PBXNativeTarget section */ 170 | 171 | /* Begin PBXProject section */ 172 | 97C146E61CF9000F007C117D /* Project object */ = { 173 | isa = PBXProject; 174 | attributes = { 175 | LastUpgradeCheck = 1300; 176 | ORGANIZATIONNAME = "The Chromium Authors"; 177 | TargetAttributes = { 178 | 97C146ED1CF9000F007C117D = { 179 | CreatedOnToolsVersion = 7.3.1; 180 | LastSwiftMigration = 1160; 181 | ProvisioningStyle = Manual; 182 | }; 183 | }; 184 | }; 185 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 186 | compatibilityVersion = "Xcode 3.2"; 187 | developmentRegion = English; 188 | hasScannedForEncodings = 0; 189 | knownRegions = ( 190 | English, 191 | en, 192 | Base, 193 | ); 194 | mainGroup = 97C146E51CF9000F007C117D; 195 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 196 | projectDirPath = ""; 197 | projectRoot = ""; 198 | targets = ( 199 | 97C146ED1CF9000F007C117D /* Runner */, 200 | ); 201 | }; 202 | /* End PBXProject section */ 203 | 204 | /* Begin PBXResourcesBuildPhase section */ 205 | 97C146EC1CF9000F007C117D /* Resources */ = { 206 | isa = PBXResourcesBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 210 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 211 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 212 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 213 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | }; 217 | /* End PBXResourcesBuildPhase section */ 218 | 219 | /* Begin PBXShellScriptBuildPhase section */ 220 | 1A076E56C3029D30462D7162 /* [CP] Check Pods Manifest.lock */ = { 221 | isa = PBXShellScriptBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | ); 225 | inputFileListPaths = ( 226 | ); 227 | inputPaths = ( 228 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 229 | "${PODS_ROOT}/Manifest.lock", 230 | ); 231 | name = "[CP] Check Pods Manifest.lock"; 232 | outputFileListPaths = ( 233 | ); 234 | outputPaths = ( 235 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | shellPath = /bin/sh; 239 | 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"; 240 | showEnvVarsInLog = 0; 241 | }; 242 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 243 | isa = PBXShellScriptBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | ); 247 | inputPaths = ( 248 | ); 249 | name = "Thin Binary"; 250 | outputPaths = ( 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | shellPath = /bin/sh; 254 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 255 | }; 256 | 9740EEB61CF901F6004384FC /* Run Script */ = { 257 | isa = PBXShellScriptBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | ); 261 | inputPaths = ( 262 | ); 263 | name = "Run Script"; 264 | outputPaths = ( 265 | ); 266 | runOnlyForDeploymentPostprocessing = 0; 267 | shellPath = /bin/sh; 268 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 269 | }; 270 | EF6FAA7416F5035E3CDB11B9 /* [CP] Embed Pods Frameworks */ = { 271 | isa = PBXShellScriptBuildPhase; 272 | buildActionMask = 2147483647; 273 | files = ( 274 | ); 275 | inputPaths = ( 276 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", 277 | "${BUILT_PRODUCTS_DIR}/agora_rtc_engine/agora_rtc_engine.framework", 278 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraIrisRTC_iOS/AgoraRtcWrapper.framework/AgoraRtcWrapper", 279 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AINS/AgoraAIDenoiseExtension.framework/AgoraAIDenoiseExtension", 280 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/AV1Dec/AgoraDav1dExtension.framework/AgoraDav1dExtension", 281 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ContentInspect/AgoraCIExtension.framework/AgoraCIExtension", 282 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/FullAudioFormat/AgoraFullAudioFormatExtension.framework/AgoraFullAudioFormatExtension", 283 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ROIEnc/AgoraFDExtension.framework/AgoraFDExtension", 284 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/ReplayKit/AgoraReplayKitExtension.framework/AgoraReplayKitExtension", 285 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic/AgoraCore.framework/AgoraCore", 286 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic/AgoraRtcKit.framework/AgoraRtcKit", 287 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic/AgoraSoundTouch.framework/AgoraSoundTouch", 288 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic/Agorafdkaac.framework/Agorafdkaac", 289 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/RtcBasic/Agoraffmpeg.framework/Agoraffmpeg", 290 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/SpatialAudio/AgoraSpatialAudioExtension.framework/AgoraSpatialAudioExtension", 291 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/SuperResolution/AgoraSuperResolutionExtension.framework/AgoraSuperResolutionExtension", 292 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VideoPreprocess/AgoraVideoProcessExtension.framework/AgoraVideoProcessExtension", 293 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/AgoraRtcEngine_iOS/VirtualBackground/AgoraVideoSegmentationExtension.framework/AgoraVideoSegmentationExtension", 294 | ); 295 | name = "[CP] Embed Pods Frameworks"; 296 | outputPaths = ( 297 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/agora_rtc_engine.framework", 298 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraRtcWrapper.framework", 299 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraAIDenoiseExtension.framework", 300 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraDav1dExtension.framework", 301 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraCIExtension.framework", 302 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraFullAudioFormatExtension.framework", 303 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraFDExtension.framework", 304 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraReplayKitExtension.framework", 305 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraCore.framework", 306 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraRtcKit.framework", 307 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraSoundTouch.framework", 308 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Agorafdkaac.framework", 309 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Agoraffmpeg.framework", 310 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraSpatialAudioExtension.framework", 311 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraSuperResolutionExtension.framework", 312 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraVideoProcessExtension.framework", 313 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AgoraVideoSegmentationExtension.framework", 314 | ); 315 | runOnlyForDeploymentPostprocessing = 0; 316 | shellPath = /bin/sh; 317 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 318 | showEnvVarsInLog = 0; 319 | }; 320 | /* End PBXShellScriptBuildPhase section */ 321 | 322 | /* Begin PBXSourcesBuildPhase section */ 323 | 97C146EA1CF9000F007C117D /* Sources */ = { 324 | isa = PBXSourcesBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 328 | F530E89124C697BE005ABA96 /* File.swift in Sources */, 329 | 97C146F31CF9000F007C117D /* main.m in Sources */, 330 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 331 | ); 332 | runOnlyForDeploymentPostprocessing = 0; 333 | }; 334 | /* End PBXSourcesBuildPhase section */ 335 | 336 | /* Begin PBXVariantGroup section */ 337 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 338 | isa = PBXVariantGroup; 339 | children = ( 340 | 97C146FB1CF9000F007C117D /* Base */, 341 | ); 342 | name = Main.storyboard; 343 | sourceTree = ""; 344 | }; 345 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 346 | isa = PBXVariantGroup; 347 | children = ( 348 | 97C147001CF9000F007C117D /* Base */, 349 | ); 350 | name = LaunchScreen.storyboard; 351 | sourceTree = ""; 352 | }; 353 | /* End PBXVariantGroup section */ 354 | 355 | /* Begin XCBuildConfiguration section */ 356 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 357 | isa = XCBuildConfiguration; 358 | buildSettings = { 359 | ALWAYS_SEARCH_USER_PATHS = NO; 360 | CLANG_ANALYZER_NONNULL = YES; 361 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 362 | CLANG_CXX_LIBRARY = "libc++"; 363 | CLANG_ENABLE_MODULES = YES; 364 | CLANG_ENABLE_OBJC_ARC = YES; 365 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 366 | CLANG_WARN_BOOL_CONVERSION = YES; 367 | CLANG_WARN_COMMA = YES; 368 | CLANG_WARN_CONSTANT_CONVERSION = YES; 369 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 370 | CLANG_WARN_EMPTY_BODY = YES; 371 | CLANG_WARN_ENUM_CONVERSION = YES; 372 | CLANG_WARN_INFINITE_RECURSION = YES; 373 | CLANG_WARN_INT_CONVERSION = YES; 374 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 375 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 376 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 377 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 378 | CLANG_WARN_STRICT_PROTOTYPES = YES; 379 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 380 | CLANG_WARN_UNREACHABLE_CODE = YES; 381 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 382 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 383 | COPY_PHASE_STRIP = NO; 384 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 385 | ENABLE_NS_ASSERTIONS = NO; 386 | ENABLE_STRICT_OBJC_MSGSEND = YES; 387 | GCC_C_LANGUAGE_STANDARD = gnu99; 388 | GCC_NO_COMMON_BLOCKS = YES; 389 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 390 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 391 | GCC_WARN_UNDECLARED_SELECTOR = YES; 392 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 393 | GCC_WARN_UNUSED_FUNCTION = YES; 394 | GCC_WARN_UNUSED_VARIABLE = YES; 395 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 396 | MTL_ENABLE_DEBUG_INFO = NO; 397 | SDKROOT = iphoneos; 398 | TARGETED_DEVICE_FAMILY = "1,2"; 399 | VALIDATE_PRODUCT = YES; 400 | }; 401 | name = Profile; 402 | }; 403 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 404 | isa = XCBuildConfiguration; 405 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 406 | buildSettings = { 407 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 408 | CLANG_ENABLE_MODULES = YES; 409 | CODE_SIGN_STYLE = Manual; 410 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 411 | DEVELOPMENT_TEAM = ""; 412 | ENABLE_BITCODE = NO; 413 | FRAMEWORK_SEARCH_PATHS = ( 414 | "$(inherited)", 415 | "$(PROJECT_DIR)/Flutter", 416 | ); 417 | INFOPLIST_FILE = Runner/Info.plist; 418 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 419 | LIBRARY_SEARCH_PATHS = ( 420 | "$(inherited)", 421 | "$(PROJECT_DIR)/Flutter", 422 | ); 423 | PRODUCT_BUNDLE_IDENTIFIER = com.example.agoraFlutterQuickstart; 424 | PRODUCT_NAME = "$(TARGET_NAME)"; 425 | PROVISIONING_PROFILE_SPECIFIER = ""; 426 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 427 | SWIFT_VERSION = 5.0; 428 | VERSIONING_SYSTEM = "apple-generic"; 429 | }; 430 | name = Profile; 431 | }; 432 | 97C147031CF9000F007C117D /* Debug */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | ALWAYS_SEARCH_USER_PATHS = NO; 436 | CLANG_ANALYZER_NONNULL = YES; 437 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 438 | CLANG_CXX_LIBRARY = "libc++"; 439 | CLANG_ENABLE_MODULES = YES; 440 | CLANG_ENABLE_OBJC_ARC = YES; 441 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 442 | CLANG_WARN_BOOL_CONVERSION = YES; 443 | CLANG_WARN_COMMA = YES; 444 | CLANG_WARN_CONSTANT_CONVERSION = YES; 445 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 446 | CLANG_WARN_EMPTY_BODY = YES; 447 | CLANG_WARN_ENUM_CONVERSION = YES; 448 | CLANG_WARN_INFINITE_RECURSION = YES; 449 | CLANG_WARN_INT_CONVERSION = YES; 450 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 451 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 452 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 453 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 454 | CLANG_WARN_STRICT_PROTOTYPES = YES; 455 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 456 | CLANG_WARN_UNREACHABLE_CODE = YES; 457 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 458 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 459 | COPY_PHASE_STRIP = NO; 460 | DEBUG_INFORMATION_FORMAT = dwarf; 461 | ENABLE_STRICT_OBJC_MSGSEND = YES; 462 | ENABLE_TESTABILITY = YES; 463 | GCC_C_LANGUAGE_STANDARD = gnu99; 464 | GCC_DYNAMIC_NO_PIC = NO; 465 | GCC_NO_COMMON_BLOCKS = YES; 466 | GCC_OPTIMIZATION_LEVEL = 0; 467 | GCC_PREPROCESSOR_DEFINITIONS = ( 468 | "DEBUG=1", 469 | "$(inherited)", 470 | ); 471 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 472 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 473 | GCC_WARN_UNDECLARED_SELECTOR = YES; 474 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 475 | GCC_WARN_UNUSED_FUNCTION = YES; 476 | GCC_WARN_UNUSED_VARIABLE = YES; 477 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 478 | MTL_ENABLE_DEBUG_INFO = YES; 479 | ONLY_ACTIVE_ARCH = YES; 480 | SDKROOT = iphoneos; 481 | TARGETED_DEVICE_FAMILY = "1,2"; 482 | }; 483 | name = Debug; 484 | }; 485 | 97C147041CF9000F007C117D /* Release */ = { 486 | isa = XCBuildConfiguration; 487 | buildSettings = { 488 | ALWAYS_SEARCH_USER_PATHS = NO; 489 | CLANG_ANALYZER_NONNULL = YES; 490 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 491 | CLANG_CXX_LIBRARY = "libc++"; 492 | CLANG_ENABLE_MODULES = YES; 493 | CLANG_ENABLE_OBJC_ARC = YES; 494 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 495 | CLANG_WARN_BOOL_CONVERSION = YES; 496 | CLANG_WARN_COMMA = YES; 497 | CLANG_WARN_CONSTANT_CONVERSION = YES; 498 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 499 | CLANG_WARN_EMPTY_BODY = YES; 500 | CLANG_WARN_ENUM_CONVERSION = YES; 501 | CLANG_WARN_INFINITE_RECURSION = YES; 502 | CLANG_WARN_INT_CONVERSION = YES; 503 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 504 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 505 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 506 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 507 | CLANG_WARN_STRICT_PROTOTYPES = YES; 508 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 509 | CLANG_WARN_UNREACHABLE_CODE = YES; 510 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 511 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 512 | COPY_PHASE_STRIP = NO; 513 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 514 | ENABLE_NS_ASSERTIONS = NO; 515 | ENABLE_STRICT_OBJC_MSGSEND = YES; 516 | GCC_C_LANGUAGE_STANDARD = gnu99; 517 | GCC_NO_COMMON_BLOCKS = YES; 518 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 519 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 520 | GCC_WARN_UNDECLARED_SELECTOR = YES; 521 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 522 | GCC_WARN_UNUSED_FUNCTION = YES; 523 | GCC_WARN_UNUSED_VARIABLE = YES; 524 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 525 | MTL_ENABLE_DEBUG_INFO = NO; 526 | SDKROOT = iphoneos; 527 | TARGETED_DEVICE_FAMILY = "1,2"; 528 | VALIDATE_PRODUCT = YES; 529 | }; 530 | name = Release; 531 | }; 532 | 97C147061CF9000F007C117D /* Debug */ = { 533 | isa = XCBuildConfiguration; 534 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 535 | buildSettings = { 536 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 537 | CLANG_ENABLE_MODULES = YES; 538 | CODE_SIGN_STYLE = Manual; 539 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 540 | DEVELOPMENT_TEAM = ""; 541 | ENABLE_BITCODE = NO; 542 | FRAMEWORK_SEARCH_PATHS = ( 543 | "$(inherited)", 544 | "$(PROJECT_DIR)/Flutter", 545 | ); 546 | INFOPLIST_FILE = Runner/Info.plist; 547 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 548 | LIBRARY_SEARCH_PATHS = ( 549 | "$(inherited)", 550 | "$(PROJECT_DIR)/Flutter", 551 | ); 552 | PRODUCT_BUNDLE_IDENTIFIER = com.example.agoraFlutterQuickstart; 553 | PRODUCT_NAME = "$(TARGET_NAME)"; 554 | PROVISIONING_PROFILE_SPECIFIER = ""; 555 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 556 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 557 | SWIFT_VERSION = 5.0; 558 | VERSIONING_SYSTEM = "apple-generic"; 559 | }; 560 | name = Debug; 561 | }; 562 | 97C147071CF9000F007C117D /* Release */ = { 563 | isa = XCBuildConfiguration; 564 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 565 | buildSettings = { 566 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 567 | CLANG_ENABLE_MODULES = YES; 568 | CODE_SIGN_STYLE = Manual; 569 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 570 | DEVELOPMENT_TEAM = ""; 571 | ENABLE_BITCODE = NO; 572 | FRAMEWORK_SEARCH_PATHS = ( 573 | "$(inherited)", 574 | "$(PROJECT_DIR)/Flutter", 575 | ); 576 | INFOPLIST_FILE = Runner/Info.plist; 577 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 578 | LIBRARY_SEARCH_PATHS = ( 579 | "$(inherited)", 580 | "$(PROJECT_DIR)/Flutter", 581 | ); 582 | PRODUCT_BUNDLE_IDENTIFIER = com.example.agoraFlutterQuickstart; 583 | PRODUCT_NAME = "$(TARGET_NAME)"; 584 | PROVISIONING_PROFILE_SPECIFIER = ""; 585 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 586 | SWIFT_VERSION = 5.0; 587 | VERSIONING_SYSTEM = "apple-generic"; 588 | }; 589 | name = Release; 590 | }; 591 | /* End XCBuildConfiguration section */ 592 | 593 | /* Begin XCConfigurationList section */ 594 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 595 | isa = XCConfigurationList; 596 | buildConfigurations = ( 597 | 97C147031CF9000F007C117D /* Debug */, 598 | 97C147041CF9000F007C117D /* Release */, 599 | 249021D3217E4FDB00AE95B9 /* Profile */, 600 | ); 601 | defaultConfigurationIsVisible = 0; 602 | defaultConfigurationName = Release; 603 | }; 604 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 605 | isa = XCConfigurationList; 606 | buildConfigurations = ( 607 | 97C147061CF9000F007C117D /* Debug */, 608 | 97C147071CF9000F007C117D /* Release */, 609 | 249021D4217E4FDB00AE95B9 /* Profile */, 610 | ); 611 | defaultConfigurationIsVisible = 0; 612 | defaultConfigurationName = Release; 613 | }; 614 | /* End XCConfigurationList section */ 615 | }; 616 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 617 | } 618 | --------------------------------------------------------------------------------