hujianhui 2022-01-10 11:32:49 +08:00
commit 801934e541
97 changed files with 2025 additions and 1076 deletions

13
.github/workflows/issue.yml vendored 100644
View File

@ -0,0 +1,13 @@
name: Notify
on:
issues:
types: [opened]
issue_comment:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Notify
run: curl --location --request POST 'https://api.finogeeks.club/api/v1/finstore/webhooks/61b331d79b3dad0001f72fa2/postreceive?nonce=jhd2QyrArsc' --header "Content-Type:application/json" --data-raw '{"msg":"仓库 ${{github.repository}} 有新的 issue"}'

View File

@ -0,0 +1,11 @@
name: Notify
on:
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Notify
run: curl --location --request POST 'https://api.finogeeks.club/api/v1/finstore/webhooks/61b331d79b3dad0001f72fa2/postreceive?nonce=jhd2QyrArsc' --header "Content-Type:application/json" --data-raw '{"msg":"仓库 ${{github.repository}} 有新的 PR ${{ github.event.pull_request._links.html.href }}"}'

17
.gitignore vendored
View File

@ -5,13 +5,9 @@
.packages .packages
.pub/ .pub/
build/
# See https://www.dartlang.org/guides/libraries/private-files
# Files and directories created by pub # Files and directories created by pub
.dart_tool/ .dart_tool/
.packages .packages
build/
# If you're building an application, you may want to check-in your pubspec.lock # If you're building an application, you may want to check-in your pubspec.lock
pubspec.lock pubspec.lock
@ -27,3 +23,16 @@ doc/api/
*.js_ *.js_
*.js.deps *.js.deps
*.js.map *.js.map
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
android/bin/
android/.project

121
README.md
View File

@ -1,18 +1,66 @@
# Flutter <p align="center">
<a href="https://www.finclip.com?from=github">
<img width="auto" src="https://www.finclip.com/mop/document/images/logo.png">
</a>
</p>
Flutter <p align="center">
<strong>FinClip Flutter SDK</strong></br>
<p>
<p align="center">
Flutter
<p>
## <p align="center">
👉 <a href="https://www.finclip.com?from=github">https://www.finclip.com/</a> 👈
</p>
pubspec.yaml <div align="center">
``` <a href="#"><img src="https://img.shields.io/badge/%E4%B8%93%E5%B1%9E%E5%BC%80%E5%8F%91%E8%80%85-20000%2B-brightgreen"></a>
<a href="#"><img src="https://img.shields.io/badge/%E5%B7%B2%E4%B8%8A%E6%9E%B6%E5%B0%8F%E7%A8%8B%E5%BA%8F-6000%2B-blue"></a>
<a href="#"><img src="https://img.shields.io/badge/%E5%B7%B2%E9%9B%86%E6%88%90%E5%B0%8F%E7%A8%8B%E5%BA%8F%E5%BA%94%E7%94%A8-75%2B-yellow"></a>
<a href="#"><img src="https://img.shields.io/badge/%E5%AE%9E%E9%99%85%E8%A6%86%E7%9B%96%E7%94%A8%E6%88%B7-2500%20%E4%B8%87%2B-orange"></a>
<a href="https://www.zhihu.com/org/finchat"><img src="https://img.shields.io/badge/FinClip--lightgrey?logo=zhihu&style=social"></a>
<a href="https://www.finclip.com/blog/"><img src="https://img.shields.io/badge/FinClip%20Blog--lightgrey?logo=ghost&style=social"></a>
</div>
<p align="center">
<div align="center">
[](https://www.finclip.com/) | [](https://www.finclip.com/#/market) | [](https://www.finclip.com/mop/document/) | [](https://www.finclip.com/mop/document/introduce/quickStart/cloud-server-deployment-guide.html) | [SDK ](https://www.finclip.com/mop/document/introduce/quickStart/intergration-guide.html) | [API ](https://www.finclip.com/mop/document/develop/api/overview.html) | [](https://www.finclip.com/mop/document/develop/component/overview.html) | [](https://www.finclip.com/mop/document/operate/safety.html)
</div>
-----
## 🤔 FinClip ?
**** APP
**** APP SDK
FinClip
## Flutter 使
FinClip SDK APP Flutter SDK 使
## Flutter
`pubspec.yaml`
```yaml
mop: latest.version mop: latest.version
``` ```
## ## 🖥
``` ```flutter
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
@ -34,7 +82,7 @@ class _MyAppState extends State<MyApp> {
// Platform messages are asynchronous, so we initialize in an async method. // Platform messages are asynchronous, so we initialize in an async method.
Future<void> init() async { Future<void> init() async {
if (Platform.isIOS) { if (Platform.isiOS) {
//com.finogeeks.mopExample //com.finogeeks.mopExample
final res = await Mop.instance.initialize( final res = await Mop.instance.initialize(
'22LyZEib0gLTQdU3MUauARlLry7JL/2fRpscC9kpGZQA', '1c11d7252c53e0b6', '22LyZEib0gLTQdU3MUauARlLry7JL/2fRpscC9kpGZQA', '1c11d7252c53e0b6',
@ -115,15 +163,13 @@ class _MyAppState extends State<MyApp> {
} }
``` ```
## ## 📋
1. ### 1.
使sdkapisdksdk 使 SDK API SDK SDK
``` ```
///
/// ///
/// initialize mop miniprogram engine. /// initialize mop miniprogram engine.
/// ///
@ -137,18 +183,16 @@ class _MyAppState extends State<MyApp> {
{String apiServer, String apiPrefix}) {String apiServer, String apiPrefix})
``` ```
使: 使
``` ```
final res = await Mop.instance.initialize( final res = await Mop.instance.initialize(
'22LyZEib0gLTQdU3MUauARlLry7JL/2fRpscC9kpGZQA', '1c11d7252c53e0b6', '22LyZEib0gLTQdU3MUauARlLry7JL/2fRpscC9kpGZQA', '1c11d7252c53e0b6',
apiServer: 'https://api.finclip.com', apiPrefix: '/api/v1/mop'); apiServer: 'https://api.finclip.com', apiPrefix: '/api/v1/mop');
``` ```
2. ### 2.
``` ```
///
/// ///
/// open the miniprogram [appId] from the mop server. /// open the miniprogram [appId] from the mop server.
/// ///
@ -161,9 +205,9 @@ final res = await Mop.instance.initialize(
{final String path, final String query, final int sequence}) {final String path, final String query, final int sequence})
``` ```
3. 使 ### 3. 使
appId,name,icon,description,version,thumbnail `appId`, `name`, `icon`, `description`, `version`, `thumbnail`
``` ```
/// ///
@ -175,7 +219,7 @@ final res = await Mop.instance.initialize(
Future<Map<String, dynamic>> currentApplet() Future<Map<String, dynamic>> currentApplet()
``` ```
4. ### 4.
``` ```
/// ///
@ -185,10 +229,9 @@ final res = await Mop.instance.initialize(
Future closeAllApplets() Future closeAllApplets()
``` ```
5. ### 5.
``` ```
/// ///
/// clear applets cache /// clear applets cache
@ -197,7 +240,7 @@ final res = await Mop.instance.initialize(
Future clearApplets() Future clearApplets()
``` ```
6. ### 6.
使 使
@ -210,7 +253,6 @@ final res = await Mop.instance.initialize(
``` ```
``` ```
abstract class AppletHandler { abstract class AppletHandler {
/// ///
@ -238,19 +280,19 @@ abstract class AppletHandler {
} }
``` ```
7. api ### 7. API
SDK APIAPIAPI SDK API API API
··· ```
/// ///
/// register extension api /// register extension api
/// api /// api
/// ///
void registerExtensionApi(String name, ExtensionApiHandler handler) void registerExtensionApi(String name, ExtensionApiHandler handler)
··· ```
iosFinChatConf.js iOS `FinChatConf.js`
``` ```
module.exports = { module.exports = {
@ -263,4 +305,23 @@ module.exports = {
} }
] ]
} }
``` ```
## 🔗
FinClip
- [FinClip ](https://www.finclip.com/#/home)
- [](https://www.finclip.com/#/market)
- [](https://www.finclip.com/mop/document/)
- [SDK ](https://www.finclip.com/mop/document/introduce/quickStart/intergration-guide.html)
- [](https://www.finclip.com/mop/document/develop/guide/structure.html)
- [iOS ](https://www.finclip.com/mop/document/runtime-sdk/ios/ios-integrate.html)
- [Android ](https://www.finclip.com/mop/document/runtime-sdk/android/android-integrate.html)
- [Flutter ](https://www.finclip.com/mop/document/runtime-sdk/flutter/flutter-integrate.html)
##
****<br>
<img width="150px" src="https://www.finclip.com/mop/document/images/ic_qr.svg">
finclip <br>
<img width="150px" src="https://finclip-homeweb-1251849568.cos.ap-guangzhou.myqcloud.com/images/ldy111.jpg">

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

View File

@ -0,0 +1,13 @@
arguments=
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(7.0-rc-1))
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=C\:/Program Files/Eclipse Foundation/jdk-11.0.12.7-hotspot
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=true
show.executions.view=true

View File

@ -31,7 +31,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.3' classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61"
} }
@ -68,6 +68,7 @@ android {
minSdkVersion 21 minSdkVersion 21
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false
@ -91,6 +92,6 @@ kapt {
} }
dependencies { dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs') implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.finogeeks.lib:finapplet:2.35.0-alpha20211231v09' implementation 'com.finogeeks.lib:finapplet:2.35.1'
implementation 'com.finogeeks.mop:plugins:2.35.0-alpha20211231v09' implementation 'com.finogeeks.mop:plugins:2.35.1'
} }

View File

@ -1,96 +0,0 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
group 'com.finogeeks.mop'
version '1.0'
buildscript {
repositories {
google()
jcenter()
maven {
url "https://gradle.finogeeks.club/repository/finogeeks/"
credentials {
username "finclip"
password "Abcd@@1234"
}
}
maven {
url "https://gradle.finogeeks.club/repository/applet/"
credentials {
username "finclip"
password "Abcd@@1234"
}
}
maven { url "https://jitpack.io" }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61"
}
}
rootProject.allprojects {
repositories {
google()
jcenter()
maven {
url "https://gradle.finogeeks.club/repository/finogeeks/"
credentials {
username "finclip"
password "Abcd@@1234"
}
}
maven {
url "https://gradle.finogeeks.club/repository/applet/"
credentials {
username "finclip"
password "Abcd@@1234"
}
}
maven { url "https://jitpack.io" }
}
}
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 21
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
disable 'InvalidPackage'
}
}
kapt {
arguments {
arg("moduleName", project.getName())
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.finogeeks.lib:finapplet:__finapplet_version__'
implementation 'com.finogeeks.mop:plugins:__finapplet_version__'
}

View File

@ -1,3 +1,3 @@
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableR8=true android.enableJetifier=true

Binary file not shown.

View File

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip

160
android/gradlew vendored
View File

@ -1,160 +0,0 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
android/gradlew.bat vendored
View File

@ -1,90 +0,0 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -5,9 +5,9 @@ import java.util.Map;
import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.EventChannel;
public class MopEventStream implements EventChannel.StreamHandler {
public class MopEventStream implements EventChannel.StreamHandler {
EventChannel.EventSink mEventSlink; EventChannel.EventSink mEventSlink;
@Override @Override
public void onListen(Object o, EventChannel.EventSink eventSink) { public void onListen(Object o, EventChannel.EventSink eventSink) {
mEventSlink = eventSink; mEventSlink = eventSink;
@ -17,12 +17,13 @@ public class MopEventStream implements EventChannel.StreamHandler {
public void onCancel(Object o) { public void onCancel(Object o) {
mEventSlink = null; mEventSlink = null;
} }
public void send(String channel,String event,Object body) {
public void send(String channel, String event, Object body) {
if (mEventSlink != null) { if (mEventSlink != null) {
Map<String,Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("channel",channel); map.put("channel", channel);
map.put("event",event); map.put("event", event);
map.put("body",body); map.put("body", body);
mEventSlink.success(map); mEventSlink.success(map);
} }
} }

View File

@ -1,7 +1,9 @@
package com.finogeeks.mop; package com.finogeeks.mop;
import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.util.Log; import android.util.Log;
import androidx.lifecycle.Lifecycle;
import com.finogeeks.mop.interfaces.Event; import com.finogeeks.mop.interfaces.Event;
import com.finogeeks.mop.interfaces.FlutterInterface; import com.finogeeks.mop.interfaces.FlutterInterface;
@ -11,6 +13,10 @@ import com.finogeeks.mop.service.MopPluginService;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter;
import io.flutter.plugin.common.EventChannel; import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel;
@ -22,78 +28,125 @@ import io.flutter.plugin.common.PluginRegistry.Registrar;
/** /**
* MopPlugin * MopPlugin
*/ */
public class MopPlugin implements MethodCallHandler { public class MopPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware {
private static final String LOG_TAG = MopPlugin.class.getSimpleName(); private static final String LOG_TAG = MopPlugin.class.getSimpleName();
private static final String CHANNEL = "mop"; private static final String CHANNEL = "mop";
private PluginRegistry.Registrar registrar; private static final String EVENT_CHANNEL = "plugins.mop.finogeeks.com/mop_event";
private FlutterInterface flutterInterface;
private MopPluginDelegate delegate;
private final FlutterInterface flutterInterface = new FlutterInterface();
private final MopPluginDelegate delegate = new MopPluginDelegate();
private final MopEventStream mopEventStream = new MopEventStream();
/** // These are null when not using v2 embedding.
* Plugin registration. private FlutterPluginBinding flutterPluginBinding;
*/ private MethodChannel channel;
public static void registerWith(Registrar registrar) { private EventChannel eventChannel;
final MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL); private Lifecycle lifecycle;
final MopPluginDelegate delegate = new MopPluginDelegate(registrar.activity());
final MopPlugin instance = new MopPlugin(registrar, delegate);
channel.setMethodCallHandler(instance);
final EventChannel eventChannel = new EventChannel(registrar.messenger(), "plugins.mop.finogeeks.com/mop_event");
MopEventStream mopEventStream = new MopEventStream();
eventChannel.setStreamHandler(mopEventStream);
MopPluginService.getInstance().initialize(registrar.activity(), mopEventStream, channel);
} /**
* Plugin registration.
*/
@SuppressWarnings("deprecation")
public static void registerWith(Registrar registrar) {
MethodChannel channel = new MethodChannel(registrar.messenger(), CHANNEL);
MopPluginDelegate delegate = new MopPluginDelegate();
final MopPlugin plugin = new MopPlugin();
channel.setMethodCallHandler(plugin);
registrar.addActivityResultListener(delegate);
MopPlugin(PluginRegistry.Registrar registrar, MopPluginDelegate delegate) { EventChannel eventChannel = new EventChannel(registrar.messenger(), EVENT_CHANNEL);
this.registrar = registrar; final MopEventStream mopEventStream = new MopEventStream();
this.flutterInterface = new FlutterInterface(); eventChannel.setStreamHandler(mopEventStream);
this.delegate = delegate; MopPluginService.getInstance().initialize(registrar.activity(), mopEventStream, channel);
} }
@Override @Override
public void onMethodCall(MethodCall call, final Result result) { public void onMethodCall(MethodCall call, final Result result) {
registrar.addActivityResultListener(delegate); ICallback callback = new ICallback<Object>() {
ICallback callback = new ICallback<Object>() { @Override
@Override public void onSuccess(Object data) {
public void onSuccess(Object data) { Map<String, Object> obj = new HashMap<String, Object>();
Map<String, Object> obj = new HashMap<String, Object>();
obj.put("success", true); obj.put("success", true);
if (data != null) if (data != null)
obj.put("data", data); obj.put("data", data);
obj.put("retMsg", "ok"); obj.put("retMsg", "ok");
result.success(obj); result.success(obj);
} }
@Override @Override
public void onFail(Object error) { public void onFail(Object error) {
Map<String, Object> obj = new HashMap<String, Object>(); Map<String, Object> obj = new HashMap<String, Object>();
obj.put("success", false); obj.put("success", false);
obj.put("retMsg", error == null ? "" : error); obj.put("retMsg", error == null ? "" : error);
result.success(obj); result.success(obj);
} }
@Override @Override
public void onCancel(Object cancel) { public void onCancel(Object cancel) {
result.notImplemented(); result.notImplemented();
} }
@Override @Override
public void startActivityForResult(Intent intent, int requestCode) { public void startActivityForResult(Intent intent, int requestCode) {
} }
}; };
Log.d(LOG_TAG, "mopplugin: invoke " + call.method); Log.d(LOG_TAG, "mopplugin: invoke " + call.method);
Event event = new Event(call.method, call.arguments, callback); Event event = new Event(call.method, call.arguments, callback);
delegate.setEvent(event); delegate.setEvent(event);
this.flutterInterface.invokeHandler(event); this.flutterInterface.invokeHandler(event);
// if (call.method.equals("getPlatformVersion")) { // if (call.method.equals("getPlatformVersion")) {
// result.success("Android " + android.os.Build.VERSION.RELEASE); // result.success("Android " + android.os.Build.VERSION.RELEASE);
// } else { // } else {
// result.notImplemented(); // result.notImplemented();
// } // }
} }
@Override
public void onAttachedToEngine(FlutterPluginBinding binding) {
this.flutterPluginBinding = binding;
channel = new MethodChannel(binding.getFlutterEngine().getDartExecutor(), CHANNEL);
channel.setMethodCallHandler(this);
EventChannel eventChannel = new EventChannel(binding.getFlutterEngine().getDartExecutor(), EVENT_CHANNEL);
eventChannel.setStreamHandler(mopEventStream);
}
@Override
public void onDetachedFromEngine(FlutterPluginBinding binding) {
this.flutterPluginBinding = null;
}
@Override
public void onAttachedToActivity(ActivityPluginBinding binding) {
binding.addActivityResultListener(delegate);
lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding);
setServicesFromActivity(binding.getActivity());
channel.setMethodCallHandler(this);
}
@Override
public void onDetachedFromActivityForConfigChanges() {
lifecycle = null;
}
@Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
binding.addActivityResultListener(delegate);
lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(binding);
setServicesFromActivity(binding.getActivity());
}
@Override
public void onDetachedFromActivity() {
lifecycle = null;
channel.setMethodCallHandler(null);
}
private void setServicesFromActivity(Activity activity) {
if (activity == null)
return;
MopPluginService.getInstance().initialize(activity, mopEventStream, channel);
}
} }

View File

@ -9,11 +9,8 @@ import com.finogeeks.mop.service.MopPluginService;
import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.common.PluginRegistry;
public class MopPluginDelegate implements PluginRegistry.ActivityResultListener { public class MopPluginDelegate implements PluginRegistry.ActivityResultListener {
private Event mEvent; private Event mEvent;
private final Activity activity;
public Event getEvent() { public Event getEvent() {
return mEvent; return mEvent;
@ -23,16 +20,11 @@ public class MopPluginDelegate implements PluginRegistry.ActivityResultListener
this.mEvent = event; this.mEvent = event;
} }
public MopPluginDelegate(final Activity activity) {
this.activity = activity;
}
@Override @Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data) { public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Constants.REQUEST_CODE_CHOOSE if (requestCode == Constants.REQUEST_CODE_CHOOSE || requestCode == Constants.REQUEST_CODE_LOCATION_CHOOSE) {
|| requestCode == Constants.REQUEST_CODE_LOCATION_CHOOSE MopPluginService.getInstance().getApisManager().getApiInstance(mEvent).onActivityResult(requestCode,
) { resultCode, data, mEvent.getCallback());
MopPluginService.getInstance().getApisManager().getApiInstance(mEvent).onActivityResult(requestCode, resultCode, data, mEvent.getCallback());
} }
return true; return true;
} }

View File

@ -1,11 +1,20 @@
package com.finogeeks.mop.api.mop; package com.finogeeks.mop.api.mop;
import android.content.Context; import android.content.Context;
import android.util.Log;
import com.finogeeks.lib.applet.anim.FadeInAnim;
import com.finogeeks.lib.applet.anim.NoneAnim;
import com.finogeeks.lib.applet.anim.SlideFromBottomToTopAnim;
import com.finogeeks.lib.applet.anim.SlideFromLeftToRightAnim;
import com.finogeeks.lib.applet.anim.SlideFromRightToLeftAnim;
import com.finogeeks.lib.applet.anim.SlideFromTopToBottomAnim;
import com.finogeeks.lib.applet.client.FinAppClient; import com.finogeeks.lib.applet.client.FinAppClient;
import com.finogeeks.lib.applet.db.entity.FinApplet; import com.finogeeks.lib.applet.db.entity.FinApplet;
import com.finogeeks.lib.applet.interfaces.FinCallback;
import com.finogeeks.mop.api.BaseApi; import com.finogeeks.mop.api.BaseApi;
import com.finogeeks.mop.interfaces.ICallback; import com.finogeeks.mop.interfaces.ICallback;
import com.google.gson.Gson;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -13,13 +22,16 @@ import java.util.Map;
public class AppletManageModule extends BaseApi { public class AppletManageModule extends BaseApi {
private static final String TAG = "AppletManageModule";
public AppletManageModule(Context context) { public AppletManageModule(Context context) {
super(context); super(context);
} }
@Override @Override
public String[] apis() { public String[] apis() {
return new String[]{"currentApplet", "closeAllApplets", "clearApplets", "removeUsedApplet"}; return new String[]{"currentApplet", "closeAllApplets", "clearApplets", "removeUsedApplet",
"setActivityTransitionAnim", "sendCustomEvent", "callJS"};
} }
@Override @Override
@ -57,6 +69,70 @@ public class AppletManageModule extends BaseApi {
} else { } else {
callback.onFail(null); callback.onFail(null);
} }
} else if (event.equals("setActivityTransitionAnim")) {
String anim = (String) param.get("anim");
Log.d(TAG, "setActivityTransitionAnim:" + anim);
if ("SlideFromLeftToRightAnim".equals(anim)) {
FinAppClient.INSTANCE.getAppletApiManager().setActivityTransitionAnim(SlideFromLeftToRightAnim.INSTANCE);
} else if ("SlideFromRightToLeftAnim".equals(anim)) {
FinAppClient.INSTANCE.getAppletApiManager().setActivityTransitionAnim(SlideFromRightToLeftAnim.INSTANCE);
} else if ("SlideFromTopToBottomAnim".equals(anim)) {
FinAppClient.INSTANCE.getAppletApiManager().setActivityTransitionAnim(SlideFromTopToBottomAnim.INSTANCE);
} else if ("SlideFromBottomToTopAnim".equals(anim)) {
FinAppClient.INSTANCE.getAppletApiManager().setActivityTransitionAnim(SlideFromBottomToTopAnim.INSTANCE);
} else if ("FadeInAnim".equals(anim)) {
FinAppClient.INSTANCE.getAppletApiManager().setActivityTransitionAnim(FadeInAnim.INSTANCE);
} else if ("NoneAnim".equals(anim)) {
FinAppClient.INSTANCE.getAppletApiManager().setActivityTransitionAnim(NoneAnim.INSTANCE);
}
callback.onSuccess(null);
} else if (event.equals("sendCustomEvent")) {
String appId = (String) param.get("appId");
Map eventData = (Map) param.get("eventData");
Log.d(TAG, "sendCustomEvent:" + appId);
if (appId != null) {
FinAppClient.INSTANCE.getAppletApiManager().sendCustomEvent(appId, eventData == null ? "" : new Gson().toJson(eventData));
callback.onSuccess(null);
} else {
callback.onFail(null);
}
} else if (event.equals("callJS")) {
String appId = (String) param.get("appId");
String eventName = (String) param.get("eventName");
String nativeViewId = (String) param.get("nativeViewId");
int viewId = 0;
if (nativeViewId != null && !nativeViewId.equals("")) {
try {
viewId = Integer.parseInt(nativeViewId);
} catch (Exception e) {
e.printStackTrace();
}
}
Map eventData = (Map) param.get("eventData");
Log.d(TAG, "callJS:" + appId);
if (appId != null && eventName != null) {
FinAppClient.INSTANCE.getAppletApiManager().callJS(appId, eventName, eventData == null ? "" : new Gson().toJson(eventData),
viewId, new FinCallback<String>() {
@Override
public void onSuccess(String s) {
Map<String, Object> res = new HashMap<>();
res.put("data", s);
callback.onSuccess(res);
}
@Override
public void onError(int i, String s) {
callback.onFail(null);
}
@Override
public void onProgress(int i, String s) {
}
});
} else {
callback.onFail(null);
}
} }
} }
} }

View File

@ -6,6 +6,7 @@ import android.util.Log;
import com.finogeeks.lib.applet.client.FinAppClient; import com.finogeeks.lib.applet.client.FinAppClient;
import com.finogeeks.lib.applet.interfaces.FinCallback; import com.finogeeks.lib.applet.interfaces.FinCallback;
import com.finogeeks.lib.applet.client.FinAppInfo;
import com.finogeeks.lib.applet.sdk.model.StartAppletDecryptRequest; import com.finogeeks.lib.applet.sdk.model.StartAppletDecryptRequest;
import com.finogeeks.mop.api.BaseApi; import com.finogeeks.mop.api.BaseApi;
import com.finogeeks.mop.interfaces.ICallback; import com.finogeeks.mop.interfaces.ICallback;
@ -56,19 +57,20 @@ public class AppletModule extends BaseApi {
String appId = String.valueOf(param.get("appId")); String appId = String.valueOf(param.get("appId"));
Integer sequence = (Integer) param.get("sequence"); Integer sequence = (Integer) param.get("sequence");
Map<String, String> params = (Map) param.get("params"); Map<String, String> params = (Map) param.get("params");
String apiServer = (String) param.get("apiServer");
// mContextFlutterActivity // mContextFlutterActivity
// Android 6.07.0contextmContext // Android 6.07.0contextmContext
// 使Application Context // 使Application Context
Context context = mContext.getApplicationContext(); Context context = mContext.getApplicationContext();
if (params == null) { FinAppInfo.StartParams startParams = params == null ? null : new FinAppInfo.StartParams(params.get("path"), params.get("query"), params.get("scene"));
if (sequence == null) { Log.d(TAG, "openApplet:" + appId + "," + param + "," + sequence + "," + apiServer);
FinAppClient.INSTANCE.getAppletApiManager().startApplet(context, appId);
} else { if (apiServer != null) {
FinAppClient.INSTANCE.getAppletApiManager().startApplet(context, appId, sequence, null); FinAppClient.INSTANCE.getAppletApiManager().startApplet(context, apiServer, appId, sequence, startParams);
}
} else { } else {
FinAppClient.INSTANCE.getAppletApiManager().startApplet(context, appId, params); FinAppClient.INSTANCE.getAppletApiManager().startApplet(context, appId, sequence, startParams);
} }
// String apiServer = (String) param.get("apiServer"); // String apiServer = (String) param.get("apiServer");
// String apiPrefix = (String) param.get("apiPrefix"); // String apiPrefix = (String) param.get("apiPrefix");
// if (apiServer == null || apiServer.isEmpty() || apiPrefix == null || apiPrefix.isEmpty()) { // if (apiServer == null || apiServer.isEmpty() || apiPrefix == null || apiPrefix.isEmpty()) {

View File

@ -2,6 +2,7 @@ package com.finogeeks.mop.api.mop;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.util.Log;
import com.finogeeks.lib.applet.BuildConfig; import com.finogeeks.lib.applet.BuildConfig;
import com.finogeeks.lib.applet.client.FinAppClient; import com.finogeeks.lib.applet.client.FinAppClient;
@ -11,6 +12,8 @@ import com.finogeeks.lib.applet.interfaces.FinCallback;
import com.finogeeks.mop.api.BaseApi; import com.finogeeks.mop.api.BaseApi;
import com.finogeeks.mop.interfaces.ICallback; import com.finogeeks.mop.interfaces.ICallback;
import com.finogeeks.mop.service.MopPluginService; import com.finogeeks.mop.service.MopPluginService;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -74,7 +77,22 @@ public class BaseModule extends BaseApi {
Boolean bindAppletWithMainProcess = (Boolean) param.get("bindAppletWithMainProcess"); Boolean bindAppletWithMainProcess = (Boolean) param.get("bindAppletWithMainProcess");
if (bindAppletWithMainProcess == null) bindAppletWithMainProcess = false; if (bindAppletWithMainProcess == null) bindAppletWithMainProcess = false;
FinAppConfig config = new FinAppConfig.Builder() String customWebViewUserAgent = (String) param.get("customWebViewUserAgent");
Integer appletIntervalUpdateLimit = (Integer) param.get("appletIntervalUpdateLimit");
Integer maxRunningApplet = (Integer) param.get("maxRunningApplet");
Gson gson = new Gson();
List<FinStoreConfig> finStoreConfigs = null;
if (param.get("finStoreConfigs") != null) {
finStoreConfigs = gson.fromJson(gson.toJson(param.get("finStoreConfigs")), new TypeToken<List<FinStoreConfig>>() {
}.getType());
}
FinAppConfig.UIConfig uiConfig = null;
if (param.get("uiConfig") != null) {
uiConfig = gson.fromJson(gson.toJson(param.get("uiConfig")), FinAppConfig.UIConfig.class);
}
FinAppConfig.Builder builder = new FinAppConfig.Builder()
.setSdkKey(appkey) .setSdkKey(appkey)
.setSdkSecret(secret) .setSdkSecret(secret)
.setApiUrl(apiServer) .setApiUrl(apiServer)
@ -84,8 +102,18 @@ public class BaseModule extends BaseApi {
.setUserId(userId) .setUserId(userId)
.setDebugMode(debug) .setDebugMode(debug)
.setDisableRequestPermissions(disablePermission) .setDisableRequestPermissions(disablePermission)
.setBindAppletWithMainProcess(bindAppletWithMainProcess) .setBindAppletWithMainProcess(bindAppletWithMainProcess);
.build();
if (customWebViewUserAgent != null)
builder.setCustomWebViewUserAgent(customWebViewUserAgent);
if (appletIntervalUpdateLimit != null)
builder.setAppletIntervalUpdateLimit(appletIntervalUpdateLimit);
if (maxRunningApplet != null) builder.setMaxRunningApplet(maxRunningApplet);
if (finStoreConfigs != null) builder.setFinStoreConfigs(finStoreConfigs);
if (uiConfig != null) builder.setUiConfig(uiConfig);
FinAppConfig config = builder.build();
Log.d(TAG, "config:" + gson.toJson(config));
final Application application = MopPluginService.getInstance().getActivity().getApplication(); final Application application = MopPluginService.getInstance().getActivity().getApplication();
// SDKSDK // SDKSDK

View File

@ -33,66 +33,126 @@ public class ExtensionApiModule extends BaseApi {
@Override @Override
public String[] apis() { public String[] apis() {
return new String[]{"registerExtensionApi"}; return new String[]{"registerExtensionApi","addWebExtentionApi"};
} }
@Override @Override
public void invoke(String s, Map param, ICallback iCallback) { public void invoke(String s, Map param, ICallback iCallback) {
MethodChannel channel = MopPluginService.getInstance().getMethodChannel(); if(s.equals("registerExtensionApi")) {
String name = (String) param.get("name"); MethodChannel channel = MopPluginService.getInstance().getMethodChannel();
FinAppClient.INSTANCE.getExtensionApiManager().registerApi(new com.finogeeks.lib.applet.api.BaseApi(getContext()) { String name = (String) param.get("name");
@Override Log.d(TAG, "registerExtensionApi:" + name);
public String[] apis() { FinAppClient.INSTANCE.getExtensionApiManager().registerApi(new com.finogeeks.lib.applet.api.BaseApi(getContext()) {
return new String[]{name}; @Override
} public String[] apis() {
return new String[]{name};
}
@Override @Override
public void invoke(String s, JSONObject jsonObject, com.finogeeks.lib.applet.interfaces.ICallback iCallback) { public void invoke(String s, JSONObject jsonObject, com.finogeeks.lib.applet.interfaces.ICallback iCallback) {
Log.d("MopPlugin", "invoke extensionApi:" + s + ",params:" + jsonObject); Log.d("MopPlugin", "invoke extensionApi:" + s + ",params:" + jsonObject);
Map params = GsonUtil.gson.fromJson(jsonObject.toString(), HashMap.class); Map params = GsonUtil.gson.fromJson(jsonObject.toString(), HashMap.class);
handler.post(() -> { handler.post(() -> {
channel.invokeMethod("extensionApi:" + name, params, new MethodChannel.Result() { channel.invokeMethod("extensionApi:" + name, params, new MethodChannel.Result() {
@Override @Override
public void success(Object result) { public void success(Object result) {
String json = GsonUtil.gson.toJson(result); String json = GsonUtil.gson.toJson(result);
FinAppTrace.d(ExtensionApiModule.TAG, "channel invokeMethod:" + name FinAppTrace.d(ExtensionApiModule.TAG, "channel invokeMethod:" + name
+ " success, result=" + result + ", json=" + json); + " success, result=" + result + ", json=" + json);
JSONObject ret = null; JSONObject ret = null;
if (json != null && !json.equals("null")) { if (json != null && !json.equals("null")) {
try { try {
ret = new JSONObject(json); ret = new JSONObject(json);
if (ret.has("errMsg")) { if (ret.has("errMsg")) {
String errMsg = ret.getString("errMsg"); String errMsg = ret.getString("errMsg");
if (errMsg.startsWith(name + ":fail")) { if (errMsg.startsWith(name + ":fail")) {
iCallback.onFail(ret); iCallback.onFail(ret);
return; return;
}
} }
} catch (JSONException e) {
e.printStackTrace();
} }
} catch (JSONException e) {
e.printStackTrace();
} }
iCallback.onSuccess(ret);
} }
iCallback.onSuccess(ret); @Override
} public void error(String errorCode, String errorMessage, Object errorDetails) {
FinAppTrace.e(ExtensionApiModule.TAG, "channel invokeMethod:" + name
+ " error, errorCode=" + errorCode
+ ", errorMessage=" + errorMessage
+ ", errorDetails=" + errorDetails);
iCallback.onFail();
}
@Override @Override
public void error(String errorCode, String errorMessage, Object errorDetails) { public void notImplemented() {
FinAppTrace.e(ExtensionApiModule.TAG, "channel invokeMethod:" + name iCallback.onFail();
+ " error, errorCode=" + errorCode }
+ ", errorMessage=" + errorMessage });
+ ", errorDetails=" + errorDetails);
iCallback.onFail();
}
@Override
public void notImplemented() {
iCallback.onFail();
}
}); });
}); }
} });
}); }else if(s.equals("addWebExtentionApi")){
MethodChannel channel = MopPluginService.getInstance().getMethodChannel();
String name = (String) param.get("name");
Log.d(TAG, "addWebExtentionApi:" + name);
FinAppClient.INSTANCE.getExtensionWebApiManager().registerApi(new com.finogeeks.lib.applet.api.BaseApi(getContext()) {
@Override
public String[] apis() {
return new String[]{name};
}
@Override
public void invoke(String s, JSONObject jsonObject, com.finogeeks.lib.applet.interfaces.ICallback iCallback) {
Log.d("MopPlugin", "invoke webextensionApi:" + s + ",params:" + jsonObject);
Map params = GsonUtil.gson.fromJson(jsonObject.toString(), HashMap.class);
handler.post(() -> {
channel.invokeMethod("webExtentionApi:" + name, params, new MethodChannel.Result() {
@Override
public void success(Object result) {
String json = GsonUtil.gson.toJson(result);
FinAppTrace.d(ExtensionApiModule.TAG, "channel invokeMethod:" + name
+ " success, result=" + result + ", json=" + json);
JSONObject ret = null;
if (json != null && !json.equals("null")) {
try {
ret = new JSONObject(json);
if (ret.has("errMsg")) {
String errMsg = ret.getString("errMsg");
if (errMsg.startsWith(name + ":fail")) {
iCallback.onFail(ret);
return;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
iCallback.onSuccess(ret);
}
@Override
public void error(String errorCode, String errorMessage, Object errorDetails) {
FinAppTrace.e(ExtensionApiModule.TAG, "channel invokeMethod:" + name
+ " error, errorCode=" + errorCode
+ ", errorMessage=" + errorMessage
+ ", errorDetails=" + errorDetails);
iCallback.onFail();
}
@Override
public void notImplemented() {
iCallback.onFail();
}
});
});
}
});
}
} }
} }

View File

@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"mop","path":"/Users/beetle/Desktop/finogeeks/gitlab/finosprite/finclip-flutter-sdk/","dependencies":[]}],"android":[{"name":"mop","path":"/Users/beetle/Desktop/finogeeks/gitlab/finosprite/finclip-flutter-sdk/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"mop","dependencies":[]}],"date_created":"2021-12-30 16:09:08.189707","version":"2.2.2"} {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"mop","path":"/Users/kangxuyao/StudioProjects/finclip-flutter-sdk/","dependencies":[]}],"android":[{"name":"flutter_plugin_android_lifecycle","path":"/Users/kangxuyao/.pub-cache/hosted/pub.flutter-io.cn/flutter_plugin_android_lifecycle-2.0.5/","dependencies":[]},{"name":"mop","path":"/Users/kangxuyao/StudioProjects/finclip-flutter-sdk/","dependencies":["flutter_plugin_android_lifecycle"]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"mop","dependencies":["flutter_plugin_android_lifecycle"]}],"date_created":"2022-01-04 13:47:58.706248","version":"2.6.0-12.0.pre.553"}

53
example/.gitignore vendored
View File

@ -22,52 +22,25 @@
# Flutter/Dart/Pub related # Flutter/Dart/Pub related
**/doc/api/ **/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/ .dart_tool/
.flutter-plugins .flutter-plugins
.flutter-plugins-dependencies
.packages .packages
.pub-cache/ .pub-cache/
.pub/ .pub/
/build/ /build/
# Android related # Web related
**/android/**/gradle-wrapper.jar lib/generated_plugin_registrant.dart
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related # Symbolication related
**/ios/**/*.mode1v3 app.*.symbols
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules. # Obfuscation related
!**/ios/**/default.mode1v3 app.*.map.json
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser # Android Studio will place build artifacts here
!**/ios/**/default.perspectivev3 /android/app/debug
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages /android/app/profile
/android/app/release

View File

@ -4,7 +4,7 @@
# This file should be version controlled and should not be manually edited. # This file should be version controlled and should not be manually edited.
version: version:
revision: 1aedbb1835bd6eb44550293d57d4d124f19901f0 revision: ffb2ecea5223acdd139a5039be2f9c796962833d
channel: stable channel: stable
project_type: app project_type: app

View File

@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

13
example/android/.gitignore vendored 100644
View File

@ -0,0 +1,13 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>android</name>
<comment>Project android created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1633860434667</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -0,0 +1,13 @@
arguments=
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=C\:/Program Files/Eclipse Foundation/jdk-11.0.12.7-hotspot
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=true
show.executions.view=true

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>app</name>
<comment>Project app created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1633860434672</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>

View File

@ -0,0 +1,2 @@
connection.project.dir=..
eclipse.preferences.version=1

View File

@ -25,20 +25,20 @@ apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android { android {
compileSdkVersion 28 compileSdkVersion 30
lintOptions { compileOptions {
disable 'InvalidPackage' sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
} }
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.finogeeks.mopexample" applicationId "com.finogeeks.mop_example"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 28 targetSdkVersion 30
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
@ -48,22 +48,8 @@ android {
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
} }
} }
packagingOptions {
// libsdkcore.so
doNotStrip "*/x86/libsdkcore.so"
doNotStrip "*/x86_64/libsdkcore.so"
doNotStrip "*/armeabi-v7a/libsdkcore.so"
doNotStrip "*/arm64-v8a/libsdkcore.so"
}
} }
flutter { flutter {
source '../..' source '../..'
} }
dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
}

View File

@ -1,7 +0,0 @@
/*___Generated_by_IDEA___*/
package com.finogeeks.mop_example;
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
public final class Manifest {
}

View File

@ -1,7 +0,0 @@
/*___Generated_by_IDEA___*/
package com.finogeeks.mop_example;
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
public final class R {
}

View File

@ -1,33 +1,41 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.finogeeks.mop_example"> package="com.finogeeks.mop_example">
<application
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="mop_example" android:label="mop_example"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:launchMode="singleTop" android:launchMode="singleTop"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing <!-- Specifies an Android theme to apply to this Activity as soon as
until Flutter renders its first frame. It can be removed if the Android process has started. This theme is visible to the user
there is no splash screen (such as the default splash screen while the Flutter UI initializes. After that, this theme continues
defined in @style/LaunchTheme). --> to determine the Window background behind the Flutter UI. -->
<meta-data <meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:name="io.flutter.embedding.android.NormalTheme"
android:value="true" /> android:resource="@style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<!-- <meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="@drawable/launch_background"
/> -->
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN"/> <action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application> </application>
</manifest> </manifest>

View File

@ -1,7 +0,0 @@
/*___Generated_by_IDEA___*/
package com.finogeeks.mop_example;
/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */
public final class Manifest {
}

View File

@ -1,7 +0,0 @@
/*___Generated_by_IDEA___*/
package com.finogeeks.mop_example;
/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */
public final class R {
}

View File

@ -1,16 +1,6 @@
package com.finogeeks.mop_example; package com.finogeeks.mop_example;
import android.os.Bundle; import io.flutter.embedding.android.FlutterActivity;
import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity { public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
}
} }

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -1,8 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when <!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame --> Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item> <item name="android:windowBackground">@drawable/launch_background</item>
</style> </style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources> </resources>

View File

@ -1,12 +1,11 @@
buildscript { buildscript {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.4' classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61"
} }
} }
@ -14,15 +13,13 @@ buildscript {
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
} }
rootProject.buildDir = '../build' rootProject.buildDir = '../build'
subprojects { subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}" project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app') project.evaluationDependsOn(':app')
} }

View File

@ -1,5 +1,3 @@
android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableR8=true android.enableJetifier=true

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip

View File

@ -1,5 +0,0 @@
-keep class com.finogeeks.** {*;}
# tbs
-keep class com.tencent.smtt.** {*;}
-keep class com.tencent.tbs.** {*;}

View File

@ -1,15 +1,11 @@
include ':app' include ':app'
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
def plugins = new Properties() assert localPropertiesFile.exists()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
if (pluginsFile.exists()) {
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
}
plugins.each { name, path -> def flutterSdkPath = properties.getProperty("flutter.sdk")
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
include ":$name" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
project(":$name").projectDir = pluginDirectory
}

33
example/ios/.gitignore vendored 100644
View File

@ -0,0 +1,33 @@
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3

View File

@ -1 +0,0 @@
9b8dc99cc1898757c03a06b2261ab8de

View File

@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>en</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>App</string> <string>App</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>8.0</string> <string>9.0</string>
</dict> </dict>
</plist> </plist>

View File

@ -1,2 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig" #include "Generated.xcconfig"

View File

@ -1,18 +0,0 @@
#
# NOTE: This podspec is NOT to be published. It is only used as a local source!
#
Pod::Spec.new do |s|
s.name = 'Flutter'
s.version = '1.0.0'
s.summary = 'High-performance, high-fidelity mobile apps.'
s.description = <<-DESC
Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS.
DESC
s.homepage = 'https://flutter.io'
s.license = { :type => 'MIT' }
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
s.ios.deployment_target = '8.0'
s.vendored_frameworks = 'Flutter.framework'
end

View File

@ -1,2 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig" #include "Generated.xcconfig"

View File

@ -1,8 +1,5 @@
# Uncomment this line to define a global platform for your project # Uncomment this line to define a global platform for your project
# platform :ios, '9.0' platform :ios, '9.0'
source 'https://git.finogeeks.club/finoapp-ios/FinPods'
source 'https://github.com/CocoaPods/Specs.git'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true' ENV['COCOAPODS_DISABLE_STATS'] = 'true'
@ -13,63 +10,40 @@ project 'Runner', {
'Release' => :release, 'Release' => :release,
} }
def parse_KV_file(file, separator='=') def flutter_root
file_abs_path = File.expand_path(file) generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
if !File.exists? file_abs_path unless File.exist?(generated_xcode_build_settings_path)
return []; raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end end
pods_ary = []
skip_line_start_symbols = ["#", "/"] File.foreach(generated_xcode_build_settings_path) do |line|
File.foreach(file_abs_path) { |line| matches = line.match(/FLUTTER_ROOT\=(.*)/)
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } return matches[1].strip if matches
plugin = line.split(pattern=separator) end
if plugin.length == 2 raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
pods_ary.push({:name => podname, :path => podpath});
else
puts "Invalid plugin specification: #{line}"
end
}
return pods_ary
end end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do target 'Runner' do
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock use_frameworks!
# referring to absolute paths on developers' machines. use_modular_headers!
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
# Flutter Pods flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig')
if generated_xcode_build_settings.empty?
puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first."
end
generated_xcode_build_settings.map { |p|
if p[:name] == 'FLUTTER_FRAMEWORK_DIR'
symlink = File.join('.symlinks', 'flutter')
File.symlink(File.dirname(p[:path]), symlink)
pod 'Flutter', :path => File.join(symlink, File.basename(p[:path]))
end
}
# Plugin Pods
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.map { |p|
symlink = File.join('.symlinks', 'plugins', p[:name])
File.symlink(p[:path], symlink)
pod p[:name], :path => File.join(symlink, 'ios')
}
end end
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
install! 'cocoapods', :disable_input_output_paths => true
post_install do |installer| post_install do |installer|
installer.pods_project.targets.each do |target| installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config| target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO' config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
if config.name == "Debug"
config.build_settings['ONLY_ACTIVE_ARCH'] = 'YES'
else
config.build_settings['ONLY_ACTIVE_ARCH'] = 'NO'
end
end end
end end
end end

View File

@ -1,3 +1,34 @@
PODFILE CHECKSUM: fa591ea0d89752dd0191ae3f82c83db034678e82 PODS:
- FinApplet (2.34.11)
- FinAppletExt (2.34.11):
- FinApplet (= 2.34.11)
- Flutter (1.0.0)
- mop (0.1.1):
- FinApplet (= 2.34.11)
- FinAppletExt (= 2.34.11)
- Flutter
COCOAPODS: 1.10.1 DEPENDENCIES:
- Flutter (from `Flutter`)
- mop (from `.symlinks/plugins/mop/ios`)
SPEC REPOS:
trunk:
- FinApplet
- FinAppletExt
EXTERNAL SOURCES:
Flutter:
:path: Flutter
mop:
:path: ".symlinks/plugins/mop/ios"
SPEC CHECKSUMS:
FinApplet: 975a76c8de4c9ddf64d6b4bfcd946ad6830f54f6
FinAppletExt: 9489276a84f908b60a75a71d09b0b4397e070bee
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
mop: 9a49a0b917e4016aa897c76656fddb69ad69b118
PODFILE CHECKSUM: 2317ba7584871ae8cd67fd0244fbd5e96fd06167
COCOAPODS: 1.11.2

View File

@ -3,19 +3,17 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 46; objectVersion = 51;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 6DB2EFFFC5FD4690C06ACB3A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B691CF78BE1464D3451E07AF /* Pods_Runner.framework */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
AF7B8F29E858B4266D8A8AD0 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ABAEB264A095769DC71DEAE1 /* libPods-Runner.a */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -32,24 +30,23 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
073CDBAAF19B6FF1EF196501 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
207F05A0BE4F11BA62008DCF /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4F9256BFB604D1207B06C14E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; 6793BBA3F03EE46BEAD75979 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 865E64E9FAB2F680272FCE6F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = "<group>"; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
ABAEB264A095769DC71DEAE1 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; B691CF78BE1464D3451E07AF /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B62C1456907598F7FC4CC93E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -57,17 +54,27 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
AF7B8F29E858B4266D8A8AD0 /* libPods-Runner.a in Frameworks */, 6DB2EFFFC5FD4690C06ACB3A /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
43950FB4B3EA29B9EA2BA804 /* Frameworks */ = { 1B5EB5EC57E12758D2A6310E /* Pods */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
ABAEB264A095769DC71DEAE1 /* libPods-Runner.a */, 6793BBA3F03EE46BEAD75979 /* Pods-Runner.debug.xcconfig */,
207F05A0BE4F11BA62008DCF /* Pods-Runner.release.xcconfig */,
865E64E9FAB2F680272FCE6F /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
8C9832689000ED580600B3AE /* Frameworks */ = {
isa = PBXGroup;
children = (
B691CF78BE1464D3451E07AF /* Pods_Runner.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -89,8 +96,8 @@
9740EEB11CF90186004384FC /* Flutter */, 9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
9A4E54748C7B614766AAD771 /* Pods */, 1B5EB5EC57E12758D2A6310E /* Pods */,
43950FB4B3EA29B9EA2BA804 /* Frameworks */, 8C9832689000ED580600B3AE /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -105,37 +112,18 @@
97C146F01CF9000F007C117D /* Runner */ = { 97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */, 97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
); );
path = Runner; path = Runner;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
97C146F11CF9000F007C117D /* Supporting Files */ = {
isa = PBXGroup;
children = (
97C146F21CF9000F007C117D /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
9A4E54748C7B614766AAD771 /* Pods */ = {
isa = PBXGroup;
children = (
073CDBAAF19B6FF1EF196501 /* Pods-Runner.debug.xcconfig */,
4F9256BFB604D1207B06C14E /* Pods-Runner.release.xcconfig */,
B62C1456907598F7FC4CC93E /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -143,13 +131,14 @@
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
BC8240216498EB68CEE5D926 /* [CP] Check Pods Manifest.lock */, 2DEACE28B1DB5888C31A623A /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
46BA5F59FC1A40CE8339661F /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
@ -166,17 +155,17 @@
97C146E61CF9000F007C117D /* Project object */ = { 97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1020; LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "The Chromium Authors"; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1; CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = H48LA2V876; LastSwiftMigration = 1100;
}; };
}; };
}; };
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 9.3";
developmentRegion = en; developmentRegion = en;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
@ -200,7 +189,6 @@
files = ( files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
); );
@ -209,35 +197,7 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 2DEACE28B1DB5888C31A623A /* [CP] Check Pods Manifest.lock */ = {
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\" embed_and_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";
};
BC8240216498EB68CEE5D926 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
@ -259,6 +219,51 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
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\" embed_and_thin";
};
46BA5F59FC1A40CE8339661F /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
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 */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
@ -266,8 +271,7 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
97C146F31CF9000F007C117D /* main.m in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -338,6 +342,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
@ -348,23 +353,18 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = 1; CLANG_ENABLE_MODULES = YES;
DEVELOPMENT_TEAM = H48LA2V876; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = (
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.finogeeks.finclip.demo;
PRODUCT_BUNDLE_IDENTIFIER = com.finogeeks.mopexample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Profile; name = Profile;
@ -468,6 +468,8 @@
IPHONEOS_DEPLOYMENT_TARGET = 9.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2"; TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES; VALIDATE_PRODUCT = YES;
}; };
@ -478,23 +480,19 @@
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = 1; CLANG_ENABLE_MODULES = YES;
DEVELOPMENT_TEAM = H48LA2V876; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = (
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.finogeeks.finclip.demo;
PRODUCT_BUNDLE_IDENTIFIER = com.finogeeks.mopexample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Debug; name = Debug;
@ -504,23 +502,18 @@
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = 1; CLANG_ENABLE_MODULES = YES;
DEVELOPMENT_TEAM = H48LA2V876; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = (
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.0; PRODUCT_BUNDLE_IDENTIFIER = com.finogeeks.finclip.demo;
PRODUCT_BUNDLE_IDENTIFIER = com.finogeeks.mopexample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Release; name = Release;

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1020" LastUpgradeVersion = "1300"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -1,6 +0,0 @@
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end

View File

@ -1,13 +0,0 @@
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end

View File

@ -0,0 +1,13 @@
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View File

@ -15,11 +15,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string> <string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string> <string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>

View File

@ -0,0 +1 @@
#import "GeneratedPluginRegistrant.h"

View File

@ -1,9 +0,0 @@
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char* argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

View File

@ -1,3 +1,7 @@
// ignore_for_file: prefer_const_constructors
import 'dart:ffi';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
@ -19,20 +23,120 @@ class _MyAppState extends State<MyApp> {
// Platform messages are asynchronous, so we initialize in an async method. // Platform messages are asynchronous, so we initialize in an async method.
Future<void> init() async { Future<void> init() async {
UIConfig uiconfig = UIConfig();
//
FinStoreConfig storeConfigA = FinStoreConfig(
"2LyZEib0gLTQdU3MUauATBwgfnTCJjdr7FCnywmAEM=",
"bdfd76cae24d4313",
"https://api.finclip.com",
"https://api.finclip.com",
);
FinStoreConfig storeConfigB = FinStoreConfig(
"2LyZEib0gLTQdU3MUauATBwgfnTCJjdr7FCnywmAEM=",
"bdfd76cae24d4313",
"https://finchat-mop-b.finogeeks.club",
"https://finchat-mop-b.finogeeks.club",
);
List<FinStoreConfig> storeConfigs = [storeConfigA];
uiconfig.isAlwaysShowBackInDefaultNavigationBar = false;
uiconfig.isClearNavigationBarNavButtonBackground = false;
uiconfig.isHideFeedbackAndComplaints = true;
uiconfig.isHideBackHome = true;
uiconfig.isHideForwardMenu = true;
uiconfig.hideTransitionCloseButton = true;
uiconfig.disableSlideCloseAppletGesture = true;
CapsuleConfig capsuleConfig = CapsuleConfig();
capsuleConfig.capsuleBgLightColor = 0x33ff00ee;
capsuleConfig.capsuleRightMargin = 25;
uiconfig.capsuleConfig = capsuleConfig;
uiconfig.appletText = "applet";
if (Platform.isIOS) { if (Platform.isIOS) {
final res = await Mop.instance.initialize( final res = await Mop.instance.initialize(
'22LyZEib0gLTQdU3MUauAZ0pZVbKTWGmNN6Lx8hXhIkA', '74bde5fad53a817c', '22LyZEib0gLTQdU3MUauATBwgfnTCJjdr7FCnywmAEM=', 'bdfd76cae24d4313',
apiServer: 'https://api.finclip.com', apiPrefix: '/api/v1/mop'); apiServer: 'https://api.finclip.com',
apiPrefix: '/api/v1/mop',
uiConfig: uiconfig,
finStoreConfigs: storeConfigs);
print(res); print(res);
} else if (Platform.isAndroid) { } else if (Platform.isAndroid) {
final res = await Mop.instance.initialize( final res = await Mop.instance.initialize(
'22LyZEib0gLTQdU3MUauAZ0pZVbKTWGmNN6Lx8hXhIkA', '74bde5fad53a817c', '22LyZEib0gLTQdU3MUauATBwgfnTCJjdr7FCnywmAEM=', 'bdfd76cae24d4313',
apiServer: 'https://api.finclip.com', apiPrefix: '/api/v1/mop'); apiServer: 'https://api.finclip.com', apiPrefix: '/api/v1/mop');
print(res); print(res);
} }
if (!mounted) return; if (!mounted) return;
} }
Widget _buildAppletItem(
String appletId, String itemName, VoidCallback tapAction) {
return GestureDetector(
onTap: tapAction,
child: Container(
padding: EdgeInsets.only(left: 7, right: 7),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(
colors: const [Color(0xFF12767e), Color(0xFF0dabb8)],
stops: const [0.0, 1.0],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: Center(
child: Text(
itemName,
style: TextStyle(color: Colors.white),
),
),
),
);
}
Widget _buildAppletWidget(String appletId, String appletName) {
return Container(
margin: EdgeInsets.only(left: 20, top: 30, right: 20),
child: Column(
children: [
Text(
appletName,
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w500, color: Colors.red),
),
SizedBox(
height: 10,
),
Container(
height: 100,
child: GridView.count(
crossAxisCount: 3,
childAspectRatio: 2,
crossAxisSpacing: 30,
// physics: NeverScrollableScrollPhysics(),
children: [
_buildAppletItem(appletId, "打开小程序", () {
Mop.instance.openApplet(appletId,
path: 'pages/index/index', query: '');
}),
_buildAppletItem(appletId, "finishRunningApplet", () {
Mop.instance.finishRunningApplet(appletId, true);
}),
_buildAppletItem(appletId, "removeUsedApplet", () {
Mop.instance.removeUsedApplet(appletId);
}),
// _buildAppletItem(appletId, "removeUsedApplet", () {
// Mop.instance.removeUsedApplet(appletId);
// }),
],
),
)
],
),
);
}
// 5e637a18cbfae4000170fa7a // 5e637a18cbfae4000170fa7a
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -41,82 +145,12 @@ class _MyAppState extends State<MyApp> {
appBar: AppBar( appBar: AppBar(
title: const Text('凡泰极客小程序 Flutter 插件'), title: const Text('凡泰极客小程序 Flutter 插件'),
), ),
body: Center( body: Column(
child: Container( children: <Widget>[
padding: EdgeInsets.only( _buildAppletWidget("5facb3a52dcbff00017469bd", "画图小程序"),
top: 20, _buildAppletWidget("5fa214a29a6a7900019b5cc1", "官方小程序"),
), _buildAppletWidget("5fa215459a6a7900019b5cc3", "我的对账单"),
child: Column( ],
children: <Widget>[
Container(
width: 140,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(
colors: const [Color(0xFF12767e), Color(0xFF0dabb8)],
stops: const [0.0, 1.0],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: FlatButton(
onPressed: () {
Mop.instance.openApplet('5ea03fa563cb900001d73863',
path: 'pages/index/index', query: '');
},
child: Text(
'打开画图小程序',
style: TextStyle(color: Colors.white),
),
),
),
SizedBox(height: 30),
Container(
width: 140,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(
colors: const [Color(0xFF12767e), Color(0xFF0dabb8)],
stops: const [0.0, 1.0],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: FlatButton(
onPressed: () {
Mop.instance.openApplet('5ea0401463cb900001d73865');
},
child: Text(
'打开官方小程序',
style: TextStyle(color: Colors.white),
),
),
),
SizedBox(height: 30),
Container(
width: 140,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(5)),
gradient: LinearGradient(
colors: const [Color(0xFF12767e), Color(0xFF0dabb8)],
stops: const [0.0, 1.0],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: FlatButton(
onPressed: () {
Mop.instance.openApplet('5ea0412663cb900001d73867');
},
child: Text(
'我的对账单',
style: TextStyle(color: Colors.white),
),
),
),
],
),
),
), ),
), ),
); );

View File

@ -7,7 +7,7 @@ packages:
name: async name: async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.6.1" version: "2.8.2"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -21,14 +21,14 @@ packages:
name: characters name: characters
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0" version: "1.3.1"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@ -49,7 +49,7 @@ packages:
name: cupertino_icons name: cupertino_icons
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.1.3" version: "1.0.4"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -62,27 +62,48 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.4"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.5"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.12.10" version: "0.12.11"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.0" version: "1.7.0"
mop: mop:
dependency: "direct dev" dependency: "direct main"
description: description:
path: ".." path: ".."
relative: true relative: true
@ -141,7 +162,7 @@ packages:
name: test_api name: test_api
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.3.0" version: "0.4.3"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -155,7 +176,7 @@ packages:
name: vector_math name: vector_math
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0" version: "2.1.1"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.14.0 <3.0.0"
flutter: ">=1.10.0" flutter: ">=2.2.3"

View File

@ -3,39 +3,57 @@ description: Demonstrates how to use the mop plugin.
publish_to: 'none' publish_to: 'none'
environment: environment:
sdk: '>=2.1.0 <3.0.0' sdk: '>=2.12.0 <3.0.0'
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
mop:
# When depending on this package from a real application you should use:
# mop: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2 cupertino_icons: ^1.0.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
mop:
path: ../ # The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^1.0.0
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter. # The following section is specific to Flutter.
flutter: flutter:
# The following line ensures that the Material Icons font is # The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in # included with your application, so that you can use the icons in
# the material Icons class. # the material Icons class.
uses-material-design: true uses-material-design: true
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
# assets: # assets:
# - images/a_dot_burr.jpeg # - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg # - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware. # https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see # For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages # https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here, # To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a # in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a # "family" key with the font family name, and a "fonts" key with a

View File

@ -19,7 +19,7 @@ void main() {
expect( expect(
find.byWidgetPredicate( find.byWidgetPredicate(
(Widget widget) => widget is Text && (Widget widget) => widget is Text &&
widget.data.startsWith('Running on:'), widget.data!.startsWith('Running on:'),
), ),
findsOneWidget, findsOneWidget,
); );

View File

@ -0,0 +1,16 @@
//
// MOB_addWebExtentionApi.h
// mop
//
// Created by on 2021/12/21.
//
#import "MOPBaseApi.h"
NS_ASSUME_NONNULL_BEGIN
@interface MOB_addWebExtentionApi : MOPBaseApi
@property(nonatomic, copy) NSString* name;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,53 @@
//
// MOB_addWebExtentionApi.m
// mop
//
// Created by on 2021/12/21.
//
#import "MOB_addWebExtentionApi.h"
#import "MopPlugin.h"
#import <FinApplet/FinApplet.h>
@implementation MOB_addWebExtentionApi
- (void)setupApiWithSuccess:(void (^)(NSDictionary<NSString *,id> * _Nonnull))success failure:(void (^)(id _Nullable))failure cancel:(void (^)(void))cancel
{
NSLog(@"MOB_addWebExtentionApi");
FlutterMethodChannel *channel = [[MopPlugin instance] methodChannel];
[[FATClient sharedClient] fat_registerWebApi:self.name handle:^(id param, FATExtensionApiCallback callback) {
NSLog(@"invoke webExtentionApi:");
NSLog(@"%@",self.name);
NSLog(@"%@",param);
NSString* api = [@"webExtentionApi:" stringByAppendingString:self.name];
[channel invokeMethod:api arguments:param result:^(id _Nullable result) {
NSLog(@"webExtentionApi reslut:%@",result);
// flutter
BOOL isFlutterError = [result isKindOfClass:[FlutterError class]] || result == FlutterMethodNotImplemented;
if (isFlutterError) {
NSLog(@"webExtentionApi reslut:fail");
callback(FATExtensionCodeFailure,nil);
return;
}
//
BOOL hasError = [[result allKeys] containsObject:@"errMsg"];
if (hasError) {
NSString *errMsg = result[@"errMsg"];
NSString *errPrefix = [NSString stringWithFormat:@"%@:fail", self.name];
BOOL isFail = [errMsg hasPrefix:errPrefix];
if (isFail) {
NSLog(@"webExtentionApi reslut:fail");
callback(FATExtensionCodeFailure,nil);
return;
}
}
//
NSLog(@"webExtentionApi callback:%@",result);
callback(FATExtensionCodeSuccess,result);
}];
}];
success(@{});
}
@end

View File

@ -0,0 +1,18 @@
//
// MOP_callJS.h
// mop
//
// Created by on 2021/12/21.
//
#import "MOPBaseApi.h"
NS_ASSUME_NONNULL_BEGIN
@interface MOP_callJS : MOPBaseApi
@property (nonatomic, copy) NSString *eventName;
@property (nonatomic, copy) NSString *nativeViewId;
@property (nonatomic, copy) NSDictionary *eventData;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,28 @@
//
// MOP_callJS.m
// mop
//
// Created by on 2021/12/21.
//
#import "MOP_callJS.h"
@implementation MOP_callJS
- (void)setupApiWithSuccess:(void (^)(NSDictionary<NSString *,id> * _Nonnull))success failure:(void (^)(id _Nullable))failure cancel:(void (^)(void))cancel
{
if (!self.eventData || !self.eventName || !self.nativeViewId) {
failure(@{@"errMsg": @"callJS:fail"});
return;
}
NSNumber *numberId = @(_nativeViewId.integerValue);
[[FATClient sharedClient].nativeViewManager sendEvent:_eventName nativeViewId:numberId detail:_eventData completion:^(id result, NSError *error) {
if (error) {
failure(@{@"errMsg": @"sendCustomEvent:fail"});
} else {
success(result);
}
}];
}
@end

View File

@ -0,0 +1,17 @@
//
// MOP_closeApplet.h
// mop
//
// Created by on 2021/12/21.
//
#import "MOPBaseApi.h"
NS_ASSUME_NONNULL_BEGIN
@interface MOP_closeApplet : MOPBaseApi
@property (nonatomic, copy) NSString *appletId;
@property (nonatomic, assign) BOOL animated;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,25 @@
//
// MOP_closeApplet.m
// mop
//
// Created by on 2021/12/21.
//
#import "MOP_closeApplet.h"
#import <FinApplet/FinApplet.h>
@implementation MOP_closeApplet
- (void)setupApiWithSuccess:(void (^)(NSDictionary<NSString *,id> * _Nonnull))success failure:(void (^)(id _Nullable))failure cancel:(void (^)(void))cancel
{
if (!self.appletId || self.appletId.length < 1) {
failure(@{@"errMsg": @"closeApplet:fail"});
return;
}
[[FATClient sharedClient] closeApplet:self.appletId animated:_animated completion:^{
success(@{});
}];
}
@end

View File

@ -0,0 +1,17 @@
//
// MOP_finishRunningApplet.h
// mop
//
// Created by on 2021/12/21.
//
#import "MOPBaseApi.h"
NS_ASSUME_NONNULL_BEGIN
@interface MOP_finishRunningApplet : MOPBaseApi
@property (nonatomic, copy) NSString *appletId;
@property (nonatomic, assign) BOOL animated;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,25 @@
//
// MOP_finishRunningApplet.m
// mop
//
// Created by on 2021/12/21.
//
#import "MOP_finishRunningApplet.h"
@implementation MOP_finishRunningApplet
- (void)setupApiWithSuccess:(void (^)(NSDictionary<NSString *,id> * _Nonnull))success failure:(void (^)(id _Nullable))failure cancel:(void (^)(void))cancel
{
if (!self.appletId || self.appletId.length < 1) {
failure(@{@"errMsg": @"finishRunningApplet:fail"});
return;
}
[[FATClient sharedClient] closeApplet:self.appletId animated:_animated completion:^{
[[FATClient sharedClient] clearMemeryApplet:self.appletId];
success(@{});
}];
}
@end

View File

@ -16,9 +16,15 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, copy) NSString *apiServer; @property (nonatomic, copy) NSString *apiServer;
@property (nonatomic, copy) NSString *apiPrefix; @property (nonatomic, copy) NSString *apiPrefix;
@property (nonatomic, copy) NSString *cryptType; @property (nonatomic, copy) NSString *cryptType;
@property (nonatomic, copy) NSString *userId;
@property (nonatomic, assign) BOOL disablePermission;
@property (nonatomic, assign) BOOL encryptServerData; @property (nonatomic, assign) BOOL encryptServerData;
@property (nonatomic, copy) NSString *userId;
@property (nonatomic, strong) NSArray *finStoreConfigs;
@property (nonatomic, strong) NSDictionary *uiConfig;
@property (nonatomic, copy) NSString *customWebViewUserAgent;
@property (nonatomic, assign) BOOL disablePermission;
@property (nonatomic, assign) NSInteger appletIntervalUpdateLimit;
@property (nonatomic, assign) NSInteger maxRunningApplet;
@end @end

View File

@ -8,15 +8,15 @@
#import "MOP_initialize.h" #import "MOP_initialize.h"
#import <FinApplet/FinApplet.h> #import <FinApplet/FinApplet.h>
#import <FinAppletExt/FinAppletExt.h> #import <FinAppletExt/FinAppletExt.h>
#import <FinAppletWebRTC/FinAppletWebRTC.h> #import "MOPTools.h"
#import <FinAppletGDMap/FinAppletGDMap.h> // #import <FinAppletWebRTC/FinAppletWebRTC.h>
@implementation MOP_initialize @implementation MOP_initialize
- (void)setupApiWithSuccess:(void (^)(NSDictionary<NSString *,id> * _Nonnull))success failure:(void (^)(id _Nullable))failure cancel:(void (^)(void))cancel - (void)setupApiWithSuccess:(void (^)(NSDictionary<NSString *,id> * _Nonnull))success failure:(void (^)(id _Nullable))failure cancel:(void (^)(void))cancel
{ {
if (!self.appkey || !self.secret) { if (!self.appkey || !self.secret) {
failure(@"appkey 或 secret不能为空"); failure(@"sdkkey 或 secret不能为空");
return; return;
} }
if (!self.apiServer || [self.apiServer isEqualToString:@""]) { if (!self.apiServer || [self.apiServer isEqualToString:@""]) {
@ -25,27 +25,102 @@
if (!self.apiPrefix|| [self.apiPrefix isEqualToString:@""]) { if (!self.apiPrefix|| [self.apiPrefix isEqualToString:@""]) {
self.apiPrefix = @"/api/v1/mop"; self.apiPrefix = @"/api/v1/mop";
} }
FATConfig *config = [FATConfig configWithAppSecret:self.secret appKey:self.appkey]; FATConfig *config;
config.apiServer = [self.apiServer copy]; if (_finStoreConfigs && _finStoreConfigs.count > 0) {
config.apiPrefix = [self.apiPrefix copy]; NSMutableArray *storeArrayM = [NSMutableArray array];
if([self.cryptType isEqualToString: @"SM"]) for (NSDictionary *dict in _finStoreConfigs) {
{ FATStoreConfig *storeConfig = [[FATStoreConfig alloc] init];
config.cryptType = FATApiCryptTypeSM; storeConfig.sdkKey = dict[@"sdkKey"];
// storeConfig.sdkKey = @"22LyZEib0gLTQdU3MUauAb4V4W8Uxd/gMgmH8Hg1bGQ=";
storeConfig.sdkSecret = dict[@"sdkSecret"];
storeConfig.apiServer = dict[@"apiServer"];
storeConfig.apmServer = dict[@"apmServer"];
storeConfig.fingerprint = dict[@"fingerprint"];
if ([@"SM" isEqualToString:dict[@"cryptType"]]) {
storeConfig.cryptType = FATApiCryptTypeSM;
} else {
storeConfig.cryptType = FATApiCryptTypeMD5;
}
storeConfig.encryptServerData = [dict[@"encryptServerData"] boolValue];
[storeArrayM addObject:storeConfig];
}
config = [FATConfig configWithStoreConfigs:storeArrayM];
} else {
config = [FATConfig configWithAppSecret:self.secret appKey:self.appkey];
config.apiServer = [self.apiServer copy];
config.apiPrefix = [self.apiPrefix copy];
if([self.cryptType isEqualToString: @"SM"])
{
config.cryptType = FATApiCryptTypeSM;
}
else
{
config.cryptType = FATApiCryptTypeMD5;
}
// encryptServerData
NSLog(@"encryptServerData:%d",self.encryptServerData);
config.encryptServerData = self.encryptServerData;
} }
else
{
config.cryptType = FATApiCryptTypeMD5;
}
config.currentUserId = [self.userId copy];
// encryptServerData
NSLog(@"encryptServerData:%d",self.encryptServerData);
config.encryptServerData = self.encryptServerData;
NSLog(@"disablePermission:%d",self.disablePermission); NSLog(@"disablePermission:%d",self.disablePermission);
config.disableAuthorize = self.disablePermission; config.disableAuthorize = self.disablePermission;
config.currentUserId = [self.userId copy];
config.appletIntervalUpdateLimit = self.appletIntervalUpdateLimit;
// bool debug = false,
// bool bindAppletWithMainProcess = false,
// List<FinStoreConfig>? finStoreConfigs,
// UIConfig? uiConfig,
// String? customWebViewUserAgent,
// int appletIntervalUpdateLimit = 0,
// int maxRunningApplet = 5,
NSError* error = nil; NSError* error = nil;
FATUIConfig *uiconfig = [[FATUIConfig alloc]init]; FATUIConfig *uiconfig = [[FATUIConfig alloc]init];
uiconfig.autoAdaptDarkMode = YES; uiconfig.autoAdaptDarkMode = YES;
if (_uiConfig) {
if (_uiConfig[@"navigationTitleTextAttributes"]) {
uiconfig.navigationTitleTextAttributes = _uiConfig[@"navigationTitleTextAttributes"];
}
if (_uiConfig[@"progressBarColor"]) {
uiconfig.progressBarColor = [MOPTools colorWithRGBHex:[_uiConfig[@"progressBarColor"] intValue]];
}
uiconfig.hideBackToHome = [_uiConfig[@"isHideBackHome"] boolValue];
uiconfig.hideFeedbackMenu = [_uiConfig[@"isHideFeedbackAndComplaints"] boolValue];
uiconfig.hideForwardMenu = [_uiConfig[@"isHideForwardMenu"] boolValue];
uiconfig.autoAdaptDarkMode = [_uiConfig[@"autoAdaptDarkMode"] boolValue];
uiconfig.appletText = _uiConfig[@"appletText"];
uiconfig.hideTransitionCloseButton = [_uiConfig[@"hideTransitionCloseButton"] boolValue];
uiconfig.disableSlideCloseAppletGesture = _uiConfig[@"disableSlideCloseAppletGesture"];
if (_uiConfig[@"capsuleConfig"]) {
NSDictionary *capsuleConfigDic = _uiConfig[@"capsuleConfig"];
FATCapsuleConfig *capsuleConfig = [[FATCapsuleConfig alloc]init];
capsuleConfig.capsuleWidth = [capsuleConfigDic[@"capsuleWidth"] floatValue];
capsuleConfig.capsuleHeight = [capsuleConfigDic[@"capsuleHeight"] floatValue];
capsuleConfig.capsuleRightMargin = [capsuleConfigDic[@"capsuleRightMargin"] floatValue];
capsuleConfig.capsuleCornerRadius = [capsuleConfigDic[@"capsuleCornerRadius"] floatValue];
capsuleConfig.capsuleBorderWidth = [capsuleConfigDic[@"capsuleBorderWidth"] floatValue];
capsuleConfig.moreBtnWidth = [capsuleConfigDic[@"moreBtnWidth"] floatValue];
capsuleConfig.moreBtnLeftMargin = [capsuleConfigDic[@"moreBtnLeftMargin"] floatValue];
capsuleConfig.closeBtnWidth = [capsuleConfigDic[@"closeBtnWidth"] floatValue];
capsuleConfig.closeBtnLeftMargin = [capsuleConfigDic[@"closeBtnLeftMargin"] floatValue];
capsuleConfig.capsuleBorderLightColor = [MOPTools colorWithRGBHex:[capsuleConfigDic[@"capsuleBorderLightColor"] intValue]];
capsuleConfig.capsuleBorderDarkColor = [MOPTools colorWithRGBHex:[capsuleConfigDic[@"capsuleBorderDarkColor"] intValue]];
capsuleConfig.capsuleBgLightColor = [MOPTools colorWithRGBHex:[capsuleConfigDic[@"capsuleBgLightColor"] intValue]];
capsuleConfig.capsuleBgDarkColor = [MOPTools colorWithRGBHex:[capsuleConfigDic[@"capsuleBgDarkColor"] intValue]];
capsuleConfig.capsuleDividerLightColor = [MOPTools colorWithRGBHex:[capsuleConfigDic[@"capsuleDividerLightColor"] intValue]];
capsuleConfig.capsuleDividerDarkColor = [MOPTools colorWithRGBHex:[capsuleConfigDic[@"capsuleDividerDarkColor"] intValue]];
uiconfig.capsuleConfig = capsuleConfig;
}
}
uiconfig.appendingCustomUserAgent = self.customWebViewUserAgent;
// uiconfig.moreMenuStyle = FATMoreViewStyleNormal; // uiconfig.moreMenuStyle = FATMoreViewStyleNormal;
[[FATClient sharedClient] initWithConfig:config uiConfig:uiconfig error:&error]; [[FATClient sharedClient] initWithConfig:config uiConfig:uiconfig error:&error];
if (error) { if (error) {
@ -55,9 +130,9 @@
// [[FATExtClient sharedClient] fat_prepareExtensionApis]; // [[FATExtClient sharedClient] fat_prepareExtensionApis];
// [[FATExtClient sharedClient] fat_UsingMapType:@"FATExtMapStyleGD" MapKey:@"6f0f28c4138cbaa51aa5890e26996ea2"]; // [[FATExtClient sharedClient] fat_UsingMapType:@"FATExtMapStyleGD" MapKey:@"6f0f28c4138cbaa51aa5890e26996ea2"];
[FATGDMapComponent setGDMapAppKey:@"6f0f28c4138cbaa51aa5890e26996ea2"]; // [FATGDMapComponent setGDMapAppKey:@"6f0f28c4138cbaa51aa5890e26996ea2"];
[[FATClient sharedClient] setEnableLog:YES]; [[FATClient sharedClient] setEnableLog:YES];
[FATWebRTCComponent registerComponent]; // [FATWebRTCComponent registerComponent];
success(@{}); success(@{});

View File

@ -11,7 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface MOP_registerExtensionApi : MOPBaseApi @interface MOP_registerExtensionApi : MOPBaseApi
@property NSString* name; @property(nonatomic, copy) NSString* name;
@end @end

View File

@ -0,0 +1,16 @@
//
// MOP_removeApplet.h
// mop
//
// Created by on 2021/12/21.
//
#import "MOPBaseApi.h"
NS_ASSUME_NONNULL_BEGIN
@interface MOP_removeApplet : MOPBaseApi
@property (nonatomic, copy) NSString *appletId;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,32 @@
//
// MOP_removeApplet.m
// mop
//
// Created by on 2021/12/21.
//
#import "MOP_removeApplet.h"
@implementation MOP_removeApplet
- (void)setupApiWithSuccess:(void (^)(NSDictionary<NSString *,id> * _Nonnull))success failure:(void (^)(id _Nullable))failure cancel:(void (^)(void))cancel
{
if (!self.appletId || self.appletId.length < 1) {
failure(@{@"errMsg": @"removeApplet:fail"});
return;
}
FATAppletInfo *appletInfo = [[FATClient sharedClient] currentApplet];
if (appletInfo && [appletInfo.appId isEqual:self.appletId]) {
[[FATClient sharedClient] closeApplet:self.appletId animated:NO completion:^{
[[FATClient sharedClient] removeAppletFromLocalCache:self.appletId];
success(@{});
}];
} else {
[[FATClient sharedClient] removeAppletFromLocalCache:self.appletId];
success(@{});
}
}
@end

View File

@ -0,0 +1,16 @@
//
// MOP_sendCustomEvent.h
// mop
//
// Created by on 2021/12/21.
//
#import "MOPBaseApi.h"
NS_ASSUME_NONNULL_BEGIN
@interface MOP_sendCustomEvent : MOPBaseApi
@property (nonatomic, strong) NSDictionary *eventData;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,28 @@
//
// MOP_sendCustomEvent.m
// mop
//
// Created by on 2021/12/21.
//
#import "MOP_sendCustomEvent.h"
@implementation MOP_sendCustomEvent
- (void)setupApiWithSuccess:(void (^)(NSDictionary<NSString *,id> * _Nonnull))success failure:(void (^)(id _Nullable))failure cancel:(void (^)(void))cancel
{
if (!self.eventData ) {
failure(@{@"errMsg": @"sendCustomEvent:fail"});
return;
}
[[FATClient sharedClient].nativeViewManager sendCustomEventWithDetail:self.eventData completion:^(id result, NSError *error) {
if (error) {
failure(@{@"errMsg": @"sendCustomEvent:fail"});
} else {
success(result);
}
}];
}
@end

View File

@ -0,0 +1,16 @@
//
// MOP_setFinStoreConfigs.h
// mop
//
// Created by on 2021/12/20.
//
#import "MOPBaseApi.h"
NS_ASSUME_NONNULL_BEGIN
@interface MOP_setFinStoreConfigs : MOPBaseApi
@property(nonatomic, strong) NSArray *storeConfigs;
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,12 @@
//
// MOP_setFinStoreConfigs.m
// mop
//
// Created by on 2021/12/20.
//
#import "MOP_setFinStoreConfigs.h"
@implementation MOP_setFinStoreConfigs
@end

View File

@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface MOP_webViewBounces : MOPBaseApi @interface MOP_webViewBounces : MOPBaseApi
@property (nonatomic, assign) BOOL bounces; @property (nonatomic, assign) bool bounces;
@end @end

View File

@ -113,7 +113,9 @@ static MopPlugin *_instance;
return [[FATClient sharedClient] handleOpenURL:url]; return [[FATClient sharedClient] handleOpenURL:url];
} }
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler - (BOOL)application:(UIApplication*)application
continueUserActivity:(NSUserActivity*)userActivity
restorationHandler:(void (^)(NSArray*))restorationHandler
{ {
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL; NSURL *url = userActivity.webpageURL;

View File

@ -88,9 +88,10 @@
id value = container[key]; id value = container[key];
id safetyValue = [self parseFromKeyValue:value]; id safetyValue = [self parseFromKeyValue:value];
if (!safetyValue) if (!safetyValue) //safetyValuenil
{ {
safetyValue = @""; // safetyValue = @"";
continue;
} }
[result setObject:safetyValue forKey:key]; [result setObject:safetyValue forKey:key];
} }

View File

@ -13,6 +13,9 @@ NS_ASSUME_NONNULL_BEGIN
+ (UIViewController *)topViewController; + (UIViewController *)topViewController;
+ (UIViewController *)topViewController:(UIViewController *)rootViewController; + (UIViewController *)topViewController:(UIViewController *)rootViewController;
+ (UIColor *)colorWithRGBHex:(UInt32)hex;
+ (UIColor *)fat_colorWithHexString:(NSString *)hexColor;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@ -28,4 +28,89 @@
return [self topViewController:presentedViewController]; return [self topViewController:presentedViewController];
} }
+ (UIColor *)colorWithRGBHex:(UInt32)hex
{
int a = (hex >> 24) & 0xFF;
int r = (hex >> 16) & 0xFF;
int g = (hex >> 8) & 0xFF;
int b = (hex) & 0xFF;
return [UIColor colorWithRed:r / 255.0f
green:g / 255.0f
blue:b / 255.0f
alpha:a / 255.0f];
}
+ (UIColor *)fat_colorWithHexString:(NSString *)hexColor {
if (!hexColor) return nil;
// blackwhite
if ([hexColor compare:@"black" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
return UIColor.blackColor;
} else if ([hexColor compare:@"white" options:NSCaseInsensitiveSearch] == NSOrderedSame) {
return UIColor.whiteColor;
}
NSString *cString = [[hexColor stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
if (cString.length == 0) return nil;
if ([cString hasPrefix:@"#"]) cString = [cString substringFromIndex:1];
if ([cString containsString:@"0X"]) cString = [cString stringByReplacingOccurrencesOfString:@"0X" withString:@""];
if (cString.length == 3) { // 36
cString = [NSString stringWithFormat:@"%c%c%c%c%c%c",
[cString characterAtIndex:0],
[cString characterAtIndex:0],
[cString characterAtIndex:1],
[cString characterAtIndex:1],
[cString characterAtIndex:2],
[cString characterAtIndex:2]];
}
if (cString.length == 4) { // 48
cString = [NSString stringWithFormat:@"%c%c%c%c%c%c%c%c",
[cString characterAtIndex:0],
[cString characterAtIndex:0],
[cString characterAtIndex:1],
[cString characterAtIndex:1],
[cString characterAtIndex:2],
[cString characterAtIndex:2],
[cString characterAtIndex:3],
[cString characterAtIndex:3]];
}
NSScanner *scanner = [NSScanner scannerWithString:cString];
unsigned hexNum;
if (![scanner scanHexInt:&hexNum]) return [UIColor blackColor];
if (cString.length == 6) {
return [self fat_colorWithRGBHex:hexNum];
} else if (cString.length == 8) {
return [self fat_colorWithARGBHex:hexNum];
}
return nil;
}
+ (UIColor *)fat_colorWithRGBHex:(UInt32)hex {
int red = (hex >> 16) & 0xFF;
int green = (hex >> 8) & 0xFF;
int blue = (hex)&0xFF;
return [UIColor colorWithRed:red / 255.0f green:green / 255.0f blue:blue / 255.0f alpha:1.0f];
}
+ (UIColor *)fat_colorWithRGBAlphaHex:(UInt32)hex {
int red = (hex >> 24) & 0xFF;
int green = (hex >> 16) & 0xFF;
int blue = (hex >> 8) & 0xFF;
int alpha = hex & 0xFF;
return [UIColor colorWithRed:red / 255.0f green:green / 255.0f blue:blue / 255.0f alpha:alpha / 255.0f];
}
+ (UIColor *)fat_colorWithARGBHex:(UInt32)hex {
int alpha = (hex >> 24) & 0xFF;
int red = (hex >> 16) & 0xFF;
int green = (hex >> 8) & 0xFF;
int blue = hex & 0xFF;
return [UIColor colorWithRed:red / 255.0f green:green / 255.0f blue:blue / 255.0f alpha:alpha / 255.0f];
}
@end @end

View File

@ -17,10 +17,7 @@ A finclip miniprogram flutter sdk.
s.dependency 'Flutter' s.dependency 'Flutter'
s.ios.deployment_target = '9.0' s.ios.deployment_target = '9.0'
s.dependency 'FinApplet' , '2.35.0-alpha20211231v04' s.dependency 'FinApplet' , '2.35.1'
s.dependency 'FinAppletExt' , '2.35.0-alpha20211231v04' s.dependency 'FinAppletExt' , '2.35.1'
s.dependency 'FinAppletGDMap' , '2.35.0-alpha20211231v04'
s.dependency 'FinAppletWebRTC' , '2.35.0-alpha20211231v04'
end end

View File

@ -1,5 +1,3 @@
import 'dart:typed_data';
class CustomMenu { class CustomMenu {
String menuId; String menuId;
String image; String image;
@ -8,8 +6,7 @@ class CustomMenu {
CustomMenu(this.menuId, this.image, this.title, this.type); CustomMenu(this.menuId, this.image, this.title, this.type);
Map<String, dynamic> toJson() => Map<String, dynamic> toJson() => {'menuId': menuId, 'image': image, 'title': title, 'type': type};
{'menuId': menuId, 'image': image, 'title': title, 'type': type};
} }
abstract class AppletHandler { abstract class AppletHandler {

View File

@ -1,5 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:ffi';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:mop/api.dart'; import 'package:mop/api.dart';
@ -8,27 +10,244 @@ typedef MopEventErrorCallback = void Function(dynamic event);
typedef ExtensionApiHandler = Future Function(dynamic params); typedef ExtensionApiHandler = Future Function(dynamic params);
class FinStoreConfig {
///SDK Key
String sdkKey;
///SDK secret
String sdkSecret;
///
String apiServer;
///apm,apiServer
String apmServer;
///MD5 SM
String cryptType;
///SDK (https://open.fdep.cn/)
String? fingerprint;
///使YES
bool encryptServerData;
FinStoreConfig(this.sdkKey, this.sdkSecret, this.apiServer, this.apmServer,
{this.cryptType = "MD5",
this.fingerprint,
this.encryptServerData = false});
Map<String, dynamic> toMap() {
return {
"sdkKey": sdkKey,
"sdkSecret": sdkSecret,
"apiServer": apiServer,
"apmServer": apmServer,
"cryptType": cryptType,
"fingerprint": fingerprint,
"encryptServerData": encryptServerData
};
}
}
class UIConfig {
Map<String, dynamic>? navigationTitleTextAttributes; //font
///
bool isAlwaysShowBackInDefaultNavigationBar = false;
///
bool isClearNavigationBarNavButtonBackground = false;
///"更多""反馈与投诉"
bool isHideFeedbackAndComplaints = false;
///"更多""返回首页"
bool isHideBackHome = false;
///"更多""转发"
bool isHideForwardMenu = false;
/// ServiceSDK
bool hideTransitionCloseButton = false;
///
bool disableSlideCloseAppletGesture = false;
///
CapsuleConfig? capsuleConfig;
FloatWindowConfig? floatWindowConfig;
//iOS
//H5 0xFFFFAA00
int? progressBarColor;
//true
bool autoAdaptDarkMode = true;
//appletText
String? appletText;
Map<String, dynamic> toMap() {
return {
"navigationTitleTextAttributes": navigationTitleTextAttributes,
"isAlwaysShowBackInDefaultNavigationBar":
isAlwaysShowBackInDefaultNavigationBar,
"isClearNavigationBarNavButtonBackground":
isClearNavigationBarNavButtonBackground,
"isHideFeedbackAndComplaints": isHideFeedbackAndComplaints,
"isHideBackHome": isHideBackHome,
"isHideForwardMenu": isHideForwardMenu,
"hideTransitionCloseButton": hideTransitionCloseButton,
"disableSlideCloseAppletGesture": disableSlideCloseAppletGesture,
"capsuleConfig": capsuleConfig?.toMap(),
"floatWindowConfig": floatWindowConfig?.toMap(),
"progressBarColor": progressBarColor,
"autoAdaptDarkMode": autoAdaptDarkMode,
"appletText": appletText
};
}
}
///
class CapsuleConfig {
/// 88
double capsuleWidth = 88;
///32
double capsuleHeight = 32;
///
double capsuleRightMargin = 7;
///5
double capsuleCornerRadius = 5;
///0.8
double capsuleBorderWidth = 1;
///
int capsuleBgLightColor = 0x33000000;
///
int capsuleBgDarkColor = 0x80ffffff;
///
int capsuleBorderLightColor = 0x80ffffff;
///
int capsuleBorderDarkColor = 0x26000000;
///线
int capsuleDividerLightColor = 0x80ffffff;
///线
int capsuleDividerDarkColor = 0x26000000;
///使
int? moreLightImage;
///使
int? moreDarkImage;
///
double moreBtnWidth = 32;
///
double moreBtnLeftMargin = 6;
///使
int? closeLightImage;
///使
int? closeDarkImage;
///
double closeBtnWidth = 32;
///
double closeBtnLeftMargin = 6;
Map<String, dynamic> toMap() {
return {
"capsuleWidth": capsuleWidth,
"capsuleHeight": capsuleHeight,
"capsuleRightMargin": capsuleRightMargin,
"capsuleCornerRadius": capsuleCornerRadius,
"capsuleBorderWidth": capsuleBorderWidth,
"capsuleBgLightColor": capsuleBgLightColor,
"capsuleBgDarkColor": capsuleBgDarkColor,
"capsuleBorderLightColor": capsuleBorderLightColor,
"capsuleBorderDarkColor": capsuleBorderDarkColor,
"capsuleDividerLightColor": capsuleDividerLightColor,
"capsuleDividerDarkColor": capsuleDividerDarkColor,
"moreLightImage": moreLightImage,
"moreDarkImage": moreDarkImage,
"moreBtnWidth": moreBtnWidth,
"moreBtnLeftMargin": moreBtnLeftMargin,
"closeLightImage": closeLightImage,
"closeDarkImage": closeDarkImage,
"closeBtnWidth": closeBtnWidth,
"closeBtnLeftMargin": closeBtnLeftMargin,
};
}
}
class FloatWindowConfig {
bool floatMode = false;
int x;
int y;
int width;
int height;
FloatWindowConfig(this.floatMode, this.x, this.y, this.width, this.height);
Map<String, dynamic> toMap() {
return {
"floatMode": floatMode,
"x": x,
"y": y,
"width": width,
"height": height
};
}
}
enum Anim {
SlideFromLeftToRightAnim,
SlideFromRightToLeftAnim,
SlideFromTopToBottomAnim,
SlideFromBottomToTopAnim,
FadeInAnim,
NoneAnim
}
class Mop { class Mop {
static final Mop _instance = new Mop._internal(); static final Mop _instance = new Mop._internal();
MethodChannel _channel; late MethodChannel _channel;
EventChannel _mopEventChannel; late EventChannel _mopEventChannel;
int eventId = 0; late int eventId = 0;
List<Map<String, dynamic>> _mopEventQueye = <Map<String, dynamic>>[]; final List<Map<String, dynamic>> _mopEventQueye = <Map<String, dynamic>>[];
Map<String, ExtensionApiHandler> _extensionApis = {}; final Map<String, ExtensionApiHandler> _extensionApis = {};
Map<String, ExtensionApiHandler> _webExtensionApis = {};
factory Mop() { factory Mop() {
return _instance; return _instance;
} }
Mop._internal() { Mop._internal() {
print('mop: _internal'); debugPrint('mop: _internal');
// init // init
_channel = new MethodChannel('mop'); _channel = const MethodChannel('mop');
_channel.setMethodCallHandler(_handlePlatformMethodCall); _channel.setMethodCallHandler(_handlePlatformMethodCall);
_mopEventChannel = new EventChannel('plugins.mop.finogeeks.com/mop_event'); _mopEventChannel =
const EventChannel('plugins.mop.finogeeks.com/mop_event');
_mopEventChannel.receiveBroadcastStream().listen((dynamic value) { _mopEventChannel.receiveBroadcastStream().listen((dynamic value) {
print('matrix: receiveBroadcastStream $value'); debugPrint('matrix: receiveBroadcastStream $value');
for (Map m in _mopEventQueye) { for (Map m in _mopEventQueye) {
if (m['event'] == value['event']) { if (m['event'] == value['event']) {
m['MopEventCallback'](value['body']); m['MopEventCallback'](value['body']);
@ -47,47 +266,77 @@ class Mop {
} }
Future<dynamic> _handlePlatformMethodCall(MethodCall call) async { Future<dynamic> _handlePlatformMethodCall(MethodCall call) async {
print("_handlePlatformMethodCall: method:${call.method}"); debugPrint("_handlePlatformMethodCall: method:${call.method}");
if (call.method.startsWith("extensionApi:")) { if (call.method.startsWith("extensionApi:")) {
final name = call.method.substring("extensionApi:".length); final name = call.method.substring("extensionApi:".length);
final handler = _extensionApis[name]; final handler = _extensionApis[name];
if (handler != null) { if (handler != null) {
return await handler(call.arguments); return await handler(call.arguments);
} }
} else if (call.method.startsWith("extensionApi:")) {} } else if (call.method.startsWith("webExtentionApi:")) {
final name = call.method.substring("webExtentionApi:".length);
final handler = _webExtensionApis[name];
if (handler != null) {
return await handler(call.arguments);
}
}
} }
/// ///
/// ///
/// initialize mop miniprogram engine. /// initialize mop miniprogram engine.
/// ///
/// [appkey] is required. it can be getted from api.finclip.com /// [sdkkey] is required. it can be getted from api.finclip.com
/// [secret] is required. it can be getted from api.finclip.com /// [secret] is required. it can be getted from api.finclip.com
/// [apiServer] is optional. the mop server address. default is https://mp.finogeek.com /// [apiServer] is optional. the mop server address. default is https://mp.finogeek.com
/// [apiPrefix] is optional. the mop server prefix. default is /api/v1/mop /// [apiPrefix] is optional. the mop server prefix. default is /api/v1/mop
/// [cryptType] is optional. cryptType, should be MD5/SM /// [cryptType] is optional. cryptType, should be MD5/SM
/// [disablePermission] is optional. /// [disablePermission] is optional.
/// [encryptServerData]
/// [userId] id
/// [finStoreConfigs]
/// [uiConfig] UI
/// [debug] debug
/// [customWebViewUserAgent] webview ua
/// [appletIntervalUpdateLimit]
/// [maxRunningApplet]
/// ///
Future<Map> initialize(String appkey, String secret, Future<Map> initialize(
{String apiServer, String sdkkey,
String apiPrefix, String secret, {
String cryptType, String? apiServer,
bool disablePermission, String? apiPrefix,
String userId, String? cryptType,
bool encryptServerData = false, bool encryptServerData = false,
bool debug = false, bool disablePermission = false,
bool bindAppletWithMainProcess = false}) async { String? userId,
bool debug = false,
bool bindAppletWithMainProcess = false,
List<FinStoreConfig>? finStoreConfigs,
UIConfig? uiConfig,
String? customWebViewUserAgent,
int? appletIntervalUpdateLimit,
int? maxRunningApplet,
}) async {
List<Map<String, dynamic>>? storeConfigs =
finStoreConfigs?.map((e) => e.toMap()).toList();
final Map ret = await _channel.invokeMethod('initialize', { final Map ret = await _channel.invokeMethod('initialize', {
'appkey': appkey, 'appkey': sdkkey,
'secret': secret, 'secret': secret,
'apiServer': apiServer, 'apiServer': apiServer,
'apiPrefix': apiPrefix, 'apiPrefix': apiPrefix,
'cryptType': cryptType, 'cryptType': cryptType,
"encryptServerData": encryptServerData,
'disablePermission': disablePermission, 'disablePermission': disablePermission,
'userId': userId, 'userId': userId,
"encryptServerData": encryptServerData,
"debug": debug, "debug": debug,
"bindAppletWithMainProcess": bindAppletWithMainProcess "bindAppletWithMainProcess": bindAppletWithMainProcess,
"finStoreConfigs": storeConfigs,
"uiConfig": uiConfig?.toMap(),
"customWebViewUserAgent": customWebViewUserAgent,
"appletIntervalUpdateLimit": appletIntervalUpdateLimit,
"maxRunningApplet": maxRunningApplet
}); });
return ret; return ret;
} }
@ -104,14 +353,11 @@ class Mop {
/// [cryptType] is optional. cryptType, should be MD5/SM /// [cryptType] is optional. cryptType, should be MD5/SM
Future<Map> openApplet( Future<Map> openApplet(
final String appId, { final String appId, {
final String path, final String? path,
final String query, final String? query,
final int sequence, final int? sequence,
final String apiServer, final String? apiServer,
final String apiPrefix, final String? scene,
final String fingerprint,
final String cryptType,
final String scene,
}) async { }) async {
Map<String, Object> params = {'appId': appId}; Map<String, Object> params = {'appId': appId};
Map param = {}; Map param = {};
@ -120,9 +366,6 @@ class Mop {
if (param.length > 0) params["params"] = param; if (param.length > 0) params["params"] = param;
if (sequence != null) params["sequence"] = sequence; if (sequence != null) params["sequence"] = sequence;
if (apiServer != null) params["apiServer"] = apiServer; if (apiServer != null) params["apiServer"] = apiServer;
if (apiPrefix != null) params["apiPrefix"] = apiPrefix;
if (fingerprint != null) params["fingerprint"] = fingerprint;
if (cryptType != null) params["cryptType"] = cryptType;
if (scene != null) param["scene"] = scene; if (scene != null) param["scene"] = scene;
final Map ret = await _channel.invokeMethod('openApplet', params); final Map ret = await _channel.invokeMethod('openApplet', params);
return ret; return ret;
@ -136,7 +379,7 @@ class Mop {
/// ///
Future<Map<String, dynamic>> currentApplet() async { Future<Map<String, dynamic>> currentApplet() async {
final ret = await _channel.invokeMapMethod("currentApplet"); final ret = await _channel.invokeMapMethod("currentApplet");
return Map<String, dynamic>.from(ret); return Map<String, dynamic>.from(ret!);
} }
/// ///
@ -167,7 +410,7 @@ class Mop {
Future<String> sdkVersion() async { Future<String> sdkVersion() async {
return await _channel return await _channel
.invokeMapMethod("sdkVersion") .invokeMapMethod("sdkVersion")
.then((value) => value["data"]); .then((value) => value?["data"]);
} }
/// ///
@ -190,7 +433,7 @@ class Mop {
String qrCode, String apiServer) async { String qrCode, String apiServer) async {
final ret = await _channel.invokeMapMethod("parseAppletInfoFromWXQrCode", final ret = await _channel.invokeMapMethod("parseAppletInfoFromWXQrCode",
{"qrCode": qrCode, "apiServer": apiServer}); {"qrCode": qrCode, "apiServer": apiServer});
return Map<String, dynamic>.from(ret); return Map<String, dynamic>.from(ret!);
} }
/// ///
@ -207,7 +450,7 @@ class Mop {
_extensionApis["getCustomMenus"] = (params) async { _extensionApis["getCustomMenus"] = (params) async {
final res = await handler.getCustomMenus(params["appId"]); final res = await handler.getCustomMenus(params["appId"]);
List<Map<String, dynamic>> list = []; List<Map<String, dynamic>> list = [];
res?.forEach((element) { res.forEach((element) {
Map<String, dynamic> map = Map(); Map<String, dynamic> map = Map();
map["menuId"] = element.menuId; map["menuId"] = element.menuId;
map["image"] = element.image; map["image"] = element.image;
@ -215,7 +458,7 @@ class Mop {
map["type"] = element.type; map["type"] = element.type;
list.add(map); list.add(map);
}); });
print("registerAppletHandler getCustomMenus list $list"); debugPrint("registerAppletHandler getCustomMenus list $list");
return list; return list;
}; };
_extensionApis["onCustomMenuClick"] = (params) async { _extensionApis["onCustomMenuClick"] = (params) async {
@ -241,8 +484,8 @@ class Mop {
Future<String> getSMSign(String plainText) async { Future<String> getSMSign(String plainText) async {
var result = var result =
await _channel.invokeMapMethod("smsign", {'plainText': plainText}); await _channel.invokeMapMethod("smsign", {'plainText': plainText});
var data = result['data']['data']; var data = result?['data']['data'];
print(data); debugPrint(data);
return data; return data;
} }
@ -251,4 +494,51 @@ class Mop {
await _channel.invokeMapMethod("webViewBounces", {'bounces': bounces}); await _channel.invokeMapMethod("webViewBounces", {'bounces': bounces});
return; return;
} }
//
Future<void> closeApplet(String appletId, bool animated) async {
await _channel.invokeMethod(
"closeApplet", {"appletId": appletId, "animated": animated});
return;
}
//
Future<void> finishRunningApplet(String appletId, bool animated) async {
await _channel.invokeMethod(
"finishRunningApplet", {"appletId": appletId, "animated": animated});
return;
}
//
Future setActivityTransitionAnim(Anim anim) async {
await _channel
.invokeMethod("setActivityTransitionAnim", {"anim": anim.name});
return;
}
//
Future<void> sendCustomEvent(
String appId, Map<String, dynamic> eventData) async {
await _channel.invokeMethod(
"sendCustomEvent", {"appId": appId, "eventData": eventData});
return;
}
//js
Future<void> callJS(String appId, String eventName, String nativeViewId,
Map<String, dynamic> eventData) async {
await _channel.invokeMethod("callJS", {
"appId": appId,
"eventName": eventName,
"nativeViewId": nativeViewId,
"eventData": eventData
});
return;
}
//h5
void addWebExtentionApi(String name, ExtensionApiHandler handler) {
_webExtensionApis[name] = handler;
_channel.invokeMethod("addWebExtentionApi", {"name": name});
}
} }

View File

@ -7,7 +7,7 @@ packages:
name: async name: async
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.6.1" version: "2.8.2"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
@ -21,14 +21,14 @@ packages:
name: characters name: characters
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.1.0" version: "1.2.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.2.0" version: "1.3.1"
clock: clock:
dependency: transitive dependency: transitive
description: description:
@ -55,25 +55,46 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.4"
flutter_plugin_android_lifecycle:
dependency: "direct main"
description:
name: flutter_plugin_android_lifecycle
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.5"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.12.10" version: "0.12.11"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.3.0" version: "1.7.0"
path: path:
dependency: transitive dependency: transitive
description: description:
@ -127,7 +148,7 @@ packages:
name: test_api name: test_api
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.3.0" version: "0.4.3"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@ -141,7 +162,7 @@ packages:
name: vector_math name: vector_math
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "2.1.0" version: "2.1.1"
sdks: sdks:
dart: ">=2.12.0 <3.0.0" dart: ">=2.14.0 <3.0.0"
flutter: ">=1.10.0" flutter: ">=2.2.3"

View File

@ -4,16 +4,18 @@ version: '__mop_flutter_sdk_version__'
homepage: https://github.com/finogeeks/mop-flutter-sdk homepage: https://github.com/finogeeks/mop-flutter-sdk
environment: environment:
sdk: '>=2.1.0 <3.0.0' sdk: '>=2.12.0 <3.0.0'
flutter: '^1.10.0' flutter: '^2.2.3'
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_plugin_android_lifecycle: ^2.0.3
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^1.0.0
flutter: flutter:
plugin: plugin:

View File

@ -1,19 +1,21 @@
name: mop name: mop
description: A Finogeeks MiniProgram Flutter SDK. description: A Finogeeks MiniProgram Flutter SDK.
version: '2.34.12' version: '2.35.1'
homepage: https://github.com/finogeeks/mop-flutter-sdk homepage: https://github.com/finogeeks/mop-flutter-sdk
environment: environment:
sdk: '>=2.1.0 <3.0.0' sdk: '>=2.12.0 <3.0.0'
flutter: '^1.10.0' flutter: '^2.2.3'
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_plugin_android_lifecycle: ^2.0.3
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^1.0.0
flutter: flutter:
plugin: plugin:

View File

@ -5,6 +5,8 @@ import 'package:mop/mop.dart';
void main() { void main() {
const MethodChannel channel = MethodChannel('mop'); const MethodChannel channel = MethodChannel('mop');
TestWidgetsFlutterBinding.ensureInitialized();
setUp(() { setUp(() {
channel.setMockMethodCallHandler((MethodCall methodCall) async { channel.setMockMethodCallHandler((MethodCall methodCall) async {
return '42'; return '42';