├── assets
└── images
│ └── README.md
├── ios
├── Runner
│ ├── Runner-Bridging-Header.h
│ ├── Assets.xcassets
│ │ ├── LaunchImage.imageset
│ │ │ ├── LaunchImage.png
│ │ │ ├── LaunchImage@2x.png
│ │ │ ├── LaunchImage@3x.png
│ │ │ ├── README.md
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ ├── Icon-App-20x20@1x.png
│ │ │ ├── Icon-App-20x20@2x.png
│ │ │ ├── Icon-App-20x20@3x.png
│ │ │ ├── Icon-App-29x29@1x.png
│ │ │ ├── Icon-App-29x29@2x.png
│ │ │ ├── Icon-App-29x29@3x.png
│ │ │ ├── Icon-App-40x40@1x.png
│ │ │ ├── Icon-App-40x40@2x.png
│ │ │ ├── Icon-App-40x40@3x.png
│ │ │ ├── Icon-App-60x60@2x.png
│ │ │ ├── Icon-App-60x60@3x.png
│ │ │ ├── Icon-App-76x76@1x.png
│ │ │ ├── Icon-App-76x76@2x.png
│ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ └── Info.plist
├── Flutter
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── AppFrameworkInfo.plist
├── Runner.xcodeproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ └── project.pbxproj
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── WorkspaceSettings.xcsettings
│ │ └── IDEWorkspaceChecks.plist
├── RunnerTests
│ └── RunnerTests.swift
├── .gitignore
└── Podfile
├── analysis_options.yaml
├── android
├── gradle.properties
├── app
│ ├── src
│ │ ├── main
│ │ │ ├── res
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ └── ic_launcher.png
│ │ │ │ ├── drawable
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── drawable-v21
│ │ │ │ │ └── launch_background.xml
│ │ │ │ ├── values
│ │ │ │ │ └── styles.xml
│ │ │ │ └── values-night
│ │ │ │ │ └── styles.xml
│ │ │ ├── kotlin
│ │ │ │ └── com
│ │ │ │ │ └── example
│ │ │ │ │ └── starterapp
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── AndroidManifest.xml
│ │ ├── debug
│ │ │ └── AndroidManifest.xml
│ │ └── profile
│ │ │ └── AndroidManifest.xml
│ └── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── .gitignore
├── settings.gradle
└── build.gradle
├── l10n.yaml
├── lib
├── l10n
│ ├── l10n.dart
│ └── translations
│ │ └── app_en.arb
├── constants
│ ├── repository_constants
│ │ ├── api_constants
│ │ │ ├── auth
│ │ │ │ └── api_token_constants.dart
│ │ │ └── routes
│ │ │ │ └── api_route_constants.dart
│ │ └── local_storage_constants
│ │ │ ├── settings
│ │ │ └── app_settings_keys.dart
│ │ │ └── auth
│ │ │ └── jwt_token_keys.dart
│ └── style
│ │ └── style_constants.dart
├── routes
│ ├── routes_constants.dart
│ └── router.dart
├── helper
│ ├── api
│ │ └── api_route_helper.dart
│ ├── locale
│ │ └── language_locale_helper.dart
│ └── auth
│ │ └── jwt_token_helper.dart
├── themes
│ └── themes.dart
├── exceptions
│ ├── auth
│ │ └── auth_exception.dart
│ └── api
│ │ └── api_exceptions.dart
├── pages
│ ├── undefinited_page.dart
│ ├── landing_page.dart
│ ├── error
│ │ └── no_internet_page.dart
│ └── splash_page.dart
├── main.dart
├── repository
│ ├── local_storage
│ │ ├── settings
│ │ │ └── preferences_local_storage.dart
│ │ ├── base
│ │ │ └── local_storage_core.dart
│ │ └── auth
│ │ │ └── jwt_local_storage.dart
│ └── api
│ │ ├── auth
│ │ └── api_login.dart
│ │ └── base
│ │ └── api_core.dart
├── starter_app.dart
└── services
│ └── locale_service_provider.dart
├── .github
└── workflows
│ ├── code_quality_flutter.yml
│ └── flutter_ci.yml
├── pubspec.yaml
├── LICENSE
├── README.md
└── .gitignore
/assets/images/README.md:
--------------------------------------------------------------------------------
1 | ## Only for fill folder
2 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 | linter:
3 | rules:
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/l10n.yaml:
--------------------------------------------------------------------------------
1 | arb-dir: lib/l10n/translations
2 | template-arb-file: app_en.arb
3 | output-localization-file: app_localizations.dart
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/l10n/l10n.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | class L10n {
4 | static final allLanguagesSupported = [
5 | const Locale('en'),
6 | ];
7 | }
8 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lib/l10n/translations/app_en.arb:
--------------------------------------------------------------------------------
1 | {
2 | "helloWorld": "Hello Starter App!",
3 | "error_noInternet":"Check you internet connection and retry!",
4 | "retry": "Retry"
5 | }
6 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lib/constants/repository_constants/api_constants/auth/api_token_constants.dart:
--------------------------------------------------------------------------------
1 | class JwtTokenConstants {
2 | static const String jwtSecretPhrase = 'token_secret_phrase';
3 | }
4 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/lib/constants/repository_constants/local_storage_constants/settings/app_settings_keys.dart:
--------------------------------------------------------------------------------
1 | class AppSettingsKeys {
2 | static const String languagePreferencesKey = "languageCodePreferences";
3 | }
4 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/starterapp/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.starterapp
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EliaTolin/flutter-template-starter-app/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/lib/routes/routes_constants.dart:
--------------------------------------------------------------------------------
1 | class RoutesConstants {
2 | static const String splashScreenRoute = "/";
3 | static const String landingRoute = "/landing";
4 | static const String noInternetRoute = "/noInternet";
5 | }
6 |
--------------------------------------------------------------------------------
/lib/constants/repository_constants/local_storage_constants/auth/jwt_token_keys.dart:
--------------------------------------------------------------------------------
1 | class JwtTokenKeys {
2 | static const String accessTokenKey = "accessTokenKey";
3 | static const String refreshTokenKey = "refreshTokenKey";
4 | }
5 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
6 |
--------------------------------------------------------------------------------
/lib/helper/api/api_route_helper.dart:
--------------------------------------------------------------------------------
1 | import 'package:starterapp/constants/repository_constants/api_constants/routes/api_route_constants.dart';
2 |
3 | class ApiRouteHelper {
4 | static String getBaseUrl() =>
5 | "${ApiRouteConstants.getBaseUrl()}${ApiRouteConstants.basePath}/";
6 | }
7 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/lib/themes/themes.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:starterapp/constants/style/style_constants.dart';
3 |
4 | ThemeData lightTheme = ThemeData(
5 | useMaterial3: true,
6 | primaryColor: StyleConstants.colorOfApp,
7 | scaffoldBackgroundColor: StyleConstants.scaffoldBackgroundColor,
8 | );
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/lib/constants/style/style_constants.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class StyleConstants {
4 | // Filled with example constants
5 | static const Color scaffoldBackgroundColor = Colors.white;
6 | static const Color colorOfApp = Color.fromRGBO(12, 98, 235, 1);
7 | static const Color colorTitle = Colors.black;
8 | }
9 |
--------------------------------------------------------------------------------
/lib/exceptions/auth/auth_exception.dart:
--------------------------------------------------------------------------------
1 | // Unauthorized Exception
2 | class UnauthorizedException implements Exception {
3 | const UnauthorizedException() : super();
4 | }
5 |
6 | // Refresh Token Expired Exception
7 | class RefreshTokenExpiredException implements Exception {
8 | const RefreshTokenExpiredException() : super();
9 | }
10 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/ios/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 | import XCTest
4 |
5 | class RunnerTests: XCTestCase {
6 |
7 | func testExample() {
8 | // If you add code to the Runner application, consider adding tests here.
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/lib/pages/undefinited_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class UndefinitedPage extends StatelessWidget {
4 | final String? name;
5 | const UndefinitedPage({Key? key, this.name = ""}) : super(key: key);
6 |
7 | @override
8 | Widget build(BuildContext context) {
9 | return Scaffold(
10 | appBar: AppBar(title: const Text("Undefinited View")),
11 | body: Center(
12 | child: Text("Route for $name is not defined"),
13 | ),
14 | );
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/constants/repository_constants/api_constants/routes/api_route_constants.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 |
3 | class ApiRouteConstants {
4 | static String getBaseUrl() {
5 | if (kDebugMode) {
6 | return "https://route.it";
7 | } else {
8 | throw Exception("Production mode is not supported yet");
9 | }
10 | }
11 |
12 | // Add here the route constants
13 | static String basePath = "/api/v1";
14 |
15 | static String tokenPath = "/token/";
16 |
17 | static String refreshTokenPath = "${tokenPath}refresh/";
18 | }
19 |
--------------------------------------------------------------------------------
/.github/workflows/code_quality_flutter.yml:
--------------------------------------------------------------------------------
1 | name: Code Quality
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | format-and-fix:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Checkout
10 | uses: actions/checkout@v2
11 |
12 | - name: Setup flutter
13 | uses: subosito/flutter-action@v2
14 | with:
15 | channel: stable
16 |
17 | - name: Get packages
18 | run: flutter pub get
19 |
20 | - name: Check format errors
21 | run: dart format --set-exit-if-changed .
22 |
23 | - name: Check lint errors
24 | run: flutter analyze .
25 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: starterapp
2 | description: A new Flutter project.
3 | publish_to: 'none'
4 |
5 | version: 1.0.0+1
6 |
7 | environment:
8 | sdk: '>=3.0.3 <4.0.0'
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 | cupertino_icons: ^1.0.2
14 | dio: ^5.1.1
15 | flutter_localizations:
16 | sdk: flutter
17 | intl: any
18 | provider: ^6.0.5
19 | shared_preferences: ^2.1.2
20 | dart_jsonwebtoken: ^2.8.0
21 | internet_connection_checker: ^1.0.0+1
22 |
23 | dev_dependencies:
24 | flutter_test:
25 | sdk: flutter
26 | flutter_lints: ^2.0.0
27 |
28 | flutter:
29 | uses-material-design: true
30 | generate: true
31 | assets:
32 | - assets/
33 | - assets/images/
--------------------------------------------------------------------------------
/lib/exceptions/api/api_exceptions.dart:
--------------------------------------------------------------------------------
1 | // No connection
2 | class NoInternetConnectionException implements Exception {
3 | const NoInternetConnectionException() : super();
4 | }
5 |
6 | // Internal Server Error Exception
7 | class InternalServerErrorException implements Exception {
8 | String description;
9 | InternalServerErrorException({this.description = ""}) : super();
10 | }
11 |
12 | // End Point not found Exception
13 | class NotFoundEndPointException implements Exception {
14 | const NotFoundEndPointException() : super();
15 | }
16 |
17 | // Bad Request Exception
18 | class BadRequestException implements Exception {
19 | String description;
20 | BadRequestException(this.description) : super();
21 | }
22 |
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.7.10'
3 | repositories {
4 | google()
5 | mavenCentral()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:7.3.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | mavenCentral()
18 | }
19 | }
20 |
21 | rootProject.buildDir = '../build'
22 | subprojects {
23 | project.buildDir = "${rootProject.buildDir}/${project.name}"
24 | }
25 | subprojects {
26 | project.evaluationDependsOn(':app')
27 | }
28 |
29 | tasks.register("clean", Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/services.dart';
2 | import 'package:provider/provider.dart';
3 | import 'package:starterapp/services/locale_service_provider.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:starterapp/starter_app.dart';
6 |
7 | void main() async {
8 | WidgetsFlutterBinding.ensureInitialized();
9 | // Set only portrait orientation
10 | await SystemChrome.setPreferredOrientations(
11 | [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown],
12 | );
13 |
14 | runApp(
15 | MultiProvider(
16 | providers: [
17 | //Add here the providers
18 | ChangeNotifierProvider(
19 | create: (context) => LocaleServiceProvider(),
20 | ),
21 | ],
22 | child: const StarterApp(),
23 | ),
24 | );
25 | }
26 |
--------------------------------------------------------------------------------
/lib/repository/local_storage/settings/preferences_local_storage.dart:
--------------------------------------------------------------------------------
1 | import 'package:starterapp/repository/local_storage/base/local_storage_core.dart';
2 | import 'package:starterapp/constants/repository_constants/local_storage_constants/settings/app_settings_keys.dart';
3 |
4 | class PreferenceLocalStorage {
5 | LocalStorageCore localStorageCore = LocalStorageCore();
6 |
7 | Future isSetLanguagePreferences() async {
8 | return await localStorageCore.exist(AppSettingsKeys.languagePreferencesKey);
9 | }
10 |
11 | Future getLanguagePreferences() async {
12 | return await localStorageCore.read(AppSettingsKeys.languagePreferencesKey);
13 | }
14 |
15 | Future setLanguagePreferences(String code) async {
16 | await localStorageCore.save(AppSettingsKeys.languagePreferencesKey, code);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/lib/pages/landing_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:starterapp/constants/style/style_constants.dart';
3 | import 'package:flutter_gen/gen_l10n/app_localizations.dart';
4 |
5 | class LandingPage extends StatelessWidget {
6 | const LandingPage({super.key});
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | Size size = MediaQuery.of(context).size;
11 | return Scaffold(
12 | appBar: AppBar(
13 | backgroundColor: StyleConstants.scaffoldBackgroundColor,
14 | toolbarHeight: size.height * 0.1,
15 | elevation: 0,
16 | automaticallyImplyLeading: false,
17 | title: const Text(
18 | "StarterApp",
19 | style: TextStyle(
20 | fontSize: 40,
21 | color: StyleConstants.colorTitle,
22 | fontWeight: FontWeight.bold,
23 | ),
24 | ),
25 | ),
26 | body: Center(
27 | child: Text(AppLocalizations.of(context)!.helloWorld),
28 | ),
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/repository/local_storage/base/local_storage_core.dart:
--------------------------------------------------------------------------------
1 | import 'package:shared_preferences/shared_preferences.dart';
2 | import 'dart:convert';
3 |
4 | class LocalStorageCore {
5 | LocalStorageCore();
6 |
7 | Future read(String key) async {
8 | final prefs = await SharedPreferences.getInstance();
9 | var data = prefs.getString(key);
10 | return json.decode(data.toString());
11 | }
12 |
13 | save(String key, value) async {
14 | final prefs = await SharedPreferences.getInstance();
15 | prefs.setString(key, json.encode(value));
16 | }
17 |
18 | remove(String key) async {
19 | final prefs = await SharedPreferences.getInstance();
20 | prefs.remove(key);
21 | }
22 |
23 | Future clear() async {
24 | final prefs = await SharedPreferences.getInstance();
25 | return await prefs.clear();
26 | }
27 |
28 | Future exist(String key) async {
29 | final prefs = await SharedPreferences.getInstance();
30 | bool exist = prefs.containsKey(key);
31 | return exist;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/lib/helper/locale/language_locale_helper.dart:
--------------------------------------------------------------------------------
1 | class LanguageLocalHelper {
2 | // Add other languages here
3 | static final Map> isoLangs = {
4 | "fr": {"name": "French", "nativeName": "Français"},
5 | "it": {"name": "Italian", "nativeName": "Italiano"},
6 | "en": {"name": "English", "nativeName": "English"},
7 | "es": {"name": "Spanish", "nativeName": "Español"},
8 | "pl": {"name": "Polish", "nativeName": "Polski"},
9 | "pt": {"name": "Portuguese", "nativeName": "Português"},
10 | "de": {"name": "German", "nativeName": "Deutsch"},
11 | };
12 |
13 | Map> getIsoLangs() => isoLangs;
14 |
15 | getDisplayLanguage(key) {
16 | if (isoLangs.containsKey(key)) {
17 | return isoLangs[key];
18 | } else {
19 | throw Exception("Language key incorrect");
20 | }
21 | }
22 |
23 | getNativeLanguageName(countryCode) {
24 | return getDisplayLanguage(countryCode)["nativeName"];
25 | }
26 |
27 | getLanguageName(countryCode) {
28 | return getDisplayLanguage(countryCode)["name"];
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Elia Tolin
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/lib/starter_app.dart:
--------------------------------------------------------------------------------
1 | import 'package:provider/provider.dart';
2 | import 'package:starterapp/l10n/l10n.dart';
3 | import 'package:starterapp/routes/routes_constants.dart';
4 | import 'package:starterapp/services/locale_service_provider.dart';
5 | import 'package:starterapp/themes/themes.dart';
6 | import 'routes/router.dart' as router;
7 | import 'package:flutter/material.dart';
8 | import 'package:flutter_gen/gen_l10n/app_localizations.dart';
9 |
10 | class StarterApp extends StatelessWidget {
11 | const StarterApp({super.key});
12 |
13 | @override
14 | Widget build(BuildContext context) {
15 | return Consumer(
16 | builder: (context, provider, child) {
17 | return MaterialApp(
18 | debugShowCheckedModeBanner: false,
19 | title: 'StarterApp',
20 | theme: lightTheme,
21 | initialRoute: RoutesConstants.splashScreenRoute,
22 | localizationsDelegates: AppLocalizations.localizationsDelegates,
23 | supportedLocales: L10n.allLanguagesSupported,
24 | onGenerateRoute: router.generateRoute,
25 | );
26 | },
27 | );
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/services/locale_service_provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:starterapp/l10n/l10n.dart';
3 | import 'package:starterapp/repository/local_storage/settings/preferences_local_storage.dart';
4 |
5 | class LocaleServiceProvider with ChangeNotifier {
6 | Locale? _locale;
7 | Locale? get locale => _locale;
8 | PreferenceLocalStorage preferenceLocalStorage = PreferenceLocalStorage();
9 |
10 | Future initLocale(String languageCode) async {
11 | if (await preferenceLocalStorage.isSetLanguagePreferences()) {
12 | String languageCode =
13 | await preferenceLocalStorage.getLanguagePreferences();
14 | if (languageCode.isNotEmpty) {
15 | setLocale(Locale(languageCode));
16 | }
17 | return;
18 | }
19 | _locale = Locale(languageCode);
20 | }
21 |
22 | void setLocale(Locale loc) async {
23 | await preferenceLocalStorage.setLanguagePreferences(loc.languageCode);
24 | if (!L10n.allLanguagesSupported.contains(loc)) return;
25 | _locale = loc;
26 | notifyListeners();
27 | }
28 |
29 | void clearLocale() {
30 | _locale = null;
31 | notifyListeners();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lib/routes/router.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:starterapp/pages/error/no_internet_page.dart';
3 | import 'package:starterapp/pages/landing_page.dart';
4 | import 'package:starterapp/pages/splash_page.dart';
5 | import 'package:starterapp/pages/undefinited_page.dart';
6 | import 'package:starterapp/routes/routes_constants.dart';
7 |
8 | Route generateRoute(RouteSettings settings) {
9 | switch (settings.name) {
10 | case RoutesConstants.splashScreenRoute:
11 | return MaterialPageRoute(
12 | settings: settings,
13 | builder: (context) => const SplashPage(),
14 | );
15 | case RoutesConstants.landingRoute:
16 | return MaterialPageRoute(
17 | settings: settings,
18 | builder: (context) => const LandingPage(),
19 | );
20 | case RoutesConstants.noInternetRoute:
21 | return MaterialPageRoute(
22 | settings: settings,
23 | builder: (context) => const NoInternetPage(),
24 | );
25 | default:
26 | return MaterialPageRoute(
27 | settings: settings,
28 | builder: (context) => UndefinitedPage(name: settings.name),
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/repository/api/auth/api_login.dart:
--------------------------------------------------------------------------------
1 | /*
2 | ###################################
3 | Use this class for authentication api
4 | ###################################
5 | */
6 |
7 | // import 'dart:developer';
8 | // import 'package:dio/dio.dart';
9 | // import 'package:starterapp/api/base/api_core.dart';
10 | // import 'package:starterapp/helper/api/api_route_helper.dart';
11 | // import 'package:starterapp/helper/api/jwt_token_helper.dart';
12 |
13 | // class ApiAuth {
14 | // ApiBaseCore apiBaseCore = ApiBaseCore();
15 | // Future login(String email, String password) async {
16 | // try {
17 | // Response? response = await apiBaseCore.postHTTP(
18 | // ApiRouteHelper.tokenPath, {"email": email, "password": password});
19 | // if (response == null) {
20 | // return false;
21 | // }
22 | // String accessToken = response.data["access"];
23 | // String refreshToken = response.data["refresh"];
24 | // log("Access token: $accessToken");
25 | // log("Refresh token: $refreshToken");
26 | // await JwtTokenHelper().saveNewJwtTokens(accessToken, refreshToken);
27 | // return true;
28 | // } on Exception {
29 | // return false;
30 | // }
31 | // }
32 | // }
33 |
--------------------------------------------------------------------------------
/.github/workflows/flutter_ci.yml:
--------------------------------------------------------------------------------
1 | name: Flutter CI
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | build-android:
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - name: Checkout repository
11 | uses: actions/checkout@v3
12 |
13 | - name: Setup Java
14 | uses: actions/setup-java@v2
15 | with:
16 | distribution: "zulu"
17 | java-version: "11"
18 |
19 | - name: Setup Flutter
20 | uses: subosito/flutter-action@v2
21 | with:
22 | channel: "stable"
23 | cache: true
24 |
25 | - name: Install dependencies
26 | run: flutter pub get
27 |
28 | - name: Build APK
29 | run: flutter build apk
30 |
31 | - name: Build App Bundle
32 | run: flutter build appbundle
33 |
34 | build-ios:
35 | runs-on: macos-latest
36 |
37 | steps:
38 | - name: Checkout repository
39 | uses: actions/checkout@v3
40 |
41 | - name: Setup Flutter
42 | uses: subosito/flutter-action@v2
43 | with:
44 | channel: "stable"
45 | cache: true
46 | architecture: x64
47 |
48 | - name: Install dependencies
49 | run: flutter pub get
50 |
51 | - name: Build iOS
52 | run: flutter build ios --release --no-codesign
53 |
--------------------------------------------------------------------------------
/lib/repository/local_storage/auth/jwt_local_storage.dart:
--------------------------------------------------------------------------------
1 | import 'package:starterapp/constants/repository_constants/local_storage_constants/auth/jwt_token_keys.dart';
2 | import 'package:starterapp/repository/local_storage/base/local_storage_core.dart';
3 |
4 | class JwtLocalStorage {
5 | LocalStorageCore localStorageCore = LocalStorageCore();
6 |
7 | Future existJwtToken() async {
8 | return await localStorageCore.exist(JwtTokenKeys.accessTokenKey);
9 | }
10 |
11 | Future existRefreshToken() async {
12 | return await localStorageCore.exist(JwtTokenKeys.refreshTokenKey);
13 | }
14 |
15 | Future saveAccessToken(String token) async {
16 | await localStorageCore.save(JwtTokenKeys.accessTokenKey, token);
17 | }
18 |
19 | Future saveRefreshToken(String token) async {
20 | await localStorageCore.save(JwtTokenKeys.refreshTokenKey, token);
21 | }
22 |
23 | Future getAccessToken() async {
24 | return await localStorageCore.read(JwtTokenKeys.accessTokenKey);
25 | }
26 |
27 | Future getRefreshToken() async {
28 | return await localStorageCore.read(JwtTokenKeys.refreshTokenKey);
29 | }
30 |
31 | Future clearJwtTokens() async {
32 | await localStorageCore.remove(JwtTokenKeys.accessTokenKey);
33 | await localStorageCore.remove(JwtTokenKeys.refreshTokenKey);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/pages/error/no_internet_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_gen/gen_l10n/app_localizations.dart';
3 | import 'package:starterapp/routes/routes_constants.dart';
4 |
5 | class NoInternetPage extends StatelessWidget {
6 | const NoInternetPage({super.key});
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 | return Scaffold(
11 | body: Center(
12 | child: Column(
13 | mainAxisAlignment: MainAxisAlignment.center,
14 | children: [
15 | Text(
16 | AppLocalizations.of(context)!.error_noInternet,
17 | style: const TextStyle(
18 | fontSize: 20,
19 | color: Colors.red,
20 | ),
21 | textAlign: TextAlign.center,
22 | ),
23 | const SizedBox(
24 | height: 20,
25 | ),
26 | const Icon(
27 | Icons.error,
28 | color: Colors.red,
29 | size: 40,
30 | ),
31 | const SizedBox(
32 | height: 20,
33 | ),
34 | ElevatedButton(
35 | child: Text(
36 | AppLocalizations.of(context)!.retry,
37 | ),
38 | onPressed: () {
39 | Navigator.of(context)
40 | .popAndPushNamed(RoutesConstants.splashScreenRoute);
41 | },
42 | ),
43 | ],
44 | ),
45 | ),
46 | );
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '11.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | target 'RunnerTests' do
36 | inherit! :search_paths
37 | end
38 | end
39 |
40 | post_install do |installer|
41 | installer.pods_project.targets.each do |target|
42 | flutter_additional_ios_build_settings(target)
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/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 | CFBundleDisplayName
8 | Starterapp
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | starterapp
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 | CADisableMinimumFrameDurationOnPhone
47 |
48 | UIApplicationSupportsIndirectInputEvents
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
14 |
18 |
22 |
23 |
24 |
25 |
26 |
27 |
29 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/lib/helper/auth/jwt_token_helper.dart:
--------------------------------------------------------------------------------
1 | import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart';
2 | import 'package:starterapp/constants/repository_constants/api_constants/auth/api_token_constants.dart';
3 | import 'package:starterapp/repository/local_storage/auth/jwt_local_storage.dart';
4 |
5 | class JwtTokenHelper {
6 | JwtLocalStorage jwtLocalStorage = JwtLocalStorage();
7 |
8 | Future existJwtToken() => jwtLocalStorage.existJwtToken();
9 |
10 | Future existRefreshToken() => jwtLocalStorage.existRefreshToken();
11 |
12 | Future saveNewJwtTokens(String accessToken, String refreshToken) async {
13 | await jwtLocalStorage.saveAccessToken(accessToken);
14 | await jwtLocalStorage.saveRefreshToken(refreshToken);
15 | }
16 |
17 | Future getAccessToken() => jwtLocalStorage.getAccessToken();
18 |
19 | Future getRefreshToken() => jwtLocalStorage.getRefreshToken();
20 |
21 | Future isValidAccessToken() async {
22 | if (!await existJwtToken()) {
23 | return false;
24 | }
25 | try {
26 | String token = await getAccessToken();
27 | _verifyToken(token);
28 | } on JWTExpiredException {
29 | await clearJwtTokens();
30 | return false;
31 | } on JWTException {
32 | await clearJwtTokens();
33 | return false;
34 | }
35 | return true;
36 | }
37 |
38 | Future isValidRefreshToken() async {
39 | if (!await existRefreshToken()) {
40 | return false;
41 | }
42 | try {
43 | String token = await getRefreshToken();
44 | _verifyToken(token);
45 | } on JWTExpiredException {
46 | return false;
47 | } on JWTException {
48 | return false;
49 | }
50 | return true;
51 | }
52 |
53 | _verifyToken(String token) =>
54 | JWT.verify(token, SecretKey(JwtTokenConstants.jwtSecretPhrase));
55 |
56 | Future clearJwtTokens() => jwtLocalStorage.clearJwtTokens();
57 | }
58 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 | namespace "com.example.starterapp"
30 | compileSdkVersion flutter.compileSdkVersion
31 | ndkVersion flutter.ndkVersion
32 |
33 | compileOptions {
34 | sourceCompatibility JavaVersion.VERSION_1_8
35 | targetCompatibility JavaVersion.VERSION_1_8
36 | }
37 |
38 | kotlinOptions {
39 | jvmTarget = '1.8'
40 | }
41 |
42 | sourceSets {
43 | main.java.srcDirs += 'src/main/kotlin'
44 | }
45 |
46 | defaultConfig {
47 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
48 | applicationId "com.example.starterapp"
49 | // You can update the following values to match your application needs.
50 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
51 | minSdkVersion flutter.minSdkVersion
52 | targetSdkVersion flutter.targetSdkVersion
53 | versionCode flutterVersionCode.toInteger()
54 | versionName flutterVersionName
55 | }
56 |
57 | buildTypes {
58 | release {
59 | // TODO: Add your own signing config for the release build.
60 | // Signing with the debug keys for now, so `flutter run --release` works.
61 | signingConfig signingConfigs.debug
62 | }
63 | }
64 | }
65 |
66 | flutter {
67 | source '../..'
68 | }
69 |
70 | dependencies {
71 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
72 | }
73 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://github.com/EliaTolin/flutter-template-starter-app/actions/workflows/flutter_ci.yml)
2 | [](https://github.com/EliaTolin/flutter-template-starter-app/actions/workflows/code_quality_flutter.yml)
3 |
4 | 
5 |
6 | ## Description
7 |
8 | This repository serves as a template Layer first for a Flutter app, providing a modular structure and integrating various packages and functionalities. The project aims to offer a solid foundation for building robust Flutter applications with the following features:
9 |
10 | - **Dio**: A powerful package for handling network requests, allowing seamless communication with APIs.
11 | - **l10n**: Enables multi-language support, making it easy to localize your app for different languages.
12 | - **Provider**: A state management solution that simplifies the management and sharing of application state.
13 | - **Shared Preferences**: Provides a simple way to persistently store key-value pairs, allowing for data persistence across app sessions.
14 | - **JWT**: Offers support for JSON Web Tokens, enabling secure authentication and authorization mechanisms.
15 | - **Various Helper Classes**: Includes a collection of utility classes that assist with common tasks, making development more efficient.
16 | - **Language Service**: A service that allows users to dynamically switch the language within the app, enhancing the user experience.
17 | - **Named Routing**: Implements a navigation system using named routes, making it easier to navigate between screens and manage app flow.
18 |
19 | ## Modularity
20 |
21 | The project has been designed with a strong focus on modularity. This modular architecture enables easy customization, extension, and maintenance of the app. Each package and functionality is independent, allowing developers to add, remove, or modify components as per their project requirements.
22 |
23 | ## Usage
24 |
25 | To use this project template, follow these steps:
26 |
27 | 1. Clone the repository to your local machine.
28 | 2. Open the project in your preferred Flutter development environment.
29 | 3. Customize the app's functionality, UI, and features according to your project requirements.
30 | 4. Build and run the app on your preferred platform or device.
31 |
32 | ## Contributions
33 |
34 | Contributions to this project are welcome. If you find any issues or have suggestions for improvements, please open an issue or submit a pull request.
35 |
36 | ## License
37 |
38 | This project is licensed under the [MIT License](https://chat.openai.com/link-to-license). Please refer to the LICENSE file for more information.
39 |
40 | ## Acknowledgements
41 |
42 | We would like to acknowledge the creators and contributors of the packages and functionalities integrated into this project template. Their work has made building Flutter apps more efficient and enjoyable.
43 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.lock
4 | *.log
5 | *.pyc
6 | *.swp
7 | .DS_Store
8 | .atom/
9 | .buildlog/
10 | .history
11 | .svn/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # Visual Studio Code related
20 | .classpath
21 | .project
22 | .settings/
23 | .vscode/*
24 |
25 | # Flutter repo-specific
26 | /bin/cache/
27 | /bin/internal/bootstrap.bat
28 | /bin/internal/bootstrap.sh
29 | /bin/mingit/
30 | /dev/benchmarks/mega_gallery/
31 | /dev/bots/.recipe_deps
32 | /dev/bots/android_tools/
33 | /dev/devicelab/ABresults*.json
34 | /dev/docs/doc/
35 | /dev/docs/flutter.docs.zip
36 | /dev/docs/lib/
37 | /dev/docs/pubspec.yaml
38 | /dev/integration_tests/**/xcuserdata
39 | /dev/integration_tests/**/Pods
40 | /packages/flutter/coverage/
41 | version
42 | analysis_benchmark.json
43 |
44 | # packages file containing multi-root paths
45 | .packages.generated
46 |
47 | # Flutter/Dart/Pub related
48 | **/doc/api/
49 | .dart_tool/
50 | .flutter-plugins
51 | .flutter-plugins-dependencies
52 | **/generated_plugin_registrant.dart
53 | .packages
54 | .pub-preload-cache/
55 | .pub/
56 | build/
57 | flutter_*.png
58 | linked_*.ds
59 | unlinked.ds
60 | unlinked_spec.ds
61 |
62 | # Android related
63 | **/android/**/gradle-wrapper.jar
64 | .gradle/
65 | **/android/captures/
66 | **/android/gradlew
67 | **/android/gradlew.bat
68 | **/android/local.properties
69 | **/android/**/GeneratedPluginRegistrant.java
70 | **/android/key.properties
71 | *.jks
72 |
73 | # iOS/XCode related
74 | **/ios/**/*.mode1v3
75 | **/ios/**/*.mode2v3
76 | **/ios/**/*.moved-aside
77 | **/ios/**/*.pbxuser
78 | **/ios/**/*.perspectivev3
79 | **/ios/**/*sync/
80 | **/ios/**/.sconsign.dblite
81 | **/ios/**/.tags*
82 | **/ios/**/.vagrant/
83 | **/ios/**/DerivedData/
84 | **/ios/**/Icon?
85 | **/ios/**/Pods/
86 | **/ios/**/.symlinks/
87 | **/ios/**/profile
88 | **/ios/**/xcuserdata
89 | **/ios/.generated/
90 | **/ios/Flutter/.last_build_id
91 | **/ios/Flutter/App.framework
92 | **/ios/Flutter/Flutter.framework
93 | **/ios/Flutter/Flutter.podspec
94 | **/ios/Flutter/Generated.xcconfig
95 | **/ios/Flutter/ephemeral
96 | **/ios/Flutter/app.flx
97 | **/ios/Flutter/app.zip
98 | **/ios/Flutter/flutter_assets/
99 | **/ios/Flutter/flutter_export_environment.sh
100 | **/ios/ServiceDefinitions.json
101 | **/ios/Runner/GeneratedPluginRegistrant.*
102 |
103 | # macOS
104 | **/Flutter/ephemeral/
105 | **/Pods/
106 | **/macos/Flutter/GeneratedPluginRegistrant.swift
107 | **/macos/Flutter/ephemeral
108 | **/xcuserdata/
109 |
110 | # Windows
111 | **/windows/flutter/generated_plugin_registrant.cc
112 | **/windows/flutter/generated_plugin_registrant.h
113 | **/windows/flutter/generated_plugins.cmake
114 |
115 | # Linux
116 | **/linux/flutter/generated_plugin_registrant.cc
117 | **/linux/flutter/generated_plugin_registrant.h
118 | **/linux/flutter/generated_plugins.cmake
119 |
120 | # Coverage
121 | coverage/
122 |
123 | # Symbols
124 | app.*.symbols
125 |
126 | # Exceptions to above rules.
127 | !**/ios/**/default.mode1v3
128 | !**/ios/**/default.mode2v3
129 | !**/ios/**/default.pbxuser
130 | !**/ios/**/default.perspectivev3
131 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
132 | !/dev/ci/**/Gemfile.lock
133 | !.vscode/settings.json
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
43 |
49 |
50 |
51 |
52 |
53 |
63 |
65 |
71 |
72 |
73 |
74 |
80 |
82 |
88 |
89 |
90 |
91 |
93 |
94 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/lib/pages/splash_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'package:internet_connection_checker/internet_connection_checker.dart';
4 | import 'package:provider/provider.dart';
5 | import 'package:starterapp/constants/style/style_constants.dart';
6 | import 'package:starterapp/routes/routes_constants.dart';
7 | import 'package:starterapp/services/locale_service_provider.dart';
8 |
9 | class SplashPage extends StatefulWidget {
10 | const SplashPage({super.key});
11 |
12 | @override
13 | State createState() => _SplashPageState();
14 | }
15 |
16 | class _SplashPageState extends State {
17 | Future loadCall() async {
18 | // Wait delay
19 | if (context.mounted) {
20 | await context
21 | .read()
22 | .initLocale(Localizations.localeOf(context).languageCode);
23 | }
24 | await Future.delayed(const Duration(seconds: 3), () {});
25 | redirectPage();
26 | }
27 |
28 | Future redirectPage() async {
29 | if (!await InternetConnectionChecker().hasConnection) {
30 | if (context.mounted) {
31 | Navigator.of(context).popAndPushNamed(RoutesConstants.noInternetRoute);
32 | }
33 | } else {
34 | if (context.mounted) {
35 | Navigator.of(context).popAndPushNamed(RoutesConstants.landingRoute);
36 | }
37 | }
38 | }
39 |
40 | @override
41 | void initState() {
42 | super.initState();
43 | WidgetsBinding.instance.addPostFrameCallback((_) => loadCall());
44 | }
45 |
46 | @override
47 | Widget build(BuildContext context) {
48 | Size size = MediaQuery.of(context).size;
49 |
50 | return Scaffold(
51 | appBar: AppBar(
52 | systemOverlayStyle: const SystemUiOverlayStyle(
53 | statusBarColor: Colors.transparent,
54 | ),
55 | backgroundColor: Colors.transparent,
56 | elevation: 0,
57 | toolbarHeight: 0,
58 | ),
59 | backgroundColor: Colors.white,
60 | body: Stack(
61 | alignment: Alignment.center,
62 | children: [
63 | Positioned(
64 | top: 200,
65 | left: 0,
66 | child: CustomPaint(
67 | painter: Circle(size.width - size.width / 5, 0, size.width,
68 | StyleConstants.colorOfApp),
69 | ),
70 | ),
71 | Positioned(
72 | top: 0,
73 | right: 0,
74 | child: CustomPaint(
75 | painter: Circle(0, 0, size.width - 100, Colors.white),
76 | ),
77 | ),
78 | const Padding(
79 | padding: EdgeInsets.all(8.0),
80 | child: Column(
81 | mainAxisAlignment: MainAxisAlignment.center,
82 | mainAxisSize: MainAxisSize.max,
83 | children: [
84 | FittedBox(
85 | child: Text(
86 | "StarterApp",
87 | style: TextStyle(
88 | fontSize: 50,
89 | color: Colors.white,
90 | ),
91 | textAlign: TextAlign.center,
92 | maxLines: 1,
93 | ),
94 | ),
95 | Text(
96 | "Your splashscreen!",
97 | style: TextStyle(
98 | color: Colors.white,
99 | ),
100 | textAlign: TextAlign.center,
101 | ),
102 | ],
103 | ),
104 | ),
105 | ],
106 | ),
107 | );
108 | }
109 | }
110 |
111 | class Circle extends CustomPainter {
112 | final double offsetX;
113 | final double offsetY;
114 | final double radius;
115 | final Color color;
116 | Circle(this.offsetX, this.offsetY, this.radius, this.color);
117 | @override
118 | void paint(Canvas canvas, Size size) {
119 | var paint1 = Paint()
120 | ..color = color
121 | ..style = PaintingStyle.fill;
122 | //a circle
123 | canvas.drawCircle(Offset(offsetX, offsetY), radius, paint1);
124 | }
125 |
126 | @override
127 | bool shouldRepaint(CustomPainter oldDelegate) => true;
128 | }
129 |
--------------------------------------------------------------------------------
/lib/repository/api/base/api_core.dart:
--------------------------------------------------------------------------------
1 | import 'dart:developer';
2 | import 'package:dio/dio.dart';
3 | import 'package:starterapp/constants/repository_constants/api_constants/routes/api_route_constants.dart';
4 | import 'package:starterapp/exceptions/api/api_exceptions.dart';
5 | import 'package:starterapp/exceptions/auth/auth_exception.dart';
6 | import 'package:starterapp/helper/api/api_route_helper.dart';
7 | import 'package:starterapp/helper/auth/jwt_token_helper.dart';
8 |
9 | class ApiBaseCore {
10 | late Dio baseAPI;
11 |
12 | final BaseOptions opts = BaseOptions(
13 | baseUrl: ApiRouteHelper.getBaseUrl(),
14 | responseType: ResponseType.json,
15 | connectTimeout: const Duration(seconds: 10),
16 | receiveTimeout: const Duration(seconds: 10),
17 | );
18 |
19 | Dio createDio() {
20 | return Dio(opts);
21 | }
22 |
23 | ApiBaseCore() {
24 | Dio dio = createDio();
25 | baseAPI = addInterceptors(dio);
26 | }
27 |
28 | Dio addInterceptors(Dio dio) {
29 | return dio
30 | ..interceptors.add(
31 | InterceptorsWrapper(
32 | onRequest:
33 | (RequestOptions options, RequestInterceptorHandler handler) {
34 | requestInterceptor(options, handler);
35 | },
36 | onError: (DioException e, ErrorInterceptorHandler handler) async {
37 | log("ERROR: $e");
38 | handler.next(e);
39 | },
40 | onResponse: (Response response, ResponseInterceptorHandler handler) {
41 | handler.next(response);
42 | },
43 | ),
44 | );
45 | }
46 |
47 | Future requestInterceptor(
48 | RequestOptions options, RequestInterceptorHandler handler) async {
49 | String token = "";
50 | final jwtTokenHelper = JwtTokenHelper();
51 |
52 | // If not exist, the user is not logged in the app, i not need add the token
53 | if (await jwtTokenHelper.existJwtToken()) {
54 | if (!await jwtTokenHelper.isValidAccessToken()) {
55 | if (!await jwtTokenHelper.isValidRefreshToken()) {
56 | throw const RefreshTokenExpiredException();
57 | }
58 | Dio dio = Dio(opts);
59 | Response response = await dio.post(
60 | ApiRouteConstants.refreshTokenPath,
61 | data: {
62 | "refresh": await jwtTokenHelper.getRefreshToken(),
63 | },
64 | ).onError(
65 | (DioException error, stackTrace) => handleError(error),
66 | );
67 | await jwtTokenHelper.saveNewJwtTokens(
68 | response.data["access"],
69 | response.data["refresh"],
70 | );
71 | log("New access token: ${response.data["access"]}");
72 | log("New refresh token: ${response.data["refresh"]}");
73 | token = response.data["access"];
74 | }
75 | token = await jwtTokenHelper.getAccessToken();
76 | options.headers.addAll({"Authorization": "Bearer $token"});
77 | }
78 | log("____________________");
79 | log("URL: ${options.baseUrl}${options.path}");
80 | log("METHOD: ${options.method}");
81 | log("Headers: ${options.headers}");
82 | log("Data: ${options.data}");
83 | log("QueryParams: ${options.queryParameters}");
84 | log("____________________");
85 | handler.next(options);
86 | }
87 |
88 | Future getHTTP(String path,
89 | {Map? queryParameters}) async {
90 | try {
91 | Response response =
92 | await baseAPI.get(path, queryParameters: queryParameters);
93 | return response;
94 | } on DioException catch (e) {
95 | handleError(e);
96 | }
97 | return null;
98 | }
99 |
100 | Future postHTTP(String path, dynamic data,
101 | {Map? queryParameters}) async {
102 | try {
103 | Response response = await baseAPI.post(path,
104 | data: data, queryParameters: queryParameters);
105 | return response;
106 | } on DioException catch (e) {
107 | handleError(e);
108 | }
109 | return null;
110 | }
111 |
112 | Future putHTTP(String path, dynamic data,
113 | {Map? queryParameters}) async {
114 | try {
115 | Response response =
116 | await baseAPI.put(path, data: data, queryParameters: queryParameters);
117 | return response;
118 | } on DioException catch (e) {
119 | handleError(e);
120 | }
121 | return null;
122 | }
123 |
124 | Future deleteHTTP(String path,
125 | {Map? queryParameters}) async {
126 | try {
127 | Response response =
128 | await baseAPI.delete(path, queryParameters: queryParameters);
129 | return response;
130 | } on DioException catch (e) {
131 | handleError(e);
132 | }
133 | return null;
134 | }
135 |
136 | handleError(DioException error) {
137 | switch (error.type) {
138 | case DioExceptionType.connectionTimeout:
139 | throw const NoInternetConnectionException();
140 | case DioExceptionType.sendTimeout:
141 | throw const NoInternetConnectionException();
142 | case DioExceptionType.receiveTimeout:
143 | throw const NoInternetConnectionException();
144 | case DioExceptionType.badResponse:
145 | if (error.response == null) {
146 | throw BadRequestException("");
147 | }
148 | switch (error.response?.statusCode) {
149 | case 401:
150 | throw const UnauthorizedException();
151 | case 400:
152 | throw BadRequestException("");
153 | case 404:
154 | throw const NotFoundEndPointException();
155 | case 500:
156 | throw InternalServerErrorException();
157 | }
158 | break;
159 | case DioExceptionType.cancel:
160 | break;
161 | default:
162 | throw BadRequestException("Unknown error");
163 | }
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
13 | 452B099C7EE0535DFCA0897E /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F16BF82A3A13F67CD96FB937 /* Pods_RunnerTests.framework */; };
14 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
15 | 8F3F6D0EB64A57F3B706ADD5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D7BB5BB4379A9D8CC68DCD1 /* Pods_Runner.framework */; };
16 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
17 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
18 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXContainerItemProxy section */
22 | 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
23 | isa = PBXContainerItemProxy;
24 | containerPortal = 97C146E61CF9000F007C117D /* Project object */;
25 | proxyType = 1;
26 | remoteGlobalIDString = 97C146ED1CF9000F007C117D;
27 | remoteInfo = Runner;
28 | };
29 | /* End PBXContainerItemProxy section */
30 |
31 | /* Begin PBXCopyFilesBuildPhase section */
32 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
33 | isa = PBXCopyFilesBuildPhase;
34 | buildActionMask = 2147483647;
35 | dstPath = "";
36 | dstSubfolderSpec = 10;
37 | files = (
38 | );
39 | name = "Embed Frameworks";
40 | runOnlyForDeploymentPostprocessing = 0;
41 | };
42 | /* End PBXCopyFilesBuildPhase section */
43 |
44 | /* Begin PBXFileReference section */
45 | 0ADC41F6B57E9D27C7027872 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; };
46 | 126ADC3F251A5AEE80A9B39F /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; };
47 | 1380D49C8CF11392C2DC4FFE /* 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 = ""; };
48 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
49 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
50 | 1C9063B17755F75EB663BA64 /* 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 = ""; };
51 | 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
52 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
53 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
54 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
55 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
56 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
57 | 8D7BB5BB4379A9D8CC68DCD1 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
58 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
59 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
60 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
61 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
62 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
63 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
64 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
65 | A9042EA9257650CCC79814BB /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; };
66 | D531C994685255E5068EA8C6 /* 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 = ""; };
67 | F16BF82A3A13F67CD96FB937 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
68 | /* End PBXFileReference section */
69 |
70 | /* Begin PBXFrameworksBuildPhase section */
71 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
72 | isa = PBXFrameworksBuildPhase;
73 | buildActionMask = 2147483647;
74 | files = (
75 | 8F3F6D0EB64A57F3B706ADD5 /* Pods_Runner.framework in Frameworks */,
76 | );
77 | runOnlyForDeploymentPostprocessing = 0;
78 | };
79 | DE272899AAC3F89DE403A521 /* Frameworks */ = {
80 | isa = PBXFrameworksBuildPhase;
81 | buildActionMask = 2147483647;
82 | files = (
83 | 452B099C7EE0535DFCA0897E /* Pods_RunnerTests.framework in Frameworks */,
84 | );
85 | runOnlyForDeploymentPostprocessing = 0;
86 | };
87 | /* End PBXFrameworksBuildPhase section */
88 |
89 | /* Begin PBXGroup section */
90 | 2C901272B95D166C1C348251 /* Frameworks */ = {
91 | isa = PBXGroup;
92 | children = (
93 | 8D7BB5BB4379A9D8CC68DCD1 /* Pods_Runner.framework */,
94 | F16BF82A3A13F67CD96FB937 /* Pods_RunnerTests.framework */,
95 | );
96 | name = Frameworks;
97 | sourceTree = "";
98 | };
99 | 331C8082294A63A400263BE5 /* RunnerTests */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 331C807B294A618700263BE5 /* RunnerTests.swift */,
103 | );
104 | path = RunnerTests;
105 | sourceTree = "";
106 | };
107 | 9740EEB11CF90186004384FC /* Flutter */ = {
108 | isa = PBXGroup;
109 | children = (
110 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
111 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
112 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
113 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
114 | );
115 | name = Flutter;
116 | sourceTree = "";
117 | };
118 | 97C146E51CF9000F007C117D = {
119 | isa = PBXGroup;
120 | children = (
121 | 9740EEB11CF90186004384FC /* Flutter */,
122 | 97C146F01CF9000F007C117D /* Runner */,
123 | 97C146EF1CF9000F007C117D /* Products */,
124 | 331C8082294A63A400263BE5 /* RunnerTests */,
125 | EA4813D0780F1F56588A0826 /* Pods */,
126 | 2C901272B95D166C1C348251 /* Frameworks */,
127 | );
128 | sourceTree = "";
129 | };
130 | 97C146EF1CF9000F007C117D /* Products */ = {
131 | isa = PBXGroup;
132 | children = (
133 | 97C146EE1CF9000F007C117D /* Runner.app */,
134 | 331C8081294A63A400263BE5 /* RunnerTests.xctest */,
135 | );
136 | name = Products;
137 | sourceTree = "";
138 | };
139 | 97C146F01CF9000F007C117D /* Runner */ = {
140 | isa = PBXGroup;
141 | children = (
142 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
143 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
144 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
145 | 97C147021CF9000F007C117D /* Info.plist */,
146 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
147 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
148 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
149 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
150 | );
151 | path = Runner;
152 | sourceTree = "";
153 | };
154 | EA4813D0780F1F56588A0826 /* Pods */ = {
155 | isa = PBXGroup;
156 | children = (
157 | D531C994685255E5068EA8C6 /* Pods-Runner.debug.xcconfig */,
158 | 1380D49C8CF11392C2DC4FFE /* Pods-Runner.release.xcconfig */,
159 | 1C9063B17755F75EB663BA64 /* Pods-Runner.profile.xcconfig */,
160 | 0ADC41F6B57E9D27C7027872 /* Pods-RunnerTests.debug.xcconfig */,
161 | A9042EA9257650CCC79814BB /* Pods-RunnerTests.release.xcconfig */,
162 | 126ADC3F251A5AEE80A9B39F /* Pods-RunnerTests.profile.xcconfig */,
163 | );
164 | name = Pods;
165 | path = Pods;
166 | sourceTree = "";
167 | };
168 | /* End PBXGroup section */
169 |
170 | /* Begin PBXNativeTarget section */
171 | 331C8080294A63A400263BE5 /* RunnerTests */ = {
172 | isa = PBXNativeTarget;
173 | buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
174 | buildPhases = (
175 | 532FE390281E3B7F7EDF8D96 /* [CP] Check Pods Manifest.lock */,
176 | 331C807D294A63A400263BE5 /* Sources */,
177 | 331C807F294A63A400263BE5 /* Resources */,
178 | DE272899AAC3F89DE403A521 /* Frameworks */,
179 | );
180 | buildRules = (
181 | );
182 | dependencies = (
183 | 331C8086294A63A400263BE5 /* PBXTargetDependency */,
184 | );
185 | name = RunnerTests;
186 | productName = RunnerTests;
187 | productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
188 | productType = "com.apple.product-type.bundle.unit-test";
189 | };
190 | 97C146ED1CF9000F007C117D /* Runner */ = {
191 | isa = PBXNativeTarget;
192 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
193 | buildPhases = (
194 | 8D7494FEAF3F3CF74C10E796 /* [CP] Check Pods Manifest.lock */,
195 | 9740EEB61CF901F6004384FC /* Run Script */,
196 | 97C146EA1CF9000F007C117D /* Sources */,
197 | 97C146EB1CF9000F007C117D /* Frameworks */,
198 | 97C146EC1CF9000F007C117D /* Resources */,
199 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
200 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
201 | 2393EB1265B3F8CF994C42BF /* [CP] Embed Pods Frameworks */,
202 | );
203 | buildRules = (
204 | );
205 | dependencies = (
206 | );
207 | name = Runner;
208 | productName = Runner;
209 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
210 | productType = "com.apple.product-type.application";
211 | };
212 | /* End PBXNativeTarget section */
213 |
214 | /* Begin PBXProject section */
215 | 97C146E61CF9000F007C117D /* Project object */ = {
216 | isa = PBXProject;
217 | attributes = {
218 | LastUpgradeCheck = 1300;
219 | ORGANIZATIONNAME = "";
220 | TargetAttributes = {
221 | 331C8080294A63A400263BE5 = {
222 | CreatedOnToolsVersion = 14.0;
223 | TestTargetID = 97C146ED1CF9000F007C117D;
224 | };
225 | 97C146ED1CF9000F007C117D = {
226 | CreatedOnToolsVersion = 7.3.1;
227 | LastSwiftMigration = 1100;
228 | };
229 | };
230 | };
231 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
232 | compatibilityVersion = "Xcode 9.3";
233 | developmentRegion = en;
234 | hasScannedForEncodings = 0;
235 | knownRegions = (
236 | en,
237 | Base,
238 | );
239 | mainGroup = 97C146E51CF9000F007C117D;
240 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
241 | projectDirPath = "";
242 | projectRoot = "";
243 | targets = (
244 | 97C146ED1CF9000F007C117D /* Runner */,
245 | 331C8080294A63A400263BE5 /* RunnerTests */,
246 | );
247 | };
248 | /* End PBXProject section */
249 |
250 | /* Begin PBXResourcesBuildPhase section */
251 | 331C807F294A63A400263BE5 /* Resources */ = {
252 | isa = PBXResourcesBuildPhase;
253 | buildActionMask = 2147483647;
254 | files = (
255 | );
256 | runOnlyForDeploymentPostprocessing = 0;
257 | };
258 | 97C146EC1CF9000F007C117D /* Resources */ = {
259 | isa = PBXResourcesBuildPhase;
260 | buildActionMask = 2147483647;
261 | files = (
262 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
263 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
264 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
265 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
266 | );
267 | runOnlyForDeploymentPostprocessing = 0;
268 | };
269 | /* End PBXResourcesBuildPhase section */
270 |
271 | /* Begin PBXShellScriptBuildPhase section */
272 | 2393EB1265B3F8CF994C42BF /* [CP] Embed Pods Frameworks */ = {
273 | isa = PBXShellScriptBuildPhase;
274 | buildActionMask = 2147483647;
275 | files = (
276 | );
277 | inputFileListPaths = (
278 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
279 | );
280 | name = "[CP] Embed Pods Frameworks";
281 | outputFileListPaths = (
282 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
283 | );
284 | runOnlyForDeploymentPostprocessing = 0;
285 | shellPath = /bin/sh;
286 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
287 | showEnvVarsInLog = 0;
288 | };
289 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
290 | isa = PBXShellScriptBuildPhase;
291 | alwaysOutOfDate = 1;
292 | buildActionMask = 2147483647;
293 | files = (
294 | );
295 | inputPaths = (
296 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
297 | );
298 | name = "Thin Binary";
299 | outputPaths = (
300 | );
301 | runOnlyForDeploymentPostprocessing = 0;
302 | shellPath = /bin/sh;
303 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
304 | };
305 | 532FE390281E3B7F7EDF8D96 /* [CP] Check Pods Manifest.lock */ = {
306 | isa = PBXShellScriptBuildPhase;
307 | buildActionMask = 2147483647;
308 | files = (
309 | );
310 | inputFileListPaths = (
311 | );
312 | inputPaths = (
313 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
314 | "${PODS_ROOT}/Manifest.lock",
315 | );
316 | name = "[CP] Check Pods Manifest.lock";
317 | outputFileListPaths = (
318 | );
319 | outputPaths = (
320 | "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
321 | );
322 | runOnlyForDeploymentPostprocessing = 0;
323 | shellPath = /bin/sh;
324 | 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";
325 | showEnvVarsInLog = 0;
326 | };
327 | 8D7494FEAF3F3CF74C10E796 /* [CP] Check Pods Manifest.lock */ = {
328 | isa = PBXShellScriptBuildPhase;
329 | buildActionMask = 2147483647;
330 | files = (
331 | );
332 | inputFileListPaths = (
333 | );
334 | inputPaths = (
335 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
336 | "${PODS_ROOT}/Manifest.lock",
337 | );
338 | name = "[CP] Check Pods Manifest.lock";
339 | outputFileListPaths = (
340 | );
341 | outputPaths = (
342 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
343 | );
344 | runOnlyForDeploymentPostprocessing = 0;
345 | shellPath = /bin/sh;
346 | 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";
347 | showEnvVarsInLog = 0;
348 | };
349 | 9740EEB61CF901F6004384FC /* Run Script */ = {
350 | isa = PBXShellScriptBuildPhase;
351 | alwaysOutOfDate = 1;
352 | buildActionMask = 2147483647;
353 | files = (
354 | );
355 | inputPaths = (
356 | );
357 | name = "Run Script";
358 | outputPaths = (
359 | );
360 | runOnlyForDeploymentPostprocessing = 0;
361 | shellPath = /bin/sh;
362 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
363 | };
364 | /* End PBXShellScriptBuildPhase section */
365 |
366 | /* Begin PBXSourcesBuildPhase section */
367 | 331C807D294A63A400263BE5 /* Sources */ = {
368 | isa = PBXSourcesBuildPhase;
369 | buildActionMask = 2147483647;
370 | files = (
371 | 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
372 | );
373 | runOnlyForDeploymentPostprocessing = 0;
374 | };
375 | 97C146EA1CF9000F007C117D /* Sources */ = {
376 | isa = PBXSourcesBuildPhase;
377 | buildActionMask = 2147483647;
378 | files = (
379 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
380 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
381 | );
382 | runOnlyForDeploymentPostprocessing = 0;
383 | };
384 | /* End PBXSourcesBuildPhase section */
385 |
386 | /* Begin PBXTargetDependency section */
387 | 331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
388 | isa = PBXTargetDependency;
389 | target = 97C146ED1CF9000F007C117D /* Runner */;
390 | targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
391 | };
392 | /* End PBXTargetDependency section */
393 |
394 | /* Begin PBXVariantGroup section */
395 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
396 | isa = PBXVariantGroup;
397 | children = (
398 | 97C146FB1CF9000F007C117D /* Base */,
399 | );
400 | name = Main.storyboard;
401 | sourceTree = "";
402 | };
403 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
404 | isa = PBXVariantGroup;
405 | children = (
406 | 97C147001CF9000F007C117D /* Base */,
407 | );
408 | name = LaunchScreen.storyboard;
409 | sourceTree = "";
410 | };
411 | /* End PBXVariantGroup section */
412 |
413 | /* Begin XCBuildConfiguration section */
414 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
415 | isa = XCBuildConfiguration;
416 | buildSettings = {
417 | ALWAYS_SEARCH_USER_PATHS = NO;
418 | CLANG_ANALYZER_NONNULL = YES;
419 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
420 | CLANG_CXX_LIBRARY = "libc++";
421 | CLANG_ENABLE_MODULES = YES;
422 | CLANG_ENABLE_OBJC_ARC = YES;
423 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
424 | CLANG_WARN_BOOL_CONVERSION = YES;
425 | CLANG_WARN_COMMA = YES;
426 | CLANG_WARN_CONSTANT_CONVERSION = YES;
427 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
428 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
429 | CLANG_WARN_EMPTY_BODY = YES;
430 | CLANG_WARN_ENUM_CONVERSION = YES;
431 | CLANG_WARN_INFINITE_RECURSION = YES;
432 | CLANG_WARN_INT_CONVERSION = YES;
433 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
434 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
435 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
436 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
437 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
438 | CLANG_WARN_STRICT_PROTOTYPES = YES;
439 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
440 | CLANG_WARN_UNREACHABLE_CODE = YES;
441 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
442 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
443 | COPY_PHASE_STRIP = NO;
444 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
445 | ENABLE_NS_ASSERTIONS = NO;
446 | ENABLE_STRICT_OBJC_MSGSEND = YES;
447 | GCC_C_LANGUAGE_STANDARD = gnu99;
448 | GCC_NO_COMMON_BLOCKS = YES;
449 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
450 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
451 | GCC_WARN_UNDECLARED_SELECTOR = YES;
452 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
453 | GCC_WARN_UNUSED_FUNCTION = YES;
454 | GCC_WARN_UNUSED_VARIABLE = YES;
455 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
456 | MTL_ENABLE_DEBUG_INFO = NO;
457 | SDKROOT = iphoneos;
458 | SUPPORTED_PLATFORMS = iphoneos;
459 | TARGETED_DEVICE_FAMILY = "1,2";
460 | VALIDATE_PRODUCT = YES;
461 | };
462 | name = Profile;
463 | };
464 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
465 | isa = XCBuildConfiguration;
466 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
467 | buildSettings = {
468 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
469 | CLANG_ENABLE_MODULES = YES;
470 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
471 | DEVELOPMENT_TEAM = X6QYJ2NQ5M;
472 | ENABLE_BITCODE = NO;
473 | INFOPLIST_FILE = Runner/Info.plist;
474 | LD_RUNPATH_SEARCH_PATHS = (
475 | "$(inherited)",
476 | "@executable_path/Frameworks",
477 | );
478 | PRODUCT_BUNDLE_IDENTIFIER = com.example.starterapp;
479 | PRODUCT_NAME = "$(TARGET_NAME)";
480 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
481 | SWIFT_VERSION = 5.0;
482 | VERSIONING_SYSTEM = "apple-generic";
483 | };
484 | name = Profile;
485 | };
486 | 331C8088294A63A400263BE5 /* Debug */ = {
487 | isa = XCBuildConfiguration;
488 | baseConfigurationReference = 0ADC41F6B57E9D27C7027872 /* Pods-RunnerTests.debug.xcconfig */;
489 | buildSettings = {
490 | BUNDLE_LOADER = "$(TEST_HOST)";
491 | CODE_SIGN_STYLE = Automatic;
492 | CURRENT_PROJECT_VERSION = 1;
493 | GENERATE_INFOPLIST_FILE = YES;
494 | MARKETING_VERSION = 1.0;
495 | PRODUCT_BUNDLE_IDENTIFIER = com.example.starterapp.RunnerTests;
496 | PRODUCT_NAME = "$(TARGET_NAME)";
497 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
498 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
499 | SWIFT_VERSION = 5.0;
500 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
501 | };
502 | name = Debug;
503 | };
504 | 331C8089294A63A400263BE5 /* Release */ = {
505 | isa = XCBuildConfiguration;
506 | baseConfigurationReference = A9042EA9257650CCC79814BB /* Pods-RunnerTests.release.xcconfig */;
507 | buildSettings = {
508 | BUNDLE_LOADER = "$(TEST_HOST)";
509 | CODE_SIGN_STYLE = Automatic;
510 | CURRENT_PROJECT_VERSION = 1;
511 | GENERATE_INFOPLIST_FILE = YES;
512 | MARKETING_VERSION = 1.0;
513 | PRODUCT_BUNDLE_IDENTIFIER = com.example.starterapp.RunnerTests;
514 | PRODUCT_NAME = "$(TARGET_NAME)";
515 | SWIFT_VERSION = 5.0;
516 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
517 | };
518 | name = Release;
519 | };
520 | 331C808A294A63A400263BE5 /* Profile */ = {
521 | isa = XCBuildConfiguration;
522 | baseConfigurationReference = 126ADC3F251A5AEE80A9B39F /* Pods-RunnerTests.profile.xcconfig */;
523 | buildSettings = {
524 | BUNDLE_LOADER = "$(TEST_HOST)";
525 | CODE_SIGN_STYLE = Automatic;
526 | CURRENT_PROJECT_VERSION = 1;
527 | GENERATE_INFOPLIST_FILE = YES;
528 | MARKETING_VERSION = 1.0;
529 | PRODUCT_BUNDLE_IDENTIFIER = com.example.starterapp.RunnerTests;
530 | PRODUCT_NAME = "$(TARGET_NAME)";
531 | SWIFT_VERSION = 5.0;
532 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
533 | };
534 | name = Profile;
535 | };
536 | 97C147031CF9000F007C117D /* Debug */ = {
537 | isa = XCBuildConfiguration;
538 | buildSettings = {
539 | ALWAYS_SEARCH_USER_PATHS = NO;
540 | CLANG_ANALYZER_NONNULL = YES;
541 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
542 | CLANG_CXX_LIBRARY = "libc++";
543 | CLANG_ENABLE_MODULES = YES;
544 | CLANG_ENABLE_OBJC_ARC = YES;
545 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
546 | CLANG_WARN_BOOL_CONVERSION = YES;
547 | CLANG_WARN_COMMA = YES;
548 | CLANG_WARN_CONSTANT_CONVERSION = YES;
549 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
550 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
551 | CLANG_WARN_EMPTY_BODY = YES;
552 | CLANG_WARN_ENUM_CONVERSION = YES;
553 | CLANG_WARN_INFINITE_RECURSION = YES;
554 | CLANG_WARN_INT_CONVERSION = YES;
555 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
556 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
557 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
558 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
559 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
560 | CLANG_WARN_STRICT_PROTOTYPES = YES;
561 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
562 | CLANG_WARN_UNREACHABLE_CODE = YES;
563 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
564 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
565 | COPY_PHASE_STRIP = NO;
566 | DEBUG_INFORMATION_FORMAT = dwarf;
567 | ENABLE_STRICT_OBJC_MSGSEND = YES;
568 | ENABLE_TESTABILITY = YES;
569 | GCC_C_LANGUAGE_STANDARD = gnu99;
570 | GCC_DYNAMIC_NO_PIC = NO;
571 | GCC_NO_COMMON_BLOCKS = YES;
572 | GCC_OPTIMIZATION_LEVEL = 0;
573 | GCC_PREPROCESSOR_DEFINITIONS = (
574 | "DEBUG=1",
575 | "$(inherited)",
576 | );
577 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
578 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
579 | GCC_WARN_UNDECLARED_SELECTOR = YES;
580 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
581 | GCC_WARN_UNUSED_FUNCTION = YES;
582 | GCC_WARN_UNUSED_VARIABLE = YES;
583 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
584 | MTL_ENABLE_DEBUG_INFO = YES;
585 | ONLY_ACTIVE_ARCH = YES;
586 | SDKROOT = iphoneos;
587 | TARGETED_DEVICE_FAMILY = "1,2";
588 | };
589 | name = Debug;
590 | };
591 | 97C147041CF9000F007C117D /* Release */ = {
592 | isa = XCBuildConfiguration;
593 | buildSettings = {
594 | ALWAYS_SEARCH_USER_PATHS = NO;
595 | CLANG_ANALYZER_NONNULL = YES;
596 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
597 | CLANG_CXX_LIBRARY = "libc++";
598 | CLANG_ENABLE_MODULES = YES;
599 | CLANG_ENABLE_OBJC_ARC = YES;
600 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
601 | CLANG_WARN_BOOL_CONVERSION = YES;
602 | CLANG_WARN_COMMA = YES;
603 | CLANG_WARN_CONSTANT_CONVERSION = YES;
604 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
605 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
606 | CLANG_WARN_EMPTY_BODY = YES;
607 | CLANG_WARN_ENUM_CONVERSION = YES;
608 | CLANG_WARN_INFINITE_RECURSION = YES;
609 | CLANG_WARN_INT_CONVERSION = YES;
610 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
611 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
612 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
613 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
614 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
615 | CLANG_WARN_STRICT_PROTOTYPES = YES;
616 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
617 | CLANG_WARN_UNREACHABLE_CODE = YES;
618 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
619 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
620 | COPY_PHASE_STRIP = NO;
621 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
622 | ENABLE_NS_ASSERTIONS = NO;
623 | ENABLE_STRICT_OBJC_MSGSEND = YES;
624 | GCC_C_LANGUAGE_STANDARD = gnu99;
625 | GCC_NO_COMMON_BLOCKS = YES;
626 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
627 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
628 | GCC_WARN_UNDECLARED_SELECTOR = YES;
629 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
630 | GCC_WARN_UNUSED_FUNCTION = YES;
631 | GCC_WARN_UNUSED_VARIABLE = YES;
632 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
633 | MTL_ENABLE_DEBUG_INFO = NO;
634 | SDKROOT = iphoneos;
635 | SUPPORTED_PLATFORMS = iphoneos;
636 | SWIFT_COMPILATION_MODE = wholemodule;
637 | SWIFT_OPTIMIZATION_LEVEL = "-O";
638 | TARGETED_DEVICE_FAMILY = "1,2";
639 | VALIDATE_PRODUCT = YES;
640 | };
641 | name = Release;
642 | };
643 | 97C147061CF9000F007C117D /* Debug */ = {
644 | isa = XCBuildConfiguration;
645 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
646 | buildSettings = {
647 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
648 | CLANG_ENABLE_MODULES = YES;
649 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
650 | DEVELOPMENT_TEAM = X6QYJ2NQ5M;
651 | ENABLE_BITCODE = NO;
652 | INFOPLIST_FILE = Runner/Info.plist;
653 | LD_RUNPATH_SEARCH_PATHS = (
654 | "$(inherited)",
655 | "@executable_path/Frameworks",
656 | );
657 | PRODUCT_BUNDLE_IDENTIFIER = com.example.starterapp;
658 | PRODUCT_NAME = "$(TARGET_NAME)";
659 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
660 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
661 | SWIFT_VERSION = 5.0;
662 | VERSIONING_SYSTEM = "apple-generic";
663 | };
664 | name = Debug;
665 | };
666 | 97C147071CF9000F007C117D /* Release */ = {
667 | isa = XCBuildConfiguration;
668 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
669 | buildSettings = {
670 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
671 | CLANG_ENABLE_MODULES = YES;
672 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
673 | DEVELOPMENT_TEAM = X6QYJ2NQ5M;
674 | ENABLE_BITCODE = NO;
675 | INFOPLIST_FILE = Runner/Info.plist;
676 | LD_RUNPATH_SEARCH_PATHS = (
677 | "$(inherited)",
678 | "@executable_path/Frameworks",
679 | );
680 | PRODUCT_BUNDLE_IDENTIFIER = com.example.starterapp;
681 | PRODUCT_NAME = "$(TARGET_NAME)";
682 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
683 | SWIFT_VERSION = 5.0;
684 | VERSIONING_SYSTEM = "apple-generic";
685 | };
686 | name = Release;
687 | };
688 | /* End XCBuildConfiguration section */
689 |
690 | /* Begin XCConfigurationList section */
691 | 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
692 | isa = XCConfigurationList;
693 | buildConfigurations = (
694 | 331C8088294A63A400263BE5 /* Debug */,
695 | 331C8089294A63A400263BE5 /* Release */,
696 | 331C808A294A63A400263BE5 /* Profile */,
697 | );
698 | defaultConfigurationIsVisible = 0;
699 | defaultConfigurationName = Release;
700 | };
701 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
702 | isa = XCConfigurationList;
703 | buildConfigurations = (
704 | 97C147031CF9000F007C117D /* Debug */,
705 | 97C147041CF9000F007C117D /* Release */,
706 | 249021D3217E4FDB00AE95B9 /* Profile */,
707 | );
708 | defaultConfigurationIsVisible = 0;
709 | defaultConfigurationName = Release;
710 | };
711 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
712 | isa = XCConfigurationList;
713 | buildConfigurations = (
714 | 97C147061CF9000F007C117D /* Debug */,
715 | 97C147071CF9000F007C117D /* Release */,
716 | 249021D4217E4FDB00AE95B9 /* Profile */,
717 | );
718 | defaultConfigurationIsVisible = 0;
719 | defaultConfigurationName = Release;
720 | };
721 | /* End XCConfigurationList section */
722 | };
723 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
724 | }
725 |
--------------------------------------------------------------------------------