├── .gitignore ├── .metadata ├── 1024px-People.png ├── LICENSE.md ├── README.md ├── UsingTheApp.jpg ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── me │ │ │ │ └── billdietrich │ │ │ │ └── fake_contacts │ │ │ │ └── MainActivity.kt │ │ └── res │ │ │ ├── drawable-v21 │ │ │ └── launch_background.xml │ │ │ ├── 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-night │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── profile │ │ └── AndroidManifest.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties └── settings.gradle ├── fastlane └── metadata │ └── android │ ├── en-US │ ├── full_description.txt │ ├── images │ │ └── phoneScreenshots │ │ │ └── 1.png │ ├── short_description.txt │ └── title.txt │ └── es │ ├── full_description.txt │ ├── short_description.txt │ └── title.txt ├── integration_test ├── app_test.dart └── driver.dart ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Runner.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ └── Runner.xcscheme ├── Runner.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Runner │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-App-1024x1024@1x.png │ │ ├── Icon-App-20x20@1x.png │ │ ├── Icon-App-20x20@2x.png │ │ ├── Icon-App-20x20@3x.png │ │ ├── Icon-App-29x29@1x.png │ │ ├── Icon-App-29x29@2x.png │ │ ├── Icon-App-29x29@3x.png │ │ ├── Icon-App-40x40@1x.png │ │ ├── Icon-App-40x40@2x.png │ │ ├── Icon-App-40x40@3x.png │ │ ├── Icon-App-60x60@2x.png │ │ ├── Icon-App-60x60@3x.png │ │ ├── Icon-App-76x76@1x.png │ │ ├── Icon-App-76x76@2x.png │ │ └── Icon-App-83.5x83.5@2x.png │ └── LaunchImage.imageset │ │ ├── Contents.json │ │ ├── LaunchImage.png │ │ ├── LaunchImage@2x.png │ │ ├── LaunchImage@3x.png │ │ └── README.md │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── Runner-Bridging-Header.h ├── lib └── main.dart ├── metadata └── me.billdietrich.fake_contacts.yml ├── pubspec.lock ├── pubspec.yaml └── test └── widget_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /.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: 8f89f6505b941329a864fef1527243a72800bf4d 8 | channel: beta 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /1024px-People.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/1024px-People.png -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Bill Dietrich 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fake Contacts 2 | 3 | Android phone app that creates fake contacts, which will be stored on your smartphone along with your real contacts. This feeds fake data to any apps or companies who are copying our private data to use or sell it. This is called "data-poisoning". 4 | 5 | Nothing about these fake contacts will interfere with your normal use of your phone or your real contacts. 6 | 7 | The app is available through F-Droid. 8 | 9 | This is a sister-application to "Fake Contacts 2", which puts fake information in some fields of all contacts. 10 | 11 | ## Functionality 12 | The user can set lists of last names and first names for fake contacts, and phone-number and email-address templates for them. Then click buttons to create or delete fake contacts with all combinations of the first and last names. 13 | 14 | 15 | ## Use 16 | 17 | 18 | 19 | The default values should be sensible. All of the first and last names start with "Z", to try to keep them from colliding with names of real contacts, and to keep them out of the way (at the end of the Contacts list). 20 | 21 | So, just install and launch the application, and click the "Create Fake Contacts" button. The system should ask you to grant Contacts permission to the application. Then the contacts (one for each firstname-lastname combination) will be created. Launch your usual Contacts app and scroll to the end to see the new contacts. Note: it may take a couple of minutes to update the list. 22 | 23 | If you wish, click the "Delete Fake Contacts" button to delete them. Note: it may take a couple of minutes to update the list. You also could use your normal Contacts app to delete them manually at any time, without causing any problem. 24 | 25 | You could uninstall this app after creating the fake contacts, without causing any problem. 26 | 27 | 28 | ### Customizing 29 | 30 | * The list of last names is just a comma-separated list. You can edit it to have any names. Best not to have any spaces. 31 | 32 | * The list of first names is similar. 33 | 34 | * The phone-number template is a single value used for all contacts. Any character "n" in it will be replaced by a digit 0-9, derived from the contact's last name. The default format is ```+2134567nnnn```, which is intended to use an unassigned country code "21". You could delete the contents of this field if you wish, and no phone numbers will be generated. 35 | 36 | * The email-address template is a single value used for all contacts. Any string "FIRST" in it will be replaced by the contact's first name. Any string "LAST" in it will be replaced by the contact's last name. The default format is ```FIRST.LAST@example.com```, which is intended to be an unused email domain. You could delete the contents of this field if you wish, and no email addresses will be generated. 37 | 38 | 39 | ### Quirks 40 | 41 | * The app is designed to be very simple and fail silently. If you deny permission to access contacts, the app will not complain, it just will not work. If you click the "Create" button multiple times, you just get one set of fake contacts. If you click the "Delete" button and the specified contacts don't exist, nothing is done, and no error message is shown. 42 | 43 | * Don't create any fake contact with the same full name as one of your real contacts. If you delete fake contacts, the real one with same name will be deleted too. 44 | 45 | * Replacements for "n" digits in phone numbers are calculated deterministicly (repeatably) from contact's last name. So for example if 5 users of this app all just leave everything set at defaults, the same contacts will show up on each of their phones with the same names, phone numbers, and email addresses. This is good, for data-poisoning purposes. Further, all fake contacts with same last name will have same phone number (debatable whether this is good or bad). 46 | 47 | 48 | --- 49 | 50 | 51 | ## Releases 52 | ### 1.0.0 53 | Got working. 54 | ### 1.6.0 55 | Got published on F-Droid. 56 | ### 1.7.0 57 | Changed color of delete button, added space between buttons, added a lot more names, cleaned up the code a little. 58 | ### 1.8.0 59 | Added Spanish description to Fastlane per https://github.com/BillDietrich/fake_contacts/pull/5 60 | 61 | 62 | 63 | --- 64 | 65 | ## Development 66 | ### To-Do list 67 | * What Android versions are supported ? I tested on 9; someone else says it works on 9 and crashes on 5. 68 | * Add buttons to add/delete fake secondary info (e.g. birthday ?) on ALL contacts. Or make a separate app for that. 69 | * Want to explicitly set Notification permission off, but there's no way to do it. 70 | * No UI feedback after create and delete operations. 71 | * Add photos from thispersondoesnotexist.com ? 72 | * Page doesn't scroll if screen is too short. 73 | * Inefficiency in the "save settings after every char changed in field" events. 74 | * Test on iOS. 75 | 76 | ### Development Environment 77 | I'm no expert on this stuff, this is my first phone app, maybe I'm doing some things stupidly. 78 | 79 | Now using: 80 | * Android Studio 81 | * Flutter 82 | * Dart 83 | * Linux 84 | * Phone running Android 9 85 | 86 | [F-Droid page for this app](https://fdroid.gitlab.io/fdroid-website/en/packages/me.billdietrich.fake_contacts/) 87 | 88 | [GitHub repo for this app](https://github.com/BillDietrich/fake_contacts) 89 | 90 | [My web site](https://www.billdietrich.me/) 91 | 92 | 93 | --- 94 | 95 | ## Privacy Policy 96 | This application doesn't collect, store or transmit your identity or personal information in any way. It contains no advertising and no trackers. 97 | 98 | 99 | ## License 100 | 101 | See LICENSE.md file. MIT license. Copyright 2021 Bill Dietrich. 102 | -------------------------------------------------------------------------------- /UsingTheApp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/UsingTheApp.jpg -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 30 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | defaultConfig { 36 | applicationId "me.billdietrich.fake_contacts" 37 | minSdkVersion 16 38 | targetSdkVersion 30 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | } 42 | 43 | buildTypes { 44 | release { 45 | // TODO: Add your own signing config for the release build. 46 | // Signing with the debug keys for now, so `flutter run --release` works. 47 | signingConfig signingConfigs.debug 48 | } 49 | } 50 | } 51 | 52 | flutter { 53 | source '../..' 54 | } 55 | 56 | dependencies { 57 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 58 | } 59 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 13 | 17 | 21 | 26 | 30 | 31 | 32 | 33 | 34 | 35 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/me/billdietrich/fake_contacts/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package me.billdietrich.fake_contacts 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /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-6.7-all.zip 7 | distributionSha256Sum=0080de8491f0918e4f529a6db6820fa0b9e818ee2386117f4394f95feb1d5583 8 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | Create fake phone contacts, that will be stored on your phone along with your real contacts. The idea is to feed fake data to any apps or companies who are copying our private data to use or sell it. This is called "data-poisoning". 2 | 3 | Nothing about these fake contacts will interfere with your normal use of your phone or your real contacts. 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | Create fake phone contacts, for data-poisoning. 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/title.txt: -------------------------------------------------------------------------------- 1 | Fake Contacts 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/es/full_description.txt: -------------------------------------------------------------------------------- 1 | Crea contactos telefónicos falsos, que se almacenarán en tu teléfono junto con tus contactos reales. La idea es alimentar con datos falsos a cualquier aplicación o empresa que copie nuestros datos privados para utilizarlos o venderlos. Esto se llama "envenenamiento de datos". 2 | 3 | Ninguno de estos contactos falsos interferirá con el uso normal de tu teléfono o tus contactos reales. -------------------------------------------------------------------------------- /fastlane/metadata/android/es/short_description.txt: -------------------------------------------------------------------------------- 1 | Crea falsos contactos de teléfono, para data-poisoning. 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/es/title.txt: -------------------------------------------------------------------------------- 1 | Fake Contacts 2 | -------------------------------------------------------------------------------- /integration_test/app_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter integration test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | import 'package:integration_test/integration_test.dart'; 11 | 12 | import 'package:fake_contacts/main.dart' as app; 13 | 14 | void main() => run(_testMain); 15 | 16 | void _testMain() { 17 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 18 | // Build our app and trigger a frame. 19 | app.main(); 20 | 21 | // Trigger a frame. 22 | await tester.pumpAndSettle(); 23 | 24 | // Verify that our counter starts at 0. 25 | expect(find.text('0'), findsOneWidget); 26 | expect(find.text('1'), findsNothing); 27 | 28 | // Tap the '+' icon and trigger a frame. 29 | await tester.tap(find.byIcon(Icons.add)); 30 | await tester.pump(); 31 | 32 | // Verify that our counter has incremented. 33 | expect(find.text('0'), findsNothing); 34 | expect(find.text('1'), findsOneWidget); 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /integration_test/driver.dart: -------------------------------------------------------------------------------- 1 | // This file is provided as a convenience for running integration tests via the 2 | // flutter drive command. 3 | // 4 | // flutter drive --driver integration_test/driver.dart --target integration_test/app_test.dart 5 | 6 | import 'package:integration_test/integration_test_driver.dart'; 7 | 8 | Future main() => integrationDriver(); 9 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | 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 "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | INFOPLIST_FILE = Runner/Info.plist; 293 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 294 | PRODUCT_BUNDLE_IDENTIFIER = me.billdietrich.fakeContacts; 295 | PRODUCT_NAME = "$(TARGET_NAME)"; 296 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 297 | SWIFT_VERSION = 5.0; 298 | VERSIONING_SYSTEM = "apple-generic"; 299 | }; 300 | name = Profile; 301 | }; 302 | 97C147031CF9000F007C117D /* Debug */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_ANALYZER_NONNULL = YES; 307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 308 | CLANG_CXX_LIBRARY = "libc++"; 309 | CLANG_ENABLE_MODULES = YES; 310 | CLANG_ENABLE_OBJC_ARC = YES; 311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_COMMA = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 326 | CLANG_WARN_STRICT_PROTOTYPES = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = dwarf; 333 | ENABLE_STRICT_OBJC_MSGSEND = YES; 334 | ENABLE_TESTABILITY = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_DYNAMIC_NO_PIC = NO; 337 | GCC_NO_COMMON_BLOCKS = YES; 338 | GCC_OPTIMIZATION_LEVEL = 0; 339 | GCC_PREPROCESSOR_DEFINITIONS = ( 340 | "DEBUG=1", 341 | "$(inherited)", 342 | ); 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 350 | MTL_ENABLE_DEBUG_INFO = YES; 351 | ONLY_ACTIVE_ARCH = YES; 352 | SDKROOT = iphoneos; 353 | TARGETED_DEVICE_FAMILY = "1,2"; 354 | }; 355 | name = Debug; 356 | }; 357 | 97C147041CF9000F007C117D /* Release */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ALWAYS_SEARCH_USER_PATHS = NO; 361 | CLANG_ANALYZER_NONNULL = YES; 362 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 363 | CLANG_CXX_LIBRARY = "libc++"; 364 | CLANG_ENABLE_MODULES = YES; 365 | CLANG_ENABLE_OBJC_ARC = YES; 366 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 367 | CLANG_WARN_BOOL_CONVERSION = YES; 368 | CLANG_WARN_COMMA = YES; 369 | CLANG_WARN_CONSTANT_CONVERSION = YES; 370 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INFINITE_RECURSION = YES; 375 | CLANG_WARN_INT_CONVERSION = YES; 376 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 377 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 378 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 380 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 381 | CLANG_WARN_STRICT_PROTOTYPES = YES; 382 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 383 | CLANG_WARN_UNREACHABLE_CODE = YES; 384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 385 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 386 | COPY_PHASE_STRIP = NO; 387 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 388 | ENABLE_NS_ASSERTIONS = NO; 389 | ENABLE_STRICT_OBJC_MSGSEND = YES; 390 | GCC_C_LANGUAGE_STANDARD = gnu99; 391 | GCC_NO_COMMON_BLOCKS = YES; 392 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 393 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 394 | GCC_WARN_UNDECLARED_SELECTOR = YES; 395 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 396 | GCC_WARN_UNUSED_FUNCTION = YES; 397 | GCC_WARN_UNUSED_VARIABLE = YES; 398 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 399 | MTL_ENABLE_DEBUG_INFO = NO; 400 | SDKROOT = iphoneos; 401 | SUPPORTED_PLATFORMS = iphoneos; 402 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 403 | TARGETED_DEVICE_FAMILY = "1,2"; 404 | VALIDATE_PRODUCT = YES; 405 | }; 406 | name = Release; 407 | }; 408 | 97C147061CF9000F007C117D /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 411 | buildSettings = { 412 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 413 | CLANG_ENABLE_MODULES = YES; 414 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 415 | ENABLE_BITCODE = NO; 416 | INFOPLIST_FILE = Runner/Info.plist; 417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 418 | PRODUCT_BUNDLE_IDENTIFIER = me.billdietrich.fakeContacts; 419 | PRODUCT_NAME = "$(TARGET_NAME)"; 420 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 421 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 422 | SWIFT_VERSION = 5.0; 423 | VERSIONING_SYSTEM = "apple-generic"; 424 | }; 425 | name = Debug; 426 | }; 427 | 97C147071CF9000F007C117D /* Release */ = { 428 | isa = XCBuildConfiguration; 429 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 430 | buildSettings = { 431 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 432 | CLANG_ENABLE_MODULES = YES; 433 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 434 | ENABLE_BITCODE = NO; 435 | INFOPLIST_FILE = Runner/Info.plist; 436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 437 | PRODUCT_BUNDLE_IDENTIFIER = me.billdietrich.fakeContacts; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 440 | SWIFT_VERSION = 5.0; 441 | VERSIONING_SYSTEM = "apple-generic"; 442 | }; 443 | name = Release; 444 | }; 445 | /* End XCBuildConfiguration section */ 446 | 447 | /* Begin XCConfigurationList section */ 448 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 449 | isa = XCConfigurationList; 450 | buildConfigurations = ( 451 | 97C147031CF9000F007C117D /* Debug */, 452 | 97C147041CF9000F007C117D /* Release */, 453 | 249021D3217E4FDB00AE95B9 /* Profile */, 454 | ); 455 | defaultConfigurationIsVisible = 0; 456 | defaultConfigurationName = Release; 457 | }; 458 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | 97C147061CF9000F007C117D /* Debug */, 462 | 97C147071CF9000F007C117D /* Release */, 463 | 249021D4217E4FDB00AE95B9 /* Profile */, 464 | ); 465 | defaultConfigurationIsVisible = 0; 466 | defaultConfigurationName = Release; 467 | }; 468 | /* End XCConfigurationList section */ 469 | }; 470 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 471 | } 472 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/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/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BillDietrich/fake_contacts/2e3400c834d182d7bf7de3e01e76bcd6070789da/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | fake_contacts 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | NSContactsUsageDescription 45 | This app requires contacts access to function properly. 46 | 47 | 48 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | //import 'dart:convert'; 2 | import 'dart:developer'; 3 | 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter/rendering.dart'; 6 | //import 'dart:math' hide log; 7 | import 'package:shared_preferences/shared_preferences.dart'; 8 | 9 | //import 'dart:io'; 10 | import 'package:contacts_service/contacts_service.dart'; 11 | import 'package:permission_handler/permission_handler.dart'; 12 | 13 | void main() { 14 | runApp(MyApp()); 15 | } 16 | 17 | class MyApp extends StatelessWidget { 18 | // This widget is the root of your application. 19 | @override 20 | Widget build(BuildContext context) { 21 | 22 | return MaterialApp( 23 | title: 'Fake Contacts', 24 | theme: ThemeData( 25 | primarySwatch: Colors.blue, 26 | ), 27 | home: MyHomePage(title: 'Fake Contacts'), 28 | ); 29 | } 30 | } 31 | 32 | class MyHomePage extends StatefulWidget { 33 | MyHomePage({Key key, this.title}) : super(key: key); 34 | 35 | final String title; 36 | 37 | @override 38 | _MyHomePageState createState() => _MyHomePageState(); 39 | } 40 | 41 | 42 | 43 | class _MyHomePageState extends State { 44 | 45 | String sListOfLastNames = ""; 46 | String sListOfFirstNames = ""; 47 | var lastNames = []; 48 | var firstNames = []; 49 | String sPhoneNumberTemplate = ""; 50 | String sEmailAddressTemplate = ""; 51 | 52 | Key keyLastNames = Key("LastNames"); 53 | Key keyFirstNames = Key("FirstNames"); 54 | Key keyPhoneNumberTemplate = Key("PhoneNumberTemplate"); 55 | Key keyEmailAddressTemplate = Key("EmailAddressTemplate"); 56 | 57 | TextEditingController lastNamesController = TextEditingController(); 58 | TextEditingController firstNamesController = TextEditingController(); 59 | TextEditingController phoneNumberTemplateController = TextEditingController(); 60 | TextEditingController emailAddressTemplateController = TextEditingController(); 61 | 62 | 63 | Future getLastNames() async { 64 | log("getLastNames: called"); 65 | SharedPreferences prefs; 66 | 67 | prefs = await SharedPreferences.getInstance(); 68 | final String sValue = prefs.getString('sListOfLastNames'); 69 | sListOfLastNames = sValue; 70 | // to create the array of names 71 | _changedLastNames(sListOfLastNames); 72 | return sValue; 73 | } 74 | 75 | Future getFirstNames() async { 76 | log("getFirstNames: called"); 77 | SharedPreferences prefs; 78 | 79 | prefs = await SharedPreferences.getInstance(); 80 | final String sValue = prefs.getString('sListOfFirstNames'); 81 | sListOfFirstNames = sValue; 82 | // to create the array of names 83 | _changedFirstNames(sListOfFirstNames); 84 | return sValue; 85 | } 86 | 87 | Future getPhoneNumberTemplate() async { 88 | log("getPhoneNumberTemplate: called"); 89 | SharedPreferences prefs; 90 | 91 | prefs = await SharedPreferences.getInstance(); 92 | final String sValue = prefs.getString('sPhoneNumberTemplate'); 93 | sPhoneNumberTemplate = sValue; 94 | return sValue; 95 | } 96 | 97 | Future getEmailAddressTemplate() async { 98 | log("getEmailAddressTemplate: called"); 99 | SharedPreferences prefs; 100 | 101 | prefs = await SharedPreferences.getInstance(); 102 | final String sValue = prefs.getString('sEmailAddressTemplate'); 103 | sEmailAddressTemplate = sValue; 104 | return sValue; 105 | } 106 | 107 | Future getStoredSettings() async { 108 | log("getStoredSettings: called"); 109 | SharedPreferences prefs; 110 | 111 | prefs = await SharedPreferences.getInstance(); 112 | sListOfLastNames = prefs.getString('sListOfLastNames'); 113 | //log("getStoredSettings: retrieved last names " + (sListOfLastNames ?? "null")); 114 | if (sListOfLastNames == null) { 115 | sListOfLastNames = "Zen,Zaragoza,Zabinski,Zimmermann,Zapata,Zona,Zidane,Zeiss,Zimmer,Zaal,Zaman,Zambrano,Zanetti,Zangari,Zappa,Zavala,Zawisza,Zeegers,Zelenka,Zellweger,Zeni,Zhang,Zhao,Zheng,Zhou,Ziegler,Zima"; 116 | sListOfFirstNames = "Zoe,Zach,Zbigniew,Zaire,Zero,Zakai,Zamir,Zan,Zanna,Zareen,Zeb,Zeki,Zelda,Zella,Zeno,Zephyr,Zhen,Zhi,Zhong,Zhu,Ziba,Ziggy,Zion,Zola,Zolyan,Zora,Zsazsa,Zuzana"; 117 | sPhoneNumberTemplate = "+2134567nnnn"; 118 | sEmailAddressTemplate = "FIRST.LAST@example.com"; 119 | saveLastNames(); 120 | saveFirstNames(); 121 | savePhoneNumberTemplate(); 122 | saveEmailAddressTemplate(); 123 | } else { 124 | sListOfFirstNames = prefs.getString('sListOfFirstNames'); 125 | sPhoneNumberTemplate = prefs.getString('sPhoneNumberTemplate'); 126 | sEmailAddressTemplate = prefs.getString('sEmailAddressTemplate'); 127 | } 128 | 129 | // create the arrays of names 130 | lastNames = sListOfLastNames.split(","); 131 | firstNames = sListOfFirstNames.split(","); 132 | 133 | lastNamesController.text = sListOfLastNames; 134 | // this gets called for every keypress in the field, but no info about what's happening 135 | //lastNamesController.addListener(() { 136 | // log("lastNamesController.Listener: called"); 137 | //}); 138 | firstNamesController.text = sListOfFirstNames; 139 | phoneNumberTemplateController.text = sPhoneNumberTemplate; 140 | emailAddressTemplateController.text = sEmailAddressTemplate; 141 | } 142 | 143 | void saveLastNames() async { 144 | log("saveLastNames: called"); 145 | 146 | final SharedPreferences prefs = await SharedPreferences.getInstance(); 147 | log("saveLastNames: sListOfLastNames " + sListOfLastNames); 148 | await prefs.setString("sListOfLastNames", sListOfLastNames); 149 | } 150 | 151 | void saveFirstNames() async { 152 | log("saveFirstNames: called"); 153 | 154 | final SharedPreferences prefs = await SharedPreferences.getInstance(); 155 | await prefs.setString("sListOfFirstNames", sListOfFirstNames); 156 | } 157 | 158 | void savePhoneNumberTemplate() async { 159 | log("savePhoneNumberTemplate: called"); 160 | 161 | final SharedPreferences prefs = await SharedPreferences.getInstance(); 162 | await prefs.setString("sPhoneNumberTemplate", sPhoneNumberTemplate); 163 | } 164 | 165 | void saveEmailAddressTemplate() async { 166 | log("saveEmailAddressTemplate: called"); 167 | 168 | final SharedPreferences prefs = await SharedPreferences.getInstance(); 169 | await prefs.setString("sEmailAddressTemplate", sEmailAddressTemplate); 170 | } 171 | 172 | String generatePhoneNumber(String sLastName) { 173 | log("generatePhoneNumber: called, sPhoneNumberTemplate " + sPhoneNumberTemplate + ", sLastName " + sLastName); 174 | String sNumber = ""; 175 | int nNext = 0; // next char to use in sLastName 176 | 177 | for (var i = 0; i < sPhoneNumberTemplate.length; i++) { 178 | //log("generatePhoneNumber: i " + i.toString() + ", sPhoneNumberTemplate[i] " + sPhoneNumberTemplate[i] + ", nNext " + nNext.toString()); 179 | if (sPhoneNumberTemplate[i] != 'n') { 180 | sNumber += sPhoneNumberTemplate[i]; 181 | } else { 182 | if (nNext >= sLastName.length) 183 | sNumber += "0"; 184 | else { 185 | sNumber += 186 | (String.fromCharCode( 187 | "0".codeUnitAt(0) + (sLastName.codeUnitAt(nNext) % 10))); 188 | nNext++; 189 | } 190 | } 191 | } 192 | 193 | log("generatePhoneNumber: returning, sNumber " + sNumber); 194 | return sNumber; 195 | } 196 | 197 | 198 | String generateEmailAddress(String sLastName, String sFirstName) { 199 | return sEmailAddressTemplate.replaceAll("FIRST", sFirstName).replaceAll("LAST", sLastName); 200 | } 201 | 202 | Future _createAllContacts() async { 203 | 204 | log("_createAllContacts: about to call Permission.contacts.request"); 205 | PermissionStatus permission = await Permission.contacts.request(); 206 | 207 | if (!permission.isGranted) { 208 | log("_createAllContacts: no permission"); 209 | } else { 210 | // Either the permission was already granted before or the user just granted it. 211 | 212 | for (var i=0 ; i _deleteAllContacts() async { 231 | log("_deleteAllContacts: about to call Permission.contacts.request"); 232 | PermissionStatus permission = await Permission.contacts.request(); 233 | if (!permission.isGranted) { 234 | log("_deleteAllContacts: no permission"); 235 | } else { 236 | // Either the permission was already granted before or the user just granted it. 237 | for (var i=0 ; i iContacts = await ContactsService.getContacts(query: newContact.displayName); 245 | for (var c in iContacts) { 246 | log( 247 | "_deleteAllContacts: about to call ContactsService.deleteContact(" + 248 | newContact.displayName + ")"); 249 | await ContactsService.deleteContact(c); 250 | } 251 | } 252 | } 253 | } 254 | log("_deleteAllContacts: about to return"); 255 | } 256 | 257 | 258 | // this gets called every time a char gets changed in the field 259 | // wasteful to recalculate every time, but doesn't matter 260 | void _changedLastNames(String sNewValue){ 261 | log("_changedLastNames: called, " + sNewValue); 262 | sListOfLastNames = sNewValue; 263 | lastNames = sListOfLastNames.split(","); 264 | //log("_changedLastNames: lastNames[0] == " + lastNames[0]); 265 | //log("_changedLastNames: lastNames.toString == " + lastNames.toString()); 266 | 267 | saveLastNames(); 268 | } 269 | 270 | 271 | // this gets called every time a char gets changed in the field 272 | // wasteful to recalculate and save every time 273 | void _changedFirstNames(String sNewValue){ 274 | log("_changedFirstNames: called, " + sNewValue); 275 | sListOfFirstNames = sNewValue; 276 | firstNames = sListOfFirstNames.split(","); 277 | //log("_changedFirstNames: firstNames[0] == " + firstNames[0]); 278 | //log("_changedFirstNames: firstNames.toString == " + firstNames.toString()); 279 | 280 | saveFirstNames(); 281 | } 282 | 283 | // this gets called every time a char gets changed in the field 284 | void _changedPhoneNumberTemplate(String sNewValue){ 285 | log("_changedPhoneNumberTemplate: called, " + sNewValue); 286 | sPhoneNumberTemplate = sNewValue; 287 | 288 | savePhoneNumberTemplate(); 289 | } 290 | 291 | // this gets called every time a char gets changed in the field 292 | void _changedEmailAddressTemplate(String sNewValue){ 293 | log("_changedEmailAddressTemplate: called, " + sNewValue); 294 | sEmailAddressTemplate = sNewValue; 295 | 296 | saveEmailAddressTemplate(); 297 | } 298 | 299 | @override 300 | Widget build(BuildContext context) { 301 | 302 | getStoredSettings(); // need to wait for it, but can't !!! 303 | //Future.wait(getStoredSettings()); // illegal ? 304 | //final int number = waitFor(getStoredSettings()); 305 | 306 | return Scaffold( 307 | appBar: AppBar( 308 | // Here we take the value from the MyHomePage object that was created by 309 | // the App.build method, and use it to set our appbar title. 310 | title: Text(widget.title), 311 | ), 312 | body: Center( 313 | // Center is a layout widget. It takes a single child and positions it 314 | // in the middle of the parent. 315 | child: Column( 316 | mainAxisAlignment: MainAxisAlignment.center, 317 | children: [ 318 | TextFormField( 319 | key: keyLastNames, // want to set value using this key, but can't 320 | onChanged: _changedLastNames, 321 | controller: lastNamesController, 322 | maxLines: 1, 323 | initialValue: sListOfLastNames, // want getLastNames() here but can't 324 | decoration: new InputDecoration( 325 | labelText: 'Last names', 326 | focusedBorder: OutlineInputBorder( 327 | borderSide: BorderSide(color: Colors.red, width: 5.0), 328 | ), 329 | enabledBorder: OutlineInputBorder( 330 | borderSide: BorderSide(color: Colors.greenAccent, width: 5.0), 331 | ), 332 | ), 333 | ), 334 | SizedBox( 335 | width: 10, 336 | height:20, 337 | ), 338 | TextFormField( 339 | key: keyFirstNames, 340 | onChanged: _changedFirstNames, 341 | controller: firstNamesController, 342 | maxLines: 1, 343 | initialValue: sListOfFirstNames, 344 | decoration: new InputDecoration( 345 | labelText: 'First names', 346 | focusedBorder: OutlineInputBorder( 347 | borderSide: BorderSide(color: Colors.red, width: 5.0), 348 | ), 349 | enabledBorder: OutlineInputBorder( 350 | borderSide: BorderSide(color: Colors.greenAccent, width: 5.0), 351 | ), 352 | ), 353 | ), 354 | SizedBox( 355 | width: 10, 356 | height:30, 357 | ), 358 | TextFormField( 359 | key: keyPhoneNumberTemplate, 360 | onChanged: _changedPhoneNumberTemplate, 361 | controller: phoneNumberTemplateController, 362 | maxLines: 1, 363 | initialValue: sPhoneNumberTemplate, 364 | decoration: new InputDecoration( 365 | labelText: 'Phone number template', 366 | focusedBorder: OutlineInputBorder( 367 | borderSide: BorderSide(color: Colors.red, width: 5.0), 368 | ), 369 | enabledBorder: OutlineInputBorder( 370 | borderSide: BorderSide(color: Colors.greenAccent, width: 5.0), 371 | ), 372 | ), 373 | ), 374 | SizedBox( 375 | width: 10, 376 | height:20, 377 | ), 378 | TextFormField( 379 | key: keyEmailAddressTemplate, 380 | onChanged: _changedEmailAddressTemplate, 381 | maxLines: 1, 382 | initialValue: sEmailAddressTemplate, 383 | controller: emailAddressTemplateController, 384 | decoration: new InputDecoration( 385 | labelText: 'Email address template', 386 | focusedBorder: OutlineInputBorder( 387 | borderSide: BorderSide(color: Colors.red, width: 5.0), 388 | ), 389 | enabledBorder: OutlineInputBorder( 390 | borderSide: BorderSide(color: Colors.greenAccent, width: 5.0), 391 | ), 392 | ), 393 | ), 394 | SizedBox( 395 | width: 10, 396 | height:40, 397 | ), 398 | ElevatedButton( 399 | onPressed: () => _createAllContacts(), 400 | child: Text("Create Fake Contacts"), 401 | ), 402 | SizedBox( 403 | width: 10, 404 | height:30, 405 | ), 406 | ElevatedButton( 407 | onPressed: () => _deleteAllContacts(), 408 | child: Text("Delete Fake Contacts"), 409 | style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.pink) ), 410 | ), 411 | ], 412 | ), 413 | ), 414 | ); 415 | } 416 | } 417 | -------------------------------------------------------------------------------- /metadata/me.billdietrich.fake_contacts.yml: -------------------------------------------------------------------------------- 1 | Categories: 2 | - Security 3 | License: MIT 4 | AuthorName: Bill Dietrich 5 | AuthorEmail: bill@billdietrich.me 6 | AuthorWebSite: https://www.billdietrich.me/ 7 | SourceCode: https://github.com/BillDietrich/fake_contacts 8 | 9 | RepoType: git 10 | Repo: https://github.com/BillDietrich/fake_contacts 11 | 12 | Builds: 13 | - versionName: '1.8' 14 | versionCode: 4 15 | commit: v1.8 16 | output: build/app/outputs/apk/release/app-release.apk 17 | srclibs: 18 | - flutter@1.26.0-12.0.pre 19 | rm: 20 | - ios 21 | - test 22 | - integration_test 23 | prebuild: echo 'android.applicationVariants.all { variant -> variant.outputs.all 24 | { output -> outputFileName = "app-${output.baseName}.apk" } }' >> android/app/build.gradle 25 | build: 26 | - $$flutter$$/bin/flutter config --no-analytics 27 | - $$flutter$$/bin/flutter packages pub get 28 | - $$flutter$$/bin/flutter build apk 29 | 30 | AutoUpdateMode: Version v%v 31 | UpdateCheckMode: HTTP 32 | UpdateCheckData: https://raw.githubusercontent.com/BillDietrich/fake_contacts/master/pubspec.yaml|version:\s.+\+(\d+)|.|version:\s(.+)\+ 33 | CurrentVersion: '1.8' 34 | CurrentVersionCode: 4 35 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: transitive 6 | description: 7 | name: archive 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "3.0.0" 11 | async: 12 | dependency: transitive 13 | description: 14 | name: async 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.5.0" 18 | boolean_selector: 19 | dependency: transitive 20 | description: 21 | name: boolean_selector 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.1.0" 25 | characters: 26 | dependency: transitive 27 | description: 28 | name: characters 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.1.0" 32 | charcode: 33 | dependency: transitive 34 | description: 35 | name: charcode 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.2.0" 39 | clock: 40 | dependency: transitive 41 | description: 42 | name: clock 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.1.0" 46 | collection: 47 | dependency: transitive 48 | description: 49 | name: collection 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.15.0" 53 | contacts_service: 54 | dependency: "direct main" 55 | description: 56 | name: contacts_service 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "0.4.6" 60 | crypto: 61 | dependency: transitive 62 | description: 63 | name: crypto 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "3.0.0" 67 | cupertino_icons: 68 | dependency: "direct main" 69 | description: 70 | name: cupertino_icons 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "1.0.2" 74 | fake_async: 75 | dependency: transitive 76 | description: 77 | name: fake_async 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "1.2.0" 81 | ffi: 82 | dependency: transitive 83 | description: 84 | name: ffi 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "0.1.3" 88 | file: 89 | dependency: transitive 90 | description: 91 | name: file 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "6.1.0" 95 | flutter: 96 | dependency: "direct main" 97 | description: flutter 98 | source: sdk 99 | version: "0.0.0" 100 | flutter_driver: 101 | dependency: transitive 102 | description: flutter 103 | source: sdk 104 | version: "0.0.0" 105 | flutter_test: 106 | dependency: "direct dev" 107 | description: flutter 108 | source: sdk 109 | version: "0.0.0" 110 | flutter_web_plugins: 111 | dependency: transitive 112 | description: flutter 113 | source: sdk 114 | version: "0.0.0" 115 | fuchsia_remote_debug_protocol: 116 | dependency: transitive 117 | description: flutter 118 | source: sdk 119 | version: "0.0.0" 120 | integration_test: 121 | dependency: "direct dev" 122 | description: flutter 123 | source: sdk 124 | version: "0.0.0" 125 | js: 126 | dependency: transitive 127 | description: 128 | name: js 129 | url: "https://pub.dartlang.org" 130 | source: hosted 131 | version: "0.6.3" 132 | matcher: 133 | dependency: transitive 134 | description: 135 | name: matcher 136 | url: "https://pub.dartlang.org" 137 | source: hosted 138 | version: "0.12.10" 139 | meta: 140 | dependency: transitive 141 | description: 142 | name: meta 143 | url: "https://pub.dartlang.org" 144 | source: hosted 145 | version: "1.3.0" 146 | path: 147 | dependency: transitive 148 | description: 149 | name: path 150 | url: "https://pub.dartlang.org" 151 | source: hosted 152 | version: "1.8.0" 153 | path_provider_linux: 154 | dependency: transitive 155 | description: 156 | name: path_provider_linux 157 | url: "https://pub.dartlang.org" 158 | source: hosted 159 | version: "0.0.1+2" 160 | path_provider_platform_interface: 161 | dependency: transitive 162 | description: 163 | name: path_provider_platform_interface 164 | url: "https://pub.dartlang.org" 165 | source: hosted 166 | version: "1.0.4" 167 | path_provider_windows: 168 | dependency: transitive 169 | description: 170 | name: path_provider_windows 171 | url: "https://pub.dartlang.org" 172 | source: hosted 173 | version: "0.0.4+3" 174 | permission_handler: 175 | dependency: "direct main" 176 | description: 177 | name: permission_handler 178 | url: "https://pub.dartlang.org" 179 | source: hosted 180 | version: "5.0.1+1" 181 | permission_handler_platform_interface: 182 | dependency: transitive 183 | description: 184 | name: permission_handler_platform_interface 185 | url: "https://pub.dartlang.org" 186 | source: hosted 187 | version: "2.0.1" 188 | platform: 189 | dependency: transitive 190 | description: 191 | name: platform 192 | url: "https://pub.dartlang.org" 193 | source: hosted 194 | version: "3.0.0" 195 | plugin_platform_interface: 196 | dependency: transitive 197 | description: 198 | name: plugin_platform_interface 199 | url: "https://pub.dartlang.org" 200 | source: hosted 201 | version: "1.0.3" 202 | process: 203 | dependency: transitive 204 | description: 205 | name: process 206 | url: "https://pub.dartlang.org" 207 | source: hosted 208 | version: "4.1.0" 209 | quiver: 210 | dependency: transitive 211 | description: 212 | name: quiver 213 | url: "https://pub.dartlang.org" 214 | source: hosted 215 | version: "2.1.5" 216 | shared_preferences: 217 | dependency: "direct main" 218 | description: 219 | name: shared_preferences 220 | url: "https://pub.dartlang.org" 221 | source: hosted 222 | version: "0.5.12+4" 223 | shared_preferences_linux: 224 | dependency: transitive 225 | description: 226 | name: shared_preferences_linux 227 | url: "https://pub.dartlang.org" 228 | source: hosted 229 | version: "0.0.2+4" 230 | shared_preferences_macos: 231 | dependency: transitive 232 | description: 233 | name: shared_preferences_macos 234 | url: "https://pub.dartlang.org" 235 | source: hosted 236 | version: "0.0.1+11" 237 | shared_preferences_platform_interface: 238 | dependency: transitive 239 | description: 240 | name: shared_preferences_platform_interface 241 | url: "https://pub.dartlang.org" 242 | source: hosted 243 | version: "1.0.4" 244 | shared_preferences_web: 245 | dependency: transitive 246 | description: 247 | name: shared_preferences_web 248 | url: "https://pub.dartlang.org" 249 | source: hosted 250 | version: "0.1.2+7" 251 | shared_preferences_windows: 252 | dependency: transitive 253 | description: 254 | name: shared_preferences_windows 255 | url: "https://pub.dartlang.org" 256 | source: hosted 257 | version: "0.0.2+2" 258 | sky_engine: 259 | dependency: transitive 260 | description: flutter 261 | source: sdk 262 | version: "0.0.99" 263 | source_span: 264 | dependency: transitive 265 | description: 266 | name: source_span 267 | url: "https://pub.dartlang.org" 268 | source: hosted 269 | version: "1.8.1" 270 | stack_trace: 271 | dependency: transitive 272 | description: 273 | name: stack_trace 274 | url: "https://pub.dartlang.org" 275 | source: hosted 276 | version: "1.10.0" 277 | stream_channel: 278 | dependency: transitive 279 | description: 280 | name: stream_channel 281 | url: "https://pub.dartlang.org" 282 | source: hosted 283 | version: "2.1.0" 284 | string_scanner: 285 | dependency: transitive 286 | description: 287 | name: string_scanner 288 | url: "https://pub.dartlang.org" 289 | source: hosted 290 | version: "1.1.0" 291 | sync_http: 292 | dependency: transitive 293 | description: 294 | name: sync_http 295 | url: "https://pub.dartlang.org" 296 | source: hosted 297 | version: "0.3.0" 298 | term_glyph: 299 | dependency: transitive 300 | description: 301 | name: term_glyph 302 | url: "https://pub.dartlang.org" 303 | source: hosted 304 | version: "1.2.0" 305 | test_api: 306 | dependency: transitive 307 | description: 308 | name: test_api 309 | url: "https://pub.dartlang.org" 310 | source: hosted 311 | version: "0.2.19" 312 | typed_data: 313 | dependency: transitive 314 | description: 315 | name: typed_data 316 | url: "https://pub.dartlang.org" 317 | source: hosted 318 | version: "1.3.0" 319 | vector_math: 320 | dependency: transitive 321 | description: 322 | name: vector_math 323 | url: "https://pub.dartlang.org" 324 | source: hosted 325 | version: "2.1.0" 326 | vm_service: 327 | dependency: transitive 328 | description: 329 | name: vm_service 330 | url: "https://pub.dartlang.org" 331 | source: hosted 332 | version: "6.0.1-nullsafety.1" 333 | webdriver: 334 | dependency: transitive 335 | description: 336 | name: webdriver 337 | url: "https://pub.dartlang.org" 338 | source: hosted 339 | version: "3.0.0" 340 | win32: 341 | dependency: transitive 342 | description: 343 | name: win32 344 | url: "https://pub.dartlang.org" 345 | source: hosted 346 | version: "1.7.4" 347 | xdg_directories: 348 | dependency: transitive 349 | description: 350 | name: xdg_directories 351 | url: "https://pub.dartlang.org" 352 | source: hosted 353 | version: "0.1.2" 354 | sdks: 355 | dart: ">=2.12.0-0.0 <3.0.0" 356 | flutter: ">=1.12.13+hotfix.5" 357 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: fake_contacts 2 | description: Create fake phone contacts to do data-poisoning 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.8+4 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | contacts_service: ^0.4.6 27 | permission_handler: ^5.0.1+1 28 | shared_preferences: ">=0.5.0 <2.0.0" 29 | 30 | 31 | # The following adds the Cupertino Icons font to your application. 32 | # Use with the CupertinoIcons class for iOS style icons. 33 | cupertino_icons: ^1.0.1 34 | 35 | dev_dependencies: 36 | flutter_test: 37 | sdk: flutter 38 | integration_test: 39 | sdk: flutter 40 | 41 | # For information on the generic Dart part of this file, see the 42 | # following page: https://dart.dev/tools/pub/pubspec 43 | 44 | # The following section is specific to Flutter. 45 | flutter: 46 | 47 | # The following line ensures that the Material Icons font is 48 | # included with your application, so that you can use the icons in 49 | # the material Icons class. 50 | uses-material-design: true 51 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:fake_contacts/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | --------------------------------------------------------------------------------