diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index 592ceee8..ec97fc6f 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 592ceee8..c4855bfe 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 00000000..1e8c3c90 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 00000000..22bcc5ad --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,34 @@ +PODS: + - countly_flutter (20.11.4): + - Flutter + - Flutter (1.0.0) + - path_provider (0.0.1): + - Flutter + - url_launcher (0.0.1): + - Flutter + +DEPENDENCIES: + - countly_flutter (from `.symlinks/plugins/countly_flutter/ios`) + - Flutter (from `Flutter`) + - path_provider (from `.symlinks/plugins/path_provider/ios`) + - url_launcher (from `.symlinks/plugins/url_launcher/ios`) + +EXTERNAL SOURCES: + countly_flutter: + :path: ".symlinks/plugins/countly_flutter/ios" + Flutter: + :path: Flutter + path_provider: + :path: ".symlinks/plugins/path_provider/ios" + url_launcher: + :path: ".symlinks/plugins/url_launcher/ios" + +SPEC CHECKSUMS: + countly_flutter: 38419412e193a1faa5babeb5d28a63fda260687d + Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a + path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c + url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef + +PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c + +COCOAPODS: 1.10.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index fa6c85f1..26a50aef 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ @@ -13,6 +13,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + F75F3F31F50CE63E6E5A007A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1943AA6278F8E5C18ECF2424 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -31,7 +32,10 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 1943AA6278F8E5C18ECF2424 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 4FBEF65ECCD73179D67A7C7F /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 73F1154A8CD1929C19D5E7CD /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -42,6 +46,7 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BD0BCE86AF10A6436A3137F3 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -49,12 +54,24 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F75F3F31F50CE63E6E5A007A /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 57A8C57E30C4E6EA19A8A24B /* Pods */ = { + isa = PBXGroup; + children = ( + 73F1154A8CD1929C19D5E7CD /* Pods-Runner.debug.xcconfig */, + 4FBEF65ECCD73179D67A7C7F /* Pods-Runner.release.xcconfig */, + BD0BCE86AF10A6436A3137F3 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -72,6 +89,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, + 57A8C57E30C4E6EA19A8A24B /* Pods */, + FC5FD8E51E42C41C4B2F3ACA /* Frameworks */, ); sourceTree = ""; }; @@ -98,6 +117,14 @@ path = Runner; sourceTree = ""; }; + FC5FD8E51E42C41C4B2F3ACA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1943AA6278F8E5C18ECF2424 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -105,12 +132,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 888FE6BDE7F2ABAFD4E356CB /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 6450BEBF47D9B2070E69D33C /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -183,6 +212,45 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; + 6450BEBF47D9B2070E69D33C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 888FE6BDE7F2ABAFD4E356CB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -288,10 +356,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.toolbox; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -399,7 +471,8 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -412,10 +485,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.toolbox; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -431,10 +508,14 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.toolbox; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a16..21a3cc14 100644 --- a/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/lib/app.dart b/lib/app.dart index 354ed1e1..9d2970a5 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -10,17 +10,9 @@ class MyApp extends StatelessWidget { return MaterialApp( title: 'ToolBox', theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. primarySwatch: Colors.blue, ), + darkTheme: ThemeData.dark(), home: const MyHomePage(title: 'ToolBox'), ); } diff --git a/lib/main.dart b/lib/main.dart index 058c559b..35ebece9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,60 @@ -import 'package:flutter/material.dart'; -import 'package:toolbox/app.dart'; +import 'dart:async'; -void main() { - runApp(const MyApp()); +import 'package:flutter/material.dart'; +import 'package:hive_flutter/hive_flutter.dart'; +import 'package:provider/provider.dart'; +import 'package:toolbox/app.dart'; +import 'package:toolbox/core/analysis.dart'; +import 'package:toolbox/data/provider/app.dart'; +import 'package:toolbox/data/provider/debug.dart'; +import 'package:toolbox/locator.dart'; + +Future initApp() async { + await Hive.initFlutter(); + await setupLocator(); } + +void runInZone(dynamic Function() body) { + final zoneSpec = ZoneSpecification( + print: (Zone self, ZoneDelegate parent, Zone zone, String line) { + parent.print(zone, line); + // This is a hack to avoid + // `setState() or markNeedsBuild() called during build` + // error. + Future.delayed(const Duration(milliseconds: 1), () { + final debugProvider = locator(); + debugProvider.addText(line); + }); + }, + ); + + runZonedGuarded( + body, + onError, + zoneSpecification: zoneSpec, + ); +} + +void onError(Object obj, StackTrace stack) { + print('error: $obj'); + Analysis.recordException(obj); + final debugProvider = locator(); + debugProvider.addError(obj); + debugProvider.addError(stack); +} + +Future main() async { + runInZone(() async { + await initApp(); + runApp( + MultiProvider( + providers: [ + ChangeNotifierProvider(create: (_) => locator()), + ChangeNotifierProvider(create: (_) => locator()), + ], + child: const MyApp(), + ), + ); + }); +} + diff --git a/lib/page/debug.dart b/lib/page/debug.dart new file mode 100644 index 00000000..9e2dcf05 --- /dev/null +++ b/lib/page/debug.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:toolbox/data/provider/debug.dart'; + +class DebugPage extends StatefulWidget { + const DebugPage({Key? key}) : super(key: key); + + @override + _DebugPageState createState() => _DebugPageState(); +} + +class _DebugPageState extends State { + DebugProvider get debug => Provider.of(context); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: + AppBar(title: const Text('Terminal'), backgroundColor: Colors.black), + body: _buildTerminal(context), + backgroundColor: Colors.black, + ); + } + + Widget _buildTerminal(BuildContext context) { + return Container( + padding: const EdgeInsets.all(10), + color: Colors.black, + child: DefaultTextStyle( + style: const TextStyle( + fontFamily: 'monospace', + color: Colors.white, + fontWeight: FontWeight.bold, + ), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: debug.widgets, + ), + ), + ), + ); + } +} diff --git a/lib/page/home.dart b/lib/page/home.dart index f7cbd7ae..4a88b566 100644 --- a/lib/page/home.dart +++ b/lib/page/home.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'package:flutter/material.dart'; +import 'package:toolbox/core/route.dart'; +import 'package:toolbox/page/debug.dart'; class MyHomePage extends StatefulWidget { const MyHomePage({Key? key, required this.title}) : super(key: key); @@ -42,16 +44,21 @@ class _MyHomePageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text(widget.title), + title: GestureDetector( + onLongPress: () => AppRoute(const DebugPage(), 'Debug Page').go(context), + child: Text(widget.title), + ), ), body: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 7), child: Column( - children: [ - _buildInputTop(), - _buildTypeOption(), - _buildResult(), - ], - )), + children: [ + const SizedBox(height: 13), + _buildInputTop(), + _buildTypeOption(), + _buildResult(), + ], + )), floatingActionButton: FloatingActionButton( onPressed: () { _textEditingControllerResult.text = doConvert();