Compare commits

..

No commits in common. "31350762c51aec8e5dc5361d567207c06c79ba39" and "af841baefb8e365fe347e7be9baf86c38c0c5411" have entirely different histories.

117 changed files with 2516 additions and 1964 deletions

View File

@ -3,47 +3,6 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## 2023-11-14
### Changes
---
Packages with breaking changes:
- [`wyatt_crud_bloc` - `v0.2.0`](#wyatt_crud_bloc---v020)
- [`wyatt_crud_bloc_firestore` - `v0.2.0`](#wyatt_crud_bloc_firestore---v020)
Packages with other changes:
- [`wyatt_bloc_layout` - `v0.1.2+4`](#wyatt_bloc_layout---v0124)
Packages with dependency updates only:
> Packages listed below depend on other packages in this workspace that have had changes. Their versions have been incremented to bump the minimum dependency versions of the packages they depend upon in this project.
- `wyatt_bloc_layout` - `v0.1.2+4`
---
#### `wyatt_crud_bloc` - `v0.2.0`
- **REFACTOR**: make CrudLoading instanciable.
- **FIX**: rename wyatt_bruc_bloc_firestore main package file.
- **FIX**: apply dart format.
- **FIX**: apply dart fix --apply.
- **FEAT**(crud): add streaming usecase (closes #180).
- **DOCS**(crud): update readme.
- **BREAKING** **FEAT**(crud): make crudbuilder integration more easy by integrating blocbuilder (closes #181).
- **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package.
#### `wyatt_crud_bloc_firestore` - `v0.2.0`
- **FIX**: rename wyatt_bruc_bloc_firestore main package file.
- **DOCS**(crud): update readme.
- **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package.
## 2023-10-04
### Changes

View File

@ -1,7 +1,3 @@
## 0.1.2+4
- Update a dependency to the latest release.
## 0.1.2+3
- Update a dependency to the latest release.

View File

@ -42,7 +42,7 @@ dependencies:
version: ^0.1.2+3
wyatt_crud_bloc:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
version: ^0.2.0
version: ^0.1.1+1
wyatt_ui_components:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
version: ^0.3.0+2

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -16,10 +16,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart' as bloc_base;
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
import 'package:wyatt_ui_components/wyatt_ui_components.dart';
mixin CrudMixin<Bloc extends bloc_base.StateStreamable<CrudState>,
mixin CrudMixin<Cubit extends bloc_base.Cubit<dynamic>,
SuccessState extends CrudSuccess> {
String? get loaderComponentId => null;
String? get errorComponentId => null;
@ -39,10 +40,11 @@ mixin CrudMixin<Bloc extends bloc_base.StateStreamable<CrudState>,
Widget successBuilder(BuildContext context, SuccessState state);
Widget crudBuilder(BuildContext context, CrudState state) =>
CrudBuilder<Bloc, CrudInitial, CrudLoading, SuccessState, CrudError>(
CrudBuilder<CrudInitial, CrudLoading, SuccessState, CrudError>(
errorBuilder: errorBuilder,
loadingBuilder: loadingBuilder,
initialBuilder: initialBuilder,
state: state,
builder: successBuilder,
);
}

View File

@ -1,7 +1,7 @@
name: wyatt_bloc_layout
description: Layouts based on bloc helper library
repository: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages/src/branch/master/packages/wyatt_bloc_layout
version: 0.1.2+4
version: 0.1.2+3
publish_to: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
@ -23,7 +23,7 @@ dependencies:
wyatt_crud_bloc:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub
version: ^0.2.0
version: ^0.1.1+1
wyatt_ui_components:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub

View File

@ -1,16 +1,3 @@
## 0.2.0
> Note: This release has breaking changes.
- **REFACTOR**: make CrudLoading instanciable.
- **FIX**: rename wyatt_bruc_bloc_firestore main package file.
- **FIX**: apply dart format.
- **FIX**: apply dart fix --apply.
- **FEAT**(crud): add streaming usecase (closes #180).
- **DOCS**(crud): update readme.
- **BREAKING** **FEAT**(crud): make crudbuilder integration more easy by integrating blocbuilder (closes #181).
- **BREAKING** **FEAT**(crud): move crud firestore implementation into his own package.
## 0.1.1+1
- **FIX**: apply dart format.

View File

@ -27,7 +27,10 @@ CRUD Bloc Pattern utilities for Flutter.
This package defines a set of classes that can be used to implement the CRUD Bloc Pattern.
* Model
* Data Source
+ In Memory
+ Firestore
* Repository
* Use Case
+ Create
@ -37,207 +40,128 @@ This package defines a set of classes that can be used to implement the CRUD Blo
+ Update All
+ Delete
+ Delete All
+ Search
+ Query
* Bloc
+ Standard (C R U D), you have to choose the responsiblity of the bloc for each use case. For example, you can have a cubit that only handles the creation of an entity, and another cubit that only handles the deletion of an entity. Each cubit can only have one operation responsibility of each type, for example you can't have a cubit that handles get and get all.
+ Advanced, you can set every use case to be handled by the bloc. This is useful if you want to have a single bloc that handles all the operations of an entity.
## Usage
Create your entity using Wyatt Architecture and Equatable
Create a model class that extends the `ObjectModel` class.
```dart
import 'package:equatable/equatable.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart';
class User extends Entity with EquatableMixin {
class User extends ObjectModel {
@override
final String? id;
final String name;
final String email;
final String phone;
final String? name;
const User({
required this.name,
required this.email,
required this.phone,
this.id,
});
Map<String, Object> toMap() {
return {
'name': name ?? '',
};
}
@override
List<Object?> get props => [id, name, email, phone];
String toString() => 'User(id: $id, name: $name)';
}
```
Then, you can create your model for this entity with Freezed, JsonSerializable or any other library.
You have to implement a bloc.
```dart
import 'package:crud_bloc_example/user_entity.dart';
import 'package:json_annotation/json_annotation.dart';
part 'user_model.g.dart';
@JsonSerializable()
class UserModel extends User {
UserModel({
super.id,
required super.name,
required super.email,
required super.phone,
});
factory UserModel.fromJson(Map<String, dynamic> json) =>
_$UserModelFromJson(json);
Map<String, dynamic> toJson() => _$UserModelToJson(this);
@override
String toString() =>
'UserModel(id: $id, name: $name, email: $email, phone: $phone)';
}
```
> This exemple uses JsonSerializable to generate the model, but you can use any other library. Or you can even create your own model without any library.
Then you have to create a **CRUD** Cubit. Each Crud cubit can only handle one operation of each type. For example, you can't have a cubit that handles get and get all. (See the `CrudAdvancedCubit` for this use case).
You also have to create a `modelIdentifier` that will be used to identify your model. This is used to identify the model in the state of the cubit. For example, if you have a list of users, you can use the id of the user to identify it in the state. **It's up to you to choose how you want to identify your model.**
```dart
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
/// A [CrudCubit] for [User].
class UserCubit extends CrudCubit<User> {
final CrudRepository<User> crudRepository;
final CrudRepository<User> _crudRepository;
UserCubit(this.crudRepository);
UserCubit(this._crudRepository);
@override
DefaultCreate<User>? get createOperation => Create(crudRepository);
CreateOperation<User, dynamic>? get createOperation =>
Create(_crudRepository);
@override
DefaultDelete? get deleteOperation => Delete(crudRepository);
DeleteOperation<User, dynamic>? get deleteOperation =>
Delete(_crudRepository);
@override
DefaultRead? get readOperation => GetAll(crudRepository);
ReadOperation<User, dynamic, dynamic>? get readOperation =>
GetAll(_crudRepository);
@override
DefaultUpdate? get updateOperation => Update(crudRepository);
@override
ModelIdentifier<User> get modelIdentifier => ModelIdentifier(
getIdentifier: (user) => user.id ?? '',
);
UpdateOperation<User, dynamic>? get updateOperation =>
Update(_crudRepository);
}
```
> In this example, the `modelIdentifier` is the id of the user. But you can use any other property of the user to identify it. But make sure that the property you use is unique.
> You can also use the `CrudAdvancedCubit` class to implement a bloc that handles all the use cases.
> In this example, the `CrudCubit` handles `Create`, `Delete`, `GetAll` and `Update` operations. But you can choose which operation you want to handle. For example, you can have a cubit that only handles the creation of an entity, and another cubit that only handles the deletion of an entity.
Then you can configure the data source and the repository.
### In Memory
The base implementation of the data source is the `CrudInMemoryDataSourceImpl`. This data source stores the data in memory. This is useful for testing.
Then you can use the bloc in your widget with a data source and a repository.
```dart
final CrudDataSource crudDataSource = CrudDataSourceInMemoryImpl(
id: (operation, json) => json['id'] as String?,
);
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
final CrudDataSource<User> userLocalDataSource =
CrudInMemoryDataSourceImpl<User>(toMap: (user) => user.toMap());
final CrudRepository<User> userRepository =
CrudRepositoryImpl(crudDataSource: userLocalDataSource);
return RepositoryProvider<CrudRepository<User>>.value(
value: userRepository,
child: BlocProvider<UserCubit>(
create: (context) => UserCubit(userRepository)..read(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
),
),
);
}
}
```
> The `id` parameter is used to get the id of the raw data. You can use the `operation` parameter to get the operation that is being performed. This is useful if you want to have different ids for each operation. For example, you can have a different id for the creation and the update of an entity.
### Firestore
You can use the `CrudFirestoreDataSourceImpl` to store your data in Firestore.
Make sure to add the `wyatt_crud_bloc_firestore` package to your dependencies.
```dart
final CrudDataSource crudDataSource = CrudDataSourceFirestoreImpl(
'users',
id: (_, json) => json['id'] as String,
fromFirestore: (document, snapshot) => document.data() ?? {},
toFirestore: (object, options) => object,
);
```
> The `id` parameter is used to get the id of the raw data. You can use the `operation` parameter to get the operation that is being performed. This is useful if you want to have different ids for each operation. For example, you can have a different id for the creation and the update of an entity.
> The `fromFirestore` and `toFirestore` parameters are used to convert the data from and to Firestore.
Finally, you can use the `CrudRepositoryImpl` to create your repository.
```dart
final CrudRepository<User> userRepository = CrudRepositoryImpl(
crudDataSource: crudDataSource,
modelMapper: ModelMapper(
fromJson: (json) => UserModel.fromJson(json ?? {}),
toJson: (user) => UserModel(
id: user.id,
name: user.name,
email: user.email,
phone: user.phone,
).toJson(),
),
);
```
> The `modelMapper` parameter is used to convert the data from and to the model. In the `toJson` make sure to use the same data structure as the one used in the data source. For example the previous `id()` function is used to get the id of the raw data, if `id` is missing from the raw data, the `id()` function will not works.
And in your widget tree you can use the `CrudBuilder` to build your UI.
And anywhere in your widget tree you can use the BlocBuilder to build your widget.
```dart
...
BlocBuilder<UserCubit, CrudState>(
buildWhen: (previous, current) {
if (current is CrudLoading && current is! CrudReading) {
return false;
}
return true;
},
builder: (context, state) {
return Expanded(
child: CrudBuilder.typed<CrudListLoaded<User?>>(
state: state,
builder: ((context, state) {
return ListView.builder(
itemCount: state.data.length,
itemBuilder: (context, index) {
final user = state.data.elementAt(index);
return ListTile(
title: Text(user?.name ?? 'Error'),
subtitle: Text(user?.email ?? 'Error'),
onTap: () {
context
.read<UserCubit>()
.delete(id: (user?.id)!);
},
onLongPress: () {
context.read<UserCubit>().update(
single: UpdateParameters(
id: user?.id ?? '',
raw: {
'email': '${user?.id}@updated.io',
}),
);
},
);
},
);
}),
initialBuilder: (context, state) =>
const Center(child: CircularProgressIndicator()),
loadingBuilder: (context, state) =>
const Center(child: CircularProgressIndicator()),
errorBuilder: (context, state) => Text("Error: $state"),
),
return CrudBuilder.typed<CrudListLoaded<User?>>(
state: state,
builder: ((context, state) {
return ListView.builder(
shrinkWrap: true,
itemCount: state.data.length,
itemBuilder: (context, index) {
final user = state.data.elementAt(index);
return ListTile(
title: Text(user?.name ?? 'Error'),
subtitle: Text(user?.id ?? 'Error'),
onTap: () {
context.read<UserCubit>().delete(id: (user?.id)!);
},
);
},
);
}),
initialBuilder: (context, state) => const Text("Loading..."),
loadingBuilder: (context, state) => const Text("Loading..."),
errorBuilder: (context, state) => Text("Error: $state"),
);
},
),
...
```
> This piece of code is used to build a list of users. When you tap on a user, it will delete it. When you long press on a user, it will update it. Also, the loading state is not always displayed, it will only be displayed when the state is `CrudReading`, so when the state is `CrudUpdating` or `CrudDeleting`, the loading state will not be displayed.

View File

@ -44,3 +44,5 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release
/lib/firebase_options.dart

View File

@ -1,11 +1,11 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
# This file should be version controlled.
version:
revision: "d211f42860350d914a5ad8102f9ec32764dc6d06"
channel: "stable"
revision: 52b3dc25f6471c27b2144594abb11c741cb88f57
channel: stable
project_type: app
@ -13,11 +13,11 @@ project_type: app
migration:
platforms:
- platform: root
create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06
base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06
- platform: android
create_revision: d211f42860350d914a5ad8102f9ec32764dc6d06
base_revision: d211f42860350d914a5ad8102f9ec32764dc6d06
create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57
base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57
- platform: ios
create_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57
base_revision: 52b3dc25f6471c27b2144594abb11c741cb88f57
# User provided section

View File

@ -1,9 +1,3 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
@ -12,6 +6,11 @@ if (localPropertiesFile.exists()) {
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
@ -22,10 +21,15 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
// START: FlutterFire Configuration
apply plugin: 'com.google.gms.google-services'
// END: FlutterFire Configuration
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
namespace "com.example.example"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@ -43,8 +47,6 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.crud_bloc_example"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
@ -64,4 +66,6 @@ flutter {
source '../..'
}
dependencies {}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

View File

@ -1,6 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.crud_bloc_example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>

View File

@ -1,6 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="example"
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.crud_bloc_example">
<application
android:label="crud_bloc_example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity

View File

@ -1,4 +1,4 @@
package com.example.example
package com.example.crud_bloc_example
import io.flutter.embedding.android.FlutterActivity

View File

@ -3,7 +3,7 @@
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.

View File

@ -3,7 +3,7 @@
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.

View File

@ -1,6 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.crud_bloc_example">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>

View File

@ -1,12 +1,12 @@
buildscript {
ext.kotlin_version = '1.7.10'
ext.kotlin_version = '1.6.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.0'
classpath 'com.android.tools.build:gradle:4.1.0'
// START: FlutterFire Configuration
classpath 'com.google.gms:google-services:4.3.10'
// END: FlutterFire Configuration
@ -29,6 +29,6 @@ subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@ -1,5 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip

View File

@ -1,20 +1,11 @@
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
include ':app'
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
include ":app"
apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle"
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"

View File

@ -0,0 +1,34 @@
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>

View File

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -0,0 +1,2 @@
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

View File

@ -0,0 +1,41 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end

View File

@ -0,0 +1,757 @@
PODS:
- abseil/algorithm (1.20211102.0):
- abseil/algorithm/algorithm (= 1.20211102.0)
- abseil/algorithm/container (= 1.20211102.0)
- abseil/algorithm/algorithm (1.20211102.0):
- abseil/base/config
- abseil/algorithm/container (1.20211102.0):
- abseil/algorithm/algorithm
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/base (1.20211102.0):
- abseil/base/atomic_hook (= 1.20211102.0)
- abseil/base/base (= 1.20211102.0)
- abseil/base/base_internal (= 1.20211102.0)
- abseil/base/config (= 1.20211102.0)
- abseil/base/core_headers (= 1.20211102.0)
- abseil/base/dynamic_annotations (= 1.20211102.0)
- abseil/base/endian (= 1.20211102.0)
- abseil/base/errno_saver (= 1.20211102.0)
- abseil/base/fast_type_id (= 1.20211102.0)
- abseil/base/log_severity (= 1.20211102.0)
- abseil/base/malloc_internal (= 1.20211102.0)
- abseil/base/pretty_function (= 1.20211102.0)
- abseil/base/raw_logging_internal (= 1.20211102.0)
- abseil/base/spinlock_wait (= 1.20211102.0)
- abseil/base/strerror (= 1.20211102.0)
- abseil/base/throw_delegate (= 1.20211102.0)
- abseil/base/atomic_hook (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/base (1.20211102.0):
- abseil/base/atomic_hook
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/base/dynamic_annotations
- abseil/base/log_severity
- abseil/base/raw_logging_internal
- abseil/base/spinlock_wait
- abseil/meta/type_traits
- abseil/base/base_internal (1.20211102.0):
- abseil/base/config
- abseil/meta/type_traits
- abseil/base/config (1.20211102.0)
- abseil/base/core_headers (1.20211102.0):
- abseil/base/config
- abseil/base/dynamic_annotations (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian (1.20211102.0):
- abseil/base/base
- abseil/base/config
- abseil/base/core_headers
- abseil/base/errno_saver (1.20211102.0):
- abseil/base/config
- abseil/base/fast_type_id (1.20211102.0):
- abseil/base/config
- abseil/base/log_severity (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/malloc_internal (1.20211102.0):
- abseil/base/base
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/base/dynamic_annotations
- abseil/base/raw_logging_internal
- abseil/base/pretty_function (1.20211102.0)
- abseil/base/raw_logging_internal (1.20211102.0):
- abseil/base/atomic_hook
- abseil/base/config
- abseil/base/core_headers
- abseil/base/log_severity
- abseil/base/spinlock_wait (1.20211102.0):
- abseil/base/base_internal
- abseil/base/core_headers
- abseil/base/errno_saver
- abseil/base/strerror (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/errno_saver
- abseil/base/throw_delegate (1.20211102.0):
- abseil/base/config
- abseil/base/raw_logging_internal
- abseil/container/common (1.20211102.0):
- abseil/meta/type_traits
- abseil/types/optional
- abseil/container/compressed_tuple (1.20211102.0):
- abseil/utility/utility
- abseil/container/container_memory (1.20211102.0):
- abseil/base/config
- abseil/memory/memory
- abseil/meta/type_traits
- abseil/utility/utility
- abseil/container/fixed_array (1.20211102.0):
- abseil/algorithm/algorithm
- abseil/base/config
- abseil/base/core_headers
- abseil/base/dynamic_annotations
- abseil/base/throw_delegate
- abseil/container/compressed_tuple
- abseil/memory/memory
- abseil/container/flat_hash_map (1.20211102.0):
- abseil/algorithm/container
- abseil/container/container_memory
- abseil/container/hash_function_defaults
- abseil/container/raw_hash_map
- abseil/memory/memory
- abseil/container/hash_function_defaults (1.20211102.0):
- abseil/base/config
- abseil/hash/hash
- abseil/strings/cord
- abseil/strings/strings
- abseil/container/hash_policy_traits (1.20211102.0):
- abseil/meta/type_traits
- abseil/container/hashtable_debug_hooks (1.20211102.0):
- abseil/base/config
- abseil/container/hashtablez_sampler (1.20211102.0):
- abseil/base/base
- abseil/base/core_headers
- abseil/container/have_sse
- abseil/debugging/stacktrace
- abseil/memory/memory
- abseil/profiling/exponential_biased
- abseil/profiling/sample_recorder
- abseil/synchronization/synchronization
- abseil/utility/utility
- abseil/container/have_sse (1.20211102.0)
- abseil/container/inlined_vector (1.20211102.0):
- abseil/algorithm/algorithm
- abseil/base/core_headers
- abseil/base/throw_delegate
- abseil/container/inlined_vector_internal
- abseil/memory/memory
- abseil/container/inlined_vector_internal (1.20211102.0):
- abseil/base/core_headers
- abseil/container/compressed_tuple
- abseil/memory/memory
- abseil/meta/type_traits
- abseil/types/span
- abseil/container/layout (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/strings/strings
- abseil/types/span
- abseil/utility/utility
- abseil/container/raw_hash_map (1.20211102.0):
- abseil/base/throw_delegate
- abseil/container/container_memory
- abseil/container/raw_hash_set
- abseil/container/raw_hash_set (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/container/common
- abseil/container/compressed_tuple
- abseil/container/container_memory
- abseil/container/hash_policy_traits
- abseil/container/hashtable_debug_hooks
- abseil/container/hashtablez_sampler
- abseil/container/have_sse
- abseil/memory/memory
- abseil/meta/type_traits
- abseil/numeric/bits
- abseil/utility/utility
- abseil/debugging/debugging_internal (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/dynamic_annotations
- abseil/base/errno_saver
- abseil/base/raw_logging_internal
- abseil/debugging/demangle_internal (1.20211102.0):
- abseil/base/base
- abseil/base/config
- abseil/base/core_headers
- abseil/debugging/stacktrace (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/debugging/debugging_internal
- abseil/debugging/symbolize (1.20211102.0):
- abseil/base/base
- abseil/base/config
- abseil/base/core_headers
- abseil/base/dynamic_annotations
- abseil/base/malloc_internal
- abseil/base/raw_logging_internal
- abseil/debugging/debugging_internal
- abseil/debugging/demangle_internal
- abseil/strings/strings
- abseil/functional/bind_front (1.20211102.0):
- abseil/base/base_internal
- abseil/container/compressed_tuple
- abseil/meta/type_traits
- abseil/utility/utility
- abseil/functional/function_ref (1.20211102.0):
- abseil/base/base_internal
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/hash/city (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/hash/hash (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/container/fixed_array
- abseil/hash/city
- abseil/hash/low_level_hash
- abseil/meta/type_traits
- abseil/numeric/int128
- abseil/strings/strings
- abseil/types/optional
- abseil/types/variant
- abseil/utility/utility
- abseil/hash/low_level_hash (1.20211102.0):
- abseil/base/config
- abseil/base/endian
- abseil/numeric/bits
- abseil/numeric/int128
- abseil/memory (1.20211102.0):
- abseil/memory/memory (= 1.20211102.0)
- abseil/memory/memory (1.20211102.0):
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/meta (1.20211102.0):
- abseil/meta/type_traits (= 1.20211102.0)
- abseil/meta/type_traits (1.20211102.0):
- abseil/base/config
- abseil/numeric/bits (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/numeric/int128 (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/numeric/bits
- abseil/numeric/representation (1.20211102.0):
- abseil/base/config
- abseil/profiling/exponential_biased (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/profiling/sample_recorder (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/synchronization/synchronization
- abseil/time/time
- abseil/random/distributions (1.20211102.0):
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/numeric/bits
- abseil/random/internal/distribution_caller
- abseil/random/internal/fast_uniform_bits
- abseil/random/internal/fastmath
- abseil/random/internal/generate_real
- abseil/random/internal/iostream_state_saver
- abseil/random/internal/traits
- abseil/random/internal/uniform_helper
- abseil/random/internal/wide_multiply
- abseil/strings/strings
- abseil/random/internal/distribution_caller (1.20211102.0):
- abseil/base/config
- abseil/base/fast_type_id
- abseil/utility/utility
- abseil/random/internal/fast_uniform_bits (1.20211102.0):
- abseil/base/config
- abseil/meta/type_traits
- abseil/random/internal/fastmath (1.20211102.0):
- abseil/numeric/bits
- abseil/random/internal/generate_real (1.20211102.0):
- abseil/meta/type_traits
- abseil/numeric/bits
- abseil/random/internal/fastmath
- abseil/random/internal/traits
- abseil/random/internal/iostream_state_saver (1.20211102.0):
- abseil/meta/type_traits
- abseil/numeric/int128
- abseil/random/internal/nonsecure_base (1.20211102.0):
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/random/internal/pool_urbg
- abseil/random/internal/salted_seed_seq
- abseil/random/internal/seed_material
- abseil/types/optional
- abseil/types/span
- abseil/random/internal/pcg_engine (1.20211102.0):
- abseil/base/config
- abseil/meta/type_traits
- abseil/numeric/bits
- abseil/numeric/int128
- abseil/random/internal/fastmath
- abseil/random/internal/iostream_state_saver
- abseil/random/internal/platform (1.20211102.0):
- abseil/base/config
- abseil/random/internal/pool_urbg (1.20211102.0):
- abseil/base/base
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/base/raw_logging_internal
- abseil/random/internal/randen
- abseil/random/internal/seed_material
- abseil/random/internal/traits
- abseil/random/seed_gen_exception
- abseil/types/span
- abseil/random/internal/randen (1.20211102.0):
- abseil/base/raw_logging_internal
- abseil/random/internal/platform
- abseil/random/internal/randen_hwaes
- abseil/random/internal/randen_slow
- abseil/random/internal/randen_engine (1.20211102.0):
- abseil/base/endian
- abseil/meta/type_traits
- abseil/random/internal/iostream_state_saver
- abseil/random/internal/randen
- abseil/random/internal/randen_hwaes (1.20211102.0):
- abseil/base/config
- abseil/random/internal/platform
- abseil/random/internal/randen_hwaes_impl
- abseil/random/internal/randen_hwaes_impl (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/numeric/int128
- abseil/random/internal/platform
- abseil/random/internal/randen_slow (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/numeric/int128
- abseil/random/internal/platform
- abseil/random/internal/salted_seed_seq (1.20211102.0):
- abseil/container/inlined_vector
- abseil/meta/type_traits
- abseil/random/internal/seed_material
- abseil/types/optional
- abseil/types/span
- abseil/random/internal/seed_material (1.20211102.0):
- abseil/base/core_headers
- abseil/base/dynamic_annotations
- abseil/base/raw_logging_internal
- abseil/random/internal/fast_uniform_bits
- abseil/strings/strings
- abseil/types/optional
- abseil/types/span
- abseil/random/internal/traits (1.20211102.0):
- abseil/base/config
- abseil/random/internal/uniform_helper (1.20211102.0):
- abseil/base/config
- abseil/meta/type_traits
- abseil/random/internal/traits
- abseil/random/internal/wide_multiply (1.20211102.0):
- abseil/base/config
- abseil/numeric/bits
- abseil/numeric/int128
- abseil/random/internal/traits
- abseil/random/random (1.20211102.0):
- abseil/random/distributions
- abseil/random/internal/nonsecure_base
- abseil/random/internal/pcg_engine
- abseil/random/internal/pool_urbg
- abseil/random/internal/randen_engine
- abseil/random/seed_sequences
- abseil/random/seed_gen_exception (1.20211102.0):
- abseil/base/config
- abseil/random/seed_sequences (1.20211102.0):
- abseil/container/inlined_vector
- abseil/random/internal/nonsecure_base
- abseil/random/internal/pool_urbg
- abseil/random/internal/salted_seed_seq
- abseil/random/internal/seed_material
- abseil/random/seed_gen_exception
- abseil/types/span
- abseil/status/status (1.20211102.0):
- abseil/base/atomic_hook
- abseil/base/config
- abseil/base/core_headers
- abseil/base/raw_logging_internal
- abseil/container/inlined_vector
- abseil/debugging/stacktrace
- abseil/debugging/symbolize
- abseil/functional/function_ref
- abseil/strings/cord
- abseil/strings/str_format
- abseil/strings/strings
- abseil/types/optional
- abseil/status/statusor (1.20211102.0):
- abseil/base/base
- abseil/base/core_headers
- abseil/base/raw_logging_internal
- abseil/meta/type_traits
- abseil/status/status
- abseil/strings/strings
- abseil/types/variant
- abseil/utility/utility
- abseil/strings/cord (1.20211102.0):
- abseil/base/base
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/base/raw_logging_internal
- abseil/container/fixed_array
- abseil/container/inlined_vector
- abseil/functional/function_ref
- abseil/meta/type_traits
- abseil/strings/cord_internal
- abseil/strings/cordz_functions
- abseil/strings/cordz_info
- abseil/strings/cordz_statistics
- abseil/strings/cordz_update_scope
- abseil/strings/cordz_update_tracker
- abseil/strings/internal
- abseil/strings/str_format
- abseil/strings/strings
- abseil/types/optional
- abseil/strings/cord_internal (1.20211102.0):
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/base/raw_logging_internal
- abseil/base/throw_delegate
- abseil/container/compressed_tuple
- abseil/container/inlined_vector
- abseil/container/layout
- abseil/functional/function_ref
- abseil/meta/type_traits
- abseil/strings/strings
- abseil/types/span
- abseil/strings/cordz_functions (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/raw_logging_internal
- abseil/profiling/exponential_biased
- abseil/strings/cordz_handle (1.20211102.0):
- abseil/base/base
- abseil/base/config
- abseil/base/raw_logging_internal
- abseil/synchronization/synchronization
- abseil/strings/cordz_info (1.20211102.0):
- abseil/base/base
- abseil/base/config
- abseil/base/core_headers
- abseil/base/raw_logging_internal
- abseil/container/inlined_vector
- abseil/debugging/stacktrace
- abseil/strings/cord_internal
- abseil/strings/cordz_functions
- abseil/strings/cordz_handle
- abseil/strings/cordz_statistics
- abseil/strings/cordz_update_tracker
- abseil/synchronization/synchronization
- abseil/types/span
- abseil/strings/cordz_statistics (1.20211102.0):
- abseil/base/config
- abseil/strings/cordz_update_tracker
- abseil/strings/cordz_update_scope (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/strings/cord_internal
- abseil/strings/cordz_info
- abseil/strings/cordz_update_tracker
- abseil/strings/cordz_update_tracker (1.20211102.0):
- abseil/base/config
- abseil/strings/internal (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/base/raw_logging_internal
- abseil/meta/type_traits
- abseil/strings/str_format (1.20211102.0):
- abseil/strings/str_format_internal
- abseil/strings/str_format_internal (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/functional/function_ref
- abseil/meta/type_traits
- abseil/numeric/bits
- abseil/numeric/int128
- abseil/numeric/representation
- abseil/strings/strings
- abseil/types/optional
- abseil/types/span
- abseil/strings/strings (1.20211102.0):
- abseil/base/base
- abseil/base/config
- abseil/base/core_headers
- abseil/base/endian
- abseil/base/raw_logging_internal
- abseil/base/throw_delegate
- abseil/memory/memory
- abseil/meta/type_traits
- abseil/numeric/bits
- abseil/numeric/int128
- abseil/strings/internal
- abseil/synchronization/graphcycles_internal (1.20211102.0):
- abseil/base/base
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/base/malloc_internal
- abseil/base/raw_logging_internal
- abseil/synchronization/kernel_timeout_internal (1.20211102.0):
- abseil/base/core_headers
- abseil/base/raw_logging_internal
- abseil/time/time
- abseil/synchronization/synchronization (1.20211102.0):
- abseil/base/atomic_hook
- abseil/base/base
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/base/dynamic_annotations
- abseil/base/malloc_internal
- abseil/base/raw_logging_internal
- abseil/debugging/stacktrace
- abseil/debugging/symbolize
- abseil/synchronization/graphcycles_internal
- abseil/synchronization/kernel_timeout_internal
- abseil/time/time
- abseil/time (1.20211102.0):
- abseil/time/internal (= 1.20211102.0)
- abseil/time/time (= 1.20211102.0)
- abseil/time/internal (1.20211102.0):
- abseil/time/internal/cctz (= 1.20211102.0)
- abseil/time/internal/cctz (1.20211102.0):
- abseil/time/internal/cctz/civil_time (= 1.20211102.0)
- abseil/time/internal/cctz/time_zone (= 1.20211102.0)
- abseil/time/internal/cctz/civil_time (1.20211102.0):
- abseil/base/config
- abseil/time/internal/cctz/time_zone (1.20211102.0):
- abseil/base/config
- abseil/time/internal/cctz/civil_time
- abseil/time/time (1.20211102.0):
- abseil/base/base
- abseil/base/core_headers
- abseil/base/raw_logging_internal
- abseil/numeric/int128
- abseil/strings/strings
- abseil/time/internal/cctz/civil_time
- abseil/time/internal/cctz/time_zone
- abseil/types (1.20211102.0):
- abseil/types/any (= 1.20211102.0)
- abseil/types/bad_any_cast (= 1.20211102.0)
- abseil/types/bad_any_cast_impl (= 1.20211102.0)
- abseil/types/bad_optional_access (= 1.20211102.0)
- abseil/types/bad_variant_access (= 1.20211102.0)
- abseil/types/compare (= 1.20211102.0)
- abseil/types/optional (= 1.20211102.0)
- abseil/types/span (= 1.20211102.0)
- abseil/types/variant (= 1.20211102.0)
- abseil/types/any (1.20211102.0):
- abseil/base/config
- abseil/base/core_headers
- abseil/base/fast_type_id
- abseil/meta/type_traits
- abseil/types/bad_any_cast
- abseil/utility/utility
- abseil/types/bad_any_cast (1.20211102.0):
- abseil/base/config
- abseil/types/bad_any_cast_impl
- abseil/types/bad_any_cast_impl (1.20211102.0):
- abseil/base/config
- abseil/base/raw_logging_internal
- abseil/types/bad_optional_access (1.20211102.0):
- abseil/base/config
- abseil/base/raw_logging_internal
- abseil/types/bad_variant_access (1.20211102.0):
- abseil/base/config
- abseil/base/raw_logging_internal
- abseil/types/compare (1.20211102.0):
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/types/optional (1.20211102.0):
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/memory/memory
- abseil/meta/type_traits
- abseil/types/bad_optional_access
- abseil/utility/utility
- abseil/types/span (1.20211102.0):
- abseil/algorithm/algorithm
- abseil/base/core_headers
- abseil/base/throw_delegate
- abseil/meta/type_traits
- abseil/types/variant (1.20211102.0):
- abseil/base/base_internal
- abseil/base/config
- abseil/base/core_headers
- abseil/meta/type_traits
- abseil/types/bad_variant_access
- abseil/utility/utility
- abseil/utility/utility (1.20211102.0):
- abseil/base/base_internal
- abseil/base/config
- abseil/meta/type_traits
- BoringSSL-GRPC (0.0.24):
- BoringSSL-GRPC/Implementation (= 0.0.24)
- BoringSSL-GRPC/Interface (= 0.0.24)
- BoringSSL-GRPC/Implementation (0.0.24):
- BoringSSL-GRPC/Interface (= 0.0.24)
- BoringSSL-GRPC/Interface (0.0.24)
- cloud_firestore (4.0.5):
- Firebase/Firestore (= 10.1.0)
- firebase_core
- Flutter
- nanopb (< 2.30910.0, >= 2.30908.0)
- Firebase/CoreOnly (10.1.0):
- FirebaseCore (= 10.1.0)
- Firebase/Firestore (10.1.0):
- Firebase/CoreOnly
- FirebaseFirestore (~> 10.1.0)
- firebase_core (2.2.0):
- Firebase/CoreOnly (= 10.1.0)
- Flutter
- FirebaseCore (10.1.0):
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8)
- FirebaseCoreInternal (10.1.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- FirebaseFirestore (10.1.0):
- abseil/algorithm (~> 1.20211102.0)
- abseil/base (~> 1.20211102.0)
- abseil/container/flat_hash_map (~> 1.20211102.0)
- abseil/memory (~> 1.20211102.0)
- abseil/meta (~> 1.20211102.0)
- abseil/strings/strings (~> 1.20211102.0)
- abseil/time (~> 1.20211102.0)
- abseil/types (~> 1.20211102.0)
- FirebaseCore (~> 10.0)
- "gRPC-C++ (~> 1.44.0)"
- leveldb-library (~> 1.22)
- nanopb (< 2.30910.0, >= 2.30908.0)
- Flutter (1.0.0)
- GoogleUtilities/Environment (7.8.0):
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.8.0):
- GoogleUtilities/Environment
- "GoogleUtilities/NSData+zlib (7.8.0)"
- "gRPC-C++ (1.44.0)":
- "gRPC-C++/Implementation (= 1.44.0)"
- "gRPC-C++/Interface (= 1.44.0)"
- "gRPC-C++/Implementation (1.44.0)":
- abseil/base/base (= 1.20211102.0)
- abseil/base/core_headers (= 1.20211102.0)
- abseil/container/flat_hash_map (= 1.20211102.0)
- abseil/container/inlined_vector (= 1.20211102.0)
- abseil/functional/bind_front (= 1.20211102.0)
- abseil/hash/hash (= 1.20211102.0)
- abseil/memory/memory (= 1.20211102.0)
- abseil/random/random (= 1.20211102.0)
- abseil/status/status (= 1.20211102.0)
- abseil/status/statusor (= 1.20211102.0)
- abseil/strings/cord (= 1.20211102.0)
- abseil/strings/str_format (= 1.20211102.0)
- abseil/strings/strings (= 1.20211102.0)
- abseil/synchronization/synchronization (= 1.20211102.0)
- abseil/time/time (= 1.20211102.0)
- abseil/types/optional (= 1.20211102.0)
- abseil/types/variant (= 1.20211102.0)
- abseil/utility/utility (= 1.20211102.0)
- "gRPC-C++/Interface (= 1.44.0)"
- gRPC-Core (= 1.44.0)
- "gRPC-C++/Interface (1.44.0)"
- gRPC-Core (1.44.0):
- gRPC-Core/Implementation (= 1.44.0)
- gRPC-Core/Interface (= 1.44.0)
- gRPC-Core/Implementation (1.44.0):
- abseil/base/base (= 1.20211102.0)
- abseil/base/core_headers (= 1.20211102.0)
- abseil/container/flat_hash_map (= 1.20211102.0)
- abseil/container/inlined_vector (= 1.20211102.0)
- abseil/functional/bind_front (= 1.20211102.0)
- abseil/hash/hash (= 1.20211102.0)
- abseil/memory/memory (= 1.20211102.0)
- abseil/random/random (= 1.20211102.0)
- abseil/status/status (= 1.20211102.0)
- abseil/status/statusor (= 1.20211102.0)
- abseil/strings/cord (= 1.20211102.0)
- abseil/strings/str_format (= 1.20211102.0)
- abseil/strings/strings (= 1.20211102.0)
- abseil/synchronization/synchronization (= 1.20211102.0)
- abseil/time/time (= 1.20211102.0)
- abseil/types/optional (= 1.20211102.0)
- abseil/types/variant (= 1.20211102.0)
- abseil/utility/utility (= 1.20211102.0)
- BoringSSL-GRPC (= 0.0.24)
- gRPC-Core/Interface (= 1.44.0)
- Libuv-gRPC (= 0.0.10)
- gRPC-Core/Interface (1.44.0)
- leveldb-library (1.22.1)
- Libuv-gRPC (0.0.10):
- Libuv-gRPC/Implementation (= 0.0.10)
- Libuv-gRPC/Interface (= 0.0.10)
- Libuv-gRPC/Implementation (0.0.10):
- Libuv-gRPC/Interface (= 0.0.10)
- Libuv-gRPC/Interface (0.0.10)
- nanopb (2.30909.0):
- nanopb/decode (= 2.30909.0)
- nanopb/encode (= 2.30909.0)
- nanopb/decode (2.30909.0)
- nanopb/encode (2.30909.0)
- PromisesObjC (2.1.1)
DEPENDENCIES:
- cloud_firestore (from `.symlinks/plugins/cloud_firestore/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- Flutter (from `Flutter`)
SPEC REPOS:
trunk:
- abseil
- BoringSSL-GRPC
- Firebase
- FirebaseCore
- FirebaseCoreInternal
- FirebaseFirestore
- GoogleUtilities
- "gRPC-C++"
- gRPC-Core
- leveldb-library
- Libuv-gRPC
- nanopb
- PromisesObjC
EXTERNAL SOURCES:
cloud_firestore:
:path: ".symlinks/plugins/cloud_firestore/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
Flutter:
:path: Flutter
SPEC CHECKSUMS:
abseil: ebe5b5529fb05d93a8bdb7951607be08b7fa71bc
BoringSSL-GRPC: 3175b25143e648463a56daeaaa499c6cb86dad33
cloud_firestore: 345ab5f423db6ae492abb648372156bdccb9df42
Firebase: 444b35a9c568a516666213c2f6cccd10cb12559f
firebase_core: d2242c6f318db1d0dcecfbfa491e943337b0d755
FirebaseCore: 55e7ae35991ccca4db03ff8d8df6ed5f17a3e4c7
FirebaseCoreInternal: 96d75228e10fd369564da51bd898414eb0f54df5
FirebaseFirestore: d482e5e0f95dba8ef5d499a7efa87ba2f56ef0c0
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
GoogleUtilities: 1d20a6ad97ef46f67bbdec158ce00563a671ebb7
"gRPC-C++": 9675f953ace2b3de7c506039d77be1f2e77a8db2
gRPC-Core: 943e491cb0d45598b0b0eb9e910c88080369290b
leveldb-library: 50c7b45cbd7bf543c81a468fe557a16ae3db8729
Libuv-gRPC: 55e51798e14ef436ad9bc45d12d43b77b49df378
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
COCOAPODS: 1.11.3

View File

@ -0,0 +1,552 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
2D3BF4E90FD3D66E6379652C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9668B7DCB1C084B61D13F13B /* Pods_Runner.framework */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
04335B06475E8C2B1917681C /* 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 = "<group>"; };
0A79DE27E9F9DDADA3D915D2 /* 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 = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
8D3EFC6842916D850020C95C /* 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 = "<group>"; };
9668B7DCB1C084B61D13F13B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2D3BF4E90FD3D66E6379652C /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
32816CF134A5ECA965EE4EF3 /* Pods */ = {
isa = PBXGroup;
children = (
0A79DE27E9F9DDADA3D915D2 /* Pods-Runner.debug.xcconfig */,
04335B06475E8C2B1917681C /* Pods-Runner.release.xcconfig */,
8D3EFC6842916D850020C95C /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
32816CF134A5ECA965EE4EF3 /* Pods */,
DF1EDFCBAB38011323A8D81B /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
DF1EDFCBAB38011323A8D81B /* Frameworks */ = {
isa = PBXGroup;
children = (
9668B7DCB1C084B61D13F13B /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
C454F828EEBC86C10B4E163A /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
897D29AE5A72F625B86D7F66 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
897D29AE5A72F625B86D7F66 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
C454F828EEBC86C10B4E163A /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
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";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6Z5P8GG96U;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6Z5P8GG96U;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 6Z5P8GG96U;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,13 @@
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View File

@ -0,0 +1,122 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@ -0,0 +1,5 @@
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
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.

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Example</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

View File

@ -1,116 +0,0 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:math';
import 'package:crud_bloc_example/user_advanced_cubit.dart';
import 'package:crud_bloc_example/user_entity.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
class AdvancedCubitView extends StatelessWidget {
const AdvancedCubitView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Advanced Cubit"),
),
body: BlocProvider(
create: (context) =>
UserAdvancedCubit(context.read<CrudRepository<User>>())
..streaming(),
child: Builder(
builder: (context) {
return Column(
children: [
Expanded(
child:
CrudBuilder.typed<UserAdvancedCubit, CrudListLoaded<User?>>(
buildWhen: (previous, current) {
if (current is CrudLoading && current is! CrudReading) {
return false;
}
return true;
},
builder: ((context, state) {
return ListView.builder(
itemCount: state.data.length,
itemBuilder: (context, index) {
final user = state.data.elementAt(index);
return ListTile(
title: Text(user?.name ?? 'Error'),
subtitle: Text(user?.email ?? 'Error'),
onTap: () {
context.read<UserAdvancedCubit>().delete((user?.id)!);
},
onLongPress: () {
context.read<UserAdvancedCubit>().update(
UpdateParameters(id: user?.id ?? '', raw: {
'email': '${user?.id}@updated.io',
}),
);
},
);
},
);
}),
initialBuilder: (context, state) =>
const Center(child: CircularProgressIndicator()),
loadingBuilder: (context, state) =>
const Center(child: CircularProgressIndicator()),
errorBuilder: (context, state) => Text("Error: $state"),
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
final r = Random().nextInt(1000);
context.read<UserAdvancedCubit>().create(
User(
id: '$r',
name: 'Wyatt $r',
email: '$r@wyattapp.io',
phone: '06$r',
),
);
},
child: CrudBuilder.onLoading<UserAdvancedCubit>(
builder: (context, state) {
if (state is CrudCreating) {
return const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
color: Colors.white,
),
);
}
return null;
},
otherBuilder: (context, state) => const Text("Create"),
),
),
],
);
}
),
),
);
}
}

View File

@ -14,44 +14,41 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:crud_bloc_example/advanced_cubit_view.dart';
import 'package:crud_bloc_example/basic_cubit_view.dart';
import 'package:crud_bloc_example/streaming_cubit_view.dart';
import 'package:crud_bloc_example/user_entity.dart';
import 'package:crud_bloc_example/user_model.dart';
import 'dart:math';
import 'package:crud_bloc_example/models.dart';
import 'package:crud_bloc_example/user_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
class MyApp extends StatelessWidget {
const MyApp({required this.crudDataSource, Key? key}) : super(key: key);
final CrudDataSource crudDataSource;
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
final CrudRepository<User> userRepository = CrudRepositoryImpl(
crudDataSource: crudDataSource,
modelMapper: ModelMapper(
fromJson: (json) => UserModel.fromJson(json ?? {}),
toJson: (user) => UserModel(
id: user.id,
name: user.name,
email: user.email,
phone: user.phone,
).toJson(),
),
);
final CrudDataSource<User> userLocalDataSource =
CrudInMemoryDataSourceImpl<User>(toMap: (user) => user.toMap());
final CrudRepository<User> userRepository =
CrudRepositoryImpl(crudDataSource: userLocalDataSource);
return RepositoryProvider<CrudRepository<User>>.value(
value: userRepository,
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
child: MultiBlocProvider(
providers: [
BlocProvider<UserCubit>(
create: (context) => UserCubit(userRepository)..read(),
),
],
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
),
home: const MyHomePage(),
),
);
}
@ -66,45 +63,58 @@ class MyHomePage extends StatelessWidget {
appBar: AppBar(
title: const Text('Flutter Demo Home Page'),
),
body: Center(
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const BasicCubitView(),
),
const SizedBox(height: 20),
const Text("Data:"),
BlocBuilder<UserCubit, CrudState>(
builder: (context, state) {
return CrudBuilder.typed<CrudListLoaded<User?>>(
state: state,
builder: ((context, state) {
return ListView.builder(
shrinkWrap: true,
itemCount: state.data.length,
itemBuilder: (context, index) {
final user = state.data.elementAt(index);
return ListTile(
title: Text(user?.name ?? 'Error'),
subtitle: Text(user?.id ?? 'Error'),
onTap: () {
context.read<UserCubit>().delete(id: (user?.id)!);
},
);
},
);
}),
initialBuilder: (context, state) => const Text("Loading..."),
loadingBuilder: (context, state) => const Text("Loading..."),
errorBuilder: (context, state) => Text("Error: $state"),
);
},
child: const Text('Basic example'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const StreamingCubitView(),
),
);
final r = Random().nextInt(1000);
context.read<UserCubit>().create(
User(
id: '$r',
name: 'Wyatt $r',
email: '$r@wyattapp.io',
phone: '06$r'),
);
},
child: const Text('Streaming example'),
child: const Text("Create"),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const AdvancedCubitView(),
),
);
context.read<UserCubit>().read();
},
child: const Text('Advanced example'),
child: const Text("GetAll"),
),
const SizedBox(height: 20),
],
),
),

View File

@ -1,135 +0,0 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:math';
import 'package:crud_bloc_example/user_cubit.dart';
import 'package:crud_bloc_example/user_entity.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
class BasicCubitView extends StatelessWidget {
const BasicCubitView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Basic Cubit"),
),
body: BlocProvider(
create: (context) =>
UserCubit(context.read<CrudRepository<User>>())..read(),
child: Builder(builder: (context) {
return Column(
children: [
Expanded(
child: CrudBuilder.typed<UserCubit, CrudListLoaded<User?>>(
buildWhen: (previous, current) {
if (current is CrudLoading && current is! CrudReading) {
return false;
}
return true;
},
builder: ((context, state) {
return ListView.builder(
itemCount: state.data.length,
itemBuilder: (context, index) {
final user = state.data.elementAt(index);
return ListTile(
title: Text(user?.name ?? 'Error'),
subtitle: Text(user?.email ?? 'Error'),
onTap: () {
context.read<UserCubit>().delete(id: (user?.id)!);
},
onLongPress: () {
context.read<UserCubit>().update(
single: UpdateParameters(
id: user?.id ?? '',
raw: {
'email': '${user?.id}@updated.io',
}),
);
},
);
},
);
}),
initialBuilder: (context, state) =>
const Center(child: CircularProgressIndicator()),
loadingBuilder: (context, state) =>
const Center(child: CircularProgressIndicator()),
errorBuilder: (context, state) => Text("Error: $state"),
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
final r = Random().nextInt(1000);
context.read<UserCubit>().create(
User(
id: '$r',
name: 'Wyatt $r',
email: '$r@wyattapp.io',
phone: '06$r',
),
);
},
child: CrudBuilder.onLoading<UserCubit>(
builder: (context, state) {
if (state is CrudCreating) {
return const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
color: Colors.white,
),
);
}
return null;
},
otherBuilder: (context, state) => const Text("Create"),
),
),
ElevatedButton(
onPressed: () {
context.read<UserCubit>().read();
},
child: CrudBuilder.onLoading<UserCubit>(
builder: (context, state) {
if (state is CrudReading) {
return const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
color: Colors.white,
),
);
}
return null;
},
otherBuilder: (context, state) => const Text("Read"),
),
),
const SizedBox(height: 20),
],
);
}),
),
);
}
}

View File

@ -1,63 +0,0 @@
// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for ios - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyAYS14uXupkS158Q5QAFP1864UrUN_yDSk',
appId: '1:136771801992:android:8482c9b90bc29de697203d',
messagingSenderId: '136771801992',
projectId: 'tchat-beta',
databaseURL: 'https://tchat-beta.firebaseio.com',
storageBucket: 'tchat-beta.appspot.com',
);
}

View File

@ -18,17 +18,10 @@ import 'package:crud_bloc_example/app.dart';
import 'package:crud_bloc_example/app_bloc_observer.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
Bloc.observer = AppBlocObserver();
final CrudDataSource crudDataSource = CrudDataSourceInMemoryImpl(
id: (_, json) => json['id'] as String?,
);
runApp(MyApp(
crudDataSource: crudDataSource,
));
runApp(const MyApp());
}

View File

@ -1,44 +0,0 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:crud_bloc_example/app.dart';
import 'package:crud_bloc_example/app_bloc_observer.dart';
import 'package:crud_bloc_example/firebase_options.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
import 'package:wyatt_crud_bloc_firestore/wyatt_crud_bloc_firestore.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
Bloc.observer = AppBlocObserver();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
final CrudDataSource crudDataSource = CrudDataSourceFirestoreImpl(
'users',
id: (_, json) => json['id'] as String,
fromFirestore: (document, snapshot) => document.data() ?? {},
toFirestore: (object, options) => object,
);
runApp(MyApp(
crudDataSource: crudDataSource,
));
}

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -14,26 +14,32 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:crud_bloc_example/user_entity.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
part 'user_model.g.dart';
class User extends ObjectModel {
@override
final String? id;
@JsonSerializable()
class UserModel extends User {
UserModel({
super.id,
required super.name,
required super.email,
required super.phone,
final String? name;
final String? email;
final String? phone;
const User({
required this.name,
required this.email,
required this.phone,
this.id,
});
factory UserModel.fromJson(Map<String, dynamic> json) =>
_$UserModelFromJson(json);
Map<String, dynamic> toJson() => _$UserModelToJson(this);
Map<String, Object> toMap() {
return {
'name': name ?? '',
'email': email ?? '',
'phone': phone ?? '',
};
}
@override
String toString() =>
'UserModel(id: $id, name: $name, email: $email, phone: $phone)';
'User(id: $id, name: $name, email: $email, phone: $phone)';
}

View File

@ -1,117 +0,0 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:math';
import 'package:crud_bloc_example/user_entity.dart';
import 'package:crud_bloc_example/user_streaming_cubit.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
class StreamingCubitView extends StatelessWidget {
const StreamingCubitView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Streaming Cubit"),
),
body: BlocProvider(
create: (context) =>
UserStreamingCubit(context.read<CrudRepository<User>>())..read(),
child: Builder(builder: (context) {
return Column(
children: [
Expanded(
child: CrudBuilder.typed<UserStreamingCubit,
CrudListLoaded<User?>>(
buildWhen: (previous, current) {
if (current is CrudLoading && current is! CrudReading) {
return false;
}
return true;
},
builder: ((context, state) {
return ListView.builder(
itemCount: state.data.length,
itemBuilder: (context, index) {
final user = state.data.elementAt(index);
return ListTile(
title: Text(user?.name ?? 'Error'),
subtitle: Text(user?.email ?? 'Error'),
onTap: () {
context
.read<UserStreamingCubit>()
.delete(id: (user?.id)!);
},
onLongPress: () {
context.read<UserStreamingCubit>().update(
single: UpdateParameters(
id: user?.id ?? '',
raw: {
'email': '${user?.id}@updated.io',
}),
);
},
);
},
);
}),
initialBuilder: (context, state) =>
const Center(child: CircularProgressIndicator()),
loadingBuilder: (context, state) =>
const Center(child: CircularProgressIndicator()),
errorBuilder: (context, state) => Text("Error: $state"),
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
final r = Random().nextInt(1000);
context.read<UserStreamingCubit>().create(
User(
id: '$r',
name: 'Wyatt $r',
email: '$r@wyattapp.io',
phone: '06$r',
),
);
},
child: CrudBuilder.onLoading<UserStreamingCubit>(
builder: (context, state) {
if (state is CrudCreating) {
return const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
color: Colors.white,
),
);
}
return null;
},
otherBuilder: (context, state) => const Text("Create"),
),
),
],
);
}),
),
);
}
}

View File

@ -1,57 +0,0 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:crud_bloc_example/user_entity.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
/// A [CrudAdvancedCubit] for [User].
class UserAdvancedCubit extends CrudAdvancedCubit<User> {
final CrudRepository<User> crudRepository;
UserAdvancedCubit(this.crudRepository);
@override
ModelIdentifier<User> get modelIdentifier => ModelIdentifier(
getIdentifier: (user) => user.id ?? '',
);
@override
Create<User>? get crudCreate => Create(crudRepository);
@override
Delete<User>? get crudDelete => Delete(crudRepository);
@override
DeleteAll<User>? get crudDeleteAll => DeleteAll(crudRepository);
@override
Get<User>? get crudGet => Get(crudRepository);
@override
GetAll<User>? get crudGetAll => GetAll(crudRepository);
@override
Search<User>? get crudSearch => Search(crudRepository);
@override
Streaming<User>? get crudStreaming => Streaming(crudRepository);
@override
Update<User>? get crudUpdate => Update(crudRepository);
@override
UpdateAll<User>? get crudUpdateAll => UpdateAll(crudRepository);
}

View File

@ -14,29 +14,28 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:crud_bloc_example/user_entity.dart';
import 'package:crud_bloc_example/models.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
/// A [CrudCubit] for [User].
class UserCubit extends CrudCubit<User> {
final CrudRepository<User> crudRepository;
final CrudRepository<User> _crudRepository;
UserCubit(this.crudRepository);
UserCubit(this._crudRepository);
@override
DefaultCreate<User>? get createOperation => Create(crudRepository);
CreateOperation<User, dynamic>? get createOperation =>
Create(_crudRepository);
@override
DefaultDelete? get deleteOperation => Delete(crudRepository);
DeleteOperation<User, dynamic>? get deleteOperation =>
Delete(_crudRepository);
@override
DefaultRead? get readOperation => GetAll(crudRepository);
ReadOperation<User, dynamic, dynamic>? get readOperation =>
GetAll(_crudRepository);
@override
DefaultUpdate? get updateOperation => Update(crudRepository);
@override
ModelIdentifier<User> get modelIdentifier => ModelIdentifier(
getIdentifier: (user) => user.id ?? '',
);
UpdateOperation<User, dynamic>? get updateOperation =>
Update(_crudRepository);
}

View File

@ -1,21 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
UserModel _$UserModelFromJson(Map<String, dynamic> json) => UserModel(
id: json['id'] as String?,
name: json['name'] as String,
email: json['email'] as String,
phone: json['phone'] as String,
);
Map<String, dynamic> _$UserModelToJson(UserModel instance) => <String, dynamic>{
'id': instance.id,
'name': instance.name,
'email': instance.email,
'phone': instance.phone,
};

View File

@ -1,42 +0,0 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:crud_bloc_example/user_entity.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart';
/// A [CrudCubit] for [User].
class UserStreamingCubit extends CrudCubit<User> {
final CrudRepository<User> crudRepository;
UserStreamingCubit(this.crudRepository);
@override
DefaultCreate<User>? get createOperation => Create(crudRepository);
@override
DefaultDelete? get deleteOperation => Delete(crudRepository);
@override
DefaultRead? get readOperation => Streaming(crudRepository);
@override
DefaultUpdate? get updateOperation => Update(crudRepository);
@override
ModelIdentifier<User> get modelIdentifier => ModelIdentifier(
getIdentifier: (user) => user.id ?? '',
);
}

View File

@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=3.0.0 <4.0.0"
sdk: ">=2.17.0 <3.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
@ -30,23 +30,13 @@ dependencies:
flutter:
sdk: flutter
equatable: ^2.0.5
firebase_core: ^2.22.0
cloud_firestore: ^4.13.0
flutter_bloc: ^8.1.3
flutter_bloc: ^8.1.1
wyatt_crud_bloc:
path: "../"
wyatt_crud_bloc_firestore:
path: "../wyatt_crud_bloc_firestore"
wyatt_architecture:
hosted: https://git.wyatt-studio.fr/api/packages/Wyatt-FOSS/pub/
version: ^0.2.0+1
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
json_annotation: ^4.8.1
dev_dependencies:
flutter_test:
@ -58,8 +48,6 @@ dev_dependencies:
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
json_serializable: ^6.7.1
build_runner: ^2.4.6
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

View File

@ -0,0 +1 @@

View File

@ -14,8 +14,5 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'enums/operation_type.dart';
export 'enums/where_query_type.dart';
export 'mixins/operation.dart';
export 'model_identifier.dart';
export 'model_mapper.dart';

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify

View File

@ -15,28 +15,20 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
/// Defines every write operation in CRUD.
mixin CreateOperation<In, Out> on AsyncUseCase<In, Out> {
/// {@macro create}
OperationType get operationType => OperationType.create;
}
mixin CreateOperation<Model extends ObjectModel, Out>
on AsyncUseCase<Model, Out> {}
/// Defines every read operation in CRUD.
mixin ReadOperation<In, Out> on AsyncUseCase<In, Out> {
/// {@macro read}
OperationType get operationType => OperationType.read;
}
mixin ReadOperation<Model extends ObjectModel, In, Out>
on AsyncUseCase<In, Out> {}
/// Defines every update operation in CRUD.
mixin UpdateOperation<In> on AsyncUseCase<In, void> {
/// {@macro update}
OperationType get operationType => OperationType.update;
}
mixin UpdateOperation<Model extends ObjectModel, In>
on AsyncUseCase<In, void> {}
/// Defines every delete operation in CRUD.
mixin DeleteOperation<In> on AsyncUseCase<In, void> {
/// {@macro delete}
OperationType get operationType => OperationType.delete;
}
mixin DeleteOperation<Model extends ObjectModel, In>
on AsyncUseCase<In, void> {}

View File

@ -1,57 +0,0 @@
// Copyright (C) 2023 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
class ModelIdentifier<Model> {
const ModelIdentifier({
required this.getIdentifier,
});
final String Function(Model model) getIdentifier;
String? getIdentifierOrNull(Model? model) {
if (model == null) {
return null;
}
return getIdentifier(model);
}
bool isIdentifier({
required Model? model,
required String identifier,
}) {
if (model == null) {
return false;
}
return getIdentifier(model) == identifier;
}
bool areEqual(
Model? model1,
Model? model2,
) {
if (model1 == null && model2 == null) {
return true;
}
if (model1 == null || model2 == null) {
return false;
}
return getIdentifier(model1) == getIdentifier(model2);
}
}

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -14,6 +14,5 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'data_sources/crud_data_source.dart';
export 'data_sources/crud_data_source_in_memory_impl.dart';
export 'repositories/crud_repository_impl.dart';
export 'data_sources/data_sources.dart';
export 'repositories/repositories.dart';

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -14,7 +14,5 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/// Create/Read/Update/Delete BLoC implementation for Firestore
library wyatt_crud_bloc_firestore;
export 'src/data/crud_data_source_firestore_impl.dart';
export 'local/crud_in_memory_data_source_impl.dart';
export 'remote/crud_firestore_data_source_impl.dart';

View File

@ -16,56 +16,28 @@
import 'dart:async';
import 'package:rxdart/subjects.dart';
import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart';
import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart';
import 'package:wyatt_crud_bloc/src/data/data_sources/crud_data_source.dart';
import 'package:wyatt_crud_bloc/src/domain/data_sources/data_sources.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/query.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
extension _ModelExtension on Map<String, dynamic> {
Map<String, dynamic> merge(
Map<String, dynamic>? other, {
bool skipNulls = false,
}) {
if (other == null) {
return this;
}
final Map<String, dynamic> result = {};
for (final key in keys) {
result[key] = other[key] ?? this[key];
}
for (final key in other.keys) {
if (!containsKey(key)) {
result[key] = other[key];
}
}
if (skipNulls) {
result.removeWhere((key, value) => other[key] == null);
}
return result;
}
}
/// {@template crud_data_source_in_memory_impl}
/// {@template crud_in_memory_data_source_impl}
/// A [CrudDataSource] that stores data in memory.
/// {@endtemplate}
class CrudDataSourceInMemoryImpl extends CrudDataSource {
/// {@macro crud_data_source_in_memory_impl}
CrudDataSourceInMemoryImpl({
required super.id,
Map<String, Map<String, dynamic>>? data,
}) : _data = data ?? {};
class CrudInMemoryDataSourceImpl<Model extends ObjectModel>
extends CrudDataSource<Model> {
/// {@macro crud_in_memory_data_source_impl}
CrudInMemoryDataSourceImpl({required this.toMap, Map<String, Model>? data})
: _data = data ?? {};
final Map<String, Model> _data;
final StreamController<List<Model?>> _streamData = StreamController();
final Map<String, Map<String, dynamic>> _data;
final BehaviorSubject<List<Map<String, dynamic>?>> _streamData =
BehaviorSubject<List<Map<String, dynamic>?>>.seeded([]);
final Map<String, Object?> Function(Model) toMap;
@override
Future<void> create(Map<String, dynamic> object, {String? id}) async {
_data[id ?? this.id(OperationType.create, object) ?? ''] = object;
Future<void> create(Model object, {String? id}) async {
_data[id ?? object.id ?? ''] = object;
_streamData.add(_data.values.toList());
}
@ -82,14 +54,14 @@ class CrudDataSourceInMemoryImpl extends CrudDataSource {
}
@override
Future<Map<String, dynamic>?> get(String id) async => _data[id];
Future<Model?> get(String id) async => _data[id];
@override
Future<List<Map<String, dynamic>?>> getAll() async => _data.values.toList();
Future<List<Model?>> getAll() async => _data.values.toList();
@override
Future<List<Map<String, dynamic>?>> search(List<Query> conditions) async {
List<Map<String, dynamic>> result = _data.values.toList();
Future<List<Model?>> query(List<QueryInterface> conditions) async {
List<Model> result = _data.values.toList();
for (final c in conditions) {
if (c is WhereQuery) {
@ -109,15 +81,15 @@ class CrudDataSourceInMemoryImpl extends CrudDataSource {
}
}
result.cast<Map<String, dynamic>>();
result.cast<Model>();
return result;
}
@override
Stream<List<Map<String, dynamic>?>> stream({
Stream<List<Model?>> stream({
String? id,
List<Query>? conditions,
List<QueryInterface>? conditions,
bool includeMetadataChanges = false,
}) =>
_streamData.stream.map((result) {
@ -125,7 +97,7 @@ class CrudDataSourceInMemoryImpl extends CrudDataSource {
return result;
}
List<Map<String, dynamic>?> res = result;
List<Model?> res = result;
for (final c in conditions) {
if (c is WhereQuery) {
@ -143,68 +115,61 @@ class CrudDataSourceInMemoryImpl extends CrudDataSource {
}
return res;
});
}).asBroadcastStream();
@override
Future<void> update(
String id, {
Map<String, dynamic>? object,
Model? object,
Map<String, dynamic>? raw,
}) {
if (object != null && _data.containsKey(id)) {
_data[id] = _data[id]!.merge(object);
_streamData.add(_data.values.toList());
}
return Future.value();
// TODO(hpcl): implement update
throw UnimplementedError();
}
@override
Future<void> updateAll(Map<String, Object?>? data) {
if (data != null) {
for (final entry in _data.entries) {
_data[entry.key] = entry.value.merge(data);
}
_streamData.add(_data.values.toList());
}
return Future.value();
// TODO(hcpl): implement updateAll
throw UnimplementedError();
}
bool _whereQuery(Query condition, Map<String, dynamic>? object) {
bool _whereQuery(QueryInterface condition, Model? object) {
if (object == null) {
return false;
}
final raw = toMap.call(object);
if (condition is WhereQuery) {
switch (condition.type) {
case WhereQueryType.isEqualTo:
return object[condition.field] == condition.value;
return raw[condition.field] == condition.value;
case WhereQueryType.isNotEqualTo:
return object[condition.field] != condition.value;
return raw[condition.field] != condition.value;
case WhereQueryType.isLessThan:
return (object[condition.field] as num?) < (condition.value as num?);
return (raw[condition.field] as num?) < (condition.value as num?);
case WhereQueryType.isLessThanOrEqualTo:
return (object[condition.field] as num?) <= (condition.value as num?);
return (raw[condition.field] as num?) <= (condition.value as num?);
case WhereQueryType.isGreaterThan:
return (object[condition.field] as num?) > (condition.value as num?);
return (raw[condition.field] as num?) > (condition.value as num?);
case WhereQueryType.isGreaterThanOrEqualTo:
return (object[condition.field] as num?) >= (condition.value as num?);
return (raw[condition.field] as num?) >= (condition.value as num?);
case WhereQueryType.arrayContains:
return (object[condition.field] as List<Object>?)
return (raw[condition.field] as List<Object>?)
?.contains(condition.value) ??
false;
case WhereQueryType.arrayContainsAny:
bool res = false;
for (final o in condition.value as List<Object>) {
res = (object[condition.field] as List<Object>?)?.contains(o) ??
false;
res = (raw[condition.field] as List<Object>?)?.contains(o) ?? false;
}
return res;
case WhereQueryType.whereIn:
return (condition.value as List<Object>)
.contains(object[condition.field]);
.contains(raw[condition.field]);
case WhereQueryType.whereNotIn:
return !(condition.value as List<Object>)
.contains(object[condition.field]);
.contains(raw[condition.field]);
case WhereQueryType.isNull:
return object[condition.field] == null;
return raw[condition.field] == null;
}
}
return true;

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -15,51 +15,49 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart' hide Query;
import 'package:wyatt_crud_bloc/wyatt_crud_bloc.dart' as crud show Query;
import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart';
import 'package:wyatt_crud_bloc/src/domain/data_sources/crud_data_source.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/query.dart';
/// {@template crud_data_source_firestore_impl}
/// {@template crud_firestore_data_source_impl}
/// A concrete implementation of [CrudDataSource] that uses
/// [FirebaseFirestore] as the data source.
/// {@endtemplate}
class CrudDataSourceFirestoreImpl extends CrudDataSource {
/// {@macro crud_data_source_firestore_impl}
CrudDataSourceFirestoreImpl(
class CrudFirestoreDataSourceImpl<Model extends ObjectModel, Entity>
extends CrudDataSource<Model> {
/// {@macro crud_firestore_data_source_impl}
CrudFirestoreDataSourceImpl(
String collection, {
required super.id,
/// The function that converts a [DocumentSnapshot] to a Model.
required Map<String, dynamic> Function(
/// The function that converts a [DocumentSnapshot] to a [Model].
required Model Function(
DocumentSnapshot<Map<String, dynamic>>,
SnapshotOptions?,
) fromFirestore,
/// The function that converts a Model to a [Map<String, Object?>].
required Map<String, Object?> Function(Map<String, dynamic>, SetOptions?)
toFirestore,
/// The function that converts a [Model] to a [Map<String, Object?>].
required Map<String, Object?> Function(Model, SetOptions?) toFirestore,
FirebaseFirestore? firestore,
}) : _firestore = firestore ?? FirebaseFirestore.instance {
}) : _firestore = firestore ?? FirebaseFirestore.instance,
_toFirestore = toFirestore {
_collectionReference =
_firestore.collection(collection).withConverter<Map<String, dynamic>>(
_firestore.collection(collection).withConverter<Model>(
fromFirestore: fromFirestore,
toFirestore: toFirestore,
);
}
final FirebaseFirestore _firestore;
late CollectionReference<Map<String, dynamic>> _collectionReference;
final Map<String, Object?> Function(Model, SetOptions?) _toFirestore;
late CollectionReference<Model> _collectionReference;
@override
Future<void> create(Map<String, dynamic> object, {String? id}) {
Future<void> create(Model object, {String? id}) {
if (id != null) {
return _collectionReference.doc(id).set(object);
} else {
final String? id = this.id(
OperationType.create,
object,
);
if (id != null) {
return _collectionReference.doc(id).set(object);
if (object.id != null) {
return _collectionReference.doc(object.id).set(object);
}
return _collectionReference.add(object);
}
@ -79,35 +77,32 @@ class CrudDataSourceFirestoreImpl extends CrudDataSource {
}
@override
Future<Map<String, dynamic>?> get(String id) async {
final DocumentSnapshot<Map<String, dynamic>> snapshot =
Future<Model?> get(String id) async {
final DocumentSnapshot<Model> snapshot =
await _collectionReference.doc(id).get();
return snapshot.data();
}
@override
Future<List<Map<String, dynamic>?>> getAll() async {
final QuerySnapshot<Map<String, dynamic>> snapshots =
await _collectionReference.get();
Future<List<Model?>> getAll() async {
final QuerySnapshot<Model> snapshots = await _collectionReference.get();
return snapshots.docs.map((snapshot) => snapshot.data()).toList();
}
@override
Future<List<Map<String, dynamic>?>> search(
List<crud.Query> conditions,
) async {
Query<Map<String, dynamic>> query = _collectionReference;
Future<List<Model?>> query(List<QueryInterface> conditions) async {
Query<Model> query = _collectionReference;
for (final condition in conditions) {
query = _queryParser(condition, query);
}
final QuerySnapshot<Map<String, dynamic>> snapshots = await query.get();
final QuerySnapshot<Model> snapshots = await query.get();
return snapshots.docs.map((snapshot) => snapshot.data()).toList();
}
@override
Stream<List<Map<String, dynamic>?>> stream({
Stream<List<Model?>> stream({
String? id,
List<crud.Query>? conditions,
List<QueryInterface>? conditions,
bool includeMetadataChanges = false,
}) {
if (id != null) {
@ -116,12 +111,12 @@ class CrudDataSourceFirestoreImpl extends CrudDataSource {
.snapshots(
includeMetadataChanges: includeMetadataChanges,
)
.map<List<Map<String, dynamic>?>>(
.map<List<Model?>>(
(snapshot) => [snapshot.data()],
);
} else {
if (conditions != null) {
Query<Map<String, dynamic>> query = _collectionReference;
Query<Model> query = _collectionReference;
for (final condition in conditions) {
query = _queryParser(condition, query);
}
@ -151,12 +146,19 @@ class CrudDataSourceFirestoreImpl extends CrudDataSource {
@override
Future<void> update(
String id, {
Map<String, dynamic>? object,
Model? object,
Map<String, dynamic>? raw,
}) {
if (object != null) {
return _collectionReference.doc(id).update(object);
return _collectionReference
.doc(id)
.update(_toFirestore.call(object, null));
} else {
throw Exception('You must provide data to update');
if (raw != null) {
return _collectionReference.doc(id).update(raw);
} else {
throw Exception('You must provide an object or a raw map');
}
}
}
@ -166,16 +168,15 @@ class CrudDataSourceFirestoreImpl extends CrudDataSource {
throw Exception('You must provide data to update');
}
final batch = _firestore.batch();
final QuerySnapshot<Map<String, dynamic>> snapshots =
await _collectionReference.get();
final QuerySnapshot<Model> snapshots = await _collectionReference.get();
for (final DocumentSnapshot snapshot in snapshots.docs) {
batch.update(snapshot.reference, data);
}
return batch.commit();
}
Query<Map<String, dynamic>> _queryParser(crud.Query condition, Object query) {
query as Query<Map<String, dynamic>>;
Query<Model> _queryParser(QueryInterface condition, Object query) {
query as Query<Model>;
if (condition is WhereQuery) {
switch (condition.type) {
case WhereQueryType.isEqualTo:

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -15,8 +15,8 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/model_mapper.dart';
import 'package:wyatt_crud_bloc/src/data/data_sources/crud_data_source.dart';
import 'package:wyatt_crud_bloc/src/domain/data_sources/crud_data_source.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/query.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
@ -24,23 +24,19 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
/// {@template crud_repository_impl}
/// A repository that implements the [CrudRepository] interface.
/// {@endtemplate}
class CrudRepositoryImpl<Model> extends CrudRepository<Model> {
class CrudRepositoryImpl<Model extends ObjectModel>
extends CrudRepository<Model> {
/// {@macro crud_repository_impl}
const CrudRepositoryImpl({
required this.modelMapper,
required CrudDataSource crudDataSource,
required CrudDataSource<Model> crudDataSource,
}) : _crudDataSource = crudDataSource;
final CrudDataSource _crudDataSource;
@override
final ModelMapper<Model> modelMapper;
final CrudDataSource<Model> _crudDataSource;
@override
FutureOrResult<void> create(Model object, {String? id}) =>
Result.tryCatchAsync<void, AppException, AppException>(
() async {
await _crudDataSource.create(modelMapper.toJson(object), id: id);
await _crudDataSource.create(object, id: id);
},
(error) => error,
);
@ -48,26 +44,14 @@ class CrudRepositoryImpl<Model> extends CrudRepository<Model> {
@override
FutureOrResult<Model?> get(String id) =>
Result.tryCatchAsync<Model?, AppException, AppException>(
() async => modelMapper.fromJson(await _crudDataSource.get(id)),
() async => _crudDataSource.get(id),
(error) => error,
);
@override
FutureOrResult<List<Model?>> getAll() =>
Result.tryCatchAsync<List<Model?>, AppException, AppException>(
() async {
final lst = await _crudDataSource.getAll();
if (lst.isNotNull) {
return lst!.map((raw) {
try {
return modelMapper.fromJson(raw as Map<String, dynamic>?);
} catch (e) {
return null;
}
}).toList();
}
throw const ServerException();
},
() async => _crudDataSource.getAll(),
(error) => error,
);
@ -78,18 +62,7 @@ class CrudRepositoryImpl<Model> extends CrudRepository<Model> {
Map<String, dynamic>? raw,
}) =>
Result.tryCatchAsync<void, AppException, AppException>(
() async {
if (object != null) {
await _crudDataSource.update(
id,
object: modelMapper.toJson(object),
);
} else if (raw != null) {
await _crudDataSource.update(id, object: raw);
} else {
throw const ServerException();
}
},
() async => _crudDataSource.update(id, object: object, raw: raw),
(error) => error,
);
@ -115,40 +88,20 @@ class CrudRepositoryImpl<Model> extends CrudRepository<Model> {
);
@override
FutureOrResult<List<Model?>> search(List<Query> conditions) =>
FutureOrResult<List<Model?>> query(List<QueryInterface> conditions) =>
Result.tryCatchAsync<List<Model?>, AppException, AppException>(
() async {
final lst = await _crudDataSource.search(conditions);
if (lst.isNotNull) {
return lst!.map((raw) {
try {
return modelMapper.fromJson(raw as Map<String, dynamic>?);
} catch (e) {
return null;
}
}).toList();
}
throw const ServerException();
},
() async => _crudDataSource.query(conditions),
(error) => error,
);
@override
StreamResult<List<Model?>> stream({
String? id,
List<Query>? conditions,
List<QueryInterface>? conditions,
}) =>
_crudDataSource.stream(id: id, conditions: conditions).map((lst) {
if (lst.isNotNull) {
return Ok<List<Model?>, AppException>(
lst!.map((raw) {
try {
return modelMapper.fromJson(raw as Map<String, dynamic>?);
} catch (e) {
return null;
}
}).toList(),
);
return Ok<List<Model?>, AppException>(lst);
}
return Err<List<Model?>, AppException>(const ServerException());
});

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -14,10 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
enum OperationType {
query,
create,
read,
update,
delete,
}
export 'crud_repository_impl.dart';

View File

@ -15,54 +15,47 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/query.dart';
/// {@template crud_data_source}
/// A [BaseDataSource] that provides SCRUD operations.
/// {@endtemplate}
abstract class CrudDataSource extends BaseDataSource {
abstract class CrudDataSource<Model> extends BaseDataSource {
/// {@macro crud_data_source}
const CrudDataSource({
required this.id,
});
const CrudDataSource();
final String? Function(
OperationType operationType,
Map<String, dynamic> object,
) id;
/// Creates a new [Model] object.
Future<void> create(Model object, {String? id});
/// Creates a new object.
Future<void> create(Map<String, dynamic> object, {String? id});
/// Gets a [Model] object by its [id].
Future<Model?> get(String id);
/// Gets a object by its [id].
Future<Map<String, dynamic>?> get(String id);
/// Gets all [Model] objects.
Future<List<Model?>> getAll();
/// Gets all objects.
Future<List<dynamic>?> getAll();
/// Updates a object by its [id].
/// Updates a [Model] object by its [id].
Future<void> update(
String id, {
Map<String, dynamic>? object,
Model? object,
Map<String, dynamic>? raw,
});
/// Updates all objects.
/// Updates all [Model] objects.
Future<void> updateAll(Map<String, Object?>? data);
/// Deletes a object by its [id].
/// Deletes a [Model] object by its [id].
Future<void> delete(String id);
/// Deletes all objects.
/// Deletes all [Model] objects.
Future<void> deleteAll();
/// Queries objects by [conditions].
Future<List<dynamic>?> search(List<Query> conditions);
/// Queries [Model] objects by [conditions].
Future<List<Model?>> query(List<QueryInterface> conditions);
/// Streams objects by [conditions].
Stream<List<dynamic>?> stream({
/// Streams [Model] objects by [conditions].
Stream<List<Model?>> stream({
String? id,
List<Query>? conditions,
List<QueryInterface>? conditions,
bool includeMetadataChanges = false,
});
}

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -14,12 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
class ModelMapper<Model> {
const ModelMapper({
required this.fromJson,
required this.toJson,
});
final Model Function(Map<String, dynamic>? json) fromJson;
final Map<String, dynamic> Function(Model model) toJson;
}
export 'crud_data_source.dart';

View File

@ -14,6 +14,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'entities/query.dart';
export 'repositories/crud_repository.dart';
export 'data_sources/data_sources.dart';
export 'entities/entities.dart';
export 'repositories/repositories.dart';
export 'usecases/usecases.dart';

View File

@ -0,0 +1,18 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'object_model.dart';
export 'query.dart';

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -14,23 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:equatable/equatable.dart';
import 'package:wyatt_architecture/wyatt_architecture.dart';
class User extends Entity with EquatableMixin {
final String? id;
/// {@template object_model}
/// An abstract class that represents an object model.
/// {@endtemplate}
abstract class ObjectModel extends Entity {
/// {@macro object_model}
const ObjectModel();
final String name;
final String email;
final String phone;
const User({
required this.name,
required this.email,
required this.phone,
this.id,
});
@override
List<Object?> get props => [id, name, email, phone];
/// The id of the object model.
String? get id;
}

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -17,20 +17,25 @@
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/enums/where_query_type.dart';
typedef QueryParser<Q> = Q Function(Query condition, Q query);
// // ignore: one_member_abstracts
// abstract class QueryParser<Q> {
// Q parser(QueryInterface condition, Q query);
// }
typedef QueryParser<Q> = Q Function(QueryInterface condition, Q query);
/// {@template query}
/// An abstract class that represents a query.
/// {@endtemplate}
base class Query extends Entity {
abstract class QueryInterface extends Entity {
/// {@macro query}
const Query();
const QueryInterface();
}
/// {@template where_query}
/// Represents a where query.
/// {@endtemplate}
final class WhereQuery<Value> extends Query {
class WhereQuery<Value> extends QueryInterface {
/// {@macro where_query}
const WhereQuery(this.type, this.field, this.value);
@ -47,7 +52,7 @@ final class WhereQuery<Value> extends Query {
/// {@template limit_query}
/// Represents a limit query.
/// {@endtemplate}
final class LimitQuery extends Query {
class LimitQuery extends QueryInterface {
/// {@macro limit_query}
const LimitQuery(this.limit);
@ -58,7 +63,7 @@ final class LimitQuery extends Query {
/// {@template offset_query}
/// Represents an offset query.
/// {@endtemplate}
final class OrderByQuery extends Query {
class OrderByQuery extends QueryInterface {
/// {@macro offset_query}
const OrderByQuery(this.field, {this.ascending = true});

View File

@ -15,18 +15,17 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/model_mapper.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/query.dart';
/// {@template crud_repository}
/// An abstract class that represents a SCRUD repository.
/// {@endtemplate}
abstract class CrudRepository<Model> extends BaseRepository {
abstract class CrudRepository<Model extends ObjectModel>
extends BaseRepository {
/// {@macro crud_repository}
const CrudRepository();
ModelMapper<Model> get modelMapper;
/// Creates a new object.
FutureOrResult<void> create(Model object, {String? id});
@ -53,11 +52,11 @@ abstract class CrudRepository<Model> extends BaseRepository {
FutureOrResult<void> deleteAll();
/// Queries objects by [conditions].
FutureOrResult<List<Model?>> search(List<Query> conditions);
FutureOrResult<List<Model?>> query(List<QueryInterface> conditions);
/// Streams objects by [conditions].
StreamResult<List<Model?>> stream({
String? id,
List<Query>? conditions,
List<QueryInterface>? conditions,
});
}

View File

@ -0,0 +1,17 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
export 'crud_repository.dart';

View File

@ -1,4 +1,4 @@
// Copyright (C) 2023 WYATT GROUP
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
@ -14,22 +14,31 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart';
/// {@template create}
/// A use case that creates an object model.
/// {@endtemplate}
class Create<Model> extends Usecase<Model, void>
class Create<Model extends ObjectModel> extends AsyncUseCase<Model, void>
with CreateOperation<Model, void> {
/// {@macro create}
const Create(this.crudRepository);
const Create(this._crudRepository);
final CrudRepository<Model> crudRepository;
final CrudRepository<Model> _crudRepository;
@override
FutureOr<void> onStart(Model? params) {
if (params == null) {
throw ClientException('$Model cannot be null.');
}
}
@override
FutureOrResult<void> execute(Model? params) =>
crudRepository.create(params as Model);
_crudRepository.create(params!);
}

View File

@ -14,21 +14,31 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart';
/// {@template delete}
/// A use case that deletes an object model.
/// {@endtemplate}
class Delete<Model> extends Usecase<String, void> with DeleteOperation<String> {
class Delete<Model extends ObjectModel> extends AsyncUseCase<String, void>
with DeleteOperation<Model, String> {
/// {@macro delete}
const Delete(this.crudRepository);
const Delete(this._crudRepository);
final CrudRepository<Model> crudRepository;
final CrudRepository<Model> _crudRepository;
@override
FutureOr<void> onStart(String? params) {
if (params == null) {
throw const ClientException('Id cannot be null.');
}
}
@override
FutureOrResult<void> execute(String? params) =>
crudRepository.delete(params!);
_crudRepository.delete(params!);
}

View File

@ -16,18 +16,19 @@
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart';
/// {@template delete_all}
/// A use case that deletes all the object models.
/// {@endtemplate}
class DeleteAll<Model> extends NoParamUsecase<void> with DeleteOperation<void> {
class DeleteAll<Model extends ObjectModel> extends AsyncUseCase<void, void>
with DeleteOperation<Model, void> {
/// {@macro delete_all}
const DeleteAll(this.crudRepository);
const DeleteAll(this._crudRepository);
final CrudRepository<Model> crudRepository;
final CrudRepository<Model> _crudRepository;
@override
FutureOrResult<void> execute(void params) => crudRepository.deleteAll();
FutureOrResult<void> execute(void params) => _crudRepository.deleteAll();
}

View File

@ -14,21 +14,31 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart';
/// {@template get}
/// A use case that gets an object model.
/// {@endtemplate}
class Get<Model> extends Usecase<String, Model?>
with ReadOperation<String, Model?> {
class Get<Model extends ObjectModel> extends AsyncUseCase<String, Model?>
with ReadOperation<Model, String, Model?> {
/// {@macro get}
Get(this.crudRepository);
Get(this._crudRepository);
final CrudRepository<Model> crudRepository;
final CrudRepository<Model> _crudRepository;
@override
FutureOrResult<Model?> execute(String? params) => crudRepository.get(params!);
FutureOr<void> onStart(String? params) {
if (params == null) {
throw const ClientException('Id cannot be null.');
}
}
@override
FutureOrResult<Model?> execute(String? params) =>
_crudRepository.get(params!);
}

View File

@ -16,19 +16,19 @@
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart';
/// {@template get_all}
/// A use case that gets all the object models.
/// {@endtemplate}
class GetAll<Model> extends NoParamUsecase<List<Model?>>
with ReadOperation<void, List<Model?>> {
class GetAll<Model extends ObjectModel> extends AsyncUseCase<void, List<Model?>>
with ReadOperation<Model, void, List<Model?>> {
/// {@macro get_all}
const GetAll(this.crudRepository);
const GetAll(this._crudRepository);
final CrudRepository<Model> crudRepository;
final CrudRepository<Model> _crudRepository;
@override
FutureOrResult<List<Model?>> execute(void params) => crudRepository.getAll();
FutureOrResult<List<Model?>> execute(void params) => _crudRepository.getAll();
}

View File

@ -30,5 +30,5 @@ class StreamParameters {
final String? id;
/// The conditions of the query.
final List<Query>? conditions;
final List<QueryInterface>? conditions;
}

View File

@ -14,23 +14,33 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/query.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart';
/// {@template search}
/// {@template query}
/// A use case that queries the object models.
/// {@endtemplate}
class Search<Model> extends Usecase<List<Query>, List<Model?>>
with ReadOperation<List<Query>, List<Model?>> {
/// {@macro search}
const Search(this.crudRepository);
class Query<Model extends ObjectModel>
extends AsyncUseCase<List<QueryInterface>, List<Model?>>
with ReadOperation<Model, List<QueryInterface>, List<Model?>> {
/// {@macro query}
const Query(this._crudRepository);
final CrudRepository<Model> crudRepository;
final CrudRepository<Model> _crudRepository;
@override
FutureOrResult<List<Model?>> execute(List<Query>? params) =>
crudRepository.search(params!);
FutureOr<void> onStart(List<QueryInterface>? params) {
if (params == null) {
throw const ClientException('List of conditions cannot be null.');
}
}
@override
FutureOrResult<List<Model?>> execute(List<QueryInterface>? params) =>
_crudRepository.query(params!);
}

View File

@ -1,44 +0,0 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
/// {@template streaming}
/// A use case that streams the object models.
/// {@endtemplate}
class Streaming<Model>
extends Usecase<StreamParameters, StreamResult<List<Model?>>>
with ReadOperation<StreamParameters, StreamResult<List<Model?>>> {
/// {@macro streaming}
const Streaming(this.crudRepository);
final CrudRepository<Model> crudRepository;
@override
FutureOrResult<StreamResult<List<Model?>>> execute(
StreamParameters? params,
) async =>
Ok(
crudRepository.stream(
id: params!.id,
conditions: params.conditions,
),
);
}

View File

@ -14,24 +14,35 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart';
import 'package:wyatt_crud_bloc/src/domain/usecases/params/update_parameters.dart';
/// {@template update}
/// A use case that updates an object model.
/// {@endtemplate}
class Update<Model> extends Usecase<UpdateParameters<Model>, void>
with UpdateOperation<UpdateParameters<Model>> {
class Update<Model extends ObjectModel>
extends AsyncUseCase<UpdateParameters<Model>, void>
with UpdateOperation<Model, UpdateParameters<Model>> {
/// {@macro update}
const Update(this.crudRepository);
const Update(this._crudRepository);
final CrudRepository<Model> crudRepository;
final CrudRepository<Model> _crudRepository;
@override
FutureOr<void> onStart(UpdateParameters<Model>? params) {
if (params == null) {
throw const ClientException('Update parameters cannot be null.');
}
}
@override
FutureOrResult<void> execute(UpdateParameters<Model>? params) =>
crudRepository.update(
_crudRepository.update(
params!.id,
object: params.object,
raw: params.raw,

View File

@ -14,22 +14,32 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/mixins/operation.dart';
import 'package:wyatt_crud_bloc/src/domain/entities/object_model.dart';
import 'package:wyatt_crud_bloc/src/domain/repositories/crud_repository.dart';
import 'package:wyatt_crud_bloc/src/domain/usecases/usecases.dart';
/// {@template update_all}
/// A use case that updates all the object models.
/// {@endtemplate}
class UpdateAll<Model> extends Usecase<Map<String, Object?>, void>
with UpdateOperation<Map<String, Object?>> {
class UpdateAll<Model extends ObjectModel>
extends AsyncUseCase<Map<String, Object?>, void>
with UpdateOperation<Model, Map<String, Object?>> {
/// {@macro update_all}
const UpdateAll(this.crudRepository);
const UpdateAll(this._crudRepository);
final CrudRepository<Model> crudRepository;
final CrudRepository<Model> _crudRepository;
@override
FutureOr<void> onStart(Map<String, Object?>? params) {
if (params == null) {
throw const ClientException('Data cannot be null.');
}
}
@override
FutureOrResult<void> execute(Map<String, Object?>? params) =>
crudRepository.updateAll(params!);
_crudRepository.updateAll(params!);
}

View File

@ -14,37 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_crud_bloc/src/core/enums/operation_type.dart';
export 'create.dart';
export 'delete.dart';
export 'delete_all.dart';
export 'get.dart';
export 'get_all.dart';
export 'params/params.dart';
export 'search.dart';
export 'streaming.dart';
export 'query.dart';
export 'update.dart';
export 'update_all.dart';
abstract class Usecase<In, Out> extends AsyncUseCase<In, Out> {
const Usecase();
@override
FutureOr<void> onStart(In? params) {
if (params == null) {
throw ClientException('$In cannot be null.');
}
}
OperationType get operationType;
}
abstract class NoParamUsecase<Out> extends AsyncUseCase<void, Out> {
const NoParamUsecase();
OperationType get operationType;
}

Some files were not shown because too many files have changed in this diff Show More