├── android
├── gradle.properties
├── .settings
│ └── org.eclipse.buildship.core.prefs
├── app
│ ├── .settings
│ │ └── org.eclipse.buildship.core.prefs
│ ├── src
│ │ └── main
│ │ │ ├── res
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── launch_image.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── launch_image.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── launch_image.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── launch_image.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── launch_image.png
│ │ │ ├── values
│ │ │ │ └── styles.xml
│ │ │ └── drawable
│ │ │ │ └── launch_background.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── watchtips
│ │ │ │ └── MainActivity.java
│ │ │ └── AndroidManifest.xml
│ ├── .classpath
│ ├── .project
│ └── build.gradle
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
├── .project
├── settings.gradle
└── build.gradle
├── ios
├── Flutter
│ ├── Debug.xcconfig
│ ├── Release.xcconfig
│ └── AppFrameworkInfo.plist
├── Runner
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── Icon.png
│ │ │ ├── Icon-40.png
│ │ │ ├── Icon-72.png
│ │ │ ├── Icon-76.png
│ │ │ ├── Icon@2x.png
│ │ │ ├── Icon-40@2x.png
│ │ │ ├── Icon-40@3x.png
│ │ │ ├── Icon-60@2x.png
│ │ │ ├── Icon-60@3x.png
│ │ │ ├── Icon-72@2x.png
│ │ │ ├── Icon-76@2x.png
│ │ │ ├── Icon-Small.png
│ │ │ ├── Icon-83.5@2x.png
│ │ │ ├── Icon-Small-50.png
│ │ │ ├── Icon-Small@2x.png
│ │ │ ├── Icon-Small@3x.png
│ │ │ ├── ios-marketing.png
│ │ │ ├── Icon-Small-50@2x.png
│ │ │ ├── NotificationIcon@2x.png
│ │ │ ├── NotificationIcon@3x.png
│ │ │ ├── NotificationIcon~ipad.png
│ │ │ ├── NotificationIcon~ipad@2x.png
│ │ │ └── Contents.json
│ │ └── watchtipssplash.imageset
│ │ │ ├── watchtipssplash.png
│ │ │ └── Contents.json
│ ├── main.m
│ ├── AppDelegate.h
│ ├── Base.lproj
│ │ ├── Main.storyboard
│ │ └── LaunchScreen.storyboard
│ ├── Info.plist
│ └── AppDelegate.m
├── WatchTips
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ ├── Icon38mm@2x.png
│ │ │ ├── Icon40mm@2x.png
│ │ │ ├── Icon42mm@2x.png
│ │ │ ├── Icon44mm@2x.png
│ │ │ ├── IconLauncher@2x.png
│ │ │ ├── IconSettings@2x.png
│ │ │ ├── IconSettings@3x.png
│ │ │ ├── watch-marketing.png
│ │ │ ├── IconQuickLook38mm@2x.png
│ │ │ ├── IconQuickLook42mm@2x.png
│ │ │ ├── IconQuickLook44mm@2x.png
│ │ │ └── Contents.json
│ ├── Info.plist
│ └── Base.lproj
│ │ └── Interface.storyboard
├── WatchTips Extension
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ └── Complication.complicationset
│ │ │ ├── Circular.imageset
│ │ │ └── Contents.json
│ │ │ ├── Modular.imageset
│ │ │ └── Contents.json
│ │ │ ├── Extra Large.imageset
│ │ │ └── Contents.json
│ │ │ ├── Graphic Bezel.imageset
│ │ │ └── Contents.json
│ │ │ ├── Utilitarian.imageset
│ │ │ └── Contents.json
│ │ │ ├── Graphic Circular.imageset
│ │ │ └── Contents.json
│ │ │ ├── Graphic Corner.imageset
│ │ │ └── Contents.json
│ │ │ ├── Graphic Large Rectangular.imageset
│ │ │ └── Contents.json
│ │ │ └── Contents.json
│ ├── Info.plist
│ ├── ExtensionDelegate.swift
│ ├── InterfaceController.swift
│ └── BillController.swift
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── Runner.xcodeproj
│ ├── project.xcworkspace
│ └── contents.xcworkspacedata
│ ├── xcshareddata
│ └── xcschemes
│ │ └── Runner.xcscheme
│ └── project.pbxproj
├── screenshots
└── watchtips.png
├── .metadata
├── lib
├── colors.dart
├── widgets
│ ├── key.dart
│ └── scaleroute.dart
├── main.dart
├── numberpad.dart
└── homescreen.dart
├── test
└── widget_test.dart
├── .gitignore
├── pubspec.yaml
└── README.md
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Generated.xcconfig"
2 |
--------------------------------------------------------------------------------
/android/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/android/app/.settings/org.eclipse.buildship.core.prefs:
--------------------------------------------------------------------------------
1 | connection.project.dir=..
2 | eclipse.preferences.version=1
3 |
--------------------------------------------------------------------------------
/screenshots/watchtips.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/screenshots/watchtips.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/launch_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/android/app/src/main/res/mipmap-hdpi/launch_image.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/launch_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/android/app/src/main/res/mipmap-mdpi/launch_image.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/launch_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/android/app/src/main/res/mipmap-xhdpi/launch_image.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/launch_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/android/app/src/main/res/mipmap-xxhdpi/launch_image.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/launch_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/android/app/src/main/res/mipmap-xxxhdpi/launch_image.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-40.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-72.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-76.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-72@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small-50.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/ios-marketing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/ios-marketing.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/Icon38mm@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/Icon38mm@2x.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/Icon40mm@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/Icon40mm@2x.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/Icon42mm@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/Icon42mm@2x.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/Icon44mm@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/Icon44mm@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-Small-50@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/NotificationIcon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/NotificationIcon@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/NotificationIcon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/NotificationIcon@3x.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconLauncher@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconLauncher@2x.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconSettings@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconSettings@2x.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconSettings@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconSettings@3x.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/watch-marketing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/watch-marketing.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/watchtipssplash.imageset/watchtipssplash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/watchtipssplash.imageset/watchtipssplash.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/NotificationIcon~ipad@2x.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconQuickLook38mm@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconQuickLook38mm@2x.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconQuickLook42mm@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconQuickLook42mm@2x.png
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconQuickLook44mm@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/magnatronus/flutter-watchtips/HEAD/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/IconQuickLook44mm@2x.png
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.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: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/android/app/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "scale" : "2x",
6 | "screen-width" : "<=145"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "scale" : "2x",
11 | "screen-width" : ">145"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "scale" : "2x",
6 | "screen-width" : "<=145"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "scale" : "2x",
11 | "screen-width" : ">145"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "scale" : "2x",
6 | "screen-width" : "<=145"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "scale" : "2x",
11 | "screen-width" : ">145"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "scale" : "2x",
6 | "screen-width" : "<=145"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "scale" : "2x",
11 | "screen-width" : ">145"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "scale" : "2x",
6 | "screen-width" : "<=145"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "scale" : "2x",
11 | "screen-width" : ">145"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "scale" : "2x",
6 | "screen-width" : "<=145"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "scale" : "2x",
11 | "screen-width" : ">145"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "scale" : "2x",
6 | "screen-width" : "<=145"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "scale" : "2x",
11 | "screen-width" : ">145"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "watch",
5 | "scale" : "2x",
6 | "screen-width" : "<=145"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "scale" : "2x",
11 | "screen-width" : ">145"
12 | }
13 | ],
14 | "info" : {
15 | "version" : 1,
16 | "author" : "xcode"
17 | }
18 | }
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 |
6 | @interface WTUserInfoHandler : NSObject
7 | @end
8 |
9 | // Modified to add the Watch Session Delegate
10 | @interface AppDelegate : FlutterAppDelegate {
11 | @private
12 | WCSession *watchSession;
13 | WTUserInfoHandler* userInfoStreamHandler;
14 | }
15 | @end
16 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/watchtipssplash.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "watchtipssplash.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/lib/colors.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | /// This defines the colours used in the app
4 | const appPrimaryColor = Color(0xFF000000);//Color(0xFFE6E6E6);
5 | const appScaffoldColor = Color(0xFF000000);//Color(0xFFE6E6E6);
6 | const accentTextColor = Color(0xFFFC6666);
7 | const appPrimaryTextColor = Color(0xFFFFFFFF);
8 | const appTextColor = Colors.grey;//Color(0xFF333333); //Color(0xFFFECC66);
9 | const appButtonColor = Color(0xFF7F7F7F);
10 | const appPrimaryButtonColor = Colors.orange;
11 |
--------------------------------------------------------------------------------
/android/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | android
4 | Project android created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.buildship.core.gradleprojectbuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.buildship.core.gradleprojectnature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | -
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/app/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | app
4 | Project app created by Buildship.
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.buildship.core.gradleprojectbuilder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.buildship.core.gradleprojectnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/lib/widgets/key.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 |
4 | class RoundKey extends StatelessWidget {
5 |
6 | final String value;
7 | final Color color;
8 | final Function onPressed;
9 |
10 | RoundKey(this.value, {@required this.onPressed, this.color: Colors.grey});
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | return Padding(
15 | padding: EdgeInsets.all(5.0),
16 | child: RaisedButton(
17 | color: color,
18 | shape: RoundedRectangleBorder(
19 | borderRadius: new BorderRadius.circular(35.0),
20 | ),
21 | onPressed: () {
22 | onPressed(value);
23 | },
24 | child: Text(
25 | value,
26 | style: Theme.of(context).primaryTextTheme.headline
27 | ),
28 | ),
29 | );
30 | }
31 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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:watchtips/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 |
--------------------------------------------------------------------------------
/ios/WatchTips/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | watch tips
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | UISupportedInterfaceOrientations
24 |
25 | UIInterfaceOrientationPortrait
26 | UIInterfaceOrientationPortraitUpsideDown
27 |
28 | WKCompanionAppBundleIdentifier
29 | uk.spiralarm.tipcalculator
30 | WKWatchKitApp
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Assets.xcassets/Complication.complicationset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "assets" : [
3 | {
4 | "idiom" : "watch",
5 | "filename" : "Circular.imageset",
6 | "role" : "circular"
7 | },
8 | {
9 | "idiom" : "watch",
10 | "filename" : "Extra Large.imageset",
11 | "role" : "extra-large"
12 | },
13 | {
14 | "idiom" : "watch",
15 | "filename" : "Graphic Bezel.imageset",
16 | "role" : "graphic-bezel"
17 | },
18 | {
19 | "idiom" : "watch",
20 | "filename" : "Graphic Circular.imageset",
21 | "role" : "graphic-circular"
22 | },
23 | {
24 | "idiom" : "watch",
25 | "filename" : "Graphic Corner.imageset",
26 | "role" : "graphic-corner"
27 | },
28 | {
29 | "idiom" : "watch",
30 | "filename" : "Graphic Large Rectangular.imageset",
31 | "role" : "graphic-large-rectangular"
32 | },
33 | {
34 | "idiom" : "watch",
35 | "filename" : "Modular.imageset",
36 | "role" : "modular"
37 | },
38 | {
39 | "idiom" : "watch",
40 | "filename" : "Utilitarian.imageset",
41 | "role" : "utilitarian"
42 | }
43 | ],
44 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/ios/WatchTips Extension/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | WatchTips Extension
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | XPC!
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | NSExtension
24 |
25 | NSExtensionAttributes
26 |
27 | WKAppBundleIdentifier
28 | uk.spiralarm.tipcalculator.watchkitapp
29 |
30 | NSExtensionPointIdentifier
31 | com.apple.watchkit
32 |
33 | WKExtensionDelegateClassName
34 | $(PRODUCT_MODULE_NAME).ExtensionDelegate
35 |
36 |
37 |
--------------------------------------------------------------------------------
/lib/widgets/scaleroute.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | /// Navigator Route that scale the specified widget up and down
4 | class ScaleRoute extends PageRouteBuilder {
5 | final Widget widget;
6 |
7 | ScaleRoute({this.widget})
8 | : super(pageBuilder: (BuildContext context, Animation animation,
9 | Animation secondaryAnimation) {
10 | return widget;
11 | }, transitionsBuilder: (BuildContext context,
12 | Animation animation,
13 | Animation secondaryAnimation,
14 | Widget child) {
15 | return ScaleTransition(
16 | scale: Tween(
17 | begin: 0.0,
18 | end: 1.0,
19 | ).animate(
20 | CurvedAnimation(
21 | parent: animation,
22 | curve: Interval(
23 | 0.00,
24 | 0.50,
25 | curve: Curves.elasticIn,
26 | ),
27 | ),
28 | ),
29 | child: ScaleTransition(
30 | scale: Tween(
31 | begin: 0.5,
32 | end: 1.0,
33 | ).animate(
34 | CurvedAnimation(
35 | parent: animation,
36 | curve: Interval(
37 | 0.50,
38 | 1.00,
39 | curve: Curves.decelerate,
40 | ),
41 | ),
42 | ),
43 | child: child,
44 | ),
45 | );
46 | });
47 | }
48 |
--------------------------------------------------------------------------------
/android/app/src/main/java/com/example/watchtips/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example.watchtips;
2 |
3 | import android.os.Bundle;
4 | import io.flutter.app.FlutterActivity;
5 | import io.flutter.plugins.GeneratedPluginRegistrant;
6 | import io.flutter.plugin.common.MethodCall;
7 | import io.flutter.plugin.common.MethodChannel;
8 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
9 | import io.flutter.plugin.common.MethodChannel.Result;
10 | import android.content.res.Resources;
11 | import android.os.LocaleList;
12 | import java.util.*;
13 |
14 |
15 | public class MainActivity extends FlutterActivity {
16 | @Override
17 | protected void onCreate(Bundle savedInstanceState) {
18 | super.onCreate(savedInstanceState);
19 | GeneratedPluginRegistrant.registerWith(this);
20 | new MethodChannel(getFlutterView(), "uk.spiralarm.watchtips/tipinfo").setMethodCallHandler(
21 | new MethodCallHandler() {
22 | @Override
23 | public void onMethodCall(MethodCall call, Result result) {
24 | if (call.method.equals("preferredLanguages")) {
25 | result.success(getPreferredLanguages());
26 | } else {
27 | result.notImplemented();
28 | }
29 | }
30 | });
31 | }
32 |
33 | private List getPreferredLanguages() {
34 | LocaleList list = Resources.getSystem().getConfiguration().getLocales().getAdjustedDefault();
35 | List result = new ArrayList();
36 | for(int i=0; i
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 | en
7 | CFBundleDisplayName
8 | Watch Tips
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | watchtips
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UIBackgroundModes
28 |
29 | fetch
30 | remote-notification
31 |
32 | UILaunchStoryboardName
33 | LaunchScreen
34 | UIMainStoryboardFile
35 | Main
36 | UISupportedInterfaceOrientations
37 |
38 | UIInterfaceOrientationPortrait
39 |
40 | UISupportedInterfaceOrientations~ipad
41 |
42 | UIInterfaceOrientationPortrait
43 | UIInterfaceOrientationPortraitUpsideDown
44 | UIInterfaceOrientationLandscapeLeft
45 | UIInterfaceOrientationLandscapeRight
46 |
47 | UIViewControllerBasedStatusBarAppearance
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
10 |
11 |
16 |
20 |
27 |
31 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'homescreen.dart';
4 | import 'colors.dart';
5 |
6 | /// Kick the Tyres and Light the Fires
7 | void main() {
8 | SystemChrome.setPreferredOrientations([
9 | DeviceOrientation.portraitUp,
10 | DeviceOrientation.portraitDown,
11 | ]);
12 | runApp(TipCalculator());
13 | }
14 |
15 | class TipCalculator extends StatelessWidget {
16 | @override
17 | Widget build(BuildContext context) {
18 | return MaterialApp(
19 | debugShowCheckedModeBanner: false,
20 | title: 'Tip Calculator',
21 | home: HomeScreen(),
22 | theme: _buildAppTheme(),
23 | );
24 | }
25 |
26 | /// Define a modified theme for the app
27 | ThemeData _buildAppTheme() {
28 | final ThemeData base = ThemeData.light();
29 | return base.copyWith(
30 | primaryColor: appPrimaryColor,
31 | backgroundColor: Colors.yellow,
32 | scaffoldBackgroundColor: appScaffoldColor,
33 | textSelectionColor: appPrimaryTextColor,
34 | cursorColor: appPrimaryTextColor,
35 |
36 | textTheme: base.textTheme.apply(
37 | bodyColor: appTextColor,
38 | displayColor: appTextColor,
39 | ),
40 |
41 | primaryTextTheme: base.primaryTextTheme.apply(
42 | bodyColor: appPrimaryTextColor,
43 | displayColor: appPrimaryTextColor,
44 | ),
45 |
46 | accentTextTheme: base.primaryTextTheme.apply(
47 | bodyColor: accentTextColor,
48 | displayColor: accentTextColor,
49 | ),
50 |
51 | buttonTheme: base.buttonTheme.copyWith(
52 | buttonColor: appButtonColor,
53 | textTheme: ButtonTextTheme.primary
54 | ),
55 |
56 | iconTheme: base.iconTheme.copyWith(
57 | color: appPrimaryButtonColor,
58 | ),
59 |
60 | /*
61 | inputDecorationTheme: InputDecorationTheme(
62 | labelStyle: TextStyle(color: appTextColor, fontSize: 25.0),
63 | enabledBorder: const OutlineInputBorder(
64 | borderSide: const BorderSide(color: appPrimaryTextColor, width: 2.0),
65 | ),
66 | focusedBorder: const OutlineInputBorder(
67 | borderSide: const BorderSide(color: appPrimaryTextColor, width: 2.0),
68 | ),
69 | ),
70 | */
71 |
72 | );
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/ios/WatchTips/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Icon38mm@2x.png",
5 | "role" : "notificationCenter",
6 | "subtype" : "38mm",
7 | "scale" : "2x",
8 | "idiom" : "watch",
9 | "size" : "24x24"
10 | },
11 | {
12 | "filename" : "Icon42mm@2x.png",
13 | "role" : "notificationCenter",
14 | "subtype" : "42mm",
15 | "scale" : "2x",
16 | "idiom" : "watch",
17 | "size" : "27.5x27.5"
18 | },
19 | {
20 | "filename" : "IconSettings@2x.png",
21 | "scale" : "2x",
22 | "role" : "companionSettings",
23 | "idiom" : "watch",
24 | "size" : "29x29"
25 | },
26 | {
27 | "filename" : "IconSettings@3x.png",
28 | "scale" : "3x",
29 | "role" : "companionSettings",
30 | "idiom" : "watch",
31 | "size" : "29x29"
32 | },
33 | {
34 | "filename" : "IconLauncher@2x.png",
35 | "role" : "appLauncher",
36 | "subtype" : "38mm",
37 | "scale" : "2x",
38 | "idiom" : "watch",
39 | "size" : "40x40"
40 | },
41 | {
42 | "filename" : "IconQuickLook38mm@2x.png",
43 | "role" : "quickLook",
44 | "subtype" : "38mm",
45 | "scale" : "2x",
46 | "idiom" : "watch",
47 | "size" : "86x86"
48 | },
49 | {
50 | "filename" : "IconQuickLook42mm@2x.png",
51 | "role" : "quickLook",
52 | "subtype" : "42mm",
53 | "scale" : "2x",
54 | "idiom" : "watch",
55 | "size" : "98x98"
56 | },
57 | {
58 | "filename" : "watch-marketing.png",
59 | "scale" : "1x",
60 | "idiom" : "watch-marketing",
61 | "size" : "1024x1024"
62 | },
63 | {
64 | "filename" : "Icon40mm@2x.png",
65 | "role" : "appLauncher",
66 | "subtype" : "40mm",
67 | "scale" : "2x",
68 | "idiom" : "watch",
69 | "size" : "44x44"
70 | },
71 | {
72 | "filename" : "Icon44mm@2x.png",
73 | "role" : "appLauncher",
74 | "subtype" : "44mm",
75 | "scale" : "2x",
76 | "idiom" : "watch",
77 | "size" : "50x50"
78 | },
79 | {
80 | "filename" : "IconQuickLook44mm@2x.png",
81 | "role" : "quickLook",
82 | "subtype" : "44mm",
83 | "scale" : "2x",
84 | "idiom" : "watch",
85 | "size" : "108x108"
86 | }
87 | ],
88 | "info" : {
89 | "author" : "xcode",
90 | "version" : 1
91 | }
92 | }
--------------------------------------------------------------------------------
/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 | def keystoreProperties = new Properties()
28 | def keystorePropertiesFile = rootProject.file('key.properties')
29 | if (keystorePropertiesFile.exists()) {
30 | keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
31 | }
32 |
33 | android {
34 | compileSdkVersion 27
35 |
36 | lintOptions {
37 | disable 'InvalidPackage'
38 | }
39 |
40 | defaultConfig {
41 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
42 | applicationId "uk.spiralarm.tipcalculator"
43 | minSdkVersion 16
44 | targetSdkVersion 27
45 | versionCode flutterVersionCode.toInteger()
46 | versionName flutterVersionName
47 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
48 | }
49 |
50 | signingConfigs {
51 | release {
52 | keyAlias keystoreProperties['keyAlias']
53 | keyPassword keystoreProperties['keyPassword']
54 | storeFile file(keystoreProperties['storeFile'])
55 | storePassword keystoreProperties['storePassword']
56 | }
57 | }
58 | buildTypes {
59 | release {
60 | signingConfig signingConfigs.release
61 | }
62 | }
63 | }
64 |
65 | flutter {
66 | source '../..'
67 | }
68 |
69 | dependencies {
70 | testImplementation 'junit:junit:4.12'
71 | androidTestImplementation 'com.android.support.test:runner:1.0.2'
72 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
73 | }
74 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: watchtips
2 | description: A Combined Flutter iOS and watchOS app, now with iPad and Android support
3 |
4 | # The following defines the version and build number for your application.
5 | # A version number is three numbers separated by dots, like 1.2.43
6 | # followed by an optional build number separated by a +.
7 | # Both the version and the builder number may be overridden in flutter
8 | # build by specifying --build-name and --build-number, respectively.
9 | # Read more about versioning at semver.org.
10 | version: 2.2.0+1
11 |
12 | environment:
13 | sdk: ">=2.0.0-dev.68.0 <3.0.0"
14 |
15 | dependencies:
16 | flutter:
17 | sdk: flutter
18 |
19 | # The following adds the Cupertino Icons font to your application.
20 | # Use with the CupertinoIcons class for iOS style icons.
21 | cupertino_icons: ^0.1.2
22 | intl: ^0.15.7
23 |
24 | dev_dependencies:
25 | flutter_test:
26 | sdk: flutter
27 |
28 |
29 | # For information on the generic Dart part of this file, see the
30 | # following page: https://www.dartlang.org/tools/pub/pubspec
31 |
32 | # The following section is specific to Flutter.
33 | flutter:
34 |
35 | # The following line ensures that the Material Icons font is
36 | # included with your application, so that you can use the icons in
37 | # the material Icons class.
38 | uses-material-design: true
39 |
40 | # To add assets to your application, add an assets section, like this:
41 | # assets:
42 | # - images/a_dot_burr.jpeg
43 | # - images/a_dot_ham.jpeg
44 |
45 | # An image asset can refer to one or more resolution-specific "variants", see
46 | # https://flutter.io/assets-and-images/#resolution-aware.
47 |
48 | # For details regarding adding assets from package dependencies, see
49 | # https://flutter.io/assets-and-images/#from-packages
50 |
51 | # To add custom fonts to your application, add a fonts section here,
52 | # in this "flutter" section. Each entry in this list should have a
53 | # "family" key with the font family name, and a "fonts" key with a
54 | # list giving the asset and other descriptors for the font. For
55 | # example:
56 | # fonts:
57 | # - family: Schyler
58 | # fonts:
59 | # - asset: fonts/Schyler-Regular.ttf
60 | # - asset: fonts/Schyler-Italic.ttf
61 | # style: italic
62 | # - family: Trajan Pro
63 | # fonts:
64 | # - asset: fonts/TrajanPro.ttf
65 | # - asset: fonts/TrajanPro_Bold.ttf
66 | # weight: 700
67 | #
68 | # For details regarding fonts from package dependencies,
69 | # see https://flutter.io/custom-fonts/#from-packages
70 |
--------------------------------------------------------------------------------
/ios/WatchTips Extension/ExtensionDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExtensionDelegate.swift
3 | // WatchTips Extension
4 | //
5 | // Created by Stephen Rogers on 27/01/2019.
6 | // Copyright © 2019 The Chromium Authors. All rights reserved.
7 | //
8 |
9 | import WatchKit
10 |
11 | class ExtensionDelegate: NSObject, WKExtensionDelegate {
12 |
13 | func applicationDidFinishLaunching() {
14 | // Perform any final initialization of your application.
15 | }
16 |
17 | func applicationDidBecomeActive() {
18 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
19 | }
20 |
21 | func applicationWillResignActive() {
22 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
23 | // Use this method to pause ongoing tasks, disable timers, etc.
24 | }
25 |
26 | func handle(_ backgroundTasks: Set) {
27 | // Sent when the system needs to launch the application in the background to process tasks. Tasks arrive in a set, so loop through and process each one.
28 | for task in backgroundTasks {
29 | // Use a switch statement to check the task type
30 | switch task {
31 | case let backgroundTask as WKApplicationRefreshBackgroundTask:
32 | // Be sure to complete the background task once you’re done.
33 | backgroundTask.setTaskCompletedWithSnapshot(false)
34 | case let snapshotTask as WKSnapshotRefreshBackgroundTask:
35 | // Snapshot tasks have a unique completion call, make sure to set your expiration date
36 | snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil)
37 | case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask:
38 | // Be sure to complete the connectivity task once you’re done.
39 | connectivityTask.setTaskCompletedWithSnapshot(false)
40 | case let urlSessionTask as WKURLSessionRefreshBackgroundTask:
41 | // Be sure to complete the URL session task once you’re done.
42 | urlSessionTask.setTaskCompletedWithSnapshot(false)
43 | //case let relevantShortcutTask as WKRelevantShortcutRefreshBackgroundTask:
44 | // Be sure to complete the relevant-shortcut task once you're done.
45 | // relevantShortcutTask.setTaskCompletedWithSnapshot(false)
46 | //case let intentDidRunTask as WKIntentDidRunRefreshBackgroundTask:
47 | // Be sure to complete the intent-did-run task once you're done.
48 | // intentDidRunTask.setTaskCompletedWithSnapshot(false)
49 | default:
50 | // make sure to complete unhandled task types
51 | task.setTaskCompletedWithSnapshot(false)
52 | }
53 | }
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/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 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/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/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #include "AppDelegate.h"
2 | #include "GeneratedPluginRegistrant.h"
3 |
4 |
5 | @implementation WTUserInfoHandler
6 |
7 | FlutterEventSink sink;
8 | NSDictionary *info;
9 |
10 | - (void) updateUserInfo:(nonnull NSDictionary *)userInfo{
11 | //NSLog(@"Update Recieved");
12 | if(info != userInfo){
13 | info = userInfo;
14 | if(sink!=nil){
15 | sink(@[userInfo]);
16 | }
17 | }
18 | }
19 |
20 | - (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink {
21 | //NSLog(@"Adding Flutter Listener");
22 | sink = eventSink;
23 | return nil;
24 | }
25 |
26 | - (FlutterError*)onCancelWithArguments:(id)arguments {
27 | //NSLog(@"Removing Flutter Listener");
28 | if(sink!=nil){
29 | sink = nil;
30 | }
31 | return nil;
32 | }
33 |
34 | @end
35 |
36 |
37 | @implementation AppDelegate
38 |
39 | // Event triggered when userInfo Rxd
40 | - (void)session:(nonnull WCSession *)session didReceiveUserInfo:(nonnull NSDictionary *)userInfo
41 | {
42 | if(userInfoStreamHandler != nil){
43 | [userInfoStreamHandler updateUserInfo:userInfo];
44 | }
45 | }
46 |
47 | // Method used to enable the Watch session
48 | - (void)activateSession
49 | {
50 | [self activateChannel];
51 | [self watchSession];
52 | }
53 |
54 | // create our eventChannel
55 | -(FlutterEventChannel *) activateChannel {
56 | userInfoStreamHandler = [[WTUserInfoHandler alloc] init];
57 | FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
58 | FlutterEventChannel *eventChannel = [FlutterEventChannel eventChannelWithName:@"uk.spiralarm.watchtips/tipinfo/watchdata" binaryMessenger:controller];
59 | [eventChannel setStreamHandler:(NSObject * _Nullable) userInfoStreamHandler ];
60 | return eventChannel;
61 | }
62 |
63 |
64 | // activate session
65 | - (WCSession *)watchSession
66 | {
67 | if (watchSession == nil) {
68 | if ([WCSession isSupported]) {
69 | watchSession = [WCSession defaultSession];
70 | [watchSession setDelegate:self];
71 | [watchSession activateSession];
72 | } else {
73 | NSLog(@"Error - Watch Connectivity NOT supported");
74 | }
75 | }
76 | return watchSession;
77 | }
78 |
79 | - (void)dealloc
80 | {
81 | if (watchSession != nil) {
82 | [watchSession setDelegate:nil];
83 | }
84 | }
85 |
86 | - (BOOL)application:(UIApplication *)application
87 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
88 |
89 | FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
90 | FlutterMethodChannel *tipinfoChannel = [FlutterMethodChannel
91 | methodChannelWithName:@"uk.spiralarm.watchtips/tipinfo"
92 | binaryMessenger:controller];
93 |
94 |
95 | [tipinfoChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
96 |
97 | // activate Session
98 | if([@"activateSession" isEqualToString:call.method]){
99 | [self activateSession];
100 | result(@"WatchTips Activated");
101 | }else if([@"preferredLanguages" isEqualToString:call.method]){
102 | result([NSLocale preferredLanguages]);
103 | } else {
104 | result(FlutterMethodNotImplemented);;
105 | }
106 |
107 | }];
108 |
109 | [GeneratedPluginRegistrant registerWithRegistry:self];
110 |
111 | // Override point for customization after application launch.
112 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
113 | }
114 |
115 | @end
116 |
--------------------------------------------------------------------------------
/ios/WatchTips Extension/InterfaceController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InterfaceController.swift
3 | // WatchTips Extension
4 | //
5 | // Created by Stephen Rogers on 27/01/2019.
6 | // Copyright © 2019 The Chromium Authors. All rights reserved.
7 | //
8 |
9 | import WatchKit
10 | import Foundation
11 | import WatchConnectivity
12 |
13 |
14 | class InterfaceController: WKInterfaceController, WCSessionDelegate {
15 |
16 |
17 | var tipAmount: Int = 10
18 | var splitBetween: Int = 1
19 | var billTotal = Double(0)
20 | var focusButton: Int = 0
21 |
22 | @IBOutlet var currentSplit: WKInterfaceLabel!
23 | @IBOutlet var currentTip: WKInterfaceLabel!
24 | @IBOutlet weak var billButton: WKInterfaceButton!
25 | @IBOutlet weak var currentTotal: WKInterfaceLabel!
26 | @IBOutlet weak var costEach: WKInterfaceLabel!
27 | @IBOutlet weak var withTip: WKInterfaceLabel!
28 |
29 |
30 | public func session(_ session: WCSession, activationDidCompleteWith activationState: WCSessionActivationState, error: Error?) {
31 | // This will be called when the activation of a session finishes.
32 | }
33 |
34 |
35 | override func awake(withContext context: Any?) {
36 | super.awake(withContext: context)
37 | // Configure interface objects here.
38 | updateCalc()
39 | }
40 |
41 | override func willActivate() {
42 | // This method is called when watch view controller is about to be visible to user
43 | super.willActivate()
44 | if WCSession.isSupported() {
45 | let session = WCSession.default
46 | session.delegate = self
47 | session.activate()
48 | }
49 | updateCalc()
50 | }
51 |
52 | override func didDeactivate() {
53 | // This method is called when watch view controller is no longer visible
54 | super.didDeactivate()
55 | }
56 |
57 | @IBAction func splitDecrease() {
58 | if(splitBetween > 1){
59 | splitBetween -= 1
60 | }
61 | updateCalc()
62 | }
63 |
64 | @IBAction func splitIncrease() {
65 | if(splitBetween < 99){
66 | splitBetween += 1
67 | }
68 | updateCalc()
69 | }
70 |
71 | @IBAction func tipPercentReduce() {
72 | if(tipAmount>0){
73 | tipAmount -= 1
74 | }
75 | updateCalc()
76 | }
77 |
78 | @IBAction func tipPercentIncrease() {
79 | if(tipAmount<100){
80 | tipAmount += 1
81 | }
82 | updateCalc()
83 | }
84 |
85 | @IBAction func showBillController() {
86 | presentController(withName: "BillController", context: self)
87 | }
88 |
89 |
90 | // Update the actual calculations
91 | func updateCalc(){
92 |
93 | // do bill calculations
94 | let tip = (billTotal/100) * Double(tipAmount)
95 | let billWithTip = billTotal + tip
96 | let perPerson = billWithTip / Double(splitBetween)
97 |
98 | // update display
99 | currentTip.setText("\(tipAmount)%")
100 | currentSplit.setText("\(splitBetween)")
101 | currentTotal.setText(String(format: "%.2f", billTotal))
102 | withTip.setText(String(format: "%.2f", billWithTip))
103 | costEach.setText(String(format: "%.2f", perPerson))
104 |
105 | // now see if we can sent the calc data back to the app
106 | if WCSession.isSupported() {
107 | let session = WCSession.default
108 | let calcInfo = [
109 | "tip":"\(tipAmount)",
110 | "split": "\(splitBetween)",
111 | "bill": "\(billTotal)"
112 | ] as [String : Any];
113 | session.transferUserInfo(calcInfo)
114 | }
115 | }
116 |
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/ios/WatchTips Extension/BillController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BillController.swift
3 | // WatchTips Extension
4 | //
5 | // Created by Stephen Rogers on 28/01/2019.
6 | // Copyright © 2019 The Chromium Authors. All rights reserved.
7 | //
8 |
9 | import WatchKit
10 | import Foundation
11 |
12 |
13 | class BillController: WKInterfaceController {
14 |
15 |
16 | var billValue = "0"
17 | var decimalAdded = false
18 | var sourceController: InterfaceController!
19 | @IBOutlet weak var totalAmount: WKInterfaceLabel!
20 |
21 |
22 |
23 | override func awake(withContext context: Any?) {
24 | super.awake(withContext: context)
25 |
26 | // Configure interface objects here.
27 | sourceController = context as? InterfaceController
28 | if sourceController.billTotal != 0.0 {
29 | billValue = "\(sourceController.billTotal)"
30 | } else {
31 | billValue = "0"
32 | }
33 | displayBillValue()
34 |
35 | }
36 |
37 | override func willActivate() {
38 | // This method is called when watch view controller is about to be visible to user
39 | super.willActivate()
40 | }
41 |
42 | override func didDeactivate() {
43 | // This method is called when watch view controller is no longer visible
44 | super.didDeactivate()
45 | }
46 |
47 |
48 | // Clear
49 | @IBAction func clearBtn() {
50 | billValue.remove(at: billValue.index(before: billValue.endIndex))
51 | if billValue.count == 0 {
52 | billValue = "0"
53 | }
54 | displayBillValue()
55 | }
56 |
57 |
58 | @IBAction func decimalBtn() {
59 | appendDecimal()
60 | }
61 |
62 |
63 | @IBAction func zeroBtn() {
64 | appendValue(value: 0)
65 | }
66 |
67 |
68 | @IBAction func oneBtn() {
69 | appendValue(value: 1)
70 | }
71 |
72 |
73 | @IBAction func twoBtn() {
74 | appendValue(value: 2)
75 | }
76 |
77 | @IBAction func threeBtn() {
78 | appendValue(value: 3)
79 | }
80 |
81 |
82 | @IBAction func fourBtn() {
83 | appendValue(value: 4)
84 | }
85 |
86 |
87 | @IBAction func fiveBtn() {
88 | appendValue(value: 5)
89 | }
90 |
91 |
92 | @IBAction func sixBtn() {
93 | appendValue(value: 6)
94 | }
95 |
96 |
97 | @IBAction func sevenBtn() {
98 | appendValue(value: 7)
99 | }
100 |
101 |
102 | @IBAction func eightBtn() {
103 | appendValue(value: 8)
104 | }
105 |
106 | @IBAction func nineBtn() {
107 | appendValue(value: 9)
108 | }
109 |
110 | // display the bill value and update amount in source controller
111 | func displayBillValue(){
112 | if let _ = billValue.index(of: (".")) {
113 | decimalAdded = true
114 | } else {
115 | decimalAdded = false
116 | }
117 | totalAmount.setText(billValue)
118 | sourceController.billTotal = Double(billValue)!
119 | }
120 |
121 | // Append an amount to the displayed bill
122 | func appendValue(value: Int){
123 |
124 | let stringValue = "\(value)"
125 | if(billValue == "0"){
126 | billValue = stringValue
127 | } else {
128 | billValue = billValue + stringValue
129 | }
130 | displayBillValue()
131 | }
132 |
133 | // only add decimal if not already added
134 | func appendDecimal(){
135 |
136 | // did we have a decimal?
137 | if !decimalAdded {
138 | billValue = billValue + "."
139 | }
140 |
141 | // display total
142 | displayBillValue()
143 |
144 |
145 | }
146 |
147 | }
148 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "Icon-40.png",
5 | "scale" : "1x",
6 | "idiom" : "ipad",
7 | "size" : "40x40"
8 | },
9 | {
10 | "filename" : "Icon-40@2x.png",
11 | "scale" : "2x",
12 | "idiom" : "ipad",
13 | "size" : "40x40"
14 | },
15 | {
16 | "filename" : "Icon-60@2x.png",
17 | "scale" : "2x",
18 | "idiom" : "iphone",
19 | "size" : "60x60"
20 | },
21 | {
22 | "filename" : "Icon-72.png",
23 | "scale" : "1x",
24 | "idiom" : "ipad",
25 | "size" : "72x72"
26 | },
27 | {
28 | "filename" : "Icon-72@2x.png",
29 | "scale" : "2x",
30 | "idiom" : "ipad",
31 | "size" : "72x72"
32 | },
33 | {
34 | "filename" : "Icon-76.png",
35 | "scale" : "1x",
36 | "idiom" : "ipad",
37 | "size" : "76x76"
38 | },
39 | {
40 | "filename" : "Icon-76@2x.png",
41 | "scale" : "2x",
42 | "idiom" : "ipad",
43 | "size" : "76x76"
44 | },
45 | {
46 | "filename" : "Icon-Small-50.png",
47 | "scale" : "1x",
48 | "idiom" : "ipad",
49 | "size" : "50x50"
50 | },
51 | {
52 | "filename" : "Icon-Small-50@2x.png",
53 | "scale" : "2x",
54 | "idiom" : "ipad",
55 | "size" : "50x50"
56 | },
57 | {
58 | "filename" : "Icon-Small.png",
59 | "scale" : "1x",
60 | "idiom" : "iphone",
61 | "size" : "29x29"
62 | },
63 | {
64 | "filename" : "Icon-Small@2x.png",
65 | "scale" : "2x",
66 | "idiom" : "iphone",
67 | "size" : "29x29"
68 | },
69 | {
70 | "filename" : "Icon.png",
71 | "scale" : "1x",
72 | "idiom" : "iphone",
73 | "size" : "57x57"
74 | },
75 | {
76 | "filename" : "Icon@2x.png",
77 | "scale" : "2x",
78 | "idiom" : "iphone",
79 | "size" : "57x57"
80 | },
81 | {
82 | "filename" : "Icon-Small@3x.png",
83 | "scale" : "3x",
84 | "idiom" : "iphone",
85 | "size" : "29x29"
86 | },
87 | {
88 | "filename" : "Icon-40@3x.png",
89 | "scale" : "3x",
90 | "idiom" : "iphone",
91 | "size" : "40x40"
92 | },
93 | {
94 | "filename" : "Icon-60@3x.png",
95 | "scale" : "3x",
96 | "idiom" : "iphone",
97 | "size" : "60x60"
98 | },
99 | {
100 | "filename" : "Icon-40@2x.png",
101 | "scale" : "2x",
102 | "idiom" : "iphone",
103 | "size" : "40x40"
104 | },
105 | {
106 | "filename" : "Icon-Small.png",
107 | "scale" : "1x",
108 | "idiom" : "ipad",
109 | "size" : "29x29"
110 | },
111 | {
112 | "filename" : "Icon-Small@2x.png",
113 | "scale" : "2x",
114 | "idiom" : "ipad",
115 | "size" : "29x29"
116 | },
117 | {
118 | "filename" : "Icon-83.5@2x.png",
119 | "scale" : "2x",
120 | "idiom" : "ipad",
121 | "size" : "83.5x83.5"
122 | },
123 | {
124 | "filename" : "NotificationIcon@2x.png",
125 | "scale" : "2x",
126 | "idiom" : "iphone",
127 | "size" : "20x20"
128 | },
129 | {
130 | "filename" : "NotificationIcon@3x.png",
131 | "scale" : "3x",
132 | "idiom" : "iphone",
133 | "size" : "20x20"
134 | },
135 | {
136 | "filename" : "NotificationIcon~ipad.png",
137 | "scale" : "1x",
138 | "idiom" : "ipad",
139 | "size" : "20x20"
140 | },
141 | {
142 | "filename" : "NotificationIcon~ipad@2x.png",
143 | "scale" : "2x",
144 | "idiom" : "ipad",
145 | "size" : "20x20"
146 | },
147 | {
148 | "filename" : "ios-marketing.png",
149 | "scale" : "1x",
150 | "idiom" : "ios-marketing",
151 | "size" : "1024x1024"
152 | }
153 | ],
154 | "info" : {
155 | "author" : "xcode",
156 | "version" : 1
157 | }
158 | }
--------------------------------------------------------------------------------
/lib/numberpad.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:intl/intl.dart';
3 | import 'widgets/key.dart';
4 |
5 | class NumberPad extends StatefulWidget {
6 |
7 | final TextStyle normalStyle;
8 | final TextStyle errorStyle;
9 | final double currentValue;
10 | final int digitLimit = 7;
11 |
12 | NumberPad(this.currentValue,{@required this.normalStyle, @required this.errorStyle});
13 |
14 | @override
15 | _NumberPadState createState() => _NumberPadState();
16 | }
17 |
18 | class _NumberPadState extends State {
19 |
20 | String displayedValue = "";
21 | double billValue = 0.0;
22 | TextStyle displayStyle;
23 | NumberFormat formatter = NumberFormat("##0.00");
24 |
25 | @override
26 | void initState() {
27 | super.initState();
28 | billValue = widget.currentValue;
29 | if(billValue > 0.0) {
30 | displayedValue = formatter.format(billValue);
31 | }
32 | displayStyle = widget.normalStyle;
33 | }
34 |
35 | @override
36 | Widget build(BuildContext context) {
37 | return Scaffold(
38 | body: Center(
39 | child: Container(
40 | width: 320.0,
41 | height: 500.0,
42 | child: Container(
43 | decoration: BoxDecoration(
44 | borderRadius: BorderRadius.all(Radius.circular(10.0),),
45 | ),
46 | child: Column(
47 | crossAxisAlignment: CrossAxisAlignment.stretch,
48 | children: [
49 |
50 | Padding(
51 | padding: EdgeInsets.all(10.0),
52 | child: Text(
53 | "Bill Total",
54 | textAlign: TextAlign.center,
55 | style: Theme.of(context).primaryTextTheme.display1,
56 | ),
57 | ),
58 |
59 |
60 | Card(
61 | margin: EdgeInsets.all(20.0),
62 | child: Text(
63 | displayedValue,
64 | textAlign: TextAlign.right,
65 | maxLines: 1,
66 | style: displayStyle,
67 | ),
68 | ),
69 |
70 | Expanded(
71 | child: GridView.count(
72 | primary: false,
73 | padding: const EdgeInsets.all(20.0),
74 | crossAxisSpacing: 10.0,
75 | crossAxisCount: 4,
76 | children: [
77 | RoundKey("6", onPressed: keyEntry,),
78 | RoundKey("7", onPressed: keyEntry,),
79 | RoundKey("8", onPressed: keyEntry,),
80 | RoundKey("9", onPressed: keyEntry,),
81 | RoundKey("2", onPressed: keyEntry,),
82 | RoundKey("3", onPressed: keyEntry,),
83 | RoundKey("4", onPressed: keyEntry,),
84 | RoundKey("5", onPressed: keyEntry,),
85 | RoundKey("C", color: Colors.blue, onPressed: keyEntry,),
86 | RoundKey(".", onPressed: keyEntry,),
87 | RoundKey("0", onPressed: keyEntry,),
88 | RoundKey("1", onPressed: keyEntry,),
89 | ],
90 | ),
91 | ),
92 |
93 | Padding(
94 | padding: EdgeInsets.all(10.0),
95 | child: RaisedButton(
96 | shape: RoundedRectangleBorder(
97 | borderRadius: new BorderRadius.circular(30.0),
98 | ),
99 | color: Colors.orange,
100 | onPressed: (){
101 | try{
102 | Navigator.pop(context, billValue);
103 | } catch(e) {
104 |
105 | }
106 | },
107 | child: Text(
108 | "ENTER",
109 | style: Theme.of(context).primaryTextTheme.headline,
110 | ),
111 | ),
112 | ),
113 |
114 | generateiOSCloseButton(),
115 |
116 | ],
117 | ),
118 | )
119 | ),
120 | ),
121 | );
122 | }
123 |
124 | Widget generateiOSCloseButton() {
125 | return Container(
126 | child: IconButton(
127 | iconSize: 40.0,
128 | onPressed: () {
129 | Navigator.pop(context);
130 | },
131 | icon: Icon(
132 | Icons.highlight_off,
133 | color: Colors.grey,
134 | )
135 | ),
136 | );
137 | }
138 |
139 | /// Method used to track, check and update the displayed bill total
140 | /// we have a display length limit imposed so we do not overflow the main dsplay
141 | keyEntry(value){
142 |
143 | String display = displayedValue;
144 | if(value == "C"){
145 | display = (display.length > 0)?display.substring(0, display.length -1):"";
146 | } else {
147 | if(display.length < widget.digitLimit){
148 | display += value;
149 | }
150 | }
151 |
152 | double billTotal = 0.0;
153 | if(display.length > 0){
154 | try{
155 | billTotal = double.parse(display);
156 | displayStyle = widget.normalStyle;
157 | } catch(e) {
158 | displayStyle = widget.errorStyle;
159 | }
160 | }
161 | setState((){
162 | displayedValue = display;
163 | billValue = billTotal;
164 | });
165 |
166 | }
167 |
168 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # watchtips
2 |
3 | ## Update May 2024
4 | I now have a companion demo app that has been broyght up to date and shows **simple** watchOS connectivity between Flutter and a watch app [here](https://github.com/magnatronus/basicwatch)
5 |
6 | ## Update Jul 2022
7 | As there has been no development on the codebase, and hence no app release for some time(this was really a POC). The app in the iOS app store has been withdrawn from sale by Apple.
8 |
9 | ## Update Version 2.2
10 | The Watch tips project has been updated again, The interface has been tidied up and a seperate value for the *tip* cost has been added and displayed ( a requested update).
11 | I have also added a custom 'keypad' rather than using the standard one available for the platform, hopefully the app now looks a bit better than it did - UX/UI design is not my strong point.
12 |
13 | But the biggest update is that there is now also an Android version (without Watch support). Doing this has helped a lot as I can use the Flutter Android app for development purposes so that I now have Hot Reload back (development is **good** again ....)
14 |
15 | For iOS, I still need to run/build (and fail) with the Flutter tools for iOS (this is required to generate the correct build scripts) and finish with XCode, but general dev is know easier.
16 |
17 | ## Overview
18 | This was an originally experiment to see if can use Flutter to build an iOS app with an accompanying watchOS app. My first attempts using the beta product were not successful so the idea was parked. Having now re-visited this I can now get a compiled blank watch app up and running with a Flutter app, so I will, in stages, try and re-create the WatchTips app using Flutter.
19 |
20 | If you interested in the original Titanium version is [here](https://github.com/magnatronus/Watch-Tips)
21 |
22 |
23 | 
24 |
25 |
26 | ## App Store Link
27 | Ths app is a *really simple* app and originally just created as a proof point.
28 |
29 | But for anyone interested here are the release links:
30 |
31 | - Old AppStore Link to Watch Tips (https://itunes.apple.com/us/app/watch-tips/id1205407902).
32 | - [Playstore Link](https://play.google.com/store/apps/details?id=uk.spiralarm.tipcalculator).
33 |
34 |
35 | ## Plan
36 |
37 | - *1.0* Create a vanilla Flutter app (this initial commit)
38 | - *1.1* Add a blank watch project and get it working
39 | - *1.2* Modify the watch app functionally into WatchTips
40 | - *1.3* Update the Flutter app to WatchTips
41 | - *1.4* See if I can bridge between the 2 app (as the Titanium version does)
42 | - *2.0* Tidy up both the Flutter code and the iOS project and use it to submit the app into the App Store
43 | - *2.x+* - updates and improvements
44 |
45 |
46 | ## Flutter Package Project
47 | From the results of this test project, I have started developing a Flutter Package to allow communication between a Flutter iOS app and a watch app. This should allow easier integration with some standard functionality, though it is still a pain ATM as after you add a Watch Kit target to the iOS project as Flutter run/build no longer works. This means all package testing and development then needs to be done via XCode.
48 |
49 | I have got messaging working from an iOS app to the watch via the plugin, this can be seen working in a[video here](https://butterfly-mobile.uk/flutter-and-apple-watch).
50 |
51 |
52 |
53 |
54 |
55 | ## Generating a Distro build
56 | The only way, so far, I have found of creating a distro build is following this seqence.
57 |
58 | ### Set the Bundle ID
59 | BEFORE adding the Watch Kit app target set the final bundle ID, as the Watch app and associated extension needs to use the same prefix. If not you may need to update all references BEFORE creating the final Archive.
60 |
61 | ### Change ALL the Version and Build values
62 | This **MUST** be done for each target (in this case 3), change them to **$(FLUTTER_BUILD_NAME)** and **$(FLUTTER_BUILD_NUMBER)** respectively, otherwise although the test runs work, the Archive will not unless the version numbers match.
63 |
64 | ### Run the Flutter build first
65 | This will fail, but it generates the *correct shell scripts* to enable iOS to carry out the build (*flutter build ios --release*).
66 |
67 | ### Create Archive in XCode
68 | - 1 Select Generic Device + watchOS Device as the destination
69 | - 2 Run Product -> Archive
70 | - 3 If build successful , run the Validate App
71 | - 4 If validate successful - upload to App Store!!!
72 |
73 |
74 |
75 | ## Versions
76 |
77 | ### 2.1
78 | - updated Watch and Phone UI
79 | - currency now defaults to the phone/ipad locale
80 | - package made universal, so it runs on iPad (no watch supoort)
81 |
82 | ### 2.0
83 | - first app store release
84 |
85 | ### 1.4 - Rough and Ready but Working!
86 | I have now managed to add the required code into the iOS project to allow it to communicate with Flutter and send data updates from the watch so they are reflected in the app.
87 | Basically if you do a calculation for a Tip on the watch then the data is transferred to the associated device.
88 |
89 | You need to forgive the (bad?) Objective C coding as it is not really my thing - who in their right mind thought of it in the first place anyway :-) . A lot of this was just brute force trial and error as well as a lot of searching and testing.
90 |
91 | Apart from that the difficult issue for me was that although **MethodChannel** is quite well documented, **EventChannel** is not, the only examples I found were to do with Plugin extensions, but again probably due to my dislike (due to not understanding it very well) of Objective C.
92 |
93 | I will try to create a generic plug-in later, but that will be done in Swift.
94 |
95 |
96 | ### 1.3
97 | So after a bit of a hair pulling out session I have managed to get this working. I now have a iWatch app as well as a Flutter iOS app to build and run. I have tested this by building and distribuing to a physical phone via HockeyApp. Now the bad news......
98 |
99 | I cannot use Flutter to either build the Flutter project or do the iOS release build, so I actually built the Flutter app in a seperate project then added the lib dir back into this one.
100 | This is a major pain as to do an testing, on device or simulator I need to use XCode to do all the build (i.e. no hot-reloading), but it does work.
101 |
102 | To create the AD-HOC distro of the app I again used XCode, set the target to Generic Device and Archived the project. The resulting AD-OC signed app works well.
103 |
104 | But I think the last stage will be a major hurdle as I WILL need to do all building using XCode.........
105 |
106 |
107 | ### 1.2
108 | Updated Watch app and added functioning WatchTips. Watch app can now be used to calculate Bill split and tips.
109 |
110 | ### 1.1
111 | After using XCode to define a simulator with an attached Watch Emulator the standard Vanilla app (from 1.0) was updated as follows
112 |
113 | - Set a bundle id on the iOS Runner app (u.spiralarm.watchtips)
114 | - Add a new Target in XCode (File->New->Target), a WatchKit app was selected
115 | - Untick *Include Notification Scene* and *Include Complication*
116 | - Name the product *WatchTips*
117 | - Generate 2 sets of assets (I use an app called **Asset Catalog Creator**), one for the Runner app and one for the Watch App so that both have a full set of icons.
118 | - Open the interface.storyboard for rhe WatchTips app and add a button to the screen
119 |
120 | After this I can no longer user the IDE (VSC) to start the app up in debug mode as I get the following error ( perhaps some sort of cusom build configuration is required):
121 |
122 | ```
123 | === BUILD TARGET WatchTips Extension OF PROJECT Runner WITH CONFIGURATION Debug ===
124 | target specifies product type 'com.apple.product-type.watchkit2-extension', but there's no such product type for the 'iphonesimulator' platform
125 | Could not build the application for the simulator.
126 | Error launching application on iPhone 7 with Watch 42mm.
127 | ```
128 |
129 | However, if I use XCode I can use XCode to compile the app and run the watch app on the emulator.
130 |
131 |
132 |
133 | ## Getting Started
134 |
135 | This project is a starting point for a Flutter application.
136 |
137 | A few resources to get you started if this is your first Flutter project:
138 |
139 | - [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab)
140 | - [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook)
141 |
142 | For help getting started with Flutter, view our
143 | [online documentation](https://flutter.io/docs), which offers tutorials,
144 | samples, guidance on mobile development, and a full API reference.
145 |
--------------------------------------------------------------------------------
/lib/homescreen.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io' show Platform;
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/services.dart';
5 | import 'package:intl/intl.dart';
6 | import 'numberpad.dart';
7 | import 'widgets/scaleroute.dart';
8 |
9 | class HomeScreen extends StatefulWidget {
10 | @override
11 | _HomeScreenState createState() => _HomeScreenState();
12 | }
13 |
14 | class _HomeScreenState extends State {
15 | static const platform = const MethodChannel('uk.spiralarm.watchtips/tipinfo');
16 | static const stream = const EventChannel('uk.spiralarm.watchtips/tipinfo/watchdata');
17 | StreamSubscription tipSubscription;
18 |
19 | NumberFormat formatter = NumberFormat("##0.00");
20 | TextEditingController billTotalController = TextEditingController();
21 | int tipPercent = 10, tipSplit = 1;
22 | double billTotal = 0.0;
23 | double tip = 0.0;
24 | double totalWithTip = 0.0;
25 | double totalEach = 0.0;
26 |
27 | @override
28 | void initState() {
29 | super.initState();
30 | setupDeviceLocale();
31 | if(Platform.isIOS){
32 | activateWatchConnection();
33 | }
34 | }
35 |
36 | @override
37 | void dispose() {
38 | if (tipSubscription != null) {
39 | tipSubscription.cancel();
40 | tipSubscription = null;
41 | }
42 | super.dispose();
43 | }
44 |
45 | @override
46 | Widget build(BuildContext context) {
47 | return Scaffold(
48 | appBar: AppBar(
49 | brightness: Brightness.light,
50 | centerTitle: true,
51 | elevation: 0.0,
52 | title: Text(
53 | "Tip Calculator",
54 | style: Theme.of(context).primaryTextTheme.display1,
55 | ),
56 | ),
57 | body: Container(
58 | padding: EdgeInsets.all(20.0),
59 | child: Column(
60 | children: [
61 |
62 | Row(
63 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
64 | children: [
65 |
66 | RaisedButton(
67 | elevation: 0.0,
68 | onPressed: () async {
69 | var value = await Navigator.push(
70 | context,
71 | ScaleRoute(widget: NumberPad(
72 | billTotal,
73 | normalStyle: Theme.of(context).textTheme.display2,
74 | errorStyle: Theme.of(context).accentTextTheme.display2,
75 | )),
76 | );
77 | if(value != null){
78 | calculateBill(value);
79 | }
80 | },
81 | color: Colors.orange,
82 | child: Text(
83 | "Bill Total",
84 | style: Theme.of(context).primaryTextTheme.headline,
85 | ),
86 | shape: RoundedRectangleBorder(
87 | borderRadius: new BorderRadius.circular(30.0),
88 | ),
89 | ),
90 |
91 | Text(
92 | "${formatter.format(billTotal)}",
93 | style: Theme.of(context).primaryTextTheme.headline,
94 | textAlign: TextAlign.right,
95 | ),
96 | ],
97 | ),
98 |
99 | SizedBox(height: 20.0),
100 |
101 | Row(
102 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
103 | children: [
104 | Text(
105 | "tip @ $tipPercent%",
106 | style: Theme.of(context).textTheme.headline,
107 | ),
108 | Text(
109 | "${formatter.format(tip)}",
110 | style: Theme.of(context).primaryTextTheme.headline,
111 | textAlign: TextAlign.right,
112 | ),
113 | ],
114 | ),
115 |
116 | Row(
117 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
118 | children: [
119 | Text(
120 | "Total with tip",
121 | style: Theme.of(context).textTheme.headline,
122 | ),
123 | Text(
124 | "${formatter.format(totalWithTip)}",
125 | style: Theme.of(context).primaryTextTheme.headline,
126 | textAlign: TextAlign.right,
127 | ),
128 | ],
129 | ),
130 |
131 | Container(
132 | margin: EdgeInsets.all(15.0),
133 | height: 1.0,
134 | color: Theme.of(context).textTheme.headline.color
135 | ),
136 |
137 | Row(
138 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
139 | children: [
140 | Text(
141 | "Split between",
142 | style: Theme.of(context).textTheme.headline,
143 | ),
144 | Text(
145 | "$tipSplit",
146 | style: Theme.of(context).primaryTextTheme.headline,
147 | textAlign: TextAlign.right,
148 | ),
149 | ],
150 | ),
151 |
152 | Row(
153 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
154 | children: [
155 | Text(
156 | "Cost each",
157 | style: Theme.of(context).textTheme.headline,
158 | ),
159 | Text(
160 | "${formatter.format(totalEach)}",
161 | style: Theme.of(context).primaryTextTheme.headline,
162 | textAlign: TextAlign.right,
163 | ),
164 | ],
165 | ),
166 |
167 |
168 | Container(
169 | margin: EdgeInsets.all(15.0),
170 | height: 1.0,
171 | color: Theme.of(context).textTheme.headline.color
172 | ),
173 |
174 | Expanded(
175 | child: Center(
176 | child: Column(
177 | mainAxisAlignment: MainAxisAlignment.center,
178 | children: [
179 |
180 |
181 | Row(
182 | mainAxisAlignment: MainAxisAlignment.end,
183 | children: [
184 | Text(
185 | "Tip Percentage",
186 | style: Theme.of(context).primaryTextTheme.title,
187 | textAlign: TextAlign.right,
188 | ),
189 |
190 | IconButton(
191 | iconSize: 50.0,
192 | onPressed: () {
193 | if (tipPercent > 0) {
194 | tipPercent--;
195 | calculateBill(null);
196 | }
197 | },
198 | icon: Icon(
199 | Icons.remove_circle,
200 | ),
201 | ),
202 |
203 | IconButton(
204 | iconSize: 50.0,
205 | onPressed: () {
206 | if (tipPercent < 100) {
207 | tipPercent++;
208 | calculateBill(null);
209 | }
210 | },
211 | icon: Icon(
212 | Icons.add_circle,
213 | ),
214 | ),
215 |
216 | ],
217 | ),
218 |
219 | Row(
220 | mainAxisAlignment: MainAxisAlignment.end,
221 | children: [
222 | Text(
223 | "Split between",
224 | style: Theme.of(context).primaryTextTheme.title,
225 | textAlign: TextAlign.right,
226 | ),
227 | IconButton(
228 | iconSize: 50.0,
229 | onPressed: () {
230 | if (tipSplit > 1) {
231 | tipSplit--;
232 | calculateBill(null);
233 | }
234 | },
235 | icon: Icon(
236 | Icons.remove_circle,
237 | ),
238 | ),
239 |
240 | IconButton(
241 | iconSize: 50.0,
242 | onPressed: () {
243 | if (tipSplit < 50) {
244 | tipSplit++;
245 | calculateBill(null);
246 | }
247 | },
248 | icon: Icon(
249 | Icons.add_circle,
250 | ),
251 | ),
252 |
253 | ],
254 | ),
255 |
256 | ],
257 | ),
258 | ),
259 | ),
260 |
261 | ],
262 | ),
263 |
264 | ),
265 | );
266 | }
267 |
268 | /// Simple calculation of bill amounts
269 | calculateBill(double total) {
270 | total = (total ?? billTotal);
271 | setState(() {
272 | billTotal = total;
273 | billTotalController.text = "${formatter.format(billTotal)}";
274 | tip = (total / 100) * tipPercent;
275 | totalWithTip = total + tip;
276 | totalEach = (totalWithTip / tipSplit);
277 | });
278 | }
279 |
280 | /// Active and start the connection to the Watch App
281 | activateWatchConnection() async {
282 |
283 | // Start initial Session to allow watch and iOS to swap user data
284 | await platform.invokeMethod("activateSession");
285 |
286 | // Connect up our stream so we can monitor for watch updates
287 | stream.receiveBroadcastStream().listen((value) {
288 | List result = value;
289 | if (result[0] != null) {
290 | tipPercent = int.tryParse(result[0]['tip']);
291 | tipSplit = int.tryParse(result[0]['split']);
292 | billTotal = double.tryParse(result[0]['bill']);
293 | calculateBill(null);
294 | }
295 | });
296 | }
297 |
298 | /// Get the device locale so we can correctly format the currency
299 | setupDeviceLocale() async {
300 | List locales = await platform.invokeMethod("preferredLanguages");
301 | debugPrint("$locales");
302 | if (locales.length > 0) {
303 | formatter = NumberFormat.simpleCurrency(locale: locales[0]);
304 | }
305 | billTotalController.text = formatter.format(0.0);
306 | setState(() {});
307 | }
308 | }
309 |
--------------------------------------------------------------------------------
/ios/WatchTips/Base.lproj/Interface.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
29 |
30 |
31 |
32 |
33 |
36 |
41 |
42 |
47 |
48 |
49 |
50 |
51 |
54 |
59 |
60 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
75 |
76 |
77 |
78 |
79 |
80 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
108 |
109 |
110 |
111 |
112 |
117 |
122 |
127 |
132 |
133 |
134 |
135 |
136 |
141 |
146 |
151 |
156 |
157 |
158 |
159 |
160 |
166 |
171 |
176 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
--------------------------------------------------------------------------------
/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 | 2D020CB921FEF5A100DC71C2 /* BillController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D020CB821FEF5A100DC71C2 /* BillController.swift */; };
12 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
13 | 2D69490521FDFD9600B94252 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2D69490321FDFD9600B94252 /* Interface.storyboard */; };
14 | 2D69490721FDFD9700B94252 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2D69490621FDFD9700B94252 /* Assets.xcassets */; };
15 | 2D69490E21FDFD9700B94252 /* WatchTips Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 2D69490D21FDFD9700B94252 /* WatchTips Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
16 | 2D69491321FDFD9700B94252 /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69491221FDFD9700B94252 /* InterfaceController.swift */; };
17 | 2D69491521FDFD9700B94252 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69491421FDFD9700B94252 /* ExtensionDelegate.swift */; };
18 | 2D69491721FDFD9700B94252 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2D69491621FDFD9700B94252 /* Assets.xcassets */; };
19 | 2D69491B21FDFD9700B94252 /* WatchTips.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 2D69490121FDFD9600B94252 /* WatchTips.app */; };
20 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
21 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
22 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
23 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
24 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
25 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
26 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
27 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
28 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
29 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
30 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
31 | /* End PBXBuildFile section */
32 |
33 | /* Begin PBXContainerItemProxy section */
34 | 2D69490F21FDFD9700B94252 /* PBXContainerItemProxy */ = {
35 | isa = PBXContainerItemProxy;
36 | containerPortal = 97C146E61CF9000F007C117D /* Project object */;
37 | proxyType = 1;
38 | remoteGlobalIDString = 2D69490C21FDFD9700B94252;
39 | remoteInfo = "WatchTips Extension";
40 | };
41 | 2D69491921FDFD9700B94252 /* PBXContainerItemProxy */ = {
42 | isa = PBXContainerItemProxy;
43 | containerPortal = 97C146E61CF9000F007C117D /* Project object */;
44 | proxyType = 1;
45 | remoteGlobalIDString = 2D69490021FDFD9600B94252;
46 | remoteInfo = WatchTips;
47 | };
48 | /* End PBXContainerItemProxy section */
49 |
50 | /* Begin PBXCopyFilesBuildPhase section */
51 | 2D69492021FDFD9700B94252 /* Embed App Extensions */ = {
52 | isa = PBXCopyFilesBuildPhase;
53 | buildActionMask = 2147483647;
54 | dstPath = "";
55 | dstSubfolderSpec = 13;
56 | files = (
57 | 2D69490E21FDFD9700B94252 /* WatchTips Extension.appex in Embed App Extensions */,
58 | );
59 | name = "Embed App Extensions";
60 | runOnlyForDeploymentPostprocessing = 0;
61 | };
62 | 2D69492521FDFD9700B94252 /* Embed Watch Content */ = {
63 | isa = PBXCopyFilesBuildPhase;
64 | buildActionMask = 2147483647;
65 | dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";
66 | dstSubfolderSpec = 16;
67 | files = (
68 | 2D69491B21FDFD9700B94252 /* WatchTips.app in Embed Watch Content */,
69 | );
70 | name = "Embed Watch Content";
71 | runOnlyForDeploymentPostprocessing = 0;
72 | };
73 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
74 | isa = PBXCopyFilesBuildPhase;
75 | buildActionMask = 2147483647;
76 | dstPath = "";
77 | dstSubfolderSpec = 10;
78 | files = (
79 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
80 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
81 | );
82 | name = "Embed Frameworks";
83 | runOnlyForDeploymentPostprocessing = 0;
84 | };
85 | /* End PBXCopyFilesBuildPhase section */
86 |
87 | /* Begin PBXFileReference section */
88 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
89 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
90 | 2D020CB821FEF5A100DC71C2 /* BillController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BillController.swift; sourceTree = ""; };
91 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
92 | 2D69490121FDFD9600B94252 /* WatchTips.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WatchTips.app; sourceTree = BUILT_PRODUCTS_DIR; };
93 | 2D69490421FDFD9600B94252 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; };
94 | 2D69490621FDFD9700B94252 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
95 | 2D69490821FDFD9700B94252 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
96 | 2D69490D21FDFD9700B94252 /* WatchTips Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "WatchTips Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
97 | 2D69491221FDFD9700B94252 /* InterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceController.swift; sourceTree = ""; };
98 | 2D69491421FDFD9700B94252 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = ""; };
99 | 2D69491621FDFD9700B94252 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
100 | 2D69491821FDFD9700B94252 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
101 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
102 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; };
103 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
104 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
105 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
106 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
107 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
108 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; };
109 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
110 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
111 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
112 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
113 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
114 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
115 | /* End PBXFileReference section */
116 |
117 | /* Begin PBXFrameworksBuildPhase section */
118 | 2D69490A21FDFD9700B94252 /* Frameworks */ = {
119 | isa = PBXFrameworksBuildPhase;
120 | buildActionMask = 2147483647;
121 | files = (
122 | );
123 | runOnlyForDeploymentPostprocessing = 0;
124 | };
125 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
126 | isa = PBXFrameworksBuildPhase;
127 | buildActionMask = 2147483647;
128 | files = (
129 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
130 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
131 | );
132 | runOnlyForDeploymentPostprocessing = 0;
133 | };
134 | /* End PBXFrameworksBuildPhase section */
135 |
136 | /* Begin PBXGroup section */
137 | 2D69490221FDFD9600B94252 /* WatchTips */ = {
138 | isa = PBXGroup;
139 | children = (
140 | 2D69490321FDFD9600B94252 /* Interface.storyboard */,
141 | 2D69490621FDFD9700B94252 /* Assets.xcassets */,
142 | 2D69490821FDFD9700B94252 /* Info.plist */,
143 | );
144 | path = WatchTips;
145 | sourceTree = "";
146 | };
147 | 2D69491121FDFD9700B94252 /* WatchTips Extension */ = {
148 | isa = PBXGroup;
149 | children = (
150 | 2D69491221FDFD9700B94252 /* InterfaceController.swift */,
151 | 2D69491421FDFD9700B94252 /* ExtensionDelegate.swift */,
152 | 2D69491621FDFD9700B94252 /* Assets.xcassets */,
153 | 2D69491821FDFD9700B94252 /* Info.plist */,
154 | 2D020CB821FEF5A100DC71C2 /* BillController.swift */,
155 | );
156 | path = "WatchTips Extension";
157 | sourceTree = "";
158 | };
159 | 9740EEB11CF90186004384FC /* Flutter */ = {
160 | isa = PBXGroup;
161 | children = (
162 | 2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
163 | 3B80C3931E831B6300D905FE /* App.framework */,
164 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
165 | 9740EEBA1CF902C7004384FC /* Flutter.framework */,
166 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
167 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
168 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
169 | );
170 | name = Flutter;
171 | sourceTree = "";
172 | };
173 | 97C146E51CF9000F007C117D = {
174 | isa = PBXGroup;
175 | children = (
176 | 9740EEB11CF90186004384FC /* Flutter */,
177 | 97C146F01CF9000F007C117D /* Runner */,
178 | 2D69490221FDFD9600B94252 /* WatchTips */,
179 | 2D69491121FDFD9700B94252 /* WatchTips Extension */,
180 | 97C146EF1CF9000F007C117D /* Products */,
181 | );
182 | sourceTree = "";
183 | };
184 | 97C146EF1CF9000F007C117D /* Products */ = {
185 | isa = PBXGroup;
186 | children = (
187 | 97C146EE1CF9000F007C117D /* Runner.app */,
188 | 2D69490121FDFD9600B94252 /* WatchTips.app */,
189 | 2D69490D21FDFD9700B94252 /* WatchTips Extension.appex */,
190 | );
191 | name = Products;
192 | sourceTree = "";
193 | };
194 | 97C146F01CF9000F007C117D /* Runner */ = {
195 | isa = PBXGroup;
196 | children = (
197 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
198 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
199 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
200 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
201 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
202 | 97C147021CF9000F007C117D /* Info.plist */,
203 | 97C146F11CF9000F007C117D /* Supporting Files */,
204 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
205 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
206 | );
207 | path = Runner;
208 | sourceTree = "";
209 | };
210 | 97C146F11CF9000F007C117D /* Supporting Files */ = {
211 | isa = PBXGroup;
212 | children = (
213 | 97C146F21CF9000F007C117D /* main.m */,
214 | );
215 | name = "Supporting Files";
216 | sourceTree = "";
217 | };
218 | /* End PBXGroup section */
219 |
220 | /* Begin PBXNativeTarget section */
221 | 2D69490021FDFD9600B94252 /* WatchTips */ = {
222 | isa = PBXNativeTarget;
223 | buildConfigurationList = 2D69492121FDFD9700B94252 /* Build configuration list for PBXNativeTarget "WatchTips" */;
224 | buildPhases = (
225 | 2D6948FF21FDFD9600B94252 /* Resources */,
226 | 2D69492021FDFD9700B94252 /* Embed App Extensions */,
227 | );
228 | buildRules = (
229 | );
230 | dependencies = (
231 | 2D69491021FDFD9700B94252 /* PBXTargetDependency */,
232 | );
233 | name = WatchTips;
234 | productName = WatchTips;
235 | productReference = 2D69490121FDFD9600B94252 /* WatchTips.app */;
236 | productType = "com.apple.product-type.application.watchapp2";
237 | };
238 | 2D69490C21FDFD9700B94252 /* WatchTips Extension */ = {
239 | isa = PBXNativeTarget;
240 | buildConfigurationList = 2D69491C21FDFD9700B94252 /* Build configuration list for PBXNativeTarget "WatchTips Extension" */;
241 | buildPhases = (
242 | 2D69490921FDFD9700B94252 /* Sources */,
243 | 2D69490A21FDFD9700B94252 /* Frameworks */,
244 | 2D69490B21FDFD9700B94252 /* Resources */,
245 | );
246 | buildRules = (
247 | );
248 | dependencies = (
249 | );
250 | name = "WatchTips Extension";
251 | productName = "WatchTips Extension";
252 | productReference = 2D69490D21FDFD9700B94252 /* WatchTips Extension.appex */;
253 | productType = "com.apple.product-type.watchkit2-extension";
254 | };
255 | 97C146ED1CF9000F007C117D /* Runner */ = {
256 | isa = PBXNativeTarget;
257 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
258 | buildPhases = (
259 | 9740EEB61CF901F6004384FC /* Run Script */,
260 | 97C146EA1CF9000F007C117D /* Sources */,
261 | 97C146EB1CF9000F007C117D /* Frameworks */,
262 | 97C146EC1CF9000F007C117D /* Resources */,
263 | 9705A1C41CF9048500538489 /* Embed Frameworks */,
264 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
265 | 2D69492521FDFD9700B94252 /* Embed Watch Content */,
266 | );
267 | buildRules = (
268 | );
269 | dependencies = (
270 | 2D69491A21FDFD9700B94252 /* PBXTargetDependency */,
271 | );
272 | name = Runner;
273 | productName = Runner;
274 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
275 | productType = "com.apple.product-type.application";
276 | };
277 | /* End PBXNativeTarget section */
278 |
279 | /* Begin PBXProject section */
280 | 97C146E61CF9000F007C117D /* Project object */ = {
281 | isa = PBXProject;
282 | attributes = {
283 | DefaultBuildSystemTypeForWorkspace = Original;
284 | LastSwiftUpdateCheck = 1010;
285 | LastUpgradeCheck = 0910;
286 | ORGANIZATIONNAME = "The Chromium Authors";
287 | TargetAttributes = {
288 | 2D69490021FDFD9600B94252 = {
289 | CreatedOnToolsVersion = 10.1;
290 | DevelopmentTeam = QJ23459J94;
291 | ProvisioningStyle = Automatic;
292 | };
293 | 2D69490C21FDFD9700B94252 = {
294 | CreatedOnToolsVersion = 10.1;
295 | DevelopmentTeam = QJ23459J94;
296 | ProvisioningStyle = Automatic;
297 | SystemCapabilities = {
298 | com.apple.BackgroundModes.watchos.extension = {
299 | enabled = 0;
300 | };
301 | };
302 | };
303 | 97C146ED1CF9000F007C117D = {
304 | CreatedOnToolsVersion = 7.3.1;
305 | DevelopmentTeam = QJ23459J94;
306 | SystemCapabilities = {
307 | com.apple.BackgroundModes = {
308 | enabled = 1;
309 | };
310 | };
311 | };
312 | };
313 | };
314 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
315 | compatibilityVersion = "Xcode 3.2";
316 | developmentRegion = English;
317 | hasScannedForEncodings = 0;
318 | knownRegions = (
319 | en,
320 | Base,
321 | );
322 | mainGroup = 97C146E51CF9000F007C117D;
323 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
324 | projectDirPath = "";
325 | projectRoot = "";
326 | targets = (
327 | 97C146ED1CF9000F007C117D /* Runner */,
328 | 2D69490021FDFD9600B94252 /* WatchTips */,
329 | 2D69490C21FDFD9700B94252 /* WatchTips Extension */,
330 | );
331 | };
332 | /* End PBXProject section */
333 |
334 | /* Begin PBXResourcesBuildPhase section */
335 | 2D6948FF21FDFD9600B94252 /* Resources */ = {
336 | isa = PBXResourcesBuildPhase;
337 | buildActionMask = 2147483647;
338 | files = (
339 | 2D69490721FDFD9700B94252 /* Assets.xcassets in Resources */,
340 | 2D69490521FDFD9600B94252 /* Interface.storyboard in Resources */,
341 | );
342 | runOnlyForDeploymentPostprocessing = 0;
343 | };
344 | 2D69490B21FDFD9700B94252 /* Resources */ = {
345 | isa = PBXResourcesBuildPhase;
346 | buildActionMask = 2147483647;
347 | files = (
348 | 2D69491721FDFD9700B94252 /* Assets.xcassets in Resources */,
349 | );
350 | runOnlyForDeploymentPostprocessing = 0;
351 | };
352 | 97C146EC1CF9000F007C117D /* Resources */ = {
353 | isa = PBXResourcesBuildPhase;
354 | buildActionMask = 2147483647;
355 | files = (
356 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
357 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
358 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
359 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
360 | 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
361 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
362 | );
363 | runOnlyForDeploymentPostprocessing = 0;
364 | };
365 | /* End PBXResourcesBuildPhase section */
366 |
367 | /* Begin PBXShellScriptBuildPhase section */
368 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
369 | isa = PBXShellScriptBuildPhase;
370 | buildActionMask = 2147483647;
371 | files = (
372 | );
373 | inputPaths = (
374 | );
375 | name = "Thin Binary";
376 | outputPaths = (
377 | );
378 | runOnlyForDeploymentPostprocessing = 0;
379 | shellPath = /bin/sh;
380 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
381 | };
382 | 9740EEB61CF901F6004384FC /* Run Script */ = {
383 | isa = PBXShellScriptBuildPhase;
384 | buildActionMask = 2147483647;
385 | files = (
386 | );
387 | inputPaths = (
388 | );
389 | name = "Run Script";
390 | outputPaths = (
391 | );
392 | runOnlyForDeploymentPostprocessing = 0;
393 | shellPath = /bin/sh;
394 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
395 | };
396 | /* End PBXShellScriptBuildPhase section */
397 |
398 | /* Begin PBXSourcesBuildPhase section */
399 | 2D69490921FDFD9700B94252 /* Sources */ = {
400 | isa = PBXSourcesBuildPhase;
401 | buildActionMask = 2147483647;
402 | files = (
403 | 2D020CB921FEF5A100DC71C2 /* BillController.swift in Sources */,
404 | 2D69491521FDFD9700B94252 /* ExtensionDelegate.swift in Sources */,
405 | 2D69491321FDFD9700B94252 /* InterfaceController.swift in Sources */,
406 | );
407 | runOnlyForDeploymentPostprocessing = 0;
408 | };
409 | 97C146EA1CF9000F007C117D /* Sources */ = {
410 | isa = PBXSourcesBuildPhase;
411 | buildActionMask = 2147483647;
412 | files = (
413 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
414 | 97C146F31CF9000F007C117D /* main.m in Sources */,
415 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
416 | );
417 | runOnlyForDeploymentPostprocessing = 0;
418 | };
419 | /* End PBXSourcesBuildPhase section */
420 |
421 | /* Begin PBXTargetDependency section */
422 | 2D69491021FDFD9700B94252 /* PBXTargetDependency */ = {
423 | isa = PBXTargetDependency;
424 | target = 2D69490C21FDFD9700B94252 /* WatchTips Extension */;
425 | targetProxy = 2D69490F21FDFD9700B94252 /* PBXContainerItemProxy */;
426 | };
427 | 2D69491A21FDFD9700B94252 /* PBXTargetDependency */ = {
428 | isa = PBXTargetDependency;
429 | target = 2D69490021FDFD9600B94252 /* WatchTips */;
430 | targetProxy = 2D69491921FDFD9700B94252 /* PBXContainerItemProxy */;
431 | };
432 | /* End PBXTargetDependency section */
433 |
434 | /* Begin PBXVariantGroup section */
435 | 2D69490321FDFD9600B94252 /* Interface.storyboard */ = {
436 | isa = PBXVariantGroup;
437 | children = (
438 | 2D69490421FDFD9600B94252 /* Base */,
439 | );
440 | name = Interface.storyboard;
441 | sourceTree = "";
442 | };
443 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
444 | isa = PBXVariantGroup;
445 | children = (
446 | 97C146FB1CF9000F007C117D /* Base */,
447 | );
448 | name = Main.storyboard;
449 | sourceTree = "";
450 | };
451 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
452 | isa = PBXVariantGroup;
453 | children = (
454 | 97C147001CF9000F007C117D /* Base */,
455 | );
456 | name = LaunchScreen.storyboard;
457 | sourceTree = "";
458 | };
459 | /* End PBXVariantGroup section */
460 |
461 | /* Begin XCBuildConfiguration section */
462 | 249021D3217E4FDB00AE95B9 /* Profile */ = {
463 | isa = XCBuildConfiguration;
464 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
465 | buildSettings = {
466 | ALWAYS_SEARCH_USER_PATHS = NO;
467 | CLANG_ANALYZER_NONNULL = YES;
468 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
469 | CLANG_CXX_LIBRARY = "libc++";
470 | CLANG_ENABLE_MODULES = YES;
471 | CLANG_ENABLE_OBJC_ARC = YES;
472 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
473 | CLANG_WARN_BOOL_CONVERSION = YES;
474 | CLANG_WARN_COMMA = YES;
475 | CLANG_WARN_CONSTANT_CONVERSION = YES;
476 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
477 | CLANG_WARN_EMPTY_BODY = YES;
478 | CLANG_WARN_ENUM_CONVERSION = YES;
479 | CLANG_WARN_INFINITE_RECURSION = YES;
480 | CLANG_WARN_INT_CONVERSION = YES;
481 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
482 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
483 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
484 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
485 | CLANG_WARN_STRICT_PROTOTYPES = YES;
486 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
487 | CLANG_WARN_UNREACHABLE_CODE = YES;
488 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
489 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
490 | COPY_PHASE_STRIP = NO;
491 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
492 | ENABLE_NS_ASSERTIONS = NO;
493 | ENABLE_STRICT_OBJC_MSGSEND = YES;
494 | GCC_C_LANGUAGE_STANDARD = gnu99;
495 | GCC_NO_COMMON_BLOCKS = YES;
496 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
497 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
498 | GCC_WARN_UNDECLARED_SELECTOR = YES;
499 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
500 | GCC_WARN_UNUSED_FUNCTION = YES;
501 | GCC_WARN_UNUSED_VARIABLE = YES;
502 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
503 | MTL_ENABLE_DEBUG_INFO = NO;
504 | SDKROOT = iphoneos;
505 | TARGETED_DEVICE_FAMILY = "1,2";
506 | VALIDATE_PRODUCT = YES;
507 | };
508 | name = Profile;
509 | };
510 | 249021D4217E4FDB00AE95B9 /* Profile */ = {
511 | isa = XCBuildConfiguration;
512 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
513 | buildSettings = {
514 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
515 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
516 | DEVELOPMENT_TEAM = QJ23459J94;
517 | ENABLE_BITCODE = NO;
518 | FRAMEWORK_SEARCH_PATHS = (
519 | "$(inherited)",
520 | "$(PROJECT_DIR)/Flutter",
521 | );
522 | INFOPLIST_FILE = Runner/Info.plist;
523 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
524 | LIBRARY_SEARCH_PATHS = (
525 | "$(inherited)",
526 | "$(PROJECT_DIR)/Flutter",
527 | );
528 | PRODUCT_BUNDLE_IDENTIFIER = uk.spiralarm.tipcalculator;
529 | PRODUCT_NAME = "$(TARGET_NAME)";
530 | TARGETED_DEVICE_FAMILY = "1,2";
531 | VERSIONING_SYSTEM = "apple-generic";
532 | };
533 | name = Profile;
534 | };
535 | 2D69491D21FDFD9700B94252 /* Debug */ = {
536 | isa = XCBuildConfiguration;
537 | buildSettings = {
538 | ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
539 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
540 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
541 | CLANG_ENABLE_OBJC_WEAK = YES;
542 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
543 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
544 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
545 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
546 | CODE_SIGN_STYLE = Automatic;
547 | DEVELOPMENT_TEAM = QJ23459J94;
548 | GCC_C_LANGUAGE_STANDARD = gnu11;
549 | INFOPLIST_FILE = "WatchTips Extension/Info.plist";
550 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
551 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
552 | MTL_FAST_MATH = YES;
553 | PRODUCT_BUNDLE_IDENTIFIER = uk.spiralarm.tipcalculator.watchkitapp.watchkitextension;
554 | PRODUCT_NAME = "${TARGET_NAME}";
555 | SDKROOT = watchos;
556 | SKIP_INSTALL = YES;
557 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
558 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
559 | SWIFT_VERSION = 4.2;
560 | TARGETED_DEVICE_FAMILY = 4;
561 | WATCHOS_DEPLOYMENT_TARGET = 4.3;
562 | };
563 | name = Debug;
564 | };
565 | 2D69491E21FDFD9700B94252 /* Release */ = {
566 | isa = XCBuildConfiguration;
567 | buildSettings = {
568 | ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
569 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
570 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
571 | CLANG_ENABLE_OBJC_WEAK = YES;
572 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
573 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
574 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
575 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
576 | CODE_SIGN_STYLE = Automatic;
577 | DEVELOPMENT_TEAM = QJ23459J94;
578 | GCC_C_LANGUAGE_STANDARD = gnu11;
579 | INFOPLIST_FILE = "WatchTips Extension/Info.plist";
580 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
581 | MTL_FAST_MATH = YES;
582 | PRODUCT_BUNDLE_IDENTIFIER = uk.spiralarm.tipcalculator.watchkitapp.watchkitextension;
583 | PRODUCT_NAME = "${TARGET_NAME}";
584 | SDKROOT = watchos;
585 | SKIP_INSTALL = YES;
586 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
587 | SWIFT_VERSION = 4.2;
588 | TARGETED_DEVICE_FAMILY = 4;
589 | WATCHOS_DEPLOYMENT_TARGET = 4.3;
590 | };
591 | name = Release;
592 | };
593 | 2D69491F21FDFD9700B94252 /* Profile */ = {
594 | isa = XCBuildConfiguration;
595 | buildSettings = {
596 | ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
597 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
598 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
599 | CLANG_ENABLE_OBJC_WEAK = YES;
600 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
601 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
602 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
603 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
604 | CODE_SIGN_STYLE = Automatic;
605 | DEVELOPMENT_TEAM = QJ23459J94;
606 | GCC_C_LANGUAGE_STANDARD = gnu11;
607 | INFOPLIST_FILE = "WatchTips Extension/Info.plist";
608 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
609 | MTL_FAST_MATH = YES;
610 | PRODUCT_BUNDLE_IDENTIFIER = uk.spiralarm.tipcalculator.watchkitapp.watchkitextension;
611 | PRODUCT_NAME = "${TARGET_NAME}";
612 | SDKROOT = watchos;
613 | SKIP_INSTALL = YES;
614 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
615 | SWIFT_VERSION = 4.2;
616 | TARGETED_DEVICE_FAMILY = 4;
617 | WATCHOS_DEPLOYMENT_TARGET = 4.3;
618 | };
619 | name = Profile;
620 | };
621 | 2D69492221FDFD9700B94252 /* Debug */ = {
622 | isa = XCBuildConfiguration;
623 | buildSettings = {
624 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
625 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
626 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
627 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
628 | CLANG_ENABLE_OBJC_WEAK = YES;
629 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
630 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
631 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
632 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
633 | CODE_SIGN_STYLE = Automatic;
634 | DEVELOPMENT_TEAM = QJ23459J94;
635 | GCC_C_LANGUAGE_STANDARD = gnu11;
636 | IBSC_MODULE = WatchTips_Extension;
637 | INFOPLIST_FILE = WatchTips/Info.plist;
638 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
639 | MTL_FAST_MATH = YES;
640 | PRODUCT_BUNDLE_IDENTIFIER = uk.spiralarm.tipcalculator.watchkitapp;
641 | PRODUCT_NAME = "$(TARGET_NAME)";
642 | SDKROOT = watchos;
643 | SKIP_INSTALL = YES;
644 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
645 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
646 | SWIFT_VERSION = 4.2;
647 | TARGETED_DEVICE_FAMILY = 4;
648 | WATCHOS_DEPLOYMENT_TARGET = 4.3;
649 | };
650 | name = Debug;
651 | };
652 | 2D69492321FDFD9700B94252 /* Release */ = {
653 | isa = XCBuildConfiguration;
654 | buildSettings = {
655 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
656 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
657 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
658 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
659 | CLANG_ENABLE_OBJC_WEAK = YES;
660 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
661 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
662 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
663 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
664 | CODE_SIGN_STYLE = Automatic;
665 | DEVELOPMENT_TEAM = QJ23459J94;
666 | GCC_C_LANGUAGE_STANDARD = gnu11;
667 | IBSC_MODULE = WatchTips_Extension;
668 | INFOPLIST_FILE = WatchTips/Info.plist;
669 | MTL_FAST_MATH = YES;
670 | PRODUCT_BUNDLE_IDENTIFIER = uk.spiralarm.tipcalculator.watchkitapp;
671 | PRODUCT_NAME = "$(TARGET_NAME)";
672 | SDKROOT = watchos;
673 | SKIP_INSTALL = YES;
674 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
675 | SWIFT_VERSION = 4.2;
676 | TARGETED_DEVICE_FAMILY = 4;
677 | WATCHOS_DEPLOYMENT_TARGET = 4.3;
678 | };
679 | name = Release;
680 | };
681 | 2D69492421FDFD9700B94252 /* Profile */ = {
682 | isa = XCBuildConfiguration;
683 | buildSettings = {
684 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
685 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
686 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
687 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
688 | CLANG_ENABLE_OBJC_WEAK = YES;
689 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
690 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
691 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
692 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
693 | CODE_SIGN_STYLE = Automatic;
694 | DEVELOPMENT_TEAM = QJ23459J94;
695 | GCC_C_LANGUAGE_STANDARD = gnu11;
696 | IBSC_MODULE = WatchTips_Extension;
697 | INFOPLIST_FILE = WatchTips/Info.plist;
698 | MTL_FAST_MATH = YES;
699 | PRODUCT_BUNDLE_IDENTIFIER = uk.spiralarm.tipcalculator.watchkitapp;
700 | PRODUCT_NAME = "$(TARGET_NAME)";
701 | SDKROOT = watchos;
702 | SKIP_INSTALL = YES;
703 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
704 | SWIFT_VERSION = 4.2;
705 | TARGETED_DEVICE_FAMILY = 4;
706 | WATCHOS_DEPLOYMENT_TARGET = 4.3;
707 | };
708 | name = Profile;
709 | };
710 | 97C147031CF9000F007C117D /* Debug */ = {
711 | isa = XCBuildConfiguration;
712 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
713 | buildSettings = {
714 | ALWAYS_SEARCH_USER_PATHS = NO;
715 | CLANG_ANALYZER_NONNULL = YES;
716 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
717 | CLANG_CXX_LIBRARY = "libc++";
718 | CLANG_ENABLE_MODULES = YES;
719 | CLANG_ENABLE_OBJC_ARC = YES;
720 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
721 | CLANG_WARN_BOOL_CONVERSION = YES;
722 | CLANG_WARN_COMMA = YES;
723 | CLANG_WARN_CONSTANT_CONVERSION = YES;
724 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
725 | CLANG_WARN_EMPTY_BODY = YES;
726 | CLANG_WARN_ENUM_CONVERSION = YES;
727 | CLANG_WARN_INFINITE_RECURSION = YES;
728 | CLANG_WARN_INT_CONVERSION = YES;
729 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
730 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
731 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
732 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
733 | CLANG_WARN_STRICT_PROTOTYPES = YES;
734 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
735 | CLANG_WARN_UNREACHABLE_CODE = YES;
736 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
737 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
738 | COPY_PHASE_STRIP = NO;
739 | DEBUG_INFORMATION_FORMAT = dwarf;
740 | ENABLE_STRICT_OBJC_MSGSEND = YES;
741 | ENABLE_TESTABILITY = YES;
742 | GCC_C_LANGUAGE_STANDARD = gnu99;
743 | GCC_DYNAMIC_NO_PIC = NO;
744 | GCC_NO_COMMON_BLOCKS = YES;
745 | GCC_OPTIMIZATION_LEVEL = 0;
746 | GCC_PREPROCESSOR_DEFINITIONS = (
747 | "DEBUG=1",
748 | "$(inherited)",
749 | );
750 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
751 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
752 | GCC_WARN_UNDECLARED_SELECTOR = YES;
753 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
754 | GCC_WARN_UNUSED_FUNCTION = YES;
755 | GCC_WARN_UNUSED_VARIABLE = YES;
756 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
757 | MTL_ENABLE_DEBUG_INFO = YES;
758 | ONLY_ACTIVE_ARCH = YES;
759 | SDKROOT = iphoneos;
760 | TARGETED_DEVICE_FAMILY = "1,2";
761 | };
762 | name = Debug;
763 | };
764 | 97C147041CF9000F007C117D /* Release */ = {
765 | isa = XCBuildConfiguration;
766 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
767 | buildSettings = {
768 | ALWAYS_SEARCH_USER_PATHS = NO;
769 | CLANG_ANALYZER_NONNULL = YES;
770 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
771 | CLANG_CXX_LIBRARY = "libc++";
772 | CLANG_ENABLE_MODULES = YES;
773 | CLANG_ENABLE_OBJC_ARC = YES;
774 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
775 | CLANG_WARN_BOOL_CONVERSION = YES;
776 | CLANG_WARN_COMMA = YES;
777 | CLANG_WARN_CONSTANT_CONVERSION = YES;
778 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
779 | CLANG_WARN_EMPTY_BODY = YES;
780 | CLANG_WARN_ENUM_CONVERSION = YES;
781 | CLANG_WARN_INFINITE_RECURSION = YES;
782 | CLANG_WARN_INT_CONVERSION = YES;
783 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
784 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
785 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
786 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
787 | CLANG_WARN_STRICT_PROTOTYPES = YES;
788 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
789 | CLANG_WARN_UNREACHABLE_CODE = YES;
790 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
791 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
792 | COPY_PHASE_STRIP = NO;
793 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
794 | ENABLE_NS_ASSERTIONS = NO;
795 | ENABLE_STRICT_OBJC_MSGSEND = YES;
796 | GCC_C_LANGUAGE_STANDARD = gnu99;
797 | GCC_NO_COMMON_BLOCKS = YES;
798 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
799 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
800 | GCC_WARN_UNDECLARED_SELECTOR = YES;
801 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
802 | GCC_WARN_UNUSED_FUNCTION = YES;
803 | GCC_WARN_UNUSED_VARIABLE = YES;
804 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
805 | MTL_ENABLE_DEBUG_INFO = NO;
806 | SDKROOT = iphoneos;
807 | TARGETED_DEVICE_FAMILY = "1,2";
808 | VALIDATE_PRODUCT = YES;
809 | };
810 | name = Release;
811 | };
812 | 97C147061CF9000F007C117D /* Debug */ = {
813 | isa = XCBuildConfiguration;
814 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
815 | buildSettings = {
816 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
817 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
818 | DEVELOPMENT_TEAM = QJ23459J94;
819 | ENABLE_BITCODE = NO;
820 | FRAMEWORK_SEARCH_PATHS = (
821 | "$(inherited)",
822 | "$(PROJECT_DIR)/Flutter",
823 | );
824 | INFOPLIST_FILE = Runner/Info.plist;
825 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
826 | LIBRARY_SEARCH_PATHS = (
827 | "$(inherited)",
828 | "$(PROJECT_DIR)/Flutter",
829 | );
830 | PRODUCT_BUNDLE_IDENTIFIER = uk.spiralarm.tipcalculator;
831 | PRODUCT_NAME = "$(TARGET_NAME)";
832 | TARGETED_DEVICE_FAMILY = "1,2";
833 | VERSIONING_SYSTEM = "apple-generic";
834 | };
835 | name = Debug;
836 | };
837 | 97C147071CF9000F007C117D /* Release */ = {
838 | isa = XCBuildConfiguration;
839 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
840 | buildSettings = {
841 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
842 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
843 | DEVELOPMENT_TEAM = QJ23459J94;
844 | ENABLE_BITCODE = NO;
845 | FRAMEWORK_SEARCH_PATHS = (
846 | "$(inherited)",
847 | "$(PROJECT_DIR)/Flutter",
848 | );
849 | INFOPLIST_FILE = Runner/Info.plist;
850 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
851 | LIBRARY_SEARCH_PATHS = (
852 | "$(inherited)",
853 | "$(PROJECT_DIR)/Flutter",
854 | );
855 | PRODUCT_BUNDLE_IDENTIFIER = uk.spiralarm.tipcalculator;
856 | PRODUCT_NAME = "$(TARGET_NAME)";
857 | TARGETED_DEVICE_FAMILY = "1,2";
858 | VERSIONING_SYSTEM = "apple-generic";
859 | };
860 | name = Release;
861 | };
862 | /* End XCBuildConfiguration section */
863 |
864 | /* Begin XCConfigurationList section */
865 | 2D69491C21FDFD9700B94252 /* Build configuration list for PBXNativeTarget "WatchTips Extension" */ = {
866 | isa = XCConfigurationList;
867 | buildConfigurations = (
868 | 2D69491D21FDFD9700B94252 /* Debug */,
869 | 2D69491E21FDFD9700B94252 /* Release */,
870 | 2D69491F21FDFD9700B94252 /* Profile */,
871 | );
872 | defaultConfigurationIsVisible = 0;
873 | defaultConfigurationName = Release;
874 | };
875 | 2D69492121FDFD9700B94252 /* Build configuration list for PBXNativeTarget "WatchTips" */ = {
876 | isa = XCConfigurationList;
877 | buildConfigurations = (
878 | 2D69492221FDFD9700B94252 /* Debug */,
879 | 2D69492321FDFD9700B94252 /* Release */,
880 | 2D69492421FDFD9700B94252 /* Profile */,
881 | );
882 | defaultConfigurationIsVisible = 0;
883 | defaultConfigurationName = Release;
884 | };
885 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
886 | isa = XCConfigurationList;
887 | buildConfigurations = (
888 | 97C147031CF9000F007C117D /* Debug */,
889 | 97C147041CF9000F007C117D /* Release */,
890 | 249021D3217E4FDB00AE95B9 /* Profile */,
891 | );
892 | defaultConfigurationIsVisible = 0;
893 | defaultConfigurationName = Release;
894 | };
895 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
896 | isa = XCConfigurationList;
897 | buildConfigurations = (
898 | 97C147061CF9000F007C117D /* Debug */,
899 | 97C147071CF9000F007C117D /* Release */,
900 | 249021D4217E4FDB00AE95B9 /* Profile */,
901 | );
902 | defaultConfigurationIsVisible = 0;
903 | defaultConfigurationName = Release;
904 | };
905 | /* End XCConfigurationList section */
906 | };
907 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
908 | }
909 |
--------------------------------------------------------------------------------