From 93c6dbb9f743e9822147af2bcbd8a14a2e7a825a Mon Sep 17 00:00:00 2001 From: szakarias Date: Mon, 13 Feb 2017 11:14:34 +0100 Subject: [PATCH] Add platform_services sample (#8058) * Add platform_services sample * update build.gradle to use latest scripts * use FlutterActivity * Updated ExampleInstrumentedTest.java and deleted FlutterPlugin.groovy * Remove getRandom code from main.dart * remove unused import --- examples/platform_services/.gitignore | 8 + examples/platform_services/README.md | 66 +++ examples/platform_services/android/.gitignore | 12 + .../platform_services/android/app/.gitignore | 1 + .../android/app/build.gradle | 46 ++ .../flutter/ExampleInstrumentedTest.java | 99 +++++ .../android/app/src/main/AndroidManifest.xml | 26 ++ .../com/example/flutter/ExampleActivity.java | 88 ++++ .../app/src/main/res/values/strings.xml | 5 + .../platform_services/android/build.gradle | 23 + .../android/buildSrc/build.gradle | 7 + .../gradle-plugins/flutter.properties | 1 + .../android/gradle.properties | 1 + .../platform_services/android/settings.gradle | 1 + examples/platform_services/ios/.gitignore | 38 ++ .../ios/Flutter/Flutter.xcconfig | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 397 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../ios/Runner/AppDelegate.h | 10 + .../ios/Runner/AppDelegate.m | 28 ++ .../AppIcon.appiconset/Contents.json | 68 +++ .../Runner/Base.lproj/LaunchScreen.storyboard | 27 ++ .../ios/Runner/Base.lproj/Main.storyboard | 25 ++ .../platform_services/ios/Runner/Info.plist | 47 +++ .../ios/Runner/LocationProvider.h | 9 + .../ios/Runner/LocationProvider.m | 39 ++ examples/platform_services/ios/Runner/main.m | 14 + examples/platform_services/lib/main.dart | 55 +++ examples/platform_services/pubspec.yaml | 9 + 29 files changed, 1158 insertions(+) create mode 100644 examples/platform_services/.gitignore create mode 100644 examples/platform_services/README.md create mode 100644 examples/platform_services/android/.gitignore create mode 100644 examples/platform_services/android/app/.gitignore create mode 100644 examples/platform_services/android/app/build.gradle create mode 100644 examples/platform_services/android/app/src/androidTest/java/com/example/flutter/ExampleInstrumentedTest.java create mode 100644 examples/platform_services/android/app/src/main/AndroidManifest.xml create mode 100644 examples/platform_services/android/app/src/main/java/com/example/flutter/ExampleActivity.java create mode 100644 examples/platform_services/android/app/src/main/res/values/strings.xml create mode 100644 examples/platform_services/android/build.gradle create mode 100644 examples/platform_services/android/buildSrc/build.gradle create mode 100644 examples/platform_services/android/buildSrc/src/main/resources/META-INF/gradle-plugins/flutter.properties create mode 100644 examples/platform_services/android/gradle.properties create mode 100644 examples/platform_services/android/settings.gradle create mode 100644 examples/platform_services/ios/.gitignore create mode 100644 examples/platform_services/ios/Flutter/Flutter.xcconfig create mode 100644 examples/platform_services/ios/Runner.xcodeproj/project.pbxproj create mode 100644 examples/platform_services/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 examples/platform_services/ios/Runner/AppDelegate.h create mode 100644 examples/platform_services/ios/Runner/AppDelegate.m create mode 100644 examples/platform_services/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 examples/platform_services/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 examples/platform_services/ios/Runner/Base.lproj/Main.storyboard create mode 100644 examples/platform_services/ios/Runner/Info.plist create mode 100644 examples/platform_services/ios/Runner/LocationProvider.h create mode 100644 examples/platform_services/ios/Runner/LocationProvider.m create mode 100644 examples/platform_services/ios/Runner/main.m create mode 100644 examples/platform_services/lib/main.dart create mode 100644 examples/platform_services/pubspec.yaml diff --git a/examples/platform_services/.gitignore b/examples/platform_services/.gitignore new file mode 100644 index 00000000000..9b3426eff30 --- /dev/null +++ b/examples/platform_services/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +.atom/ +.idea +.packages +.pub/ +build/ +packages/ +pubspec.lock diff --git a/examples/platform_services/README.md b/examples/platform_services/README.md new file mode 100644 index 00000000000..38ed07ae798 --- /dev/null +++ b/examples/platform_services/README.md @@ -0,0 +1,66 @@ +# Example of calling platform services from Flutter + +This project demonstrates how to connect a Flutter app to platform specific services. + +You can read more about +[accessing platform and third-party services in Flutter](https://flutter.io/platform-services/). + +## iOS + +### Configure + +Create an `ios/Flutter/Generated.xcconfig` file with this entry: + + * `FLUTTER_ROOT=[absolute path to the Flutter SDK]` + +There are a number of other parameters you can control with this file: + + * `FLUTTER_APPLICATION_PATH`: The path to the directory that contains your + `pubspec.yaml` file relative to your `xcodeproj` file. + * `FLUTTER_BUILD_MODE`: Whether to build for `debug`, `profile`, or `release`. + Defaults to `release`. + * `FLUTTER_TARGET`: The path to your `main.dart` relative to your + `pubspec.yaml`. Defaults to `lib/main.dart`. + * `FLUTTER_FRAMEWORK_DIR`: The absolute path to the directory that contains + `Flutter.framework`. Defaults to the `ios-release` version of + `Flutter.framework` in the `bin/cache` directory of the Flutter SDK. + +### Build + +Once you've configured your project, you can open `ios/Runner.xcodeproj` +in Xcode and build the project as usual. + +## Android + +### Configure + +Create an `android/local.properties` file with these entries: + + * `sdk.dir=[path to the Android SDK]` + * `flutter.sdk=[path to the Flutter SDK]` + +There are a number of other parameters you can control with this file: + + * `flutter.buildMode`: Whether to build for `debug`, `profile`, or `release`. + Defaults to `release`. + * `flutter.jar`: The path to `flutter.jar`. Defaults to the + `android-arm-release` version of `flutter.jar` in the `bin/cache` directory + of the Flutter SDK. + +See `android/app/build.gradle` for project specific settings, including: + + * `source`: The path to the directory that contains your `pubspec.yaml` file + relative to your `build.gradle` file. + * `target`: The path to your `main.dart` relative to your `pubspec.yaml`. + Defaults to `lib/main.dart`. + +### Build + +To build directly with `gradle`, use the following commands: + + * `cd android` + * `gradle wrapper` + * `./gradlew build` + +To build with Android Studio, open the `android` folder in Android Studio and +build the project as usual. diff --git a/examples/platform_services/android/.gitignore b/examples/platform_services/android/.gitignore new file mode 100644 index 00000000000..5c4ef82869b --- /dev/null +++ b/examples/platform_services/android/.gitignore @@ -0,0 +1,12 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures + +/gradle +/gradlew +/gradlew.bat diff --git a/examples/platform_services/android/app/.gitignore b/examples/platform_services/android/app/.gitignore new file mode 100644 index 00000000000..796b96d1c40 --- /dev/null +++ b/examples/platform_services/android/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/examples/platform_services/android/app/build.gradle b/examples/platform_services/android/app/build.gradle new file mode 100644 index 00000000000..4e2e46b56c2 --- /dev/null +++ b/examples/platform_services/android/app/build.gradle @@ -0,0 +1,46 @@ +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" + +android { + compileSdkVersion 25 + buildToolsVersion '25.0.2' + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + 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 + } + } +} + +flutter { + source '../..' +} + +dependencies { + androidTestCompile 'com.android.support:support-annotations:25.0.0' + androidTestCompile 'com.android.support.test:runner:0.5' + androidTestCompile 'com.android.support.test:rules:0.5' +} diff --git a/examples/platform_services/android/app/src/androidTest/java/com/example/flutter/ExampleInstrumentedTest.java b/examples/platform_services/android/app/src/androidTest/java/com/example/flutter/ExampleInstrumentedTest.java new file mode 100644 index 00000000000..2fc8eebe99f --- /dev/null +++ b/examples/platform_services/android/app/src/androidTest/java/com/example/flutter/ExampleInstrumentedTest.java @@ -0,0 +1,99 @@ +package com.example.flutter; + +import android.graphics.Bitmap; +import android.support.test.InstrumentationRegistry; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import io.flutter.view.FlutterView; + +import android.app.Instrumentation; +import android.support.test.InstrumentationRegistry; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Rule + public ActivityTestRule activityRule = + new ActivityTestRule<>(ExampleActivity.class); + + + @Test + public void testBitmap() { + final Instrumentation instr = InstrumentationRegistry.getInstrumentation(); + final BitmapPoller poller = new BitmapPoller(5); + instr.runOnMainSync(new Runnable() { + public void run() { + final FlutterView flutterView = (FlutterView) activityRule.getActivity() + .getFlutterView(); + + // Call onPostResume to start the engine's renderer even if the activity + // is paused in the test environment. + flutterView.onPostResume(); + + poller.start(flutterView); + } + }); + + Bitmap bitmap = null; + try { + bitmap = poller.waitForBitmap(); + } catch (InterruptedException e) { + fail(e.getMessage()); + } + + assertNotNull(bitmap); + assertTrue(bitmap.getWidth() > 0); + assertTrue(bitmap.getHeight() > 0); + + // Check that a pixel matches the default Material background color. + assertTrue(bitmap.getPixel(bitmap.getWidth() - 1, bitmap.getHeight() - 1) == 0xFFFAFAFA); + } + + // Waits on a FlutterView until it is able to produce a bitmap. + private class BitmapPoller { + private int triesPending; + private int waitMsec; + private FlutterView flutterView; + private Bitmap bitmap; + private CountDownLatch latch = new CountDownLatch(1); + + private final int delayMsec = 1000; + + BitmapPoller(int tries) { + triesPending = tries; + waitMsec = delayMsec * tries + 100; + } + + void start(FlutterView flutterView) { + this.flutterView = flutterView; + flutterView.postDelayed(checkBitmap, delayMsec); + } + + Bitmap waitForBitmap() throws InterruptedException { + latch.await(waitMsec, TimeUnit.MILLISECONDS); + return bitmap; + } + + private Runnable checkBitmap = new Runnable() { + public void run() { + bitmap = flutterView.getBitmap(); + triesPending--; + if (bitmap != null || triesPending == 0) { + latch.countDown(); + } else { + flutterView.postDelayed(checkBitmap, delayMsec); + } + } + }; + } +} diff --git a/examples/platform_services/android/app/src/main/AndroidManifest.xml b/examples/platform_services/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000000..772377e0e88 --- /dev/null +++ b/examples/platform_services/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + diff --git a/examples/platform_services/android/app/src/main/java/com/example/flutter/ExampleActivity.java b/examples/platform_services/android/app/src/main/java/com/example/flutter/ExampleActivity.java new file mode 100644 index 00000000000..f63582ce0b0 --- /dev/null +++ b/examples/platform_services/android/app/src/main/java/com/example/flutter/ExampleActivity.java @@ -0,0 +1,88 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package com.example.flutter; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationManager; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; + +import io.flutter.app.FlutterActivity; +import io.flutter.view.FlutterMain; +import io.flutter.view.FlutterView; + +import java.io.File; +import org.json.JSONException; +import org.json.JSONObject; + +public class ExampleActivity extends FlutterActivity { + private static final String TAG = "ExampleActivity"; + private FlutterView flutterView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + flutterView = getFlutterView(); + flutterView.addOnMessageListener("getLocation", + new FlutterView.OnMessageListener() { + @Override + public String onMessage(FlutterView view, String message) { + return onGetLocation(message); + } + }); + } + + private String onGetLocation(String json) { + String provider; + try { + JSONObject message = new JSONObject(json); + provider = message.getString("provider"); + } catch (JSONException e) { + Log.e(TAG, "JSON exception", e); + return null; + } + + String locationProvider; + if (provider.equals("network")) { + locationProvider = LocationManager.NETWORK_PROVIDER; + } else if (provider.equals("gps")) { + locationProvider = LocationManager.GPS_PROVIDER; + } else { + return null; + } + + String permission = "android.permission.ACCESS_FINE_LOCATION"; + Location location = null; + if (checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) { + LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + location = locationManager.getLastKnownLocation(locationProvider); + } + + JSONObject reply = new JSONObject(); + try { + if (location != null) { + reply.put("latitude", location.getLatitude()); + reply.put("longitude", location.getLongitude()); + } else { + reply.put("latitude", 0); + reply.put("longitude", 0); + } + } catch (JSONException e) { + Log.e(TAG, "JSON exception", e); + return null; + } + + return reply.toString(); + } +} \ No newline at end of file diff --git a/examples/platform_services/android/app/src/main/res/values/strings.xml b/examples/platform_services/android/app/src/main/res/values/strings.xml new file mode 100644 index 00000000000..878e11ff6eb --- /dev/null +++ b/examples/platform_services/android/app/src/main/res/values/strings.xml @@ -0,0 +1,5 @@ + + + Platform Services + Flutter Application + diff --git a/examples/platform_services/android/build.gradle b/examples/platform_services/android/build.gradle new file mode 100644 index 00000000000..d82a1548b98 --- /dev/null +++ b/examples/platform_services/android/build.gradle @@ -0,0 +1,23 @@ +buildscript { + repositories { + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:2.2.3' + } +} + +allprojects { + repositories { + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} + +task wrapper(type: Wrapper) { + gradleVersion = '2.14.1' +} diff --git a/examples/platform_services/android/buildSrc/build.gradle b/examples/platform_services/android/buildSrc/build.gradle new file mode 100644 index 00000000000..b85575e9de5 --- /dev/null +++ b/examples/platform_services/android/buildSrc/build.gradle @@ -0,0 +1,7 @@ +repositories { + jcenter() +} + +dependencies { + compile "com.android.tools.build:gradle:2.2.3" +} diff --git a/examples/platform_services/android/buildSrc/src/main/resources/META-INF/gradle-plugins/flutter.properties b/examples/platform_services/android/buildSrc/src/main/resources/META-INF/gradle-plugins/flutter.properties new file mode 100644 index 00000000000..1d3e2dda74c --- /dev/null +++ b/examples/platform_services/android/buildSrc/src/main/resources/META-INF/gradle-plugins/flutter.properties @@ -0,0 +1 @@ +implementation-class=io.flutter.gradle.FlutterPlugin diff --git a/examples/platform_services/android/gradle.properties b/examples/platform_services/android/gradle.properties new file mode 100644 index 00000000000..8bd86f68051 --- /dev/null +++ b/examples/platform_services/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/examples/platform_services/android/settings.gradle b/examples/platform_services/android/settings.gradle new file mode 100644 index 00000000000..e7b4def49cb --- /dev/null +++ b/examples/platform_services/android/settings.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/examples/platform_services/ios/.gitignore b/examples/platform_services/ios/.gitignore new file mode 100644 index 00000000000..fc394654569 --- /dev/null +++ b/examples/platform_services/ios/.gitignore @@ -0,0 +1,38 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +*.lock +profile + +DerivedData/ +build/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/app.flx +/Flutter/app.dylib +/Flutter/app.zip +/Flutter/Flutter.framework +/Flutter/Generated.xcconfig +/ServiceDefinitions.json diff --git a/examples/platform_services/ios/Flutter/Flutter.xcconfig b/examples/platform_services/ios/Flutter/Flutter.xcconfig new file mode 100644 index 00000000000..592ceee85b8 --- /dev/null +++ b/examples/platform_services/ios/Flutter/Flutter.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/examples/platform_services/ios/Runner.xcodeproj/project.pbxproj b/examples/platform_services/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000000..9c7318c7e6c --- /dev/null +++ b/examples/platform_services/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,397 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 9705A1C51CF9049000538489 /* app.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEB81CF902C7004384FC /* app.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + 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 /* Flutter.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Flutter.xcconfig */; }; + 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; + 9740EEBB1CF902C7004384FC /* app.flx in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB71CF902C7004384FC /* app.flx */; }; + 977505191CFDF23500BC28DA /* LocationProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 977505181CFDF23500BC28DA /* LocationProvider.m */; }; + 97A38A351CFDEC880099F1B4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 97A38A341CFDEC880099F1B4 /* 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 = ( + 9705A1C51CF9049000538489 /* app.dylib in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 9740EEB21CF90195004384FC /* Flutter.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Flutter.xcconfig; path = Flutter/Flutter.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 = ""; }; + 9740EEB81CF902C7004384FC /* app.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = app.dylib; path = Flutter/app.dylib; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 977505171CFDF21E00BC28DA /* LocationProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocationProvider.h; sourceTree = ""; }; + 977505181CFDF23500BC28DA /* LocationProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LocationProvider.m; sourceTree = ""; }; + 97A38A331CFDEC680099F1B4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 97A38A341CFDEC880099F1B4 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; 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 */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 9740EEB71CF902C7004384FC /* app.flx */, + 9740EEB81CF902C7004384FC /* app.dylib */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Flutter.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 97A38A331CFDEC680099F1B4 /* AppDelegate.h */, + 97A38A341CFDEC880099F1B4 /* AppDelegate.m */, + 977505171CFDF21E00BC28DA /* LocationProvider.h */, + 977505181CFDF23500BC28DA /* LocationProvider.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 /* ShellScript */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + ); + 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 = 0820; + 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 */, + 9740EEB41CF90195004384FC /* Flutter.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 9740EEB61CF901F6004384FC /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh $FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97A38A351CFDEC880099F1B4 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 977505191CFDF23500BC28DA /* LocationProvider.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 /* Flutter.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 = 9740EEB21CF90195004384FC /* Flutter.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 /* Flutter.xcconfig */; + buildSettings = { + 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.example.PlatformServices; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Flutter.xcconfig */; + buildSettings = { + 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.example.PlatformServices; + 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/examples/platform_services/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/platform_services/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000..4c426651560 --- /dev/null +++ b/examples/platform_services/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/platform_services/ios/Runner/AppDelegate.h b/examples/platform_services/ios/Runner/AppDelegate.h new file mode 100644 index 00000000000..145ec31efd4 --- /dev/null +++ b/examples/platform_services/ios/Runner/AppDelegate.h @@ -0,0 +1,10 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/examples/platform_services/ios/Runner/AppDelegate.m b/examples/platform_services/ios/Runner/AppDelegate.m new file mode 100644 index 00000000000..bf8e1915c5f --- /dev/null +++ b/examples/platform_services/ios/Runner/AppDelegate.m @@ -0,0 +1,28 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "AppDelegate.h" + +#import +#import "LocationProvider.h" + +@implementation AppDelegate { + LocationProvider* _locationProvider; +} + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + FlutterDartProject* project = [[FlutterDartProject alloc] initFromDefaultSourceForConfiguration]; + self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; + FlutterViewController* flutterController = [[FlutterViewController alloc] initWithProject:project + nibName:nil + bundle:nil]; + _locationProvider = [[LocationProvider alloc] init]; + [flutterController addMessageListener:_locationProvider]; + + self.window.rootViewController = flutterController; + [self.window makeKeyAndVisible]; + return YES; +} + +@end diff --git a/examples/platform_services/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/platform_services/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000000..36d2c80d889 --- /dev/null +++ b/examples/platform_services/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/examples/platform_services/ios/Runner/Base.lproj/LaunchScreen.storyboard b/examples/platform_services/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000000..ebf48f60397 --- /dev/null +++ b/examples/platform_services/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/platform_services/ios/Runner/Base.lproj/Main.storyboard b/examples/platform_services/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000000..f56d2f3bb56 --- /dev/null +++ b/examples/platform_services/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/platform_services/ios/Runner/Info.plist b/examples/platform_services/ios/Runner/Info.plist new file mode 100644 index 00000000000..64f7ee4910e --- /dev/null +++ b/examples/platform_services/ios/Runner/Info.plist @@ -0,0 +1,47 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + PlatformServices + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/examples/platform_services/ios/Runner/LocationProvider.h b/examples/platform_services/ios/Runner/LocationProvider.h new file mode 100644 index 00000000000..e646fdf4fc5 --- /dev/null +++ b/examples/platform_services/ios/Runner/LocationProvider.h @@ -0,0 +1,9 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import + +@interface LocationProvider : NSObject + +@end diff --git a/examples/platform_services/ios/Runner/LocationProvider.m b/examples/platform_services/ios/Runner/LocationProvider.m new file mode 100644 index 00000000000..e6e0cc7b628 --- /dev/null +++ b/examples/platform_services/ios/Runner/LocationProvider.m @@ -0,0 +1,39 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "LocationProvider.h" + +#import + +@implementation LocationProvider { + CLLocationManager* _locationManager; +} + +@synthesize messageName = _messageName; + +- (instancetype) init { + self = [super init]; + if (self) + self->_messageName = @"getLocation"; + return self; +} + +- (NSString*)didReceiveString:(NSString*)message { + if (_locationManager == nil) { + _locationManager = [[CLLocationManager alloc] init]; + [_locationManager startMonitoringSignificantLocationChanges]; + } + + CLLocation* location = _locationManager.location; + + NSDictionary* response = @{ + @"latitude": @(location.coordinate.latitude), + @"longitude": @(location.coordinate.longitude), + }; + + NSData* data = [NSJSONSerialization dataWithJSONObject:response options:0 error:nil]; + return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; +} + +@end diff --git a/examples/platform_services/ios/Runner/main.m b/examples/platform_services/ios/Runner/main.m new file mode 100644 index 00000000000..a9220f12d84 --- /dev/null +++ b/examples/platform_services/ios/Runner/main.m @@ -0,0 +1,14 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, + NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/platform_services/lib/main.dart b/examples/platform_services/lib/main.dart new file mode 100644 index 00000000000..a0870d36f94 --- /dev/null +++ b/examples/platform_services/lib/main.dart @@ -0,0 +1,55 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class PlatformServices extends StatefulWidget { + @override + _PlatformServicesState createState() => new _PlatformServicesState(); +} + +class _PlatformServicesState extends State { + double _latitude; + double _longitude; + + @override + Widget build(BuildContext context) { + return new Material( + child: new Center( + child: new Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + new Text('Hello from Flutter!'), + new RaisedButton( + child: new Text('Get Location'), + onPressed: _getLocation + ), + new Text('Latitude: $_latitude, Longitude: $_longitude'), + ] + ) + ) + ); + } + + Future _getLocation() async { + final Map message = {'provider': 'network'}; + final Map reply = await PlatformMessages.sendJSON('getLocation', message); + // If the widget was removed from the tree while the message was in flight, + // we want to discard the reply rather than calling setState to update our + // non-existent appearance. + if (!mounted) + return; + setState(() { + _latitude = reply['latitude'].toDouble(); + _longitude = reply['longitude'].toDouble(); + }); + } +} + +void main() { + runApp(new PlatformServices()); +} diff --git a/examples/platform_services/pubspec.yaml b/examples/platform_services/pubspec.yaml new file mode 100644 index 00000000000..c0cbf0b0695 --- /dev/null +++ b/examples/platform_services/pubspec.yaml @@ -0,0 +1,9 @@ +name: platform_services + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter