├── .gitignore
├── .metadata
├── README.md
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── flutter_bloc_architecture
│ │ │ │ └── MainActivity.kt
│ │ └── res
│ │ │ ├── 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
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── fonts
│ ├── ArialRoundedMTBold.ttf
│ ├── Muli-Bold.ttf
│ ├── OpenSans-Bold.ttf
│ ├── OpenSans-Light.ttf
│ ├── OpenSans-Regular.ttf
│ └── OpenSans-Semibold.ttf
└── images
│ ├── logo.png
│ └── powered_by.png
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ └── contents.xcworkspacedata
└── 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
├── lib
├── main.dart
└── src
│ ├── bloc
│ ├── bottom_nav
│ │ ├── bottom_nav_cubit.dart
│ │ └── checkbox_cubit.dart
│ └── login
│ │ ├── login.dart
│ │ ├── login_bloc.dart
│ │ ├── login_event.dart
│ │ └── login_state.dart
│ ├── bloc_delegate
│ └── simple_bloc_delegate.dart
│ ├── constants
│ ├── font_constants.dart
│ ├── page_route_constants.dart
│ ├── regex_constant.dart
│ ├── string_constant.dart
│ └── url_constant.dart
│ ├── di
│ └── app_config.dart
│ ├── localization
│ └── app_localizations.dart
│ ├── models
│ ├── local_data_models
│ │ └── login_user_details.dart
│ └── network_data_models
│ │ └── login
│ │ ├── request
│ │ ├── login_request.dart
│ │ └── login_request.g.dart
│ │ └── response
│ │ ├── data.dart
│ │ ├── data.g.dart
│ │ ├── login_response.dart
│ │ ├── login_response.g.dart
│ │ ├── result.dart
│ │ └── result.g.dart
│ ├── my_app.dart
│ ├── network
│ ├── api_client
│ │ ├── api_rest_client.dart
│ │ └── api_rest_client.g.dart
│ └── repository
│ │ └── api_repository.dart
│ ├── resources
│ ├── app_colors.dart
│ ├── app_localization.dart
│ ├── app_theme.dart
│ ├── dimens.dart
│ ├── font_family.dart
│ ├── hex_color.dart
│ └── text_styles.dart
│ ├── sharedpref
│ ├── constants
│ │ └── preferences.dart
│ └── preference_connector.dart
│ ├── ui
│ ├── common
│ │ └── ui_helpers.dart
│ ├── custom_widgets
│ │ └── custom_text_field.dart
│ └── screens
│ │ ├── home
│ │ └── home_screen.dart
│ │ ├── login
│ │ └── login_screen.dart
│ │ └── splash
│ │ └── splash_screen.dart
│ └── utils
│ ├── date_time_util.dart
│ ├── device_utils.dart
│ ├── helper.dart
│ ├── navigation_service.dart
│ ├── screen_router.dart
│ ├── url_launcher.dart
│ ├── utils.dart
│ └── validator.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── widget_test.dart
/.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 | # Web related
34 | lib/generated_plugin_registrant.dart
35 |
36 | # Exceptions to above rules.
37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
38 |
--------------------------------------------------------------------------------
/.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: 0b8abb4724aa590dd0f429683339b1e045a1594d
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Flutter Bloc Architecture
2 |
3 |
4 | # flutter_bloc [](https://pub.dev/packages/flutter_bloc)
5 |
6 | Flutter Widgets that make it easy to implement the BLoC (Business Logic Component) design pattern. Built to be used with the bloc state management package.
7 |
8 | ## *Why Bloc?*
9 | Bloc makes it easy to separate presentation from business logic, making your code fast, easy to test, and reusable.
10 |
11 |
12 | When building production quality applications, managing state becomes critical.
13 |
14 | As developers we want to:
15 |
16 | - know what state our application is in at any point in time.
17 | - easily test every case to make sure our app is responding appropriately.
18 | - record every single user interaction in our application so that we can make data-driven decisions.
19 | - work as efficiently as possible and reuse components both within our application and across other applications.
20 | - have many developers seamlessly working within a single code base following the same patterns and conventions.
21 | - develop fast and reactive apps.
22 |
23 | There are many state management solutions and deciding which one to use can be a daunting task.
24 |
25 | Bloc was designed with three core values in mind:
26 |
27 | - Simple
28 |
29 | - Easy to understand & can be used by developers with varying skill levels.
30 | - Powerful
31 |
32 | - Help make amazing, complex applications by composing them of smaller components.
33 |
34 | - Testable
35 |
36 | - Easily test every aspect of an application so that we can iterate with confidence.
37 |
38 | Bloc attempts to make state changes predictable by regulating when a state change can occur and enforcing a single way to change state throughout an entire application.
39 |
40 | ## *Architecture*
41 |
42 |
43 |
44 |
45 | Using Bloc allows us to separate our application into three layers:
46 |
47 | - Data
48 |
49 | - Data Provider
50 |
51 | - Repository
52 |
53 | - Business Logic
54 | - Presentation
55 |
56 | We're going to start at the lowest level layer (farthest from the user interface) and work our way up to the presentation layer.
57 |
58 | ## *Data Layer*
59 | The data layer's responsibility is to retrieve/manipulate data from one or more sources.
60 |
61 | The data layer can be split into two parts:
62 |
63 | - Repository
64 | - Data Provide
65 |
66 | This layer is the lowest level of the application and interacts with databases, network requests, and other asynchronous data sources.
67 |
68 | ## *Data Provider*
69 |
70 | The data provider's responsibility is to provide raw data. The data provider should be generic and versatile.
71 |
72 | The data provider will usually expose simple APIs to perform CRUD operations. We might have a createData, readData, updateData, and deleteData method as part of our data layer.
73 |
74 | ```dart
75 | #Login Request
76 |
77 | @JsonSerializable()
78 | class LoginRequest {
79 | String email;
80 | String password;
81 |
82 | LoginRequest({
83 | this.email,
84 | this.password,
85 | });
86 |
87 | factory LoginRequest.fromJson(Map json) =>
88 | _$LoginRequestFromJson(json);
89 |
90 | Map toJson() => _$LoginRequestToJson(this);
91 | }
92 |
93 | #Login Response
94 |
95 | @JsonSerializable()
96 | class LoginResponse {
97 | String status;
98 | int code;
99 | String message;
100 | Result result;
101 |
102 | LoginResponse({
103 | this.status,
104 | this.code,
105 | this.message,
106 | this.result,
107 | });
108 |
109 | factory LoginResponse.fromJson(Map json) =>
110 | _$LoginResponseFromJson(json);
111 |
112 | Map toJson() => _$LoginResponseToJson(this);
113 | }
114 |
115 | ```
116 | ## *Repository*
117 |
118 | The repository layer is a wrapper around one or more data providers with which the Bloc Layer communicates.
119 |
120 | ```dart
121 | class ApiRepository {
122 | ApiRestClient apiRestClient;
123 |
124 | ApiRepository() {
125 | Dio _dio = Dio();
126 | _dio.options.headers["Content-Type"] = "application/json";
127 | apiRestClient = ApiRestClient(_dio);
128 | }
129 |
130 | Future login({
131 | @required String email,
132 | @required String password,
133 | }) async {
134 | LoginRequest loginRequest = LoginRequest(
135 | email: email,
136 | password: password,
137 | );
138 | return await ApiRestClient(Dio()).login(loginRequest);
139 | }
140 | }
141 | ```
142 | As you can see, our repository layer can interact with multiple data providers and perform transformations on the data before handing the result to the business logic Layer.
143 |
144 | ## *Bloc (Business Logic) Layer*
145 |
146 | The bloc layer's responsibility is to respond to events from the presentation layer with new states. The bloc layer can depend on one or more repositories to retrieve data needed to build up the application state.
147 |
148 | Think of the bloc layer as the bridge between the user interface (presentation layer) and the data layer. The bloc layer takes events generated by user input and then communicates with repository in order to build a new state for the presentation layer to consume.
149 |
150 | ```dart
151 | class LoginBloc extends Bloc {
152 | final ApiRepository apiRepository;
153 | final Validator validator = Validator();
154 |
155 | LoginBloc({@required this.apiRepository});
156 |
157 | @override
158 | LoginState get initialState => UserUnavailable();
159 |
160 | @override
161 | Stream mapEventToState(LoginEvent event) async* {
162 | if (event is SignInUser) {
163 | yield LoginLoading();
164 | try {
165 | LoginResponse loginResponse = await apiRepository.login(
166 | email: event.email,
167 | password: event.password,
168 | );
169 | if (loginResponse != null) {
170 | Helper.printLogValue("UserLoggedIn");
171 | yield UserLoggedIn();
172 | } else {
173 | Helper.printLogValue("UserLoggedOut");
174 | yield UserLoggedOut();
175 | }
176 | } catch (error) {
177 | Helper.printLogValue("LoginFailure");
178 | yield LoginFailure(error: error.toString());
179 | }
180 | }
181 | if (event is PasswordChanged) {
182 | yield state.copyWith(
183 | isPasswordValid: _isPasswordValid(event.password),
184 | );
185 | }
186 |
187 | if (event is EmailChanged) {
188 | yield state.copyWith(
189 | isEmailValid: _isEmailValid(event.email),
190 | );
191 | }
192 | }
193 |
194 | bool _isEmailValid(String email) {
195 | return validator.validateEmail(email);
196 | }
197 |
198 | bool _isPasswordValid(String password) {
199 | return validator.validatePassword(password);
200 | }
201 | }
202 |
203 | ```
204 | ## *Presentation Layer*
205 |
206 | The presentation layer's responsibility is to figure out how to render itself based on one or more bloc states. In addition, it should handle user input and application lifecycle events.
207 |
208 | ```dart
209 | Container(
210 | width: size.width,
211 | height: kBottomNavigationBarHeight,
212 | child: BlocListener(
213 | listener: (context, state) {
214 | if (state is UserLoggedIn) {
215 | Navigator.of(context).pushNamedAndRemoveUntil(
216 | PageRouteConstants.home_screen,
217 | (Route route) => false);
218 | } else if (state is LoginFailure) {
219 | Helper.showAlert(context, StringConstant.error_message,
220 | StringConstant.invalid_user_credentials);
221 | }
222 | },
223 | child: BlocBuilder(
224 | builder: (context, state) {
225 | if (state is LoginLoading) {
226 | return Helper.progressWidget(progressKey);
227 | } else {
228 | return RaisedButton(
229 | child: Text(
230 | StringConstant.sign_in,
231 | style: AppTextStyles.getMediumText(
232 | size.width, AppColors.white, FontConstant.kSemiBold),
233 | ),
234 | onPressed: () {
235 | if (!(_emailController.text.length > 0) ||
236 | !state.isEmailValid) {
237 | showInSnackBar(StringConstant.invalid_email);
238 | } else if (!(_passwordController.text.length > 0) ||
239 | !state.isPasswordValid) {
240 | showInSnackBar(StringConstant.invalid_password);
241 | } else {
242 | Helper.checkConnectivity().then((internetStatus) {
243 | if (internetStatus) {
244 | if (progressKey.currentWidget == null) {
245 | BlocProvider.of(context).add(
246 | SignInUser(
247 | email: _emailController.text,
248 | password: _passwordController.text,
249 | ),
250 | );
251 | }
252 | } else {
253 | Helper.showAlert(context, StringConstant.internet_alert,
254 | StringConstant.please_check_internet_connectivity);
255 | }
256 | });
257 | }
258 | },
259 | color: Theme.of(context).primaryColor,
260 | shape: RoundedRectangleBorder(
261 | borderRadius: BorderRadius.circular(Dimens.px28),
262 | ),
263 | );
264 | }
265 | },
266 | ),
267 | ),
268 | );
269 | ```
270 | ## *Pros of BLoC*
271 |
272 | - Easy to separate UI from logic
273 | - Easy to test code
274 | - Easy to reuse code
275 | - Good performance
276 |
277 | ## *Cons of BLoC*
278 |
279 | - Technically, you need to use streams in both directions, creating a lot of boilerplate. However, many people cheat this by using streams only from the backend to the UI, but when events occur they’re simply calling functions directly instead of feeding those events into a sink.
280 |
281 | - More boilerplate for small app, but it can be worth it for anything larger than a small app.
282 |
283 | ## *Refrences*
284 | 1. https://bloclibrary.dev
285 | 2. https://pub.dev/packages/bloc
286 | 3. https://flutter.dev/
287 | 4. https://blog.codemagic.io/flutter-tutorial-pros-and-cons-of-state-management-approaches/
288 |
289 | ## *User login credentials*
290 | ```json
291 | {
292 | "email":"paras@aeologic.com",
293 | "password":"Paras@123"
294 | }
295 | ```
296 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
--------------------------------------------------------------------------------
/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 plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | compileSdkVersion 28
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | lintOptions {
36 | disable 'InvalidPackage'
37 | }
38 |
39 | defaultConfig {
40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
41 | applicationId "com.example.flutter_bloc_architecture"
42 | minSdkVersion 16
43 | targetSdkVersion 28
44 | versionCode flutterVersionCode.toInteger()
45 | versionName flutterVersionName
46 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
47 | }
48 |
49 | buildTypes {
50 | release {
51 | // TODO: Add your own signing config for the release build.
52 | // Signing with the debug keys for now, so `flutter run --release` works.
53 | signingConfig signingConfigs.debug
54 | }
55 | }
56 | }
57 |
58 | flutter {
59 | source '../..'
60 | }
61 |
62 | dependencies {
63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
64 | testImplementation 'junit:junit:4.12'
65 | androidTestImplementation 'androidx.test:runner:1.1.1'
66 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
67 | }
68 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
26 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/flutter_bloc_architecture/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.flutter_bloc_architecture
2 |
3 | import androidx.annotation.NonNull;
4 | import io.flutter.embedding.android.FlutterActivity
5 | import io.flutter.embedding.engine.FlutterEngine
6 | import io.flutter.plugins.GeneratedPluginRegistrant
7 |
8 | class MainActivity: FlutterActivity() {
9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
10 | GeneratedPluginRegistrant.registerWith(flutterEngine);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.5.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
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 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/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-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/assets/fonts/ArialRoundedMTBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/assets/fonts/ArialRoundedMTBold.ttf
--------------------------------------------------------------------------------
/assets/fonts/Muli-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/assets/fonts/Muli-Bold.ttf
--------------------------------------------------------------------------------
/assets/fonts/OpenSans-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/assets/fonts/OpenSans-Bold.ttf
--------------------------------------------------------------------------------
/assets/fonts/OpenSans-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/assets/fonts/OpenSans-Light.ttf
--------------------------------------------------------------------------------
/assets/fonts/OpenSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/assets/fonts/OpenSans-Regular.ttf
--------------------------------------------------------------------------------
/assets/fonts/OpenSans-Semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/assets/fonts/OpenSans-Semibold.ttf
--------------------------------------------------------------------------------
/assets/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/assets/images/logo.png
--------------------------------------------------------------------------------
/assets/images/powered_by.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/assets/images/powered_by.png
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/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 parse_KV_file(file, separator='=')
14 | file_abs_path = File.expand_path(file)
15 | if !File.exists? file_abs_path
16 | return [];
17 | end
18 | generated_key_values = {}
19 | skip_line_start_symbols = ["#", "/"]
20 | File.foreach(file_abs_path) do |line|
21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
22 | plugin = line.split(pattern=separator)
23 | if plugin.length == 2
24 | podname = plugin[0].strip()
25 | path = plugin[1].strip()
26 | podpath = File.expand_path("#{path}", file_abs_path)
27 | generated_key_values[podname] = podpath
28 | else
29 | puts "Invalid plugin specification: #{line}"
30 | end
31 | end
32 | generated_key_values
33 | end
34 |
35 | target 'Runner' do
36 | use_frameworks!
37 | use_modular_headers!
38 |
39 | # Flutter Pod
40 |
41 | copied_flutter_dir = File.join(__dir__, 'Flutter')
42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
48 |
49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
50 | unless File.exist?(generated_xcode_build_settings_path)
51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
52 | end
53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
55 |
56 | unless File.exist?(copied_framework_path)
57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
58 | end
59 | unless File.exist?(copied_podspec_path)
60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
61 | end
62 | end
63 |
64 | # Keep pod path relative so it can be checked into Podfile.lock.
65 | pod 'Flutter', :path => 'Flutter'
66 |
67 | # Plugin Pods
68 |
69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
70 | # referring to absolute paths on developers' machines.
71 | system('rm -rf .symlinks')
72 | system('mkdir -p .symlinks/plugins')
73 | plugin_pods = parse_KV_file('../.flutter-plugins')
74 | plugin_pods.each do |name, path|
75 | symlink = File.join('.symlinks', 'plugins', name)
76 | File.symlink(path, symlink)
77 | pod name, :path => File.join(symlink, 'ios')
78 | end
79 | end
80 |
81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
82 | install! 'cocoapods', :disable_input_output_paths => true
83 |
84 | post_install do |installer|
85 | installer.pods_project.targets.each do |target|
86 | target.build_configurations.each do |config|
87 | config.build_settings['ENABLE_BITCODE'] = 'NO'
88 | end
89 | end
90 | end
91 |
--------------------------------------------------------------------------------
/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - path_provider (0.0.1):
4 | - Flutter
5 | - path_provider_macos (0.0.1):
6 | - Flutter
7 | - shared_preferences (0.0.1):
8 | - Flutter
9 | - shared_preferences_macos (0.0.1):
10 | - Flutter
11 | - shared_preferences_web (0.0.1):
12 | - Flutter
13 | - url_launcher (0.0.1):
14 | - Flutter
15 | - url_launcher_macos (0.0.1):
16 | - Flutter
17 | - url_launcher_web (0.0.1):
18 | - Flutter
19 |
20 | DEPENDENCIES:
21 | - Flutter (from `Flutter`)
22 | - path_provider (from `.symlinks/plugins/path_provider/ios`)
23 | - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`)
24 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
25 | - shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`)
26 | - shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`)
27 | - url_launcher (from `.symlinks/plugins/url_launcher/ios`)
28 | - url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`)
29 | - url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`)
30 |
31 | EXTERNAL SOURCES:
32 | Flutter:
33 | :path: Flutter
34 | path_provider:
35 | :path: ".symlinks/plugins/path_provider/ios"
36 | path_provider_macos:
37 | :path: ".symlinks/plugins/path_provider_macos/ios"
38 | shared_preferences:
39 | :path: ".symlinks/plugins/shared_preferences/ios"
40 | shared_preferences_macos:
41 | :path: ".symlinks/plugins/shared_preferences_macos/ios"
42 | shared_preferences_web:
43 | :path: ".symlinks/plugins/shared_preferences_web/ios"
44 | url_launcher:
45 | :path: ".symlinks/plugins/url_launcher/ios"
46 | url_launcher_macos:
47 | :path: ".symlinks/plugins/url_launcher_macos/ios"
48 | url_launcher_web:
49 | :path: ".symlinks/plugins/url_launcher_web/ios"
50 |
51 | SPEC CHECKSUMS:
52 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
53 | path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d
54 | path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
55 | shared_preferences: 430726339841afefe5142b9c1f50cb6bd7793e01
56 | shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087
57 | shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9
58 | url_launcher: a1c0cc845906122c4784c542523d8cacbded5626
59 | url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313
60 | url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c
61 |
62 | PODFILE CHECKSUM: 1b66dae606f75376c5f2135a8290850eeb09ae83
63 |
64 | COCOAPODS: 1.8.4
65 |
--------------------------------------------------------------------------------
/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 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
15 | 8C19605C9CD80196A2A080A7 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAFCC0DB5DD9156BCE4FBB4B /* Pods_Runner.framework */; };
16 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
17 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
18 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
19 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
20 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
21 | /* End PBXBuildFile section */
22 |
23 | /* Begin PBXCopyFilesBuildPhase section */
24 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
25 | isa = PBXCopyFilesBuildPhase;
26 | buildActionMask = 2147483647;
27 | dstPath = "";
28 | dstSubfolderSpec = 10;
29 | files = (
30 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
31 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
32 | );
33 | name = "Embed Frameworks";
34 | runOnlyForDeploymentPostprocessing = 0;
35 | };
36 | /* End PBXCopyFilesBuildPhase section */
37 |
38 | /* Begin PBXFileReference section */
39 | 0BC3DEF66F606C30C298C59E /* 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 = ""; };
40 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
41 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
42 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
43 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
44 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
45 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
46 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
47 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
48 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
49 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
50 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
51 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
52 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
53 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
54 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
55 | AAFCC0DB5DD9156BCE4FBB4B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
56 | ABFBF0F6C0BB453E818F25B3 /* 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 = ""; };
57 | B73E8A5028C8A5587D0F9C34 /* 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 = ""; };
58 | /* End PBXFileReference section */
59 |
60 | /* Begin PBXFrameworksBuildPhase section */
61 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
66 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
67 | 8C19605C9CD80196A2A080A7 /* Pods_Runner.framework in Frameworks */,
68 | );
69 | runOnlyForDeploymentPostprocessing = 0;
70 | };
71 | /* End PBXFrameworksBuildPhase section */
72 |
73 | /* Begin PBXGroup section */
74 | 53C1D23CFA3EC158D337C074 /* Pods */ = {
75 | isa = PBXGroup;
76 | children = (
77 | ABFBF0F6C0BB453E818F25B3 /* Pods-Runner.debug.xcconfig */,
78 | B73E8A5028C8A5587D0F9C34 /* Pods-Runner.release.xcconfig */,
79 | 0BC3DEF66F606C30C298C59E /* Pods-Runner.profile.xcconfig */,
80 | );
81 | name = Pods;
82 | path = Pods;
83 | sourceTree = "";
84 | };
85 | 9740EEB11CF90186004384FC /* Flutter */ = {
86 | isa = PBXGroup;
87 | children = (
88 | 3B80C3931E831B6300D905FE /* App.framework */,
89 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
90 | 9740EEBA1CF902C7004384FC /* Flutter.framework */,
91 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
92 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
93 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
94 | );
95 | name = Flutter;
96 | sourceTree = "";
97 | };
98 | 97C146E51CF9000F007C117D = {
99 | isa = PBXGroup;
100 | children = (
101 | 9740EEB11CF90186004384FC /* Flutter */,
102 | 97C146F01CF9000F007C117D /* Runner */,
103 | 97C146EF1CF9000F007C117D /* Products */,
104 | 53C1D23CFA3EC158D337C074 /* Pods */,
105 | F6BB80108ED49A1A7112BC4A /* Frameworks */,
106 | );
107 | sourceTree = "";
108 | };
109 | 97C146EF1CF9000F007C117D /* Products */ = {
110 | isa = PBXGroup;
111 | children = (
112 | 97C146EE1CF9000F007C117D /* Runner.app */,
113 | );
114 | name = Products;
115 | sourceTree = "";
116 | };
117 | 97C146F01CF9000F007C117D /* Runner */ = {
118 | isa = PBXGroup;
119 | children = (
120 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
121 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
122 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
123 | 97C147021CF9000F007C117D /* Info.plist */,
124 | 97C146F11CF9000F007C117D /* Supporting Files */,
125 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
126 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
127 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
128 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
129 | );
130 | path = Runner;
131 | sourceTree = "";
132 | };
133 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
134 | isa = PBXGroup;
135 | children = (
136 | );
137 | name = "Supporting Files";
138 | sourceTree = "";
139 | };
140 | F6BB80108ED49A1A7112BC4A /* Frameworks */ = {
141 | isa = PBXGroup;
142 | children = (
143 | AAFCC0DB5DD9156BCE4FBB4B /* Pods_Runner.framework */,
144 | );
145 | name = Frameworks;
146 | sourceTree = "";
147 | };
148 | /* End PBXGroup section */
149 |
150 | /* Begin PBXNativeTarget section */
151 | 97C146ED1CF9000F007C117D /* Runner */ = {
152 | isa = PBXNativeTarget;
153 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
154 | buildPhases = (
155 | B28BD5474FCCE4212C19425B /* [CP] Check Pods Manifest.lock */,
156 | 9740EEB61CF901F6004384FC /* Run Script */,
157 | 97C146EA1CF9000F007C117D /* Sources */,
158 | 97C146EB1CF9000F007C117D /* Frameworks */,
159 | 97C146EC1CF9000F007C117D /* Resources */,
160 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
161 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
162 | D5B293E27F4C0C09E9C34420 /* [CP] Embed Pods Frameworks */,
163 | );
164 | buildRules = (
165 | );
166 | dependencies = (
167 | );
168 | name = Runner;
169 | productName = Runner;
170 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
171 | productType = "com.apple.product-type.application";
172 | };
173 | /* End PBXNativeTarget section */
174 |
175 | /* Begin PBXProject section */
176 | 97C146E61CF9000F007C117D /* Project object */ = {
177 | isa = PBXProject;
178 | attributes = {
179 | LastUpgradeCheck = 1020;
180 | ORGANIZATIONNAME = "The Chromium Authors";
181 | TargetAttributes = {
182 | 97C146ED1CF9000F007C117D = {
183 | CreatedOnToolsVersion = 7.3.1;
184 | LastSwiftMigration = 1100;
185 | };
186 | };
187 | };
188 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
189 | compatibilityVersion = "Xcode 3.2";
190 | developmentRegion = en;
191 | hasScannedForEncodings = 0;
192 | knownRegions = (
193 | en,
194 | Base,
195 | );
196 | mainGroup = 97C146E51CF9000F007C117D;
197 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
198 | projectDirPath = "";
199 | projectRoot = "";
200 | targets = (
201 | 97C146ED1CF9000F007C117D /* Runner */,
202 | );
203 | };
204 | /* End PBXProject section */
205 |
206 | /* Begin PBXResourcesBuildPhase section */
207 | 97C146EC1CF9000F007C117D /* Resources */ = {
208 | isa = PBXResourcesBuildPhase;
209 | buildActionMask = 2147483647;
210 | files = (
211 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
212 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
213 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
214 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
215 | );
216 | runOnlyForDeploymentPostprocessing = 0;
217 | };
218 | /* End PBXResourcesBuildPhase section */
219 |
220 | /* Begin PBXShellScriptBuildPhase section */
221 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
222 | isa = PBXShellScriptBuildPhase;
223 | buildActionMask = 2147483647;
224 | files = (
225 | );
226 | inputPaths = (
227 | );
228 | name = "Thin Binary";
229 | outputPaths = (
230 | );
231 | runOnlyForDeploymentPostprocessing = 0;
232 | shellPath = /bin/sh;
233 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
234 | };
235 | 9740EEB61CF901F6004384FC /* Run Script */ = {
236 | isa = PBXShellScriptBuildPhase;
237 | buildActionMask = 2147483647;
238 | files = (
239 | );
240 | inputPaths = (
241 | );
242 | name = "Run Script";
243 | outputPaths = (
244 | );
245 | runOnlyForDeploymentPostprocessing = 0;
246 | shellPath = /bin/sh;
247 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
248 | };
249 | B28BD5474FCCE4212C19425B /* [CP] Check Pods Manifest.lock */ = {
250 | isa = PBXShellScriptBuildPhase;
251 | buildActionMask = 2147483647;
252 | files = (
253 | );
254 | inputFileListPaths = (
255 | );
256 | inputPaths = (
257 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
258 | "${PODS_ROOT}/Manifest.lock",
259 | );
260 | name = "[CP] Check Pods Manifest.lock";
261 | outputFileListPaths = (
262 | );
263 | outputPaths = (
264 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
265 | );
266 | runOnlyForDeploymentPostprocessing = 0;
267 | shellPath = /bin/sh;
268 | 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";
269 | showEnvVarsInLog = 0;
270 | };
271 | D5B293E27F4C0C09E9C34420 /* [CP] Embed Pods Frameworks */ = {
272 | isa = PBXShellScriptBuildPhase;
273 | buildActionMask = 2147483647;
274 | files = (
275 | );
276 | inputPaths = (
277 | );
278 | name = "[CP] Embed Pods Frameworks";
279 | outputPaths = (
280 | );
281 | runOnlyForDeploymentPostprocessing = 0;
282 | shellPath = /bin/sh;
283 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
284 | showEnvVarsInLog = 0;
285 | };
286 | /* End PBXShellScriptBuildPhase section */
287 |
288 | /* Begin PBXSourcesBuildPhase section */
289 | 97C146EA1CF9000F007C117D /* Sources */ = {
290 | isa = PBXSourcesBuildPhase;
291 | buildActionMask = 2147483647;
292 | files = (
293 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
294 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
295 | );
296 | runOnlyForDeploymentPostprocessing = 0;
297 | };
298 | /* End PBXSourcesBuildPhase section */
299 |
300 | /* Begin PBXVariantGroup section */
301 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
302 | isa = PBXVariantGroup;
303 | children = (
304 | 97C146FB1CF9000F007C117D /* Base */,
305 | );
306 | name = Main.storyboard;
307 | sourceTree = "";
308 | };
309 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
310 | isa = PBXVariantGroup;
311 | children = (
312 | 97C147001CF9000F007C117D /* Base */,
313 | );
314 | name = LaunchScreen.storyboard;
315 | sourceTree = "";
316 | };
317 | /* End PBXVariantGroup section */
318 |
319 | /* Begin XCBuildConfiguration section */
320 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
321 | isa = XCBuildConfiguration;
322 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
323 | buildSettings = {
324 | ALWAYS_SEARCH_USER_PATHS = NO;
325 | CLANG_ANALYZER_NONNULL = YES;
326 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
327 | CLANG_CXX_LIBRARY = "libc++";
328 | CLANG_ENABLE_MODULES = YES;
329 | CLANG_ENABLE_OBJC_ARC = YES;
330 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
331 | CLANG_WARN_BOOL_CONVERSION = YES;
332 | CLANG_WARN_COMMA = YES;
333 | CLANG_WARN_CONSTANT_CONVERSION = YES;
334 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
335 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
336 | CLANG_WARN_EMPTY_BODY = YES;
337 | CLANG_WARN_ENUM_CONVERSION = YES;
338 | CLANG_WARN_INFINITE_RECURSION = YES;
339 | CLANG_WARN_INT_CONVERSION = YES;
340 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
341 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
342 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
343 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
344 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
345 | CLANG_WARN_STRICT_PROTOTYPES = YES;
346 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
347 | CLANG_WARN_UNREACHABLE_CODE = YES;
348 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
349 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
350 | COPY_PHASE_STRIP = NO;
351 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
352 | ENABLE_NS_ASSERTIONS = NO;
353 | ENABLE_STRICT_OBJC_MSGSEND = YES;
354 | GCC_C_LANGUAGE_STANDARD = gnu99;
355 | GCC_NO_COMMON_BLOCKS = YES;
356 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
357 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
358 | GCC_WARN_UNDECLARED_SELECTOR = YES;
359 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
360 | GCC_WARN_UNUSED_FUNCTION = YES;
361 | GCC_WARN_UNUSED_VARIABLE = YES;
362 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
363 | MTL_ENABLE_DEBUG_INFO = NO;
364 | SDKROOT = iphoneos;
365 | SUPPORTED_PLATFORMS = iphoneos;
366 | TARGETED_DEVICE_FAMILY = "1,2";
367 | VALIDATE_PRODUCT = YES;
368 | };
369 | name = Profile;
370 | };
371 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
372 | isa = XCBuildConfiguration;
373 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
374 | buildSettings = {
375 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
376 | CLANG_ENABLE_MODULES = YES;
377 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
378 | ENABLE_BITCODE = NO;
379 | FRAMEWORK_SEARCH_PATHS = (
380 | "$(inherited)",
381 | "$(PROJECT_DIR)/Flutter",
382 | );
383 | INFOPLIST_FILE = Runner/Info.plist;
384 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
385 | LIBRARY_SEARCH_PATHS = (
386 | "$(inherited)",
387 | "$(PROJECT_DIR)/Flutter",
388 | );
389 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBlocArchitecture;
390 | PRODUCT_NAME = "$(TARGET_NAME)";
391 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
392 | SWIFT_VERSION = 5.0;
393 | VERSIONING_SYSTEM = "apple-generic";
394 | };
395 | name = Profile;
396 | };
397 | 97C147031CF9000F007C117D /* Debug */ = {
398 | isa = XCBuildConfiguration;
399 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
400 | buildSettings = {
401 | ALWAYS_SEARCH_USER_PATHS = NO;
402 | CLANG_ANALYZER_NONNULL = YES;
403 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
404 | CLANG_CXX_LIBRARY = "libc++";
405 | CLANG_ENABLE_MODULES = YES;
406 | CLANG_ENABLE_OBJC_ARC = YES;
407 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
408 | CLANG_WARN_BOOL_CONVERSION = YES;
409 | CLANG_WARN_COMMA = YES;
410 | CLANG_WARN_CONSTANT_CONVERSION = YES;
411 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
412 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
413 | CLANG_WARN_EMPTY_BODY = YES;
414 | CLANG_WARN_ENUM_CONVERSION = YES;
415 | CLANG_WARN_INFINITE_RECURSION = YES;
416 | CLANG_WARN_INT_CONVERSION = YES;
417 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
418 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
419 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
420 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
421 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
422 | CLANG_WARN_STRICT_PROTOTYPES = YES;
423 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
424 | CLANG_WARN_UNREACHABLE_CODE = YES;
425 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
426 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
427 | COPY_PHASE_STRIP = NO;
428 | DEBUG_INFORMATION_FORMAT = dwarf;
429 | ENABLE_STRICT_OBJC_MSGSEND = YES;
430 | ENABLE_TESTABILITY = YES;
431 | GCC_C_LANGUAGE_STANDARD = gnu99;
432 | GCC_DYNAMIC_NO_PIC = NO;
433 | GCC_NO_COMMON_BLOCKS = YES;
434 | GCC_OPTIMIZATION_LEVEL = 0;
435 | GCC_PREPROCESSOR_DEFINITIONS = (
436 | "DEBUG=1",
437 | "$(inherited)",
438 | );
439 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
440 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
441 | GCC_WARN_UNDECLARED_SELECTOR = YES;
442 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
443 | GCC_WARN_UNUSED_FUNCTION = YES;
444 | GCC_WARN_UNUSED_VARIABLE = YES;
445 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
446 | MTL_ENABLE_DEBUG_INFO = YES;
447 | ONLY_ACTIVE_ARCH = YES;
448 | SDKROOT = iphoneos;
449 | TARGETED_DEVICE_FAMILY = "1,2";
450 | };
451 | name = Debug;
452 | };
453 | 97C147041CF9000F007C117D /* Release */ = {
454 | isa = XCBuildConfiguration;
455 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
456 | buildSettings = {
457 | ALWAYS_SEARCH_USER_PATHS = NO;
458 | CLANG_ANALYZER_NONNULL = YES;
459 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
460 | CLANG_CXX_LIBRARY = "libc++";
461 | CLANG_ENABLE_MODULES = YES;
462 | CLANG_ENABLE_OBJC_ARC = YES;
463 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
464 | CLANG_WARN_BOOL_CONVERSION = YES;
465 | CLANG_WARN_COMMA = YES;
466 | CLANG_WARN_CONSTANT_CONVERSION = YES;
467 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
468 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
469 | CLANG_WARN_EMPTY_BODY = YES;
470 | CLANG_WARN_ENUM_CONVERSION = YES;
471 | CLANG_WARN_INFINITE_RECURSION = YES;
472 | CLANG_WARN_INT_CONVERSION = YES;
473 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
474 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
475 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
476 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
477 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
478 | CLANG_WARN_STRICT_PROTOTYPES = YES;
479 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
480 | CLANG_WARN_UNREACHABLE_CODE = YES;
481 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
482 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
483 | COPY_PHASE_STRIP = NO;
484 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
485 | ENABLE_NS_ASSERTIONS = NO;
486 | ENABLE_STRICT_OBJC_MSGSEND = YES;
487 | GCC_C_LANGUAGE_STANDARD = gnu99;
488 | GCC_NO_COMMON_BLOCKS = YES;
489 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
490 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
491 | GCC_WARN_UNDECLARED_SELECTOR = YES;
492 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
493 | GCC_WARN_UNUSED_FUNCTION = YES;
494 | GCC_WARN_UNUSED_VARIABLE = YES;
495 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
496 | MTL_ENABLE_DEBUG_INFO = NO;
497 | SDKROOT = iphoneos;
498 | SUPPORTED_PLATFORMS = iphoneos;
499 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
500 | TARGETED_DEVICE_FAMILY = "1,2";
501 | VALIDATE_PRODUCT = YES;
502 | };
503 | name = Release;
504 | };
505 | 97C147061CF9000F007C117D /* Debug */ = {
506 | isa = XCBuildConfiguration;
507 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
508 | buildSettings = {
509 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
510 | CLANG_ENABLE_MODULES = YES;
511 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
512 | ENABLE_BITCODE = NO;
513 | FRAMEWORK_SEARCH_PATHS = (
514 | "$(inherited)",
515 | "$(PROJECT_DIR)/Flutter",
516 | );
517 | INFOPLIST_FILE = Runner/Info.plist;
518 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
519 | LIBRARY_SEARCH_PATHS = (
520 | "$(inherited)",
521 | "$(PROJECT_DIR)/Flutter",
522 | );
523 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBlocArchitecture;
524 | PRODUCT_NAME = "$(TARGET_NAME)";
525 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
526 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
527 | SWIFT_VERSION = 5.0;
528 | VERSIONING_SYSTEM = "apple-generic";
529 | };
530 | name = Debug;
531 | };
532 | 97C147071CF9000F007C117D /* Release */ = {
533 | isa = XCBuildConfiguration;
534 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
535 | buildSettings = {
536 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
537 | CLANG_ENABLE_MODULES = YES;
538 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
539 | ENABLE_BITCODE = NO;
540 | FRAMEWORK_SEARCH_PATHS = (
541 | "$(inherited)",
542 | "$(PROJECT_DIR)/Flutter",
543 | );
544 | INFOPLIST_FILE = Runner/Info.plist;
545 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
546 | LIBRARY_SEARCH_PATHS = (
547 | "$(inherited)",
548 | "$(PROJECT_DIR)/Flutter",
549 | );
550 | PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBlocArchitecture;
551 | PRODUCT_NAME = "$(TARGET_NAME)";
552 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
553 | SWIFT_VERSION = 5.0;
554 | VERSIONING_SYSTEM = "apple-generic";
555 | };
556 | name = Release;
557 | };
558 | /* End XCBuildConfiguration section */
559 |
560 | /* Begin XCConfigurationList section */
561 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
562 | isa = XCConfigurationList;
563 | buildConfigurations = (
564 | 97C147031CF9000F007C117D /* Debug */,
565 | 97C147041CF9000F007C117D /* Release */,
566 | 249021D3217E4FDB00AE95B9 /* Profile */,
567 | );
568 | defaultConfigurationIsVisible = 0;
569 | defaultConfigurationName = Release;
570 | };
571 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
572 | isa = XCConfigurationList;
573 | buildConfigurations = (
574 | 97C147061CF9000F007C117D /* Debug */,
575 | 97C147071CF9000F007C117D /* Release */,
576 | 249021D4217E4FDB00AE95B9 /* Profile */,
577 | );
578 | defaultConfigurationIsVisible = 0;
579 | defaultConfigurationName = Release;
580 | };
581 | /* End XCConfigurationList section */
582 | };
583 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
584 | }
585 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/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/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/flutter-devs/Flutter-BlocArchitecture/49701125dc9c86cb19e8d0bb3d331447833636dc/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/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.
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | flutter_bloc_architecture
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_bloc/flutter_bloc.dart';
3 | import 'package:flutter_bloc_architecture/src/bloc_delegate/simple_bloc_delegate.dart';
4 | import 'package:flutter_bloc_architecture/src/di/app_config.dart';
5 | import 'package:flutter_bloc_architecture/src/my_app.dart';
6 |
7 | void main() {
8 | Bloc.observer = SimpleBlocDelegate();
9 | setupAppConfig();
10 | runApp(MyApp());
11 | }
12 |
--------------------------------------------------------------------------------
/lib/src/bloc/bottom_nav/bottom_nav_cubit.dart:
--------------------------------------------------------------------------------
1 | import 'package:bloc/bloc.dart';
2 |
3 | class BottomNavCubit extends Cubit {
4 | BottomNavCubit() : super(0);
5 |
6 | void selectTab(int index) {
7 | emit(index);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/src/bloc/bottom_nav/checkbox_cubit.dart:
--------------------------------------------------------------------------------
1 | import 'package:bloc/bloc.dart';
2 |
3 | class CheckboxCubit extends Cubit {
4 | CheckboxCubit() : super(false);
5 | void selectCheckBox(bool value) {
6 | emit(value);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/lib/src/bloc/login/login.dart:
--------------------------------------------------------------------------------
1 | export 'login_bloc.dart';
2 | export 'login_event.dart';
3 | export 'login_state.dart';
4 |
--------------------------------------------------------------------------------
/lib/src/bloc/login/login_bloc.dart:
--------------------------------------------------------------------------------
1 | import 'package:bloc/bloc.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_bloc_architecture/src/di/app_config.dart';
4 | import 'package:flutter_bloc_architecture/src/models/network_data_models/login/response/login_response.dart';
5 | import 'package:flutter_bloc_architecture/src/network/repository/api_repository.dart';
6 | import 'package:flutter_bloc_architecture/src/utils/helper.dart';
7 | import 'package:flutter_bloc_architecture/src/utils/validator.dart';
8 |
9 | import 'login.dart';
10 |
11 | class LoginBloc extends Bloc {
12 | final Validator validator = Validator();
13 |
14 | LoginBloc() : super(UserUnavailable());
15 |
16 | @override
17 | LoginState get initialState => UserUnavailable();
18 |
19 | @override
20 | Stream mapEventToState(LoginEvent event) async* {
21 | if (event is SignInUser) {
22 | yield LoginLoading();
23 | try {
24 | LoginResponse loginResponse = await appConfig().login(
25 | email: event.email,
26 | password: event.password,
27 | );
28 | if (loginResponse != null) {
29 | Helper.printLogValue("UserLoggedIn");
30 | yield UserLoggedIn();
31 | } else {
32 | Helper.printLogValue("UserLoggedOut");
33 | yield UserLoggedOut();
34 | }
35 | } catch (error) {
36 | Helper.printLogValue("LoginFailure");
37 | yield LoginFailure(error: error.toString());
38 | }
39 | }
40 | if (event is PasswordChanged) {
41 | yield state.copyWith(
42 | isPasswordValid: _isPasswordValid(event.password),
43 | );
44 | }
45 |
46 | if (event is EmailChanged) {
47 | yield state.copyWith(
48 | isEmailValid: _isEmailValid(event.email),
49 | );
50 | }
51 | }
52 | bool _isEmailValid(String email) {
53 | return validator.validateEmail(email);
54 | }
55 |
56 | bool _isPasswordValid(String password) {
57 | return validator.validatePassword(password);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/lib/src/bloc/login/login_event.dart:
--------------------------------------------------------------------------------
1 | import 'package:meta/meta.dart';
2 |
3 | abstract class LoginEvent {
4 | LoginEvent();
5 | }
6 |
7 | class EmailChanged extends LoginEvent {
8 | final String email;
9 |
10 | EmailChanged({@required this.email});
11 | }
12 |
13 | class PasswordChanged extends LoginEvent {
14 | final String password;
15 |
16 | PasswordChanged({@required this.password});
17 | }
18 |
19 | class SignInUser extends LoginEvent {
20 | final String email;
21 | final String password;
22 |
23 | SignInUser({
24 | this.email,
25 | @required this.password,
26 | });
27 | }
28 |
29 | class SignOutUser extends LoginEvent {}
30 |
31 | class AppStarted extends LoginEvent {}
32 |
33 | class AppRestarted extends LoginEvent {}
34 |
35 | class AppClose extends LoginEvent {}
36 |
37 | class CheckScreenStatus extends LoginEvent {}
38 |
39 | class HitRefreshApi extends LoginEvent {}
40 |
--------------------------------------------------------------------------------
/lib/src/bloc/login/login_state.dart:
--------------------------------------------------------------------------------
1 | class LoginState {
2 | final bool isEmailValid;
3 | final bool isPasswordValid;
4 |
5 | const LoginState({
6 | this.isEmailValid = true,
7 | this.isPasswordValid = true,
8 | });
9 |
10 | factory LoginState.initial() {
11 | return LoginState(
12 | isEmailValid: true,
13 | isPasswordValid: true,
14 | );
15 | }
16 |
17 | LoginState copyWith({
18 | bool isEmailValid,
19 | bool isPasswordValid,
20 | }) {
21 | return LoginState(
22 | isEmailValid: isEmailValid ?? this.isEmailValid,
23 | isPasswordValid: isPasswordValid ?? this.isPasswordValid,
24 | );
25 | }
26 |
27 | @override
28 | String toString() {
29 | return '''LoginState {
30 | isEmailValid: $isEmailValid,
31 | isPasswordValid: $isPasswordValid,
32 | }''';
33 | }
34 | }
35 |
36 | class LoginLoading extends LoginState {}
37 |
38 | class LoginFailure extends LoginState {
39 | var error;
40 |
41 | LoginFailure({this.error});
42 | }
43 |
44 | class UserLoggedIn extends LoginState {}
45 |
46 | class UserLoggedOut extends LoginState {}
47 |
48 | class UserUnavailable extends LoginState {}
49 |
--------------------------------------------------------------------------------
/lib/src/bloc_delegate/simple_bloc_delegate.dart:
--------------------------------------------------------------------------------
1 | import 'package:bloc/bloc.dart';
2 | import 'package:flutter_bloc/flutter_bloc.dart';
3 | class SimpleBlocDelegate extends BlocObserver {
4 | final bool verbose = false;
5 |
6 | @override
7 | void onEvent(Bloc bloc, Object event) {
8 | super.onEvent(bloc, event);
9 | print(event.toString());
10 | }
11 |
12 | @override
13 | void onTransition(Bloc bloc, Transition transition) {
14 | super.onTransition(bloc, transition);
15 | print('''
16 | ${bloc.runtimeType} - Transition {
17 | event: ${transition.event.runtimeType}
18 | currentState: ${transition.currentState.runtimeType}
19 | nextState: ${transition.nextState.runtimeType}
20 | }
21 | ''');
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/src/constants/font_constants.dart:
--------------------------------------------------------------------------------
1 | class FontConstant {
2 | static const String open_sans_semi_bold = 'OpenSans-Semibold';
3 | static const String open_sans_regular = 'OpenSans-Regular';
4 | static const String open_sans_light = 'OpenSans-Light';
5 | static const String open_sans_bold = 'OpenSans-Bold';
6 | static const String open_sans_muli_bold = 'Muli-Bold';
7 | static const String arial_rounded_mt_bold = 'ArialRoundedMTBold';
8 |
9 | static const int kBold = 1;
10 | static const int kSemiBold = 2;
11 | static const int kRegular = 3;
12 | static const int kLight = 4;
13 | static const int kArialRoundedMTBold = 5;
14 | }
15 |
--------------------------------------------------------------------------------
/lib/src/constants/page_route_constants.dart:
--------------------------------------------------------------------------------
1 | class PageRouteConstants {
2 | static const String home_screen = '/HomeScreeen';
3 | static const String splash_screen = '/SplashScreen';
4 | static const String login_screen = '/LoginScreen';
5 | }
6 |
--------------------------------------------------------------------------------
/lib/src/constants/regex_constant.dart:
--------------------------------------------------------------------------------
1 | class RegexConstant {
2 | static const valid_email =
3 | r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
4 | }
5 |
--------------------------------------------------------------------------------
/lib/src/constants/string_constant.dart:
--------------------------------------------------------------------------------
1 | class StringConstant {
2 | /*Validator class*/
3 |
4 | static const String empty_email = 'Email is Required';
5 | static const String invalid_email = 'Invalid Email';
6 | static const String empty_user_name = 'User-Name is Required';
7 | static const String invalid_user_name = 'Invalid User-Name';
8 | static const String password_hint = '**************';
9 | static const String invalid_password = 'Invalid Password';
10 | static const String error_message = 'Error Message';
11 | static const String empty_first_name = 'First Name is Required';
12 | static const String sign_in = 'Sign in';
13 | static const String invalid_user_credentials = "Invalid user credentials";
14 | static const app_name = "AppName";
15 | static const String email = 'Email';
16 | static const String welcome_to_home_screen = 'Welocome to Home Screen';
17 | static const String password = 'Password';
18 | static const String type_email = 'Type email';
19 | static const String no = 'No';
20 | static const String yes = 'Yes';
21 | static const String ok = 'Ok';
22 | static const String home = 'Home';
23 | static const String help = 'Self Help';
24 | static const String profile = 'Profile';
25 | static const String please_enter_email_address = "Please enter email address";
26 |
27 | static const String please_check_internet_connectivity =
28 | "Please check internet connectivity.";
29 | static const String internet_alert = "Internet Alert";
30 | }
31 |
--------------------------------------------------------------------------------
/lib/src/constants/url_constant.dart:
--------------------------------------------------------------------------------
1 | class UrlConstant {
2 | static const String BASE_URL =
3 | "http://phplaravel-358955-1115224.cloudwaysapps.com/api";
4 |
5 | //Login
6 | static const String LOGIN = "/login";
7 | }
8 |
--------------------------------------------------------------------------------
/lib/src/di/app_config.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_bloc_architecture/src/network/repository/api_repository.dart';
2 | import 'package:flutter_bloc_architecture/src/sharedpref/preference_connector.dart';
3 | import 'package:flutter_bloc_architecture/src/utils/navigation_service.dart';
4 | import 'package:get_it/get_it.dart';
5 |
6 | GetIt appConfig = GetIt.I;
7 |
8 | void setupAppConfig() {
9 | appConfig.registerFactory(() => ApiRepository());
10 | appConfig.registerFactory(() => NavigationService());
11 | appConfig.registerFactory(() => PreferenceConnector());
12 | }
13 |
--------------------------------------------------------------------------------
/lib/src/localization/app_localizations.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:flutter/foundation.dart' show SynchronousFuture;
4 | import 'package:flutter/material.dart';
5 |
6 | class AppLocalizations {
7 | AppLocalizations(this.locale);
8 |
9 | final Locale locale;
10 |
11 | static AppLocalizations of(BuildContext context) {
12 | return Localizations.of(context, AppLocalizations);
13 | }
14 |
15 | static Map> _localizedValues = {
16 | "en": {
17 | "app_name": "SampleApp",
18 | }
19 | };
20 |
21 | String get appName => _localizedValues[locale.languageCode]['app_name'];
22 | }
23 |
24 | class AppLocalizationsDelegate extends LocalizationsDelegate {
25 | const AppLocalizationsDelegate();
26 |
27 | @override
28 | bool isSupported(Locale locale) => ['en'].contains(locale.languageCode);
29 |
30 | @override
31 | Future load(Locale locale) {
32 | return SynchronousFuture(AppLocalizations(locale));
33 | }
34 |
35 | @override
36 | bool shouldReload(AppLocalizationsDelegate old) => false;
37 | }
38 |
--------------------------------------------------------------------------------
/lib/src/models/local_data_models/login_user_details.dart:
--------------------------------------------------------------------------------
1 | class LoginUserDetails {
2 | String userEmail;
3 | String password;
4 | }
5 |
--------------------------------------------------------------------------------
/lib/src/models/network_data_models/login/request/login_request.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'login_request.g.dart';
4 |
5 | @JsonSerializable()
6 | class LoginRequest {
7 | String email;
8 | String password;
9 |
10 | LoginRequest({
11 | this.email,
12 | this.password,
13 | });
14 |
15 | factory LoginRequest.fromJson(Map json) =>
16 | _$LoginRequestFromJson(json);
17 |
18 | Map toJson() => _$LoginRequestToJson(this);
19 | }
20 |
--------------------------------------------------------------------------------
/lib/src/models/network_data_models/login/request/login_request.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'login_request.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | LoginRequest _$LoginRequestFromJson(Map json) {
10 | return LoginRequest(
11 | email: json['email'] as String,
12 | password: json['password'] as String,
13 | );
14 | }
15 |
16 | Map _$LoginRequestToJson(LoginRequest instance) =>
17 | {
18 | 'email': instance.email,
19 | 'password': instance.password,
20 | };
21 |
--------------------------------------------------------------------------------
/lib/src/models/network_data_models/login/response/data.dart:
--------------------------------------------------------------------------------
1 | import 'package:json_annotation/json_annotation.dart';
2 |
3 | part 'data.g.dart';
4 |
5 | @JsonSerializable()
6 | class Data {
7 | String name;
8 | int id;
9 | String email;
10 | String gender;
11 | String region;
12 | String contact1;
13 | String contact2;
14 | String contact3;
15 | String contact4;
16 | String contact5;
17 | DateTime dob;
18 | String type;
19 |
20 | Data({
21 | this.name,
22 | this.id,
23 | this.email,
24 | this.gender,
25 | this.region,
26 | this.contact1,
27 | this.contact2,
28 | this.contact3,
29 | this.contact4,
30 | this.contact5,
31 | this.dob,
32 | this.type,
33 | });
34 |
35 | factory Data.fromJson(Map json) => _$DataFromJson(json);
36 |
37 | Map toJson() => _$DataToJson(this);
38 | }
39 |
--------------------------------------------------------------------------------
/lib/src/models/network_data_models/login/response/data.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'data.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | Data _$DataFromJson(Map json) {
10 | return Data(
11 | name: json['name'] as String,
12 | id: json['id'] as int,
13 | email: json['email'] as String,
14 | gender: json['gender'] as String,
15 | region: json['region'] as String,
16 | contact1: json['contact1'] as String,
17 | contact2: json['contact2'] as String,
18 | contact3: json['contact3'] as String,
19 | contact4: json['contact4'] as String,
20 | contact5: json['contact5'] as String,
21 | dob: json['dob'] == null ? null : DateTime.parse(json['dob'] as String),
22 | type: json['type'] as String,
23 | );
24 | }
25 |
26 | Map _$DataToJson(Data instance) => {
27 | 'name': instance.name,
28 | 'id': instance.id,
29 | 'email': instance.email,
30 | 'gender': instance.gender,
31 | 'region': instance.region,
32 | 'contact1': instance.contact1,
33 | 'contact2': instance.contact2,
34 | 'contact3': instance.contact3,
35 | 'contact4': instance.contact4,
36 | 'contact5': instance.contact5,
37 | 'dob': instance.dob?.toIso8601String(),
38 | 'type': instance.type,
39 | };
40 |
--------------------------------------------------------------------------------
/lib/src/models/network_data_models/login/response/login_response.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_bloc_architecture/src/models/network_data_models/login/response/result.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'login_response.g.dart';
5 |
6 | @JsonSerializable()
7 | class LoginResponse {
8 | String status;
9 | int code;
10 | String message;
11 | Result result;
12 |
13 | LoginResponse({
14 | this.status,
15 | this.code,
16 | this.message,
17 | this.result,
18 | });
19 |
20 | factory LoginResponse.fromJson(Map json) =>
21 | _$LoginResponseFromJson(json);
22 |
23 | Map toJson() => _$LoginResponseToJson(this);
24 | }
25 |
--------------------------------------------------------------------------------
/lib/src/models/network_data_models/login/response/login_response.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'login_response.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | LoginResponse _$LoginResponseFromJson(Map json) {
10 | return LoginResponse(
11 | status: json['status'] as String,
12 | code: json['code'] as int,
13 | message: json['message'] as String,
14 | result: json['result'] == null
15 | ? null
16 | : Result.fromJson(json['result'] as Map),
17 | );
18 | }
19 |
20 | Map _$LoginResponseToJson(LoginResponse instance) =>
21 | {
22 | 'status': instance.status,
23 | 'code': instance.code,
24 | 'message': instance.message,
25 | 'result': instance.result,
26 | };
27 |
--------------------------------------------------------------------------------
/lib/src/models/network_data_models/login/response/result.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_bloc_architecture/src/models/network_data_models/login/response/data.dart';
2 | import 'package:json_annotation/json_annotation.dart';
3 |
4 | part 'result.g.dart';
5 |
6 | @JsonSerializable()
7 | class Result {
8 | String accessToken;
9 | String tokenType;
10 | int expiresIn;
11 | Data data;
12 |
13 | Result({
14 | this.accessToken,
15 | this.tokenType,
16 | this.expiresIn,
17 | this.data,
18 | });
19 |
20 | factory Result.fromJson(Map json) => _$ResultFromJson(json);
21 |
22 | Map toJson() => _$ResultToJson(this);
23 | }
24 |
--------------------------------------------------------------------------------
/lib/src/models/network_data_models/login/response/result.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'result.dart';
4 |
5 | // **************************************************************************
6 | // JsonSerializableGenerator
7 | // **************************************************************************
8 |
9 | Result _$ResultFromJson(Map json) {
10 | return Result(
11 | accessToken: json['accessToken'] as String,
12 | tokenType: json['tokenType'] as String,
13 | expiresIn: json['expiresIn'] as int,
14 | data: json['data'] == null
15 | ? null
16 | : Data.fromJson(json['data'] as Map),
17 | );
18 | }
19 |
20 | Map _$ResultToJson(Result instance) => {
21 | 'accessToken': instance.accessToken,
22 | 'tokenType': instance.tokenType,
23 | 'expiresIn': instance.expiresIn,
24 | 'data': instance.data,
25 | };
26 |
--------------------------------------------------------------------------------
/lib/src/my_app.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter_bloc/flutter_bloc.dart';
4 | import 'package:flutter_bloc_architecture/src/bloc/bottom_nav/checkbox_cubit.dart';
5 | import 'package:flutter_bloc_architecture/src/constants/string_constant.dart';
6 | import 'package:flutter_bloc_architecture/src/network/repository/api_repository.dart';
7 | import 'package:flutter_bloc_architecture/src/resources/app_theme.dart';
8 | import 'package:flutter_bloc_architecture/src/utils/navigation_service.dart';
9 | import 'package:flutter_bloc_architecture/src/utils/screen_router.dart';
10 |
11 | import 'bloc/bottom_nav/bottom_nav_cubit.dart';
12 | import 'bloc/login/login_bloc.dart';
13 | import 'di/app_config.dart';
14 | import 'ui/screens/splash/splash_screen.dart';
15 |
16 | class MyApp extends StatelessWidget {
17 | @override
18 | Widget build(BuildContext context) {
19 | return MultiBlocProvider(
20 | providers: [
21 | BlocProvider(
22 | create: (context) {
23 | return LoginBloc(
24 | );
25 | },
26 | ),
27 | BlocProvider(
28 | create: (context) => BottomNavCubit(),
29 | ),
30 | BlocProvider(
31 | create: (context) => CheckboxCubit(),
32 | ),
33 | ],
34 | child: MaterialApp(
35 | title: StringConstant.app_name,
36 | theme: AppTheme.appTheme(),
37 | navigatorKey: appConfig().navigatorKey,
38 | onGenerateRoute: ScreenRouter.generateRoute,
39 | debugShowCheckedModeBanner: false,
40 | home: SplashScreen()));
41 | }
42 | }
--------------------------------------------------------------------------------
/lib/src/network/api_client/api_rest_client.dart:
--------------------------------------------------------------------------------
1 | import 'package:dio/dio.dart' hide Headers;
2 | import 'package:flutter_bloc_architecture/src/constants/url_constant.dart';
3 | import 'package:flutter_bloc_architecture/src/models/network_data_models/login/request/login_request.dart';
4 | import 'package:flutter_bloc_architecture/src/models/network_data_models/login/response/login_response.dart';
5 | import 'package:retrofit/retrofit.dart';
6 |
7 | part 'api_rest_client.g.dart';
8 |
9 | @RestApi(baseUrl: "")
10 | abstract class ApiRestClient {
11 | factory ApiRestClient(Dio dio) = _ApiRestClient;
12 |
13 | /*Login Api*/
14 | @POST(UrlConstant.BASE_URL + UrlConstant.LOGIN)
15 | @FormUrlEncoded()
16 | Future login(@Body() LoginRequest loginRequest);
17 | }
18 |
--------------------------------------------------------------------------------
/lib/src/network/api_client/api_rest_client.g.dart:
--------------------------------------------------------------------------------
1 | // GENERATED CODE - DO NOT MODIFY BY HAND
2 |
3 | part of 'api_rest_client.dart';
4 |
5 | // **************************************************************************
6 | // RetrofitGenerator
7 | // **************************************************************************
8 |
9 | class _ApiRestClient implements ApiRestClient {
10 | _ApiRestClient(this._dio, {this.baseUrl}) {
11 | ArgumentError.checkNotNull(_dio, '_dio');
12 | }
13 |
14 | final Dio _dio;
15 |
16 | String baseUrl;
17 |
18 | @override
19 | Future login(loginRequest) async {
20 | ArgumentError.checkNotNull(loginRequest, 'loginRequest');
21 | const _extra = {};
22 | final queryParameters = {};
23 | final _data = {};
24 | _data.addAll(loginRequest?.toJson() ?? {});
25 | final _result = await _dio.request