├── .gitignore
├── .metadata
├── README.md
├── android
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── formvalidation
│ │ │ │ └── MainActivity.java
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── jar-loading.gif
└── no-image.png
├── ios
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Podfile.lock
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── main.m
├── lib
├── main.dart
└── src
│ ├── bloc
│ ├── login_bloc.dart
│ ├── productos_bloc.dart
│ ├── provider.dart
│ └── validators.dart
│ ├── models
│ └── producto_model.dart
│ ├── pages
│ ├── home_page.dart
│ ├── login_page.dart
│ ├── producto_page.dart
│ └── registro_page.dart
│ ├── preferencias_usuario
│ └── preferencias_usuario.dart
│ ├── providers
│ ├── productos_provider.dart
│ └── usuario_provider.dart
│ └── utils
│ └── utils.dart
├── pubspec.lock
└── pubspec.yaml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # Visual Studio Code related
19 | .vscode/
20 |
21 | # Flutter/Dart/Pub related
22 | **/doc/api/
23 | .dart_tool/
24 | .flutter-plugins
25 | .packages
26 | .pub-cache/
27 | .pub/
28 | /build/
29 |
30 | # Android related
31 | **/android/**/gradle-wrapper.jar
32 | **/android/.gradle
33 | **/android/captures/
34 | **/android/gradlew
35 | **/android/gradlew.bat
36 | **/android/local.properties
37 | **/android/**/GeneratedPluginRegistrant.java
38 |
39 | # iOS/XCode related
40 | **/ios/**/*.mode1v3
41 | **/ios/**/*.mode2v3
42 | **/ios/**/*.moved-aside
43 | **/ios/**/*.pbxuser
44 | **/ios/**/*.perspectivev3
45 | **/ios/**/*sync/
46 | **/ios/**/.sconsign.dblite
47 | **/ios/**/.tags*
48 | **/ios/**/.vagrant/
49 | **/ios/**/DerivedData/
50 | **/ios/**/Icon?
51 | **/ios/**/Pods/
52 | **/ios/**/.symlinks/
53 | **/ios/**/profile
54 | **/ios/**/xcuserdata
55 | **/ios/.generated/
56 | **/ios/Flutter/App.framework
57 | **/ios/Flutter/Flutter.framework
58 | **/ios/Flutter/Generated.xcconfig
59 | **/ios/Flutter/app.flx
60 | **/ios/Flutter/app.zip
61 | **/ios/Flutter/flutter_assets/
62 | **/ios/ServiceDefinitions.json
63 | **/ios/Runner/GeneratedPluginRegistrant.*
64 |
65 | # Exceptions to above rules.
66 | !**/ios/**/default.mode1v3
67 | !**/ios/**/default.mode2v3
68 | !**/ios/**/default.pbxuser
69 | !**/ios/**/default.perspectivev3
70 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
71 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 8661d8aecd626f7f57ccbcb735553edc05a2e713
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FormValidation, CRUD y Fotos
2 |
3 | Repositorio oficial de mi curso de Flutter
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
26 |
27 | android {
28 | compileSdkVersion 28
29 |
30 | lintOptions {
31 | disable 'InvalidPackage'
32 | }
33 |
34 | defaultConfig {
35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
36 | applicationId "com.example.formvalidation"
37 | minSdkVersion 21
38 | targetSdkVersion 28
39 | versionCode flutterVersionCode.toInteger()
40 | versionName flutterVersionName
41 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
42 | }
43 |
44 | buildTypes {
45 | release {
46 | // TODO: Add your own signing config for the release build.
47 | // Signing with the debug keys for now, so `flutter run --release` works.
48 | signingConfig signingConfigs.debug
49 | }
50 | }
51 | }
52 |
53 | flutter {
54 | source '../..'
55 | }
56 |
57 | dependencies {
58 | testImplementation 'junit:junit:4.12'
59 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
60 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
61 | }
62 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
13 |
20 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/example/formvalidation/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.formvalidation;
2 |
3 | import android.os.Bundle;
4 | import io.flutter.app.FlutterActivity;
5 | import io.flutter.plugins.GeneratedPluginRegistrant;
6 |
7 | public class MainActivity extends FlutterActivity {
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | GeneratedPluginRegistrant.registerWith(this);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:3.2.1'
9 | }
10 | }
11 |
12 | allprojects {
13 | repositories {
14 | google()
15 | jcenter()
16 | }
17 | }
18 |
19 | rootProject.buildDir = '../build'
20 | subprojects {
21 | project.buildDir = "${rootProject.buildDir}/${project.name}"
22 | }
23 | subprojects {
24 | project.evaluationDependsOn(':app')
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
4 |
5 | def plugins = new Properties()
6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
7 | if (pluginsFile.exists()) {
8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
9 | }
10 |
11 | plugins.each { name, path ->
12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
13 | include ":$name"
14 | project(":$name").projectDir = pluginDirectory
15 | }
16 |
--------------------------------------------------------------------------------
/assets/jar-loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/assets/jar-loading.gif
--------------------------------------------------------------------------------
/assets/no-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/assets/no-image.png
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def parse_KV_file(file, separator='=')
14 | file_abs_path = File.expand_path(file)
15 | if !File.exists? file_abs_path
16 | return [];
17 | end
18 | pods_ary = []
19 | skip_line_start_symbols = ["#", "/"]
20 | File.foreach(file_abs_path) { |line|
21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
22 | plugin = line.split(pattern=separator)
23 | if plugin.length == 2
24 | podname = plugin[0].strip()
25 | path = plugin[1].strip()
26 | podpath = File.expand_path("#{path}", file_abs_path)
27 | pods_ary.push({:name => podname, :path => podpath});
28 | else
29 | puts "Invalid plugin specification: #{line}"
30 | end
31 | }
32 | return pods_ary
33 | end
34 |
35 | target 'Runner' do
36 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
37 | # referring to absolute paths on developers' machines.
38 | system('rm -rf .symlinks')
39 | system('mkdir -p .symlinks/plugins')
40 |
41 | # Flutter Pods
42 | generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
43 | if generated_xcode_build_settings.empty?
44 | puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first."
45 | end
46 | generated_xcode_build_settings.map { |p|
47 | if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
48 | symlink = File.join('.symlinks', 'flutter')
49 | File.symlink(File.dirname(p[:path]), symlink)
50 | pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
51 | end
52 | }
53 |
54 | # Plugin Pods
55 | plugin_pods = parse_KV_file('../.flutter-plugins')
56 | plugin_pods.map { |p|
57 | symlink = File.join('.symlinks', 'plugins', p[:name])
58 | File.symlink(p[:path], symlink)
59 | pod p[:name], :path => File.join(symlink, 'ios')
60 | }
61 | end
62 |
63 | post_install do |installer|
64 | installer.pods_project.targets.each do |target|
65 | target.build_configurations.each do |config|
66 | config.build_settings['ENABLE_BITCODE'] = 'NO'
67 | end
68 | end
69 | end
70 |
--------------------------------------------------------------------------------
/ios/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Flutter (1.0.0)
3 | - image_picker (0.0.1):
4 | - Flutter
5 | - shared_preferences (0.0.1):
6 | - Flutter
7 |
8 | DEPENDENCIES:
9 | - Flutter (from `.symlinks/flutter/ios`)
10 | - image_picker (from `.symlinks/plugins/image_picker/ios`)
11 | - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
12 |
13 | EXTERNAL SOURCES:
14 | Flutter:
15 | :path: ".symlinks/flutter/ios"
16 | image_picker:
17 | :path: ".symlinks/plugins/image_picker/ios"
18 | shared_preferences:
19 | :path: ".symlinks/plugins/shared_preferences/ios"
20 |
21 | SPEC CHECKSUMS:
22 | Flutter: 58dd7d1b27887414a370fcccb9e645c08ffd7a6a
23 | image_picker: 16e5fec1fbc87fd3b297c53e4048521eaf17cd06
24 | shared_preferences: 1feebfa37bb57264736e16865e7ffae7fc99b523
25 |
26 | PODFILE CHECKSUM: aff02bfeed411c636180d6812254b2daeea14d09
27 |
28 | COCOAPODS: 1.6.0
29 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 002DF601907DC46785A996B9 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D80E00F94D05E30871C017D1 /* libPods-Runner.a */; };
11 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
13 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
14 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
17 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
18 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
19 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
20 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
21 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
22 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXCopyFilesBuildPhase section */
26 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
27 | isa = PBXCopyFilesBuildPhase;
28 | buildActionMask = 2147483647;
29 | dstPath = "";
30 | dstSubfolderSpec = 10;
31 | files = (
32 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
33 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
34 | );
35 | name = "Embed Frameworks";
36 | runOnlyForDeploymentPostprocessing = 0;
37 | };
38 | /* End PBXCopyFilesBuildPhase section */
39 |
40 | /* Begin PBXFileReference section */
41 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
42 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
43 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
44 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
45 | 5B2C7C563BC1FA27FAD2C7BA /* 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 = ""; };
46 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
47 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
48 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
49 | 8B0B68D9DA383C1FCAFCDB93 /* 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 = ""; };
50 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
51 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
52 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
53 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
54 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
55 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
56 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
57 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
58 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
59 | 9A43B92A86282AE0DFE76390 /* 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 = ""; };
60 | D80E00F94D05E30871C017D1 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
61 | /* End PBXFileReference section */
62 |
63 | /* Begin PBXFrameworksBuildPhase section */
64 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
65 | isa = PBXFrameworksBuildPhase;
66 | buildActionMask = 2147483647;
67 | files = (
68 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
69 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
70 | 002DF601907DC46785A996B9 /* libPods-Runner.a in Frameworks */,
71 | );
72 | runOnlyForDeploymentPostprocessing = 0;
73 | };
74 | /* End PBXFrameworksBuildPhase section */
75 |
76 | /* Begin PBXGroup section */
77 | 1C75DB097A334F05A7B904B6 /* Frameworks */ = {
78 | isa = PBXGroup;
79 | children = (
80 | D80E00F94D05E30871C017D1 /* libPods-Runner.a */,
81 | );
82 | name = Frameworks;
83 | sourceTree = "";
84 | };
85 | 9740EEB11CF90186004384FC /* Flutter */ = {
86 | isa = PBXGroup;
87 | children = (
88 | 3B80C3931E831B6300D905FE /* App.framework */,
89 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
90 | 9740EEBA1CF902C7004384FC /* Flutter.framework */,
91 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
92 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
93 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
94 | );
95 | name = Flutter;
96 | sourceTree = "";
97 | };
98 | 97C146E51CF9000F007C117D = {
99 | isa = PBXGroup;
100 | children = (
101 | 9740EEB11CF90186004384FC /* Flutter */,
102 | 97C146F01CF9000F007C117D /* Runner */,
103 | 97C146EF1CF9000F007C117D /* Products */,
104 | A36F14260A34B08F51D674BB /* Pods */,
105 | 1C75DB097A334F05A7B904B6 /* Frameworks */,
106 | );
107 | sourceTree = "";
108 | };
109 | 97C146EF1CF9000F007C117D /* Products */ = {
110 | isa = PBXGroup;
111 | children = (
112 | 97C146EE1CF9000F007C117D /* Runner.app */,
113 | );
114 | name = Products;
115 | sourceTree = "";
116 | };
117 | 97C146F01CF9000F007C117D /* Runner */ = {
118 | isa = PBXGroup;
119 | children = (
120 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
121 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
122 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
123 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
124 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
125 | 97C147021CF9000F007C117D /* Info.plist */,
126 | 97C146F11CF9000F007C117D /* Supporting Files */,
127 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
128 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
129 | );
130 | path = Runner;
131 | sourceTree = "";
132 | };
133 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 97C146F21CF9000F007C117D /* main.m */,
137 | );
138 | name = "Supporting Files";
139 | sourceTree = "";
140 | };
141 | A36F14260A34B08F51D674BB /* Pods */ = {
142 | isa = PBXGroup;
143 | children = (
144 | 8B0B68D9DA383C1FCAFCDB93 /* Pods-Runner.debug.xcconfig */,
145 | 5B2C7C563BC1FA27FAD2C7BA /* Pods-Runner.release.xcconfig */,
146 | 9A43B92A86282AE0DFE76390 /* Pods-Runner.profile.xcconfig */,
147 | );
148 | name = Pods;
149 | path = Pods;
150 | sourceTree = "";
151 | };
152 | /* End PBXGroup section */
153 |
154 | /* Begin PBXNativeTarget section */
155 | 97C146ED1CF9000F007C117D /* Runner */ = {
156 | isa = PBXNativeTarget;
157 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
158 | buildPhases = (
159 | 84C62925D2F4A97CBFD49D6F /* [CP] Check Pods Manifest.lock */,
160 | 9740EEB61CF901F6004384FC /* Run Script */,
161 | 97C146EA1CF9000F007C117D /* Sources */,
162 | 97C146EB1CF9000F007C117D /* Frameworks */,
163 | 97C146EC1CF9000F007C117D /* Resources */,
164 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
165 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
166 | 5E3B87EC8EDA4FD5A0A2D3DD /* [CP] Embed Pods Frameworks */,
167 | );
168 | buildRules = (
169 | );
170 | dependencies = (
171 | );
172 | name = Runner;
173 | productName = Runner;
174 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
175 | productType = "com.apple.product-type.application";
176 | };
177 | /* End PBXNativeTarget section */
178 |
179 | /* Begin PBXProject section */
180 | 97C146E61CF9000F007C117D /* Project object */ = {
181 | isa = PBXProject;
182 | attributes = {
183 | LastUpgradeCheck = 0910;
184 | ORGANIZATIONNAME = "The Chromium Authors";
185 | TargetAttributes = {
186 | 97C146ED1CF9000F007C117D = {
187 | CreatedOnToolsVersion = 7.3.1;
188 | };
189 | };
190 | };
191 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
192 | compatibilityVersion = "Xcode 3.2";
193 | developmentRegion = English;
194 | hasScannedForEncodings = 0;
195 | knownRegions = (
196 | en,
197 | Base,
198 | );
199 | mainGroup = 97C146E51CF9000F007C117D;
200 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
201 | projectDirPath = "";
202 | projectRoot = "";
203 | targets = (
204 | 97C146ED1CF9000F007C117D /* Runner */,
205 | );
206 | };
207 | /* End PBXProject section */
208 |
209 | /* Begin PBXResourcesBuildPhase section */
210 | 97C146EC1CF9000F007C117D /* Resources */ = {
211 | isa = PBXResourcesBuildPhase;
212 | buildActionMask = 2147483647;
213 | files = (
214 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
215 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
216 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
217 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
218 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
219 | );
220 | runOnlyForDeploymentPostprocessing = 0;
221 | };
222 | /* End PBXResourcesBuildPhase section */
223 |
224 | /* Begin PBXShellScriptBuildPhase section */
225 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
226 | isa = PBXShellScriptBuildPhase;
227 | buildActionMask = 2147483647;
228 | files = (
229 | );
230 | inputPaths = (
231 | );
232 | name = "Thin Binary";
233 | outputPaths = (
234 | );
235 | runOnlyForDeploymentPostprocessing = 0;
236 | shellPath = /bin/sh;
237 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
238 | };
239 | 5E3B87EC8EDA4FD5A0A2D3DD /* [CP] Embed Pods Frameworks */ = {
240 | isa = PBXShellScriptBuildPhase;
241 | buildActionMask = 2147483647;
242 | files = (
243 | );
244 | inputFileListPaths = (
245 | );
246 | inputPaths = (
247 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
248 | "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework",
249 | );
250 | name = "[CP] Embed Pods Frameworks";
251 | outputFileListPaths = (
252 | );
253 | outputPaths = (
254 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
255 | );
256 | runOnlyForDeploymentPostprocessing = 0;
257 | shellPath = /bin/sh;
258 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
259 | showEnvVarsInLog = 0;
260 | };
261 | 84C62925D2F4A97CBFD49D6F /* [CP] Check Pods Manifest.lock */ = {
262 | isa = PBXShellScriptBuildPhase;
263 | buildActionMask = 2147483647;
264 | files = (
265 | );
266 | inputFileListPaths = (
267 | );
268 | inputPaths = (
269 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
270 | "${PODS_ROOT}/Manifest.lock",
271 | );
272 | name = "[CP] Check Pods Manifest.lock";
273 | outputFileListPaths = (
274 | );
275 | outputPaths = (
276 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
277 | );
278 | runOnlyForDeploymentPostprocessing = 0;
279 | shellPath = /bin/sh;
280 | 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";
281 | showEnvVarsInLog = 0;
282 | };
283 | 9740EEB61CF901F6004384FC /* Run Script */ = {
284 | isa = PBXShellScriptBuildPhase;
285 | buildActionMask = 2147483647;
286 | files = (
287 | );
288 | inputPaths = (
289 | );
290 | name = "Run Script";
291 | outputPaths = (
292 | );
293 | runOnlyForDeploymentPostprocessing = 0;
294 | shellPath = /bin/sh;
295 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
296 | };
297 | /* End PBXShellScriptBuildPhase section */
298 |
299 | /* Begin PBXSourcesBuildPhase section */
300 | 97C146EA1CF9000F007C117D /* Sources */ = {
301 | isa = PBXSourcesBuildPhase;
302 | buildActionMask = 2147483647;
303 | files = (
304 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
305 | 97C146F31CF9000F007C117D /* main.m in Sources */,
306 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
307 | );
308 | runOnlyForDeploymentPostprocessing = 0;
309 | };
310 | /* End PBXSourcesBuildPhase section */
311 |
312 | /* Begin PBXVariantGroup section */
313 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
314 | isa = PBXVariantGroup;
315 | children = (
316 | 97C146FB1CF9000F007C117D /* Base */,
317 | );
318 | name = Main.storyboard;
319 | sourceTree = "";
320 | };
321 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
322 | isa = PBXVariantGroup;
323 | children = (
324 | 97C147001CF9000F007C117D /* Base */,
325 | );
326 | name = LaunchScreen.storyboard;
327 | sourceTree = "";
328 | };
329 | /* End PBXVariantGroup section */
330 |
331 | /* Begin XCBuildConfiguration section */
332 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
333 | isa = XCBuildConfiguration;
334 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
335 | buildSettings = {
336 | ALWAYS_SEARCH_USER_PATHS = NO;
337 | CLANG_ANALYZER_NONNULL = YES;
338 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
339 | CLANG_CXX_LIBRARY = "libc++";
340 | CLANG_ENABLE_MODULES = YES;
341 | CLANG_ENABLE_OBJC_ARC = YES;
342 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
343 | CLANG_WARN_BOOL_CONVERSION = YES;
344 | CLANG_WARN_COMMA = YES;
345 | CLANG_WARN_CONSTANT_CONVERSION = YES;
346 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
347 | CLANG_WARN_EMPTY_BODY = YES;
348 | CLANG_WARN_ENUM_CONVERSION = YES;
349 | CLANG_WARN_INFINITE_RECURSION = YES;
350 | CLANG_WARN_INT_CONVERSION = YES;
351 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
352 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
353 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
354 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
355 | CLANG_WARN_STRICT_PROTOTYPES = YES;
356 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
357 | CLANG_WARN_UNREACHABLE_CODE = YES;
358 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
359 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
360 | COPY_PHASE_STRIP = NO;
361 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
362 | ENABLE_NS_ASSERTIONS = NO;
363 | ENABLE_STRICT_OBJC_MSGSEND = YES;
364 | GCC_C_LANGUAGE_STANDARD = gnu99;
365 | GCC_NO_COMMON_BLOCKS = YES;
366 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
367 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
368 | GCC_WARN_UNDECLARED_SELECTOR = YES;
369 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
370 | GCC_WARN_UNUSED_FUNCTION = YES;
371 | GCC_WARN_UNUSED_VARIABLE = YES;
372 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
373 | MTL_ENABLE_DEBUG_INFO = NO;
374 | SDKROOT = iphoneos;
375 | TARGETED_DEVICE_FAMILY = "1,2";
376 | VALIDATE_PRODUCT = YES;
377 | };
378 | name = Profile;
379 | };
380 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
381 | isa = XCBuildConfiguration;
382 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
383 | buildSettings = {
384 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
385 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
386 | DEVELOPMENT_TEAM = S8QB4VV633;
387 | ENABLE_BITCODE = NO;
388 | FRAMEWORK_SEARCH_PATHS = (
389 | "$(inherited)",
390 | "$(PROJECT_DIR)/Flutter",
391 | );
392 | INFOPLIST_FILE = Runner/Info.plist;
393 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
394 | LIBRARY_SEARCH_PATHS = (
395 | "$(inherited)",
396 | "$(PROJECT_DIR)/Flutter",
397 | );
398 | PRODUCT_BUNDLE_IDENTIFIER = com.example.formvalidation;
399 | PRODUCT_NAME = "$(TARGET_NAME)";
400 | VERSIONING_SYSTEM = "apple-generic";
401 | };
402 | name = Profile;
403 | };
404 | 97C147031CF9000F007C117D /* Debug */ = {
405 | isa = XCBuildConfiguration;
406 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
407 | buildSettings = {
408 | ALWAYS_SEARCH_USER_PATHS = NO;
409 | CLANG_ANALYZER_NONNULL = YES;
410 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
411 | CLANG_CXX_LIBRARY = "libc++";
412 | CLANG_ENABLE_MODULES = YES;
413 | CLANG_ENABLE_OBJC_ARC = YES;
414 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
415 | CLANG_WARN_BOOL_CONVERSION = YES;
416 | CLANG_WARN_COMMA = YES;
417 | CLANG_WARN_CONSTANT_CONVERSION = YES;
418 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
419 | CLANG_WARN_EMPTY_BODY = YES;
420 | CLANG_WARN_ENUM_CONVERSION = YES;
421 | CLANG_WARN_INFINITE_RECURSION = YES;
422 | CLANG_WARN_INT_CONVERSION = YES;
423 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
424 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
425 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
426 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
427 | CLANG_WARN_STRICT_PROTOTYPES = YES;
428 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
429 | CLANG_WARN_UNREACHABLE_CODE = YES;
430 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
431 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
432 | COPY_PHASE_STRIP = NO;
433 | DEBUG_INFORMATION_FORMAT = dwarf;
434 | ENABLE_STRICT_OBJC_MSGSEND = YES;
435 | ENABLE_TESTABILITY = YES;
436 | GCC_C_LANGUAGE_STANDARD = gnu99;
437 | GCC_DYNAMIC_NO_PIC = NO;
438 | GCC_NO_COMMON_BLOCKS = YES;
439 | GCC_OPTIMIZATION_LEVEL = 0;
440 | GCC_PREPROCESSOR_DEFINITIONS = (
441 | "DEBUG=1",
442 | "$(inherited)",
443 | );
444 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
445 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
446 | GCC_WARN_UNDECLARED_SELECTOR = YES;
447 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
448 | GCC_WARN_UNUSED_FUNCTION = YES;
449 | GCC_WARN_UNUSED_VARIABLE = YES;
450 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
451 | MTL_ENABLE_DEBUG_INFO = YES;
452 | ONLY_ACTIVE_ARCH = YES;
453 | SDKROOT = iphoneos;
454 | TARGETED_DEVICE_FAMILY = "1,2";
455 | };
456 | name = Debug;
457 | };
458 | 97C147041CF9000F007C117D /* Release */ = {
459 | isa = XCBuildConfiguration;
460 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
461 | buildSettings = {
462 | ALWAYS_SEARCH_USER_PATHS = NO;
463 | CLANG_ANALYZER_NONNULL = YES;
464 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
465 | CLANG_CXX_LIBRARY = "libc++";
466 | CLANG_ENABLE_MODULES = YES;
467 | CLANG_ENABLE_OBJC_ARC = YES;
468 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
469 | CLANG_WARN_BOOL_CONVERSION = YES;
470 | CLANG_WARN_COMMA = YES;
471 | CLANG_WARN_CONSTANT_CONVERSION = YES;
472 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
473 | CLANG_WARN_EMPTY_BODY = YES;
474 | CLANG_WARN_ENUM_CONVERSION = YES;
475 | CLANG_WARN_INFINITE_RECURSION = YES;
476 | CLANG_WARN_INT_CONVERSION = YES;
477 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
478 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
479 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
480 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
481 | CLANG_WARN_STRICT_PROTOTYPES = YES;
482 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
483 | CLANG_WARN_UNREACHABLE_CODE = YES;
484 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
485 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
486 | COPY_PHASE_STRIP = NO;
487 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
488 | ENABLE_NS_ASSERTIONS = NO;
489 | ENABLE_STRICT_OBJC_MSGSEND = YES;
490 | GCC_C_LANGUAGE_STANDARD = gnu99;
491 | GCC_NO_COMMON_BLOCKS = YES;
492 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
493 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
494 | GCC_WARN_UNDECLARED_SELECTOR = YES;
495 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
496 | GCC_WARN_UNUSED_FUNCTION = YES;
497 | GCC_WARN_UNUSED_VARIABLE = YES;
498 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
499 | MTL_ENABLE_DEBUG_INFO = NO;
500 | SDKROOT = iphoneos;
501 | TARGETED_DEVICE_FAMILY = "1,2";
502 | VALIDATE_PRODUCT = YES;
503 | };
504 | name = Release;
505 | };
506 | 97C147061CF9000F007C117D /* Debug */ = {
507 | isa = XCBuildConfiguration;
508 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
509 | buildSettings = {
510 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
511 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
512 | ENABLE_BITCODE = NO;
513 | FRAMEWORK_SEARCH_PATHS = (
514 | "$(inherited)",
515 | "$(PROJECT_DIR)/Flutter",
516 | );
517 | INFOPLIST_FILE = Runner/Info.plist;
518 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
519 | LIBRARY_SEARCH_PATHS = (
520 | "$(inherited)",
521 | "$(PROJECT_DIR)/Flutter",
522 | );
523 | PRODUCT_BUNDLE_IDENTIFIER = com.example.formvalidation;
524 | PRODUCT_NAME = "$(TARGET_NAME)";
525 | VERSIONING_SYSTEM = "apple-generic";
526 | };
527 | name = Debug;
528 | };
529 | 97C147071CF9000F007C117D /* Release */ = {
530 | isa = XCBuildConfiguration;
531 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
532 | buildSettings = {
533 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
534 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
535 | ENABLE_BITCODE = NO;
536 | FRAMEWORK_SEARCH_PATHS = (
537 | "$(inherited)",
538 | "$(PROJECT_DIR)/Flutter",
539 | );
540 | INFOPLIST_FILE = Runner/Info.plist;
541 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
542 | LIBRARY_SEARCH_PATHS = (
543 | "$(inherited)",
544 | "$(PROJECT_DIR)/Flutter",
545 | );
546 | PRODUCT_BUNDLE_IDENTIFIER = com.example.formvalidation;
547 | PRODUCT_NAME = "$(TARGET_NAME)";
548 | VERSIONING_SYSTEM = "apple-generic";
549 | };
550 | name = Release;
551 | };
552 | /* End XCBuildConfiguration section */
553 |
554 | /* Begin XCConfigurationList section */
555 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
556 | isa = XCConfigurationList;
557 | buildConfigurations = (
558 | 97C147031CF9000F007C117D /* Debug */,
559 | 97C147041CF9000F007C117D /* Release */,
560 | 249021D3217E4FDB00AE95B9 /* Profile */,
561 | );
562 | defaultConfigurationIsVisible = 0;
563 | defaultConfigurationName = Release;
564 | };
565 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
566 | isa = XCConfigurationList;
567 | buildConfigurations = (
568 | 97C147061CF9000F007C117D /* Debug */,
569 | 97C147071CF9000F007C117D /* Release */,
570 | 249021D4217E4FDB00AE95B9 /* Profile */,
571 | );
572 | defaultConfigurationIsVisible = 0;
573 | defaultConfigurationName = Release;
574 | };
575 | /* End XCConfigurationList section */
576 | };
577 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
578 | }
579 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
40 |
41 |
42 |
43 |
44 |
45 |
56 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
77 |
83 |
84 |
85 |
86 |
88 |
89 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application
7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
8 | [GeneratedPluginRegistrant registerWithRegistry:self];
9 | // Override point for customization after application launch.
10 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
11 | }
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Klerith/flutter-form-validation/00b5b6f1fb3c3ae0b5b1868f02b1d4abebd9e9ff/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | NSPhotoLibraryUsageDescription
7 | Necesito acceso al carrete
8 |
9 | NSCameraUsageDescription
10 | Necesito acceso a la cámara
11 |
12 | NSMicrophoneUsageDescription
13 | Quiero escucharte
14 |
15 |
16 | CFBundleDevelopmentRegion
17 | en
18 | CFBundleExecutable
19 | $(EXECUTABLE_NAME)
20 | CFBundleIdentifier
21 | $(PRODUCT_BUNDLE_IDENTIFIER)
22 | CFBundleInfoDictionaryVersion
23 | 6.0
24 | CFBundleName
25 | formvalidation
26 | CFBundlePackageType
27 | APPL
28 | CFBundleShortVersionString
29 | $(FLUTTER_BUILD_NAME)
30 | CFBundleSignature
31 | ????
32 | CFBundleVersion
33 | $(FLUTTER_BUILD_NUMBER)
34 | LSRequiresIPhoneOS
35 |
36 | UILaunchStoryboardName
37 | LaunchScreen
38 | UIMainStoryboardFile
39 | Main
40 | UISupportedInterfaceOrientations
41 |
42 | UIInterfaceOrientationPortrait
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | UISupportedInterfaceOrientations~ipad
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationPortraitUpsideDown
50 | UIInterfaceOrientationLandscapeLeft
51 | UIInterfaceOrientationLandscapeRight
52 |
53 | UIViewControllerBasedStatusBarAppearance
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char* argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'package:formvalidation/src/bloc/provider.dart';
4 |
5 | import 'package:formvalidation/src/pages/home_page.dart';
6 | import 'package:formvalidation/src/pages/login_page.dart';
7 | import 'package:formvalidation/src/pages/producto_page.dart';
8 | import 'package:formvalidation/src/pages/registro_page.dart';
9 | import 'package:formvalidation/src/preferencias_usuario/preferencias_usuario.dart';
10 |
11 | void main() async {
12 |
13 | final prefs = new PreferenciasUsuario();
14 | await prefs.initPrefs();
15 |
16 | runApp(MyApp());
17 |
18 | }
19 |
20 | class MyApp extends StatelessWidget {
21 | @override
22 | Widget build(BuildContext context) {
23 |
24 | final prefs = new PreferenciasUsuario();
25 | print( prefs.token );
26 |
27 | return Provider(
28 | child: MaterialApp(
29 | debugShowCheckedModeBanner: false,
30 | title: 'Material App',
31 | initialRoute: 'login',
32 | routes: {
33 | 'login' : ( BuildContext context ) => LoginPage(),
34 | 'registro' : ( BuildContext context ) => RegistroPage(),
35 | 'home' : ( BuildContext context ) => HomePage(),
36 | 'producto' : ( BuildContext context ) => ProductoPage(),
37 | },
38 | theme: ThemeData(
39 | primaryColor: Colors.deepPurple,
40 | ),
41 | ),
42 | );
43 |
44 | }
45 | }
--------------------------------------------------------------------------------
/lib/src/bloc/login_bloc.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'package:formvalidation/src/bloc/validators.dart';
3 | import 'package:rxdart/rxdart.dart';
4 |
5 | class LoginBloc with Validators {
6 |
7 |
8 | final _emailController = BehaviorSubject();
9 | final _passwordController = BehaviorSubject();
10 |
11 | // Recuperar los datos del Stream
12 | Stream get emailStream => _emailController.stream.transform( validarEmail );
13 | Stream get passwordStream => _passwordController.stream.transform( validarPassword );
14 |
15 | Stream get formValidStream =>
16 | Observable.combineLatest2(emailStream, passwordStream, (e, p) => true );
17 |
18 |
19 |
20 | // Insertar valores al Stream
21 | Function(String) get changeEmail => _emailController.sink.add;
22 | Function(String) get changePassword => _passwordController.sink.add;
23 |
24 |
25 | // Obtener el último valor ingresado a los streams
26 | String get email => _emailController.value;
27 | String get password => _passwordController.value;
28 |
29 | dispose() {
30 | _emailController?.close();
31 | _passwordController?.close();
32 | }
33 |
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/lib/src/bloc/productos_bloc.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:formvalidation/src/providers/productos_provider.dart';
4 | import 'package:rxdart/rxdart.dart';
5 |
6 | import 'package:formvalidation/src/models/producto_model.dart';
7 |
8 |
9 |
10 |
11 | class ProductosBloc {
12 |
13 | final _productosController = new BehaviorSubject>();
14 | final _cargandoController = new BehaviorSubject();
15 |
16 | final _productosProvider = new ProductosProvider();
17 |
18 |
19 | Stream> get productosStream => _productosController.stream;
20 | Stream get cargando => _cargandoController.stream;
21 |
22 |
23 |
24 | void cargarProductos() async {
25 |
26 | final productos = await _productosProvider.cargarProductos();
27 | _productosController.sink.add( productos );
28 | }
29 |
30 |
31 | void agregarProducto( ProductoModel producto ) async {
32 |
33 | _cargandoController.sink.add(true);
34 | await _productosProvider.crearProducto(producto);
35 | _cargandoController.sink.add(false);
36 |
37 | }
38 |
39 | Future subirFoto( File foto ) async {
40 |
41 | _cargandoController.sink.add(true);
42 | final fotoUrl = await _productosProvider.subirImagen(foto);
43 | _cargandoController.sink.add(false);
44 |
45 | return fotoUrl;
46 |
47 | }
48 |
49 |
50 | void editarProducto( ProductoModel producto ) async {
51 |
52 | _cargandoController.sink.add(true);
53 | await _productosProvider.editarProducto(producto);
54 | _cargandoController.sink.add(false);
55 |
56 | }
57 |
58 | void borrarProducto( String id ) async {
59 |
60 | await _productosProvider.borrarProducto(id);
61 |
62 | }
63 |
64 |
65 | dispose() {
66 | _productosController?.close();
67 | _cargandoController?.close();
68 | }
69 |
70 | }
--------------------------------------------------------------------------------
/lib/src/bloc/provider.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | import 'package:formvalidation/src/bloc/login_bloc.dart';
4 | export 'package:formvalidation/src/bloc/login_bloc.dart';
5 |
6 | import 'package:formvalidation/src/bloc/productos_bloc.dart';
7 | export 'package:formvalidation/src/bloc/productos_bloc.dart';
8 |
9 |
10 | class Provider extends InheritedWidget {
11 |
12 | final loginBloc = new LoginBloc();
13 | final _productosBloc = new ProductosBloc();
14 |
15 |
16 | static Provider _instancia;
17 |
18 | factory Provider({ Key key, Widget child }) {
19 |
20 | if ( _instancia == null ) {
21 | _instancia = new Provider._internal(key: key, child: child );
22 | }
23 |
24 | return _instancia;
25 |
26 | }
27 |
28 | Provider._internal({ Key key, Widget child })
29 | : super(key: key, child: child );
30 |
31 |
32 |
33 |
34 | // Provider({ Key key, Widget child })
35 | // : super(key: key, child: child );
36 |
37 |
38 | @override
39 | bool updateShouldNotify(InheritedWidget oldWidget) => true;
40 |
41 | static LoginBloc of ( BuildContext context ) {
42 | return ( context.inheritFromWidgetOfExactType(Provider) as Provider ).loginBloc;
43 | }
44 |
45 | static ProductosBloc productosBloc ( BuildContext context ) {
46 | return ( context.inheritFromWidgetOfExactType(Provider) as Provider )._productosBloc;
47 | }
48 |
49 | }
--------------------------------------------------------------------------------
/lib/src/bloc/validators.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 |
4 |
5 | class Validators {
6 |
7 |
8 | final validarEmail = StreamTransformer.fromHandlers(
9 | handleData: ( email, sink ) {
10 |
11 |
12 | Pattern pattern = r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
13 | RegExp regExp = new RegExp(pattern);
14 |
15 | if ( regExp.hasMatch( email ) ) {
16 | sink.add( email );
17 | } else {
18 | sink.addError('Email no es correcto');
19 | }
20 |
21 | }
22 | );
23 |
24 |
25 | final validarPassword = StreamTransformer.fromHandlers(
26 | handleData: ( password, sink ) {
27 |
28 | if ( password.length >= 6 ) {
29 | sink.add( password );
30 | } else {
31 | sink.addError('Más de 6 caracteres por favor');
32 | }
33 |
34 | }
35 | );
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/lib/src/models/producto_model.dart:
--------------------------------------------------------------------------------
1 | // To parse this JSON data, do
2 | //
3 | // final productoModel = productoModelFromJson(jsonString);
4 |
5 | import 'dart:convert';
6 |
7 | ProductoModel productoModelFromJson(String str) => ProductoModel.fromJson(json.decode(str));
8 |
9 | String productoModelToJson(ProductoModel data) => json.encode(data.toJson());
10 |
11 | class ProductoModel {
12 |
13 | String id;
14 | String titulo;
15 | double valor;
16 | bool disponible;
17 | String fotoUrl;
18 |
19 | ProductoModel({
20 | this.id,
21 | this.titulo = '',
22 | this.valor = 0.0,
23 | this.disponible = true,
24 | this.fotoUrl,
25 | });
26 |
27 | factory ProductoModel.fromJson(Map json) => new ProductoModel(
28 | id : json["id"],
29 | titulo : json["titulo"],
30 | valor : json["valor"],
31 | disponible : json["disponible"],
32 | fotoUrl : json["fotoUrl"],
33 | );
34 |
35 | Map toJson() => {
36 | // "id" : id,
37 | "titulo" : titulo,
38 | "valor" : valor,
39 | "disponible" : disponible,
40 | "fotoUrl" : fotoUrl,
41 | };
42 | }
43 |
--------------------------------------------------------------------------------
/lib/src/pages/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:formvalidation/src/bloc/provider.dart';
3 | import 'package:formvalidation/src/models/producto_model.dart';
4 |
5 | class HomePage extends StatelessWidget {
6 |
7 |
8 | @override
9 | Widget build(BuildContext context) {
10 |
11 | final productosBloc = Provider.productosBloc(context);
12 | productosBloc.cargarProductos();
13 |
14 | return Scaffold(
15 | appBar: AppBar(
16 | title: Text('Home')
17 | ),
18 | body: _crearListado(productosBloc),
19 | floatingActionButton: _crearBoton( context ),
20 | );
21 | }
22 |
23 |
24 | Widget _crearListado(ProductosBloc productosBloc ) {
25 |
26 | return StreamBuilder(
27 | stream: productosBloc.productosStream,
28 | builder: (BuildContext context, AsyncSnapshot> snapshot){
29 |
30 | if ( snapshot.hasData ) {
31 |
32 | final productos = snapshot.data;
33 |
34 | return ListView.builder(
35 | itemCount: productos.length,
36 | itemBuilder: (context, i) => _crearItem(context, productosBloc, productos[i] ),
37 | );
38 |
39 | } else {
40 | return Center( child: CircularProgressIndicator());
41 | }
42 | },
43 | );
44 |
45 | }
46 |
47 | Widget _crearItem(BuildContext context, ProductosBloc productosBloc, ProductoModel producto ) {
48 |
49 | return Dismissible(
50 | key: UniqueKey(),
51 | background: Container(
52 | color: Colors.red,
53 | ),
54 | onDismissed: ( direccion )=> productosBloc.borrarProducto(producto.id),
55 | child: Card(
56 | child: Column(
57 | children: [
58 |
59 | ( producto.fotoUrl == null )
60 | ? Image(image: AssetImage('assets/no-image.png'))
61 | : FadeInImage(
62 | image: NetworkImage( producto.fotoUrl ),
63 | placeholder: AssetImage('assets/jar-loading.gif'),
64 | height: 300.0,
65 | width: double.infinity,
66 | fit: BoxFit.cover,
67 | ),
68 |
69 | ListTile(
70 | title: Text('${ producto.titulo } - ${ producto.valor }'),
71 | subtitle: Text( producto.id ),
72 | onTap: () => Navigator.pushNamed(context, 'producto', arguments: producto ),
73 | ),
74 |
75 | ],
76 | ),
77 | )
78 | );
79 |
80 |
81 |
82 |
83 | }
84 |
85 |
86 | _crearBoton(BuildContext context) {
87 | return FloatingActionButton(
88 | child: Icon( Icons.add ),
89 | backgroundColor: Colors.deepPurple,
90 | onPressed: ()=> Navigator.pushNamed(context, 'producto'),
91 | );
92 | }
93 |
94 | }
--------------------------------------------------------------------------------
/lib/src/pages/login_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:formvalidation/src/bloc/provider.dart';
3 | import 'package:formvalidation/src/providers/usuario_provider.dart';
4 |
5 | import 'package:formvalidation/src/utils/utils.dart';
6 |
7 | class LoginPage extends StatelessWidget {
8 |
9 | final usuarioProvider = new UsuarioProvider();
10 |
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | return Scaffold(
15 | body: Stack(
16 | children: [
17 | _crearFondo( context ),
18 | _loginForm( context ),
19 | ],
20 | )
21 | );
22 | }
23 |
24 | Widget _loginForm(BuildContext context) {
25 |
26 | final bloc = Provider.of(context);
27 | final size = MediaQuery.of(context).size;
28 |
29 | return SingleChildScrollView(
30 | child: Column(
31 | children: [
32 |
33 | SafeArea(
34 | child: Container(
35 | height: 180.0,
36 | ),
37 | ),
38 |
39 | Container(
40 | width: size.width * 0.85,
41 | margin: EdgeInsets.symmetric(vertical: 30.0),
42 | padding: EdgeInsets.symmetric( vertical: 50.0 ),
43 | decoration: BoxDecoration(
44 | color: Colors.white,
45 | borderRadius: BorderRadius.circular(5.0),
46 | boxShadow: [
47 | BoxShadow(
48 | color: Colors.black26,
49 | blurRadius: 3.0,
50 | offset: Offset(0.0, 5.0),
51 | spreadRadius: 3.0
52 | )
53 | ]
54 | ),
55 | child: Column(
56 | children: [
57 | Text('Ingreso', style: TextStyle(fontSize: 20.0)),
58 | SizedBox( height: 60.0 ),
59 | _crearEmail( bloc ),
60 | SizedBox( height: 30.0 ),
61 | _crearPassword( bloc ),
62 | SizedBox( height: 30.0 ),
63 | _crearBoton( bloc )
64 | ],
65 | ),
66 | ),
67 |
68 | FlatButton(
69 | child: Text('Crear una nueva cuenta'),
70 | onPressed: ()=> Navigator.pushReplacementNamed(context, 'registro'),
71 | ),
72 | SizedBox( height: 100.0 )
73 | ],
74 | ),
75 | );
76 |
77 |
78 | }
79 |
80 | Widget _crearEmail(LoginBloc bloc) {
81 |
82 | return StreamBuilder(
83 | stream: bloc.emailStream,
84 | builder: (BuildContext context, AsyncSnapshot snapshot){
85 |
86 | return Container(
87 | padding: EdgeInsets.symmetric(horizontal: 20.0),
88 |
89 | child: TextField(
90 | keyboardType: TextInputType.emailAddress,
91 | decoration: InputDecoration(
92 | icon: Icon( Icons.alternate_email, color: Colors.deepPurple ),
93 | hintText: 'ejemplo@correo.com',
94 | labelText: 'Correo electrónico',
95 | counterText: snapshot.data,
96 | errorText: snapshot.error
97 | ),
98 | onChanged: bloc.changeEmail,
99 | ),
100 |
101 | );
102 |
103 |
104 | },
105 | );
106 |
107 |
108 | }
109 |
110 | Widget _crearPassword(LoginBloc bloc) {
111 |
112 | return StreamBuilder(
113 | stream: bloc.passwordStream,
114 | builder: (BuildContext context, AsyncSnapshot snapshot){
115 |
116 | return Container(
117 | padding: EdgeInsets.symmetric(horizontal: 20.0),
118 |
119 | child: TextField(
120 | obscureText: true,
121 | decoration: InputDecoration(
122 | icon: Icon( Icons.lock_outline, color: Colors.deepPurple ),
123 | labelText: 'Contraseña',
124 | counterText: snapshot.data,
125 | errorText: snapshot.error
126 | ),
127 | onChanged: bloc.changePassword,
128 | ),
129 |
130 | );
131 |
132 | },
133 | );
134 |
135 |
136 | }
137 |
138 | Widget _crearBoton( LoginBloc bloc) {
139 |
140 | // formValidStream
141 | // snapshot.hasData
142 | // true ? algo si true : algo si false
143 |
144 | return StreamBuilder(
145 | stream: bloc.formValidStream,
146 | builder: (BuildContext context, AsyncSnapshot snapshot){
147 |
148 | return RaisedButton(
149 | child: Container(
150 | padding: EdgeInsets.symmetric( horizontal: 80.0, vertical: 15.0),
151 | child: Text('Ingresar'),
152 | ),
153 | shape: RoundedRectangleBorder(
154 | borderRadius: BorderRadius.circular(5.0)
155 | ),
156 | elevation: 0.0,
157 | color: Colors.deepPurple,
158 | textColor: Colors.white,
159 | onPressed: snapshot.hasData ? ()=> _login(bloc, context) : null
160 | );
161 | },
162 | );
163 | }
164 |
165 | _login(LoginBloc bloc, BuildContext context) async {
166 |
167 | Map info = await usuarioProvider.login(bloc.email, bloc.password);
168 |
169 | if ( info['ok'] ) {
170 | Navigator.pushReplacementNamed(context, 'home');
171 | } else {
172 | mostrarAlerta( context, info['mensaje'] );
173 | }
174 |
175 | }
176 |
177 |
178 | Widget _crearFondo(BuildContext context) {
179 |
180 | final size = MediaQuery.of(context).size;
181 |
182 | final fondoModaro = Container(
183 | height: size.height * 0.4,
184 | width: double.infinity,
185 | decoration: BoxDecoration(
186 | gradient: LinearGradient(
187 | colors: [
188 | Color.fromRGBO(63, 63, 156, 1.0),
189 | Color.fromRGBO(90, 70, 178, 1.0)
190 | ]
191 | )
192 | ),
193 | );
194 |
195 | final circulo = Container(
196 | width: 100.0,
197 | height: 100.0,
198 | decoration: BoxDecoration(
199 | borderRadius: BorderRadius.circular(100.0),
200 | color: Color.fromRGBO(255, 255, 255, 0.05)
201 | ),
202 | );
203 |
204 |
205 | return Stack(
206 | children: [
207 | fondoModaro,
208 | Positioned( top: 90.0, left: 30.0, child: circulo ),
209 | Positioned( top: -40.0, right: -30.0, child: circulo ),
210 | Positioned( bottom: -50.0, right: -10.0, child: circulo ),
211 | Positioned( bottom: 120.0, right: 20.0, child: circulo ),
212 | Positioned( bottom: -50.0, left: -20.0, child: circulo ),
213 |
214 | Container(
215 | padding: EdgeInsets.only(top: 80.0),
216 | child: Column(
217 | children: [
218 | Icon( Icons.person_pin_circle, color: Colors.white, size: 100.0 ),
219 | SizedBox( height: 10.0, width: double.infinity ),
220 | Text('Fernando Herrera', style: TextStyle( color: Colors.white, fontSize: 25.0 ))
221 | ],
222 | ),
223 | )
224 |
225 | ],
226 | );
227 |
228 | }
229 |
230 | }
--------------------------------------------------------------------------------
/lib/src/pages/producto_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:formvalidation/src/bloc/provider.dart';
5 | import 'package:image_picker/image_picker.dart';
6 |
7 |
8 | import 'package:formvalidation/src/models/producto_model.dart';
9 | import 'package:formvalidation/src/utils/utils.dart' as utils;
10 |
11 |
12 | class ProductoPage extends StatefulWidget {
13 |
14 | @override
15 | _ProductoPageState createState() => _ProductoPageState();
16 | }
17 |
18 | class _ProductoPageState extends State {
19 |
20 | final formKey = GlobalKey();
21 | final scaffoldKey = GlobalKey();
22 |
23 | ProductosBloc productosBloc;
24 | ProductoModel producto = new ProductoModel();
25 | bool _guardando = false;
26 | File foto;
27 |
28 | @override
29 | Widget build(BuildContext context) {
30 |
31 | productosBloc = Provider.productosBloc(context);
32 |
33 |
34 | final ProductoModel prodData = ModalRoute.of(context).settings.arguments;
35 | if ( prodData != null ) {
36 | producto = prodData;
37 | }
38 |
39 | return Scaffold(
40 | key: scaffoldKey,
41 | appBar: AppBar(
42 | title: Text('Producto'),
43 | actions: [
44 | IconButton(
45 | icon: Icon( Icons.photo_size_select_actual ),
46 | onPressed: _seleccionarFoto,
47 | ),
48 | IconButton(
49 | icon: Icon( Icons.camera_alt ),
50 | onPressed: _tomarFoto,
51 | ),
52 | ],
53 | ),
54 | body: SingleChildScrollView(
55 | child: Container(
56 | padding: EdgeInsets.all(15.0),
57 | child: Form(
58 | key: formKey,
59 | child: Column(
60 | children: [
61 | _mostrarFoto(),
62 | _crearNombre(),
63 | _crearPrecio(),
64 | _crearDisponible(),
65 | _crearBoton()
66 | ],
67 | ),
68 | ),
69 | ),
70 | ),
71 | );
72 |
73 | }
74 |
75 | Widget _crearNombre() {
76 |
77 | return TextFormField(
78 | initialValue: producto.titulo,
79 | textCapitalization: TextCapitalization.sentences,
80 | decoration: InputDecoration(
81 | labelText: 'Producto'
82 | ),
83 | onSaved: (value) => producto.titulo = value,
84 | validator: (value) {
85 | if ( value.length < 3 ) {
86 | return 'Ingrese el nombre del producto';
87 | } else {
88 | return null;
89 | }
90 | },
91 | );
92 |
93 | }
94 |
95 | Widget _crearPrecio() {
96 | return TextFormField(
97 | initialValue: producto.valor.toString(),
98 | keyboardType: TextInputType.numberWithOptions(decimal: true),
99 | decoration: InputDecoration(
100 | labelText: 'Precio'
101 | ),
102 | onSaved: (value) => producto.valor = double.parse(value),
103 | validator: (value) {
104 |
105 | if ( utils.isNumeric(value) ) {
106 | return null;
107 | } else {
108 | return 'Sólo números';
109 | }
110 |
111 | },
112 | );
113 | }
114 |
115 | Widget _crearDisponible() {
116 |
117 | return SwitchListTile(
118 | value: producto.disponible,
119 | title: Text('Disponible'),
120 | activeColor: Colors.deepPurple,
121 | onChanged: (value)=> setState((){
122 | producto.disponible = value;
123 | }),
124 | );
125 |
126 | }
127 |
128 |
129 |
130 | Widget _crearBoton() {
131 | return RaisedButton.icon(
132 | shape: RoundedRectangleBorder(
133 | borderRadius: BorderRadius.circular(20.0)
134 | ),
135 | color: Colors.deepPurple,
136 | textColor: Colors.white,
137 | label: Text('Guardar'),
138 | icon: Icon( Icons.save ),
139 | onPressed: ( _guardando ) ? null : _submit,
140 | );
141 | }
142 |
143 | void _submit() async {
144 |
145 |
146 |
147 | if ( !formKey.currentState.validate() ) return;
148 |
149 | formKey.currentState.save();
150 |
151 | setState(() {_guardando = true; });
152 |
153 | if ( foto != null ) {
154 | producto.fotoUrl = await productosBloc.subirFoto(foto);
155 | }
156 |
157 |
158 |
159 | if ( producto.id == null ) {
160 | productosBloc.agregarProducto(producto);
161 | } else {
162 | productosBloc.editarProducto(producto);
163 | }
164 |
165 |
166 | // setState(() {_guardando = false; });
167 | mostrarSnackbar('Registro guardado');
168 |
169 | Navigator.pop(context);
170 |
171 | }
172 |
173 |
174 | void mostrarSnackbar(String mensaje) {
175 |
176 | final snackbar = SnackBar(
177 | content: Text( mensaje ),
178 | duration: Duration( milliseconds: 1500),
179 | );
180 |
181 | scaffoldKey.currentState.showSnackBar(snackbar);
182 |
183 | }
184 |
185 |
186 | Widget _mostrarFoto() {
187 |
188 | if ( producto.fotoUrl != null ) {
189 |
190 | return FadeInImage(
191 | image: NetworkImage( producto.fotoUrl ),
192 | placeholder: AssetImage('assets/jar-loading.gif'),
193 | height: 300.0,
194 | fit: BoxFit.contain,
195 | );
196 |
197 | } else {
198 |
199 | return Image(
200 |
201 | image: AssetImage( foto?.path ?? 'assets/no-image.png'),
202 | height: 300.0,
203 | fit: BoxFit.cover,
204 |
205 | );
206 |
207 | }
208 |
209 | }
210 |
211 |
212 | _seleccionarFoto() async {
213 |
214 | _procesarImagen( ImageSource.gallery );
215 |
216 | }
217 |
218 |
219 | _tomarFoto() async {
220 |
221 | _procesarImagen( ImageSource.camera );
222 |
223 | }
224 |
225 | _procesarImagen( ImageSource origen ) async {
226 |
227 | foto = await ImagePicker.pickImage(
228 | source: origen
229 | );
230 |
231 | if ( foto != null ) {
232 | producto.fotoUrl = null;
233 | }
234 |
235 | setState(() {});
236 |
237 | }
238 |
239 |
240 | }
241 |
242 |
243 |
244 |
--------------------------------------------------------------------------------
/lib/src/pages/registro_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:formvalidation/src/bloc/provider.dart';
3 | import 'package:formvalidation/src/providers/usuario_provider.dart';
4 | import 'package:formvalidation/src/utils/utils.dart';
5 |
6 | class RegistroPage extends StatelessWidget {
7 |
8 | final usuarioProvider = new UsuarioProvider();
9 |
10 | @override
11 | Widget build(BuildContext context) {
12 | return Scaffold(
13 | body: Stack(
14 | children: [
15 | _crearFondo( context ),
16 | _loginForm( context ),
17 | ],
18 | )
19 | );
20 | }
21 |
22 | Widget _loginForm(BuildContext context) {
23 |
24 | final bloc = Provider.of(context);
25 | final size = MediaQuery.of(context).size;
26 |
27 | return SingleChildScrollView(
28 | child: Column(
29 | children: [
30 |
31 | SafeArea(
32 | child: Container(
33 | height: 180.0,
34 | ),
35 | ),
36 |
37 | Container(
38 | width: size.width * 0.85,
39 | margin: EdgeInsets.symmetric(vertical: 30.0),
40 | padding: EdgeInsets.symmetric( vertical: 50.0 ),
41 | decoration: BoxDecoration(
42 | color: Colors.white,
43 | borderRadius: BorderRadius.circular(5.0),
44 | boxShadow: [
45 | BoxShadow(
46 | color: Colors.black26,
47 | blurRadius: 3.0,
48 | offset: Offset(0.0, 5.0),
49 | spreadRadius: 3.0
50 | )
51 | ]
52 | ),
53 | child: Column(
54 | children: [
55 | Text('Crear cuenta', style: TextStyle(fontSize: 20.0)),
56 | SizedBox( height: 60.0 ),
57 | _crearEmail( bloc ),
58 | SizedBox( height: 30.0 ),
59 | _crearPassword( bloc ),
60 | SizedBox( height: 30.0 ),
61 | _crearBoton( bloc )
62 | ],
63 | ),
64 | ),
65 |
66 | FlatButton(
67 | child: Text('¿Ya tienes cuenta? Login'),
68 | onPressed: ()=> Navigator.pushReplacementNamed(context, 'login'),
69 | ),
70 | SizedBox( height: 100.0 )
71 | ],
72 | ),
73 | );
74 |
75 |
76 | }
77 |
78 | Widget _crearEmail(LoginBloc bloc) {
79 |
80 | return StreamBuilder(
81 | stream: bloc.emailStream,
82 | builder: (BuildContext context, AsyncSnapshot snapshot){
83 |
84 | return Container(
85 | padding: EdgeInsets.symmetric(horizontal: 20.0),
86 |
87 | child: TextField(
88 | keyboardType: TextInputType.emailAddress,
89 | decoration: InputDecoration(
90 | icon: Icon( Icons.alternate_email, color: Colors.deepPurple ),
91 | hintText: 'ejemplo@correo.com',
92 | labelText: 'Correo electrónico',
93 | counterText: snapshot.data,
94 | errorText: snapshot.error
95 | ),
96 | onChanged: bloc.changeEmail,
97 | ),
98 |
99 | );
100 |
101 |
102 | },
103 | );
104 |
105 |
106 | }
107 |
108 | Widget _crearPassword(LoginBloc bloc) {
109 |
110 | return StreamBuilder(
111 | stream: bloc.passwordStream,
112 | builder: (BuildContext context, AsyncSnapshot snapshot){
113 |
114 | return Container(
115 | padding: EdgeInsets.symmetric(horizontal: 20.0),
116 |
117 | child: TextField(
118 | obscureText: true,
119 | decoration: InputDecoration(
120 | icon: Icon( Icons.lock_outline, color: Colors.deepPurple ),
121 | labelText: 'Contraseña',
122 | counterText: snapshot.data,
123 | errorText: snapshot.error
124 | ),
125 | onChanged: bloc.changePassword,
126 | ),
127 |
128 | );
129 |
130 | },
131 | );
132 |
133 |
134 | }
135 |
136 | Widget _crearBoton( LoginBloc bloc) {
137 |
138 | // formValidStream
139 | // snapshot.hasData
140 | // true ? algo si true : algo si false
141 |
142 | return StreamBuilder(
143 | stream: bloc.formValidStream,
144 | builder: (BuildContext context, AsyncSnapshot snapshot){
145 |
146 | return RaisedButton(
147 | child: Container(
148 | padding: EdgeInsets.symmetric( horizontal: 80.0, vertical: 15.0),
149 | child: Text('Ingresar'),
150 | ),
151 | shape: RoundedRectangleBorder(
152 | borderRadius: BorderRadius.circular(5.0)
153 | ),
154 | elevation: 0.0,
155 | color: Colors.deepPurple,
156 | textColor: Colors.white,
157 | onPressed: snapshot.hasData ? ()=> _register(bloc, context) : null
158 | );
159 | },
160 | );
161 | }
162 |
163 | _register(LoginBloc bloc, BuildContext context) async {
164 |
165 | final info = await usuarioProvider.nuevoUsuario(bloc.email, bloc.password);
166 |
167 | if ( info['ok'] ) {
168 | Navigator.pushReplacementNamed(context, 'home');
169 | } else {
170 | mostrarAlerta( context, info['mensaje'] );
171 | }
172 |
173 |
174 | // Navigator.pushReplacementNamed(context, 'home');
175 |
176 | }
177 |
178 |
179 | Widget _crearFondo(BuildContext context) {
180 |
181 | final size = MediaQuery.of(context).size;
182 |
183 | final fondoModaro = Container(
184 | height: size.height * 0.4,
185 | width: double.infinity,
186 | decoration: BoxDecoration(
187 | gradient: LinearGradient(
188 | colors: [
189 | Color.fromRGBO(63, 63, 156, 1.0),
190 | Color.fromRGBO(90, 70, 178, 1.0)
191 | ]
192 | )
193 | ),
194 | );
195 |
196 | final circulo = Container(
197 | width: 100.0,
198 | height: 100.0,
199 | decoration: BoxDecoration(
200 | borderRadius: BorderRadius.circular(100.0),
201 | color: Color.fromRGBO(255, 255, 255, 0.05)
202 | ),
203 | );
204 |
205 |
206 | return Stack(
207 | children: [
208 | fondoModaro,
209 | Positioned( top: 90.0, left: 30.0, child: circulo ),
210 | Positioned( top: -40.0, right: -30.0, child: circulo ),
211 | Positioned( bottom: -50.0, right: -10.0, child: circulo ),
212 | Positioned( bottom: 120.0, right: 20.0, child: circulo ),
213 | Positioned( bottom: -50.0, left: -20.0, child: circulo ),
214 |
215 | Container(
216 | padding: EdgeInsets.only(top: 80.0),
217 | child: Column(
218 | children: [
219 | Icon( Icons.person_pin_circle, color: Colors.white, size: 100.0 ),
220 | SizedBox( height: 10.0, width: double.infinity ),
221 | Text('Fernando Herrera', style: TextStyle( color: Colors.white, fontSize: 25.0 ))
222 | ],
223 | ),
224 | )
225 |
226 | ],
227 | );
228 |
229 | }
230 |
231 | }
--------------------------------------------------------------------------------
/lib/src/preferencias_usuario/preferencias_usuario.dart:
--------------------------------------------------------------------------------
1 | import 'package:shared_preferences/shared_preferences.dart';
2 |
3 | /*
4 | Recordar instalar el paquete de:
5 | shared_preferences:
6 |
7 | Inicializar en el main
8 | final prefs = new PreferenciasUsuario();
9 | prefs.initPrefs();
10 |
11 | */
12 |
13 | class PreferenciasUsuario {
14 |
15 | static final PreferenciasUsuario _instancia = new PreferenciasUsuario._internal();
16 |
17 | factory PreferenciasUsuario() {
18 | return _instancia;
19 | }
20 |
21 | PreferenciasUsuario._internal();
22 |
23 | SharedPreferences _prefs;
24 |
25 | initPrefs() async {
26 | this._prefs = await SharedPreferences.getInstance();
27 | }
28 |
29 | // GET y SET de la última página
30 | get token {
31 | return _prefs.getString('token') ?? '';
32 | }
33 |
34 | set token( String value ) {
35 | _prefs.setString('token', value);
36 | }
37 |
38 |
39 | // GET y SET de la última página
40 | get ultimaPagina {
41 | return _prefs.getString('ultimaPagina') ?? 'login';
42 | }
43 |
44 | set ultimaPagina( String value ) {
45 | _prefs.setString('ultimaPagina', value);
46 | }
47 |
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/lib/src/providers/productos_provider.dart:
--------------------------------------------------------------------------------
1 |
2 | import 'dart:convert';
3 | import 'dart:io';
4 |
5 | import 'package:formvalidation/src/preferencias_usuario/preferencias_usuario.dart';
6 | import 'package:http/http.dart' as http;
7 | import 'package:http_parser/http_parser.dart';
8 |
9 | import 'package:mime_type/mime_type.dart';
10 |
11 | import 'package:formvalidation/src/models/producto_model.dart';
12 |
13 | class ProductosProvider {
14 |
15 | final String _url = 'https://flutter-varios.firebaseio.com';
16 | final _prefs = new PreferenciasUsuario();
17 |
18 | Future crearProducto( ProductoModel producto ) async {
19 |
20 | final url = '$_url/productos.json?auth=${ _prefs.token }';
21 |
22 | final resp = await http.post( url, body: productoModelToJson(producto) );
23 |
24 | final decodedData = json.decode(resp.body);
25 |
26 | print( decodedData );
27 |
28 | return true;
29 |
30 | }
31 |
32 | Future editarProducto( ProductoModel producto ) async {
33 |
34 | final url = '$_url/productos/${ producto.id }.json?auth=${ _prefs.token }';
35 |
36 | final resp = await http.put( url, body: productoModelToJson(producto) );
37 |
38 | final decodedData = json.decode(resp.body);
39 |
40 | print( decodedData );
41 |
42 | return true;
43 |
44 | }
45 |
46 |
47 |
48 | Future> cargarProductos() async {
49 |
50 | final url = '$_url/productos.json?auth=${ _prefs.token }';
51 | final resp = await http.get(url);
52 |
53 | final Map decodedData = json.decode(resp.body);
54 | final List productos = new List();
55 |
56 |
57 | if ( decodedData == null ) return [];
58 |
59 | if ( decodedData['error'] != null ) return [];
60 |
61 |
62 | decodedData.forEach( ( id, prod ){
63 |
64 | final prodTemp = ProductoModel.fromJson(prod);
65 | prodTemp.id = id;
66 |
67 | productos.add( prodTemp );
68 |
69 | });
70 |
71 | // print( productos[0].id );
72 |
73 | return productos;
74 |
75 | }
76 |
77 |
78 | Future borrarProducto( String id ) async {
79 |
80 | final url = '$_url/productos/$id.json?auth=${ _prefs.token }';
81 | final resp = await http.delete(url);
82 |
83 | print( resp.body );
84 |
85 | return 1;
86 | }
87 |
88 |
89 | Future subirImagen( File imagen ) async {
90 |
91 | final url = Uri.parse('https://api.cloudinary.com/v1_1/dc0tufkzf/image/upload?upload_preset=cwye3brj');
92 | final mimeType = mime(imagen.path).split('/'); //image/jpeg
93 |
94 | final imageUploadRequest = http.MultipartRequest(
95 | 'POST',
96 | url
97 | );
98 |
99 | final file = await http.MultipartFile.fromPath(
100 | 'file',
101 | imagen.path,
102 | contentType: MediaType( mimeType[0], mimeType[1] )
103 | );
104 |
105 | imageUploadRequest.files.add(file);
106 |
107 |
108 | final streamResponse = await imageUploadRequest.send();
109 | final resp = await http.Response.fromStream(streamResponse);
110 |
111 | if ( resp.statusCode != 200 && resp.statusCode != 201 ) {
112 | print('Algo salio mal');
113 | print( resp.body );
114 | return null;
115 | }
116 |
117 | final respData = json.decode(resp.body);
118 | print( respData);
119 |
120 | return respData['secure_url'];
121 |
122 |
123 | }
124 |
125 |
126 | }
127 |
128 |
--------------------------------------------------------------------------------
/lib/src/providers/usuario_provider.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert';
2 |
3 | import 'package:formvalidation/src/preferencias_usuario/preferencias_usuario.dart';
4 | import 'package:http/http.dart' as http;
5 |
6 | class UsuarioProvider {
7 |
8 | final String _firebaseToken = 'AIzaSyAO749eZf3E35cmxgZA06mRygilezkNVsM';
9 | final _prefs = new PreferenciasUsuario();
10 |
11 |
12 | Future