Skip to content

Commit 0381706

Browse files
amalik2Adil Malik
andauthored
Flutter deep linking + multi-platform controls example (#37)
* wip * Finished flutter deep linking examples * remove gitignored files Co-authored-by: Adil Malik <[email protected]>
1 parent 8be692a commit 0381706

File tree

31 files changed

+614
-228
lines changed

31 files changed

+614
-228
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ fastlane/Preview.html
7575
fastlane/screenshots
7676
.dart_tool
7777
.packages
78+
.flutter-plugins
79+
.flutter-plugins-dependencies
7880

7981
storybook-static/
8082
*.log

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ If you wanted to use those query parameters, your application would need to pars
3131
Examples of parsing query parameters:
3232
- [Android](examples/android-material-ui/app/app/src/main/java/com/intuit/august2020/storybookdemoapp/MainActivity.kt#L42)
3333
- [iOS](examples/ios-material-ui/app/iOSStoryBookDemo/iOSStoryBookDemo/AppDelegate.swift#L83)
34+
- [Flutter](examples/flutter/app/lib/main.dart#L60)
3435

3536
You can read more about how to setup deep linking for Android [here](https://developer.android.com/training/app-links/deep-linking).
3637

3738
For iOS, [this article](https://medium.com/wolox/ios-deep-linking-url-scheme-vs-universal-links-50abd3802f97) explains how to set up deep linking. Note that for the examples in this repo, we use URL schemes instead of Universal Links since they are simpler to set up.
3839

39-
Deep linking should also work on Flutter, but there are no examples for this yet.
40+
For Flutter, the [uni_links](https://pub.dev/packages/uni_links) package makes it easy to set up deep linking support for both Android and iOS.
4041

4142
### 2. Launch Parameters
4243
appetize.io allows you to pass in custom launch parameters which will be sent to your mobile application when it first starts up. In your application, you must create a handler that determines what to render based on what those launch parameters are.
@@ -81,9 +82,8 @@ If you are using deep linking, your `.storybook` folder should also have a `prev
8182
Examples of how to use this module as both a build tool and as a component library can be found [in this folder](examples/). The `app` folder inside each example contains the source code of the application the example is for.
8283

8384
- [Android storybook with controls](https://storybookjs.github.io/native/@storybook/native-controls-example/index.html?path=/story/button--example)
84-
- [Android storybook with deep linking](https://storybookjs.github.io/native/@storybook/native-android-material-deep-link-example/index.html)
85+
- [Flutter storybook with controls](https://storybookjs.github.io/native/@storybook/native-flutter-example/index.html?path=/story/android--button)
8586
- [iOS storybook with deep linking](https://storybookjs.github.io/native/@storybook/native-ios-example-deep-link/index.html?path=/story/button--example)
86-
- [Flutter storybook with launch parameters](https://storybookjs.github.io/native/@storybook/native-flutter-example/index.html?path=/story/android--button)
8787

8888
More example static storybooks can be found [here](https://storybookjs.github.io/native/)
8989

examples/controls/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "@storybook/native-controls-example",
33
"version": "1.1.1",
44
"private": true,
5-
"description": "A demo app showing how to use controls",
5+
"description": "An Android demo app showing how to use controls",
66
"repository": "",
77
"author": "Adil Malik <[email protected]>",
88
"license": "MIT",

examples/flutter/.storybook/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module.exports = {
2-
stories: ["../stories/*.stories.jsx"],
2+
stories: ["../src/*.stories.jsx"],
33
addons: [
44
"@storybook/addon-docs",
55
"@storybook/addon-controls",

examples/flutter/app/android/app/build.gradle

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,6 @@ android {
4444
versionCode flutterVersionCode.toInteger()
4545
versionName flutterVersionName
4646
}
47-
48-
buildTypes {
49-
release {
50-
// TODO: Add your own signing config for the release build.
51-
// Signing with the debug keys for now, so `flutter run --release` works.
52-
signingConfig signingConfigs.debug
53-
}
54-
}
5547
}
5648

5749
flutter {

examples/flutter/app/android/app/src/main/AndroidManifest.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@
4646
<data android:mimeType="text/plain" />
4747
</intent-filter>
4848

49+
<intent-filter>
50+
<action android:name="android.intent.action.VIEW" />
51+
<category android:name="android.intent.category.DEFAULT" />
52+
<category android:name="android.intent.category.BROWSABLE" />
53+
<data android:scheme="sb-native" android:host="deeplink" />
54+
</intent-filter>
55+
4956
</activity>
5057
<!-- Don't delete the meta-data below.
5158
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package flutter.company.com.flutter_storybook;
2+
3+
import android.net.Uri;
4+
5+
import org.json.JSONException;
6+
import org.json.JSONObject;
7+
8+
public class JsonUtils {
9+
10+
public static String convertQueryStringToJSON(Uri uri) throws JSONException {
11+
JSONObject object = new JSONObject();
12+
for (String param : uri.getQueryParameterNames()) {
13+
object.put(param, uri.getQueryParameter(param));
14+
}
15+
16+
return object.toString();
17+
}
18+
19+
}
Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,6 @@
11
package flutter.company.com.flutter_storybook
22

3-
import android.content.Intent
4-
import android.os.Bundle
5-
import io.flutter.app.FlutterActivity
6-
import io.flutter.plugin.common.MethodChannel
7-
3+
import io.flutter.embedding.android.FlutterActivity;
84

95
class MainActivity : FlutterActivity() {
10-
private var sharedText: String? = null
11-
12-
override fun onCreate(savedInstanceState: Bundle?) {
13-
super.onCreate(savedInstanceState)
14-
val intent = intent
15-
val action = intent.action
16-
val type = intent.type
17-
if (Intent.ACTION_SEND == action && type != null) {
18-
if ("text/plain" == type) {
19-
sharedText = intent.getStringExtra(Intent.EXTRA_TEXT)
20-
}
21-
} else {
22-
// If appetize sends text another way, use their API
23-
val pageName = intent.getStringExtra("page")
24-
if(pageName != null) {
25-
sharedText = "{\"page\":\"$pageName\"}"
26-
}
27-
}
28-
MethodChannel(flutterView, "app.channel.shared.data").setMethodCallHandler { call, result ->
29-
if (call.method.contentEquals("getSharedData")) {
30-
result.success(sharedText)
31-
sharedText = null
32-
}
33-
}
34-
}
356
}

examples/flutter/app/ios/Flutter/AppFrameworkInfo.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<plist version="1.0">
44
<dict>
55
<key>CFBundleDevelopmentRegion</key>
6-
<string>$(DEVELOPMENT_LANGUAGE)</string>
6+
<string>en</string>
77
<key>CFBundleExecutable</key>
88
<string>App</string>
99
<key>CFBundleIdentifier</key>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
1+
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
22
#include "Generated.xcconfig"

0 commit comments

Comments
 (0)