diff --git a/.gitignore b/.gitignore index 1f379ff..5e1a3ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,11 @@ +# mac system +.DS_Store + +# intellij .idea + +# dart / flutter .packages pubspec.lock coverage -__temp_coverage* \ No newline at end of file +__temp_coverage* diff --git a/README.md b/README.md index 6bbd8e5..2226695 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,40 @@ -# Router + +

+ +The brightest, hippest, coolest router for Flutter. [![Build Status](https://travis-ci.org/goposse/flutter-router.svg?branch=master)](https://travis-ci.org/goposse/flutter-router) -[![codecov](https://codecov.io/gh/goposse/flutter-router/branch/master/graph/badge.svg)](https://codecov.io/gh/goposse/flutter-router) +[![Coverage](https://codecov.io/gh/goposse/flutter-router/branch/master/graph/badge.svg)](https://codecov.io/gh/goposse/flutter-router) + +## Features + +- Simple route navigation +- Wildcard parameter matching +- Querystring parameter parsing +- Common transitions built-in +- Simple custom transition creation ## Getting started - - You should ensure that you add the router as a dependency in your flutter project. - Currently, you will need to add the git repo directly. A submitted pub package will - be available soon. - - To add the dependency directly: - + +You should ensure that you add the router as a dependency in your flutter project. +Currently, you will need to add the git repo directly. A submitted pub package will be available **soon**. + +To add the dependency directly: + ```yaml dependencies: - router: + fluro: git: git://github.com/goposse/flutter-router.git ``` -You should then run `pub update` or update your packages in IntelliJ. +You should then run `flutter packages upgrade` or update your packages in IntelliJ. + +## Example Project + +There is a pretty sweet example project in the `example` folder. Check it out. Otherwise, keep reading to get up and running. ## Setting up -First, you should define a new `Router` object by initializing it as such: +First, you should define a new `Router` object by initializing it as such: ```dart final Router router = new Router(); ``` @@ -38,21 +52,22 @@ void defineRoutes(Router router) { } ``` -In the above example, the router will intercept a route such as +In the above example, the router will intercept a route such as `/users/1234` and route the application to the `UsersScreen` passing the value `1234` as a parameter to that screen. ## Navigating You can use the `Router` with the `MaterialApp.onGenerateRoute` parameter - via the `Router.generator` function. To do so, pass the function reference to - the `onGenerate` parameter like: `onGenerateRoute: router.generator`. - +via the `Router.generator` function. To do so, pass the function reference to +the `onGenerate` parameter like: `onGenerateRoute: router.generator`. + You can then use `Navigator.push` and the flutter routing mechanism will match the routes -for you. +for you. You can also manually push to a route yourself. To do so: ```dart -router.navigateTo(context, "/users/1234"); -``` \ No newline at end of file +router.navigateTo(context, "/users/1234", + transition: TransitionType.fadeIn); +``` diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..da2f246 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,49 @@ +.DS_Store + +.atom/ +.idea +.packages +.pub/ +build/ +ios/.generated/ +packages +pubspec.lock +.flutter-plugins + +# temporary +Podfile.lock + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xcuserstate + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +.build/ diff --git a/example/android.iml b/example/android.iml new file mode 100644 index 0000000..462b903 --- /dev/null +++ b/example/android.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/example/android/.gitignore b/example/android/.gitignore new file mode 100644 index 0000000..e6a9f06 --- /dev/null +++ b/example/android/.gitignore @@ -0,0 +1,13 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +PluginRegistry.java + +/gradle +/gradlew +/gradlew.bat diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle new file mode 100644 index 0000000..726561a --- /dev/null +++ b/example/android/app/build.gradle @@ -0,0 +1,103 @@ +// flutter +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withInputStream { stream -> + localProperties.load(stream) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +flutter { + source '../..' +} + +// build versioning +def currentVersionCode() { + def propsFile = file('versions.properties') + def props = new Properties() + props.load(new FileInputStream(propsFile)) + return props['build.versionCode'].toInteger() +} + +def incrementVersionCode() { + def propsFile = file('versions.properties') + def props = new Properties() + props.load(new FileInputStream(propsFile)) + def currentCode = props['build.versionCode'].toInteger() + def nextCode = currentCode + 1 + props['build.versionCode'] = nextCode.toString() + props.store(propsFile.newWriter(), null) + return nextCode +} + +// increments build version code on release builds +task('incrementVersionCode') << { + incrementVersionCode() +} + +tasks.whenTaskAdded { task -> + if (task.name == 'assembleRelease') { + task.dependsOn 'incrementVersionCode' + } +} + +buildscript { + // application variables + ext.app_ver_name = "1.0" + + // google version codes + ext.build_tools_ver = '25.0.3' + ext.support_lib_ver = '25.3.1' + ext.google_play_ver = '10.2.4' + ext.constraint_layout_ver = '1.0.2' +} + +android { + compileSdkVersion 25 + buildToolsVersion "$build_tools_ver" + + defaultConfig { + minSdkVersion 19 + targetSdkVersion 25 + applicationId "com.goposse.routersample" + versionCode currentVersionCode() + versionName "$app_ver_name" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + lintOptions { + disable 'InvalidPackage' + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + + // google + compile "com.android.support:appcompat-v7:$support_lib_ver" + compile "com.android.support:support-v13:$support_lib_ver" + compile "com.android.support:support-v4:$support_lib_ver" + + // testing + androidTestCompile "com.android.support:support-annotations:$support_lib_ver" + androidTestCompile 'com.android.support.test:runner:0.5' + androidTestCompile 'com.android.support.test:rules:0.5' +} diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..a16b270 --- /dev/null +++ b/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/example/android/app/src/main/java/com/goposse/routersample/App.java b/example/android/app/src/main/java/com/goposse/routersample/App.java new file mode 100644 index 0000000..4b8c122 --- /dev/null +++ b/example/android/app/src/main/java/com/goposse/routersample/App.java @@ -0,0 +1,6 @@ +package com.goposse.routersample; + +import io.flutter.app.FlutterApplication; + +public class App extends FlutterApplication { +} diff --git a/example/android/app/src/main/java/com/goposse/routersample/activities/MainActivity.java b/example/android/app/src/main/java/com/goposse/routersample/activities/MainActivity.java new file mode 100644 index 0000000..b05f1b5 --- /dev/null +++ b/example/android/app/src/main/java/com/goposse/routersample/activities/MainActivity.java @@ -0,0 +1,50 @@ +package com.goposse.routersample.activities; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.util.Log; + +import com.goposse.routersample.constants.Channels; + +import io.flutter.app.FlutterActivity; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugins.PluginRegistry; + +public class MainActivity extends FlutterActivity { + + private static final String LOG_TAG = "A:Main"; + + PluginRegistry pluginRegistry; + private static MethodChannel deepLinkChannel; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + pluginRegistry = new PluginRegistry(); + pluginRegistry.registerAll(this); + + if (deepLinkChannel == null) { + deepLinkChannel = new MethodChannel(getFlutterView(), Channels.DEEP_LINK_RECEIVED); + } + + Intent intent = getIntent(); + checkForLinkEvent(intent); + } + + private void checkForLinkEvent(Intent intent) { + String action = intent.getAction(); + Log.d(LOG_TAG, "Hey!!! " + action); + if (action.equals(Intent.ACTION_VIEW)) { + Uri data = intent.getData(); + if (data != null) { + String path = data.getQueryParameter("path"); + if (path != null) { + Log.d(LOG_TAG, String.format("Received external link: %s", data.toString())); + deepLinkChannel.invokeMethod("linkReceived", path); + } + } + } + } + +} diff --git a/example/android/app/src/main/java/com/goposse/routersample/constants/Channels.java b/example/android/app/src/main/java/com/goposse/routersample/constants/Channels.java new file mode 100644 index 0000000..b88ad03 --- /dev/null +++ b/example/android/app/src/main/java/com/goposse/routersample/constants/Channels.java @@ -0,0 +1,6 @@ +package com.goposse.routersample.constants; + +public class Channels { + private static final String CHANNEL_PREFIX = "channel:com.goposse.routerdemo"; + public static final String DEEP_LINK_RECEIVED = CHANNEL_PREFIX + "/deeplink"; +} diff --git a/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java new file mode 100644 index 0000000..e07931d --- /dev/null +++ b/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -0,0 +1,11 @@ +package io.flutter.plugins; + +import io.flutter.plugin.common.PluginRegistry; + +/** + * Generated file. Do not edit. + */ +public final class GeneratedPluginRegistrant { + public static void registerWith(PluginRegistry registry) { + } +} diff --git a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/values/strings.xml b/example/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..c39705a --- /dev/null +++ b/example/android/app/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Router Sample + \ No newline at end of file diff --git a/example/android/app/versions.properties b/example/android/app/versions.properties new file mode 100644 index 0000000..e6d445b --- /dev/null +++ b/example/android/app/versions.properties @@ -0,0 +1 @@ +build.versionCode=1 \ No newline at end of file diff --git a/example/android/build.gradle b/example/android/build.gradle new file mode 100644 index 0000000..ec6951d --- /dev/null +++ b/example/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:2.4.0-alpha7' + } +} + +allprojects { + repositories { + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} + +task wrapper(type: Wrapper) { + gradleVersion = '2.14.1' +} diff --git a/example/android/gradle.properties b/example/android/gradle.properties new file mode 100644 index 0000000..8bd86f6 --- /dev/null +++ b/example/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/example/android/settings.gradle b/example/android/settings.gradle new file mode 100644 index 0000000..115da6c --- /dev/null +++ b/example/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withInputStream { stream -> plugins.load(stream) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/example/assets/images/2.0x/acc_boom.png b/example/assets/images/2.0x/acc_boom.png new file mode 100644 index 0000000..f5a0556 Binary files /dev/null and b/example/assets/images/2.0x/acc_boom.png differ diff --git a/example/assets/images/2.0x/logo_fluro.png b/example/assets/images/2.0x/logo_fluro.png new file mode 100644 index 0000000..873bdcd Binary files /dev/null and b/example/assets/images/2.0x/logo_fluro.png differ diff --git a/example/assets/images/acc_boom.png b/example/assets/images/acc_boom.png new file mode 100644 index 0000000..71999c0 Binary files /dev/null and b/example/assets/images/acc_boom.png differ diff --git a/example/assets/images/logo_fluro.png b/example/assets/images/logo_fluro.png new file mode 100644 index 0000000..3f02e4b Binary files /dev/null and b/example/assets/images/logo_fluro.png differ diff --git a/example/ios/.gitignore b/example/ios/.gitignore new file mode 100644 index 0000000..5ec8cc0 --- /dev/null +++ b/example/ios/.gitignore @@ -0,0 +1,41 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +PluginRegistry.h +PluginRegistry.m + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/app.flx +/Flutter/app.zip +/Flutter/App.framework +/Flutter/Flutter.framework +/Flutter/Generated.xcconfig +/ServiceDefinitions.json + +Pods/ diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..6c2de80 --- /dev/null +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + UIRequiredDeviceCapabilities + + arm64 + + MinimumOSVersion + 8.0 + + diff --git a/example/ios/Flutter/Debug.xcconfig b/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/example/ios/Flutter/Release.xcconfig b/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..592ceee --- /dev/null +++ b/example/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/example/ios/Podfile b/example/ios/Podfile new file mode 100644 index 0000000..74b3de0 --- /dev/null +++ b/example/ios/Podfile @@ -0,0 +1,38 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +if ENV['FLUTTER_FRAMEWORK_DIR'] == nil + abort('Please set FLUTTER_FRAMEWORK_DIR to the directory containing Flutter.framework') +end + +target 'Runner' do + use_frameworks! + + # Pods for Runner + + # Flutter Pods + pod 'Flutter', :path => ENV['FLUTTER_FRAMEWORK_DIR'] + + if File.exists? '../.flutter-plugins' + flutter_root = File.expand_path('..') + File.foreach('../.flutter-plugins') { |line| + plugin = line.split(pattern='=') + if plugin.length == 2 + name = plugin[0].strip() + path = plugin[1].strip() + resolved_path = File.expand_path("#{path}/ios", flutter_root) + pod name, :path => resolved_path + else + puts "Invalid plugin specification: #{line}" + end + } + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end +end diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..6e8073a --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,424 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* PluginRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* PluginRegistry.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; + 9740EEBB1CF902C7004384FC /* app.flx in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB71CF902C7004384FC /* app.flx */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* PluginRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PluginRegistry.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* PluginRegistry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PluginRegistry.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEB71CF902C7004384FC /* app.flx */ = {isa = PBXFileReference; lastKnownFileType = file; name = app.flx; path = Flutter/app.flx; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 9740EEB71CF902C7004384FC /* app.flx */, + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* PluginRegistry.h */, + 1498D2331E8E89220040F4C2 /* PluginRegistry.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9740EEBB1CF902C7004384FC /* app.flx in Resources */, + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* PluginRegistry.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ARCHS = arm64; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.routerExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ARCHS = arm64; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.routerExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..1c95807 --- /dev/null +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/example/ios/Runner/AppDelegate.h b/example/ios/Runner/AppDelegate.h new file mode 100644 index 0000000..cf210d2 --- /dev/null +++ b/example/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/example/ios/Runner/AppDelegate.m b/example/ios/Runner/AppDelegate.m new file mode 100644 index 0000000..3b6ab51 --- /dev/null +++ b/example/ios/Runner/AppDelegate.m @@ -0,0 +1,38 @@ +#include "AppDelegate.h" +#include "PluginRegistry.h" + +@implementation AppDelegate { + PluginRegistry *plugins; +} + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + FlutterViewController *flutterController = + (FlutterViewController *)self.window.rootViewController; + plugins = [[PluginRegistry alloc] initWithController:flutterController]; + return YES; +} + +- (void)applicationWillResignActive:(UIApplication *)application { + // 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. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // 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. +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + +@end diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d22f10b --- /dev/null +++ b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..28c6bf0 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..f091b6b Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cde121 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..d0ef06e Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..dcdc230 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..c8f9ed8 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..75b2d16 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..6a84f41 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..d0e1f58 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..ebf48f6 --- /dev/null +++ b/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner/Base.lproj/Main.storyboard b/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner/GeneratedPluginRegistrant.h b/example/ios/Runner/GeneratedPluginRegistrant.h new file mode 100644 index 0000000..5ec6a8f --- /dev/null +++ b/example/ios/Runner/GeneratedPluginRegistrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +#ifndef GeneratedPluginRegistrant_h +#define GeneratedPluginRegistrant_h + +#import + + +@interface GeneratedPluginRegistrant : NSObject ++ (void)registerWithRegistry:(NSObject*)registry; +@end + +#endif /* GeneratedPluginRegistrant_h */ diff --git a/example/ios/Runner/GeneratedPluginRegistrant.m b/example/ios/Runner/GeneratedPluginRegistrant.m new file mode 100644 index 0000000..60dfa42 --- /dev/null +++ b/example/ios/Runner/GeneratedPluginRegistrant.m @@ -0,0 +1,12 @@ +// +// Generated file. Do not edit. +// + +#import "GeneratedPluginRegistrant.h" + +@implementation GeneratedPluginRegistrant + ++ (void)registerWithRegistry:(NSObject*)registry { +} + +@end diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist new file mode 100644 index 0000000..e04e37b --- /dev/null +++ b/example/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + router_example + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/example/ios/Runner/main.m b/example/ios/Runner/main.m new file mode 100644 index 0000000..1bdb8e2 --- /dev/null +++ b/example/ios/Runner/main.m @@ -0,0 +1,10 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, + NSStringFromClass([AppDelegate class])); + } +} diff --git a/example/lib/app.dart b/example/lib/app.dart new file mode 100644 index 0000000..0385b4a --- /dev/null +++ b/example/lib/app.dart @@ -0,0 +1,49 @@ +/* + * router + * A Posse Production + * http://goposse.com + * Copyright (c) 2017 Posse Productions LLC. All rights reserved. + * See LICENSE for distribution and usage details. + */ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:router/router.dart'; +import 'package:router_example/config/application.dart'; +import 'package:router_example/config/route_handlers.dart'; +import 'package:router_example/screens/home_screen.dart'; + +class App extends StatelessWidget { + + static const platform = const MethodChannel('channel:com.goposse.routerdemo/deeplink'); + + App() { + Router router = new Router(); + router.define("/demo", handler: showDemoHandler); + Application.router = router; + configureDeepLinker(); + } + + @override + Widget build(BuildContext context) { + return new MaterialApp( + title: 'Flutter Demo', + theme: new ThemeData( + primarySwatch: Colors.blue, + ), + home: new HomeScreen(), + ); + } + + void configureDeepLinker() { + platform.setMethodCallHandler((MethodCall call) async { + if (call.method == "linkReceived") { + String path = call.arguments; + if (path != null) { + print("got path: $path"); + } + } + }); + } + +} + diff --git a/example/lib/config/application.dart b/example/lib/config/application.dart new file mode 100644 index 0000000..3bf5e57 --- /dev/null +++ b/example/lib/config/application.dart @@ -0,0 +1,5 @@ +import 'package:router/router.dart'; + +class Application { + static Router router; +} \ No newline at end of file diff --git a/example/lib/config/route_handlers.dart b/example/lib/config/route_handlers.dart new file mode 100644 index 0000000..fd4c8eb --- /dev/null +++ b/example/lib/config/route_handlers.dart @@ -0,0 +1,21 @@ +/* + * router + * A Posse Production + * http://goposse.com + * Copyright (c) 2017 Posse Productions LLC. All rights reserved. + * See LICENSE for distribution and usage details. + */ +import 'package:flutter/painting.dart'; +import 'package:router/router.dart'; +import 'package:router_example/helpers/color_helpers.dart'; +import 'package:router_example/screens/test_screen_01.dart'; + +RouteHandler showDemoHandler = (Map params) { + String message = params["message"]; + String colorHex = params["color_hex"]; + Color color = new Color(0xFFFFFFFF); + if (colorHex != null && colorHex.length > 0) { + color = new Color(ColorHelpers.fromHexString(colorHex)); + } + return new TestScreen01(message: message, color: color); +}; \ No newline at end of file diff --git a/example/lib/helpers/color_helpers.dart b/example/lib/helpers/color_helpers.dart new file mode 100644 index 0000000..61dc25c --- /dev/null +++ b/example/lib/helpers/color_helpers.dart @@ -0,0 +1,51 @@ +/* + * router + * A Posse Production + * http://goposse.com + * Copyright (c) 2017 Posse Productions LLC. All rights reserved. + * See LICENSE for distribution and usage details. + */ +import 'package:flutter/material.dart'; + +enum ContrastPreference { + none, + light, + dark, +} + +class ColorHelpers { + + static int fromHexString(String argbHexString) { + String useString = argbHexString; + if (useString.startsWith("#")) { + useString = useString.substring(1); // trim the starting '#' + } + if (useString.length < 8) { + useString = "FF" + useString; + } + if (!useString.startsWith("0x")) { + useString = "0x" + useString; + } + return int.parse(useString); + } + + static final double _kMinContrastModifierRange = 0.35; + static final double _kMaxContrastModifierRange = 0.65; + + /// Returns black or white depending on whether the source color is darker + /// or lighter. If darker, will return white. If lighter, will return + /// black. If the color is within 35-65% of the spectrum and a prefer + /// value is specified, then white or black will be preferred. + static Color blackOrWhiteContrastColor(Color sourceColor, {ContrastPreference prefer = ContrastPreference.none}) { + // Will return a value between 0.0 (black) and 1.0 (white) + double value = (((sourceColor.red * 299.0) + (sourceColor.green * 587.0) + + (sourceColor.blue * 114.0)) / 1000.0) / 255.0; + if (prefer != ContrastPreference.none) { + if (value >= _kMinContrastModifierRange && value <= _kMaxContrastModifierRange) { + return prefer == ContrastPreference.light ? new Color(0xFFFFFFFF) : new Color(0xFF000000); + } + } + return value > 0.6 ? new Color(0xFF000000) : new Color(0xFFFFFFFF); + } + +} \ No newline at end of file diff --git a/example/lib/main.dart b/example/lib/main.dart new file mode 100644 index 0000000..aca2ed4 --- /dev/null +++ b/example/lib/main.dart @@ -0,0 +1,13 @@ +/* + * router + * A Posse Production + * http://goposse.com + * Copyright (c) 2017 Posse Productions LLC. All rights reserved. + * See LICENSE for distribution and usage details. + */ +import 'package:flutter/material.dart'; +import 'package:router_example/app.dart'; + +void main() { + runApp(new App()); +} \ No newline at end of file diff --git a/example/lib/screens/home_screen.dart b/example/lib/screens/home_screen.dart new file mode 100644 index 0000000..21cefda --- /dev/null +++ b/example/lib/screens/home_screen.dart @@ -0,0 +1,98 @@ +/* + * router + * A Posse Production + * http://goposse.com + * Copyright (c) 2017 Posse Productions LLC. All rights reserved. + * See LICENSE for distribution and usage details. + */ +import 'package:flutter/material.dart'; +import 'package:router/router.dart'; +import 'package:router_example/config/application.dart'; + +class HomeScreen extends StatelessWidget { + + BuildContext context; + + @override + Widget build(BuildContext context) { + this.context = context; + var menuWidgets = [ + new Padding( + padding: new EdgeInsets.only(bottom: 15.0), + child: new Image(image: new AssetImage("assets/images/logo_fluro.png"), width: 200.0), + ), + menuButton("Native Animation", "native"), + menuButton("Preset (In from Left)", "preset-from-left"), + menuButton("Preset (Fade In)", "preset-fade"), + menuButton("Custom", "custom"), + ]; + return new Material( + color: new Color(0xFF00D6F7), + child: new Column( + mainAxisAlignment: MainAxisAlignment.center, + children: menuWidgets, + ), + ); + } + + // helpers + Widget menuButton(String title, String key) { + return new Padding( + padding: new EdgeInsets.all(4.0), + child: new ConstrainedBox( + constraints: new BoxConstraints(minHeight: 42.0), + child: new FlatButton( + child: new Text( + title, + style: new TextStyle( + color: new Color(0xFF004F8F), + ), + ), + onPressed: () { + tappedMenuButton(key); + }, + ), + ), + ); + } + + // actions + void tappedMenuButton(String key) { + String message = ""; + String hexCode = "#FFFFFF"; + TransitionType transitionType = TransitionType.native; + if (key != "custom") { + if (key == "native") { + hexCode = "#F76F00"; + message = "This screen should have appeared using the default flutter animation for the current OS"; + } else if (key == "preset-from-left") { + hexCode = "#5BF700"; + message = "This screen should have appeared with a slide in from left transition"; + transitionType = TransitionType.inFromLeft; + } else if (key == "preset-fade") { + hexCode = "#F700D2"; + message = "This screen should have appeared with a fade in transition"; + transitionType = TransitionType.fadeIn; + } + Application.router.navigateTo(this.context, "/demo?message=$message&color_hex=$hexCode", + transition: transitionType); + } else { + hexCode = "#DFF700"; + message = "This screen should have appeared with a crazy custom transition"; + var transition = (BuildContext context, Animation animation, Animation secondaryAnimation, + Widget child) { + return new ScaleTransition( + scale: animation, + child: new RotationTransition( + turns: animation, + child: child, + ), + ); + }; + Application.router.navigateTo(this.context, "/demo?message=$message&color_hex=$hexCode", + transition: TransitionType.fadeIn, transitionBuilder: transition, + transitionDuration: const Duration(milliseconds: 600), + ); + } + } +} \ No newline at end of file diff --git a/example/lib/screens/test_screen_01.dart b/example/lib/screens/test_screen_01.dart new file mode 100644 index 0000000..fecb498 --- /dev/null +++ b/example/lib/screens/test_screen_01.dart @@ -0,0 +1,62 @@ +/* + * router + * A Posse Production + * http://goposse.com + * Copyright (c) 2017 Posse Productions LLC. All rights reserved. + * See LICENSE for distribution and usage details. + */ +import 'package:flutter/material.dart'; +import 'package:router_example/helpers/color_helpers.dart'; + +class TestScreen01 extends StatelessWidget { + + TestScreen01({String message = "Testing", Color color = const Color(0xFFFFFFFF)}) + : this.message = message, + this.color = color; + + final String message; + final Color color; + + @override + Widget build(BuildContext context) { + return new Material( + color: color, + child: new Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + new Image( + image: new AssetImage("assets/images/acc_boom.png"), + color: ColorHelpers.blackOrWhiteContrastColor(color), + width: 350.0, + ), + new Padding( + padding: new EdgeInsets.only(left: 50.0, right: 50.0, top: 15.0), + child: new Text( + message, + textAlign: TextAlign.center, + style: new TextStyle( + color: ColorHelpers.blackOrWhiteContrastColor(color), + height: 2.0, + ), + ), + ), + new Padding( + padding: new EdgeInsets.only(top: 15.0), + child: new FlatButton( + onPressed: () { + Navigator.pop(context); + }, + child: new Text( + "OK", + style: new TextStyle( + fontSize: 18.0, + color: ColorHelpers.blackOrWhiteContrastColor(color), + ), + ), + ), + ), + ], + ), + ); + } +} \ No newline at end of file diff --git a/example/pubspec.yaml b/example/pubspec.yaml new file mode 100644 index 0000000..7c2e762 --- /dev/null +++ b/example/pubspec.yaml @@ -0,0 +1,13 @@ +name: router_example +description: An example project for the flutter router. + +dependencies: + flutter: + sdk: flutter + router: + path: ../ +flutter: + uses-material-design: false + assets: + - assets/images/logo_fluro.png + - assets/images/acc_boom.png \ No newline at end of file diff --git a/example/router_example.iml b/example/router_example.iml new file mode 100644 index 0000000..9d5dae1 --- /dev/null +++ b/example/router_example.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/router.dart b/lib/router.dart index e9551eb..9039385 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -5,10 +5,10 @@ * Copyright (c) 2017 Posse Productions LLC. All rights reserved. * See LICENSE for distribution and usage details. */ -library router; +library fluro; import 'package:flutter/foundation.dart'; -import 'package:flutter/src/material/page.dart'; +import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; part 'src/common.dart'; diff --git a/lib/src/common.dart b/lib/src/common.dart index 9b4f1fd..b57d2d4 100644 --- a/lib/src/common.dart +++ b/lib/src/common.dart @@ -5,7 +5,7 @@ * Copyright (c) 2017 Posse Productions LLC. All rights reserved. * See LICENSE for distribution and usage details. */ -part of router; +part of fluro; /// typedef Route RouteCreator(RouteSettings route, Map parameters); diff --git a/lib/src/router.dart b/lib/src/router.dart index 8bee613..3580989 100644 --- a/lib/src/router.dart +++ b/lib/src/router.dart @@ -5,7 +5,7 @@ * Copyright (c) 2017 Posse Productions LLC. All rights reserved. * See LICENSE for distribution and usage details. */ -part of router; +part of fluro; enum TransitionType { native, diff --git a/lib/src/tree.dart b/lib/src/tree.dart index 578f658..724a6c3 100644 --- a/lib/src/tree.dart +++ b/lib/src/tree.dart @@ -5,7 +5,7 @@ * Copyright (c) 2017 Posse Productions LLC. All rights reserved. * See LICENSE for distribution and usage details. */ -part of router; +part of fluro; enum RouteTreeNodeType { component,