commit 6e02aaf22b9798f4b01554a9153d2c66591da8c1 Author: 杨华轩 <646903573@qq.com> Date: Wed Oct 14 09:13:22 2020 +0800 1.初始化代码库,完成阿里百川渠道授权、商品详情的手淘调用 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..816fcc4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +build/ +*.iml +.idea/ +.gradle/ +.vscode/ + +android/.classpath +android/.project +android/.settings/org.eclipse.buildship.core.prefs +example/android/.project +example/android/.settings/org.eclipse.buildship.core.prefs +example/android/app/.classpath +example/android/app/.project +example/android/app/.settings/org.eclipse.buildship.core.prefs diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..29735e9 --- /dev/null +++ b/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: e4ebcdf6f4facee5779c38a04d91d08dc58ea7a4 + channel: beta + +project_type: plugin diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..71f6d97 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,62 @@ + +## 0.0.1 +完成开发 +* TODO: Describe initial release. +## 0.0.2 +修改readme +## 0.0.3 +Android 修正缺少的接口参数 + +## 0.0.4 + +AndroidX 测试 + +## 0.0.5 +1.修复Android与iOS逻辑不一致的地方 +2.修复枚举混乱的问题 +3.修复Android返回参数不正确的问题 +4.通过openurl,openItem,openShop,openCart的返回值在失败的情况下,移除tradeFailResult这个失败的回调data(因为Android没有) + +## 0.0.6 +升级到百川V4.0.2版本 +具体升级变动[百川官方更新说明](https://baichuan.taobao.com/docs/doc.htm?spm=a3c0d.7629140.0.0.749bbe48KRlbQC&treeId=129&articleId=106383&docType=1#s1) + +## 0.0.7 +1.修正iOS的回调,感谢[JarvanMo](https://github.com/JarvanMo) +2.修正iOS不传入backUrl导致的崩溃问题 +## 0.0.8 +新增二次授权获取accessToken用于二次授权登录 + +## 0.0.8 +1.新增淘客登录返回token用于服务端二次登录 + +## 0.0.9 +更新百川sdk到4.0.8 + +## 0.0.12 +iOS 更新到 4.0.1.0 + UIwebview换成Wkwebview +Android4.0.0.8 + +## 0.0.13 +iOS 更新到 4.0.1.0 + UIwebview换成Wkwebview + 支持swift +Android4.0.0.8 + +## 0.0.14 +iOS 4.0.1.0 +Android4.0.0.8 +iOS的依赖不再保存百川的库了,请自行添加淘宝pod源拉取 + + +## 0.0.15 +iOS升级 +iOS 4.0.1.6 +Android4.0.0.8 \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..76bfb8b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 FlutterTaoBaoKe + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..eae5e21 --- /dev/null +++ b/README.md @@ -0,0 +1,218 @@ + +# flutter_alibc + +Flutter版本的阿里百川 +android V4.0.0.8版本 +ios V4.0.1.6 版本 + +pub地址:[flutter_alibc](https://pub.dev/packages/flutter_alibc) +github地址:[flutter_alibc](https://github.com/FlutterTaoBaoKe/flutter_alibc.git) + +可以给个star🐴,混口饭吃 + +支持Android和iOS + +邮箱: + +Android:983598009@qq.com + +iOS:329106954@qq.com +P.S:另有开普勒插件[flutter_kepler](https://github.com/FlutterTaoBaoKe/flutter_kepler) +## Getting Started + +### 工程性配置 + +参考[阿里百川官网](https://baichuan.taobao.com/docs/doc.htm?spm=a3c0d.7629140.0.0.3043be48zxxuk5&treeId=129&articleId=118102&docType=1) + +### 引入 +[如何引入项目](https://pub.dev/packages/flutter_alibc#-installing-tab-) +iOS请在podfile文件非注释的第一行,加入淘宝源,如果有其他源,请放在其他源下方,没有其他源只需要加这一个即可 +``` +source 'http://repo.baichuan-ios.taobao.com/baichuanSDK/AliBCSpecs.git' +``` +看不懂这句话就看下demo中的example/ios/podfile文件第4行代码,第3行是其他源的示例可以不加 + +### 支持swift了 +### 感谢[@a4081675](https://github.com/a4081675)同学 +[issues44](https://github.com/FlutterTaoBaoKe/flutter_alibc/issues/44) +### 方法说明 +* 头文件引入 +``` +import 'package:flutter_alibc/flutter_alibc.dart'; +``` + +* 初始化 + +``` + /** + * 初始化 + * version:当前app版本 + * appName:当前app名称 + * result:{ + * errorCode, //0为初始化成功,其他为失败 + * errorMessage, //message + * } + */ +var result = await FlutterAlibc.initAlibc(version:"",appName:""); +``` + +* 登录淘宝 +``` +/** + * 登录淘宝 + * version:当前app版本 + * appName:当前app名称 + * result:{ + * errorCode, //0为初始化成功,其他为失败 + * errorMessage, //message + * data:{ //登录成功的情况下返回data,为用户数据 + * //nick 用户昵称,avatarUrl 头像地址 + * nick,avatarUrl,openId,openSid,topAccessToken,topAuthCode + * } + * } + * 备注:登录过会直接返回淘宝用户的信息,不会多次唤醒淘宝,请放心 + */ +var result = await FlutterAlibc.loginTaoBao(); +``` + +* 淘宝登出 +``` +FlutterAlibc.loginOut(); +``` + +* 淘客登录,二次授权获取access_token + +``` + /** + * @description: 获取access_token + * @param + * url:用于授权登录的url + * openType:打开类型,默认auto + * isNeedCustomNativeFailMode:是否需要设置唤端失败策略,默认false + * nativeFailMode:唤端失败策略,默认None + * schemeType:唤起哪个端,默认天猫 + * taokeParams:淘客数据 + * backUrl: 跳转回来的url + * @return: {accessToken:""}//获取成功为token,获取失败为空字符串 + */ + var result = await FlutterAlibc.taoKeLogin( + url:"", //必须参数,用于授权登录的url + openType : AlibcOpenType.AlibcOpenTypeAuto, + isNeedCustomNativeFailMode : false, + nativeFailMode : AlibcNativeFailMode.AlibcNativeFailModeNone, + schemeType : AlibcSchemeType.AlibcSchemeTmall, + taokeParams : {}, + backUrl:"", + ); +``` + +* 唤起淘宝,openByUrl方式 + +``` + /** + * @description: 通过url打开,包括h5,唤起手淘等 + * @param + * url:目标url + * openType:打开类型,默认auto + * isNeedCustomNativeFailMode:是否需要设置唤端失败策略,默认false + * nativeFailMode:唤端失败策略,默认None + * schemeType:唤起哪个端,默认天猫 + * taokeParams:淘客数据 + * backUrl: 跳转回来的url + * @return: { + * errorCode, + * errorMessage, + * type, //0为添加购物车,1为付款成功 + * payResult, //type为1时返回 + * } + */ + var result = await FlutterAlibc.openByUrl( + url:"", //必须参数 + openType : AlibcOpenType.AlibcOpenTypeAuto, + isNeedCustomNativeFailMode : false, + nativeFailMode : AlibcNativeFailMode.AlibcNativeFailModeNone, + schemeType : AlibcSchemeType.AlibcSchemeTmall, + taokeParams : {}, + backUrl:"", + ); +``` + +* 唤起淘宝,openItemDetail方式 +``` +/** + * @description: 打开商品详情 + * @param + * itemID 商品id,可以是真实的也可以是混淆的,必须参数 + * trackParam 需要额外追踪的业务数据 + * 其他同上 + * @return: 同openByUrl + */ +var result = await FlutterAlibc.openItemDetail( + itemID:"", //必须参数 + openType : AlibcOpenType.AlibcOpenTypeAuto, + isNeedCustomNativeFailMode : false, + nativeFailMode : AlibcNativeFailMode.AlibcNativeFailModeNone, + schemeType : AlibcSchemeType.AlibcSchemeTmall, + taokeParams : {}, + trackParam : {}, //需要额外追踪的业务数据 + backUrl:"", +); +``` + +* 打开店铺,openShop方式 +``` +/** + * @description: 打开店铺 + * @param + * shopId 店铺id,必须参数 + * 其他同上 + * @return: 同openByUrl + */ +var result = await FlutterAlibc.openShop( + shopId:"", //必须参数 + openType : AlibcOpenType.AlibcOpenTypeAuto, + isNeedCustomNativeFailMode : false, + nativeFailMode : AlibcNativeFailMode.AlibcNativeFailModeNone, + schemeType : AlibcSchemeType.AlibcSchemeTmall, + taokeParams : {}, + trackParam : {}, //需要额外追踪的业务数据 + backUrl:"", +); +``` + +* 打开购物车,openCart方式 +``` +/** + * @description: 打开购物车 + * @param + * 无必须参数 + * 其他同上 + * @return: 同openByUrl + */ +var result = await FlutterAlibc.openCart( + openType : AlibcOpenType.AlibcOpenTypeAuto, + isNeedCustomNativeFailMode : false, + nativeFailMode : AlibcNativeFailMode.AlibcNativeFailModeNone, + schemeType : AlibcSchemeType.AlibcSchemeTmall, + taokeParams : {}, + trackParam : {}, //需要额外追踪的业务数据 + backUrl:"", +); +``` + + +* 是否设置同步打点 +``` +FlutterAlibc.syncForTaoke(true); +```` + +* 是否使用Native Alipay +``` +FlutterAlibc.useAlipayNative(true); +``` diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..c6cbe56 --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000..ffa57ef --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,70 @@ +group 'com.wxwx.flutter_alibc' +version '1.0-SNAPSHOT' + +buildscript { + repositories { + google() + jcenter() + maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'} + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'} + maven { + url "http://repo.baichuan-android.taobao.com/content/groups/BaichuanRepositories/" + } + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + defaultConfig { + buildConfigField "boolean", "LOG_DEBUG", "true" + minSdkVersion 16 + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + lintOptions { + disable 'InvalidPackage' + } + compileOptions { + sourceCompatibility = '1.8' + targetCompatibility = '1.8' + } +} + +dependencies{ + +//登陆 + implementation 'com.ali.auth.sdk:alibabauth_core:2.0.0.11@aar' + implementation 'com.ali.auth.sdk:alibabauth_ui:2.0.0.11@aar' + implementation 'com.ali.auth.sdk:alibabauth_ext:2.0.0.11@aar' + //安全组件 + implementation 'com.taobao.android:securityguardaar3:5.4.171@aar' + implementation 'com.taobao.android:securitybodyaar3:5.4.99@aar' + implementation 'com.taobao.android:avmpaar3:5.4.36@aar' + implementation 'com.taobao.android:sgmiddletieraar3:5.4.9@aar' + //Mtop + implementation 'com.taobao.android:mtopsdk_allinone_open:3.1.2.5@jar' + //applink + implementation 'com.alibaba.sdk.android:alibc_link_partner:4.1.15@aar' + //ut + implementation 'com.taobao.android:utdid4all:1.5.2' + implementation 'com.alibaba.mtl:app-monitor-sdk:2.6.4.5_for_bc' + // 电商基础组件 + implementation 'com.alibaba.sdk.android:AlibcTradeCommon:4.0.0.16@aar' + implementation 'com.alibaba.sdk.android:AlibcTradeBiz:4.0.0.16@aar' + implementation 'com.alibaba.sdk.android:nb_trade:4.0.0.16@aar' + implementation 'com.alibaba:fastjson:1.2.52@jar' + +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..2bd6f4f --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx1536M + diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f Binary files /dev/null and b/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..3851bbe --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Oct 09 15:41:03 CST 2020 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/android/gradlew b/android/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/android/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# 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 + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# 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 +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +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" -a "$nonstop" = "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 + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/android/gradlew.bat b/android/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/android/gradlew.bat @@ -0,0 +1,84 @@ +@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 + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@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= + +@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 Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_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=%* + +: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 diff --git a/android/libs/sweet-alert-dialog_v1.3.aar b/android/libs/sweet-alert-dialog_v1.3.aar new file mode 100644 index 0000000..183c3dd Binary files /dev/null and b/android/libs/sweet-alert-dialog_v1.3.aar differ diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..07771b9 --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'flutter_alibc' diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8c60934 --- /dev/null +++ b/android/src/main/AndroidManifest.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/android/src/main/java/com/wxwx/flutter_alibc/FlutterAlibcHandle.java b/android/src/main/java/com/wxwx/flutter_alibc/FlutterAlibcHandle.java new file mode 100644 index 0000000..aeb4651 --- /dev/null +++ b/android/src/main/java/com/wxwx/flutter_alibc/FlutterAlibcHandle.java @@ -0,0 +1,334 @@ +package com.wxwx.flutter_alibc; + +import android.util.Log; +import android.webkit.WebChromeClient; +import android.webkit.WebViewClient; +import android.widget.Toast; +import android.content.Intent; +import com.ali.auth.third.core.model.Session; +import com.alibaba.baichuan.trade.biz.context.AlibcResultType; +import com.alibaba.baichuan.android.trade.AlibcTrade; +import com.alibaba.baichuan.android.trade.callback.AlibcTradeCallback; +import com.alibaba.baichuan.android.trade.model.AlibcShowParams; +import com.alibaba.baichuan.android.trade.model.OpenType; +import com.alibaba.baichuan.android.trade.page.AlibcBasePage; +import com.alibaba.baichuan.android.trade.page.AlibcDetailPage; +import com.alibaba.baichuan.android.trade.page.AlibcMyCartsPage; +import com.alibaba.baichuan.android.trade.page.AlibcShopPage; +import com.alibaba.baichuan.trade.biz.applink.adapter.AlibcFailModeType; +import com.alibaba.baichuan.trade.biz.context.AlibcTradeResult; +import com.alibaba.baichuan.trade.biz.core.taoke.AlibcTaokeParams; +import com.alibaba.baichuan.trade.biz.login.AlibcLogin; +import com.alibaba.baichuan.trade.biz.login.AlibcLoginCallback; +import com.alibaba.baichuan.android.trade.AlibcTradeSDK; +import com.alibaba.baichuan.android.trade.callback.AlibcTradeInitCallback; +import com.alibaba.baichuan.trade.common.utils.AlibcLogger; +import io.flutter.plugin.common.PluginRegistry.Registrar; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.MethodCall; +import java.util.HashMap; +import android.app.AlertDialog; +import static com.wxwx.flutter_alibc.PluginConstants.*; +import static com.wxwx.flutter_alibc.PluginUtil.*; +import com.wxwx.flutter_alibc.web.WebViewActivity; +import java.util.Map; + +/** + * @Author karedem + * @Date 2019/9/7 19:55 + * @Description 接口处理者 +**/ +public class FlutterAlibcHandle{ + + private static FlutterAlibcHandle handle; + private Registrar register; + + //第一次调用getInstance register不能为空 + public static FlutterAlibcHandle getInstance(Registrar register){ + if (handle == null){ + synchronized (FlutterAlibcHandle.class){ + handle = new FlutterAlibcHandle(); + handle.register = register; + } + } + return handle; + } + + /** + * 初始化阿里百川 + * @param call + * @param result + */ + public void initAlibc(MethodCall call, Result result){ + AlibcTradeSDK.asyncInit(register.activity().getApplication(), new AlibcTradeInitCallback() { + @Override + public void onSuccess() { + result.success(PluginResponse.success(null).toMap()); + } + @Override + public void onFailure(int code, String msg) { + result.success(new PluginResponse(Integer.toString(code), msg, null).toMap()); + } + }); + } + + /** + * 登陆淘宝 + * @param result + */ + public void loginTaoBao(Result result){ + final AlibcLogin alibcLogin = AlibcLogin.getInstance(); + if (alibcLogin.isLogin()){ + Session session = AlibcLogin.getInstance().getSession(); + Map userInfo = new HashMap<>(); + userInfo.put("nick", session.nick); + userInfo.put("avatarUrl", session.avatarUrl); + userInfo.put("openId", session.openId); + userInfo.put("openSid", session.openSid); + userInfo.put("topAccessToken", session.topAccessToken); + userInfo.put("topAuthCode", session.topAuthCode); + result.success(PluginResponse.success(userInfo).toMap()); + return; + } + alibcLogin.showLogin(new AlibcLoginCallback() { + @Override + public void onSuccess(int loginResult, String openId, String userNick) { + Map userInfo = new HashMap<>(); + Session session = AlibcLogin.getInstance().getSession(); + userInfo.put("nick", session.nick); + userInfo.put("avatarUrl", session.avatarUrl); + userInfo.put("openId", session.openId); + userInfo.put("openSid", session.openSid); + userInfo.put("topAccessToken", session.topAccessToken); + userInfo.put("topAuthCode", session.topAuthCode); + result.success(PluginResponse.success(userInfo).toMap()); + } + @Override + public void onFailure(int code, String msg) { + // code:错误码 msg: 错误信息 + result.success(new PluginResponse(Integer.toString(code), msg, null).toMap()); + } + }); + } + + /** + * 登出 + * @param result + */ + public void loginOut(Result result){ + AlibcLogin alibcLogin = AlibcLogin.getInstance(); + alibcLogin.logout(new AlibcLoginCallback() { + @Override + public void onSuccess(int loginResult, String openId, String userNick) { + } + @Override + public void onFailure(int code, String msg) { + // code:错误码 msg: 错误信息 + } + }); + } + + /** + * 淘宝授权登陆 获取access_token + * 官方说明文档 {https://open.taobao.com/doc.htm?docId=118&docType=1} + * @param call + * @param result + */ + public void taoKeLogin(MethodCall call, Result result){ + HashMap map = (HashMap)call.arguments; + String url = call.argument("url"); + WebViewActivity.setCallBack(new WebViewActivity.CallBack() { + @Override + public void success(String accessToken) { + Map resMap = new HashMap(); + resMap.put("accessToken", accessToken); + result.success(resMap); + } + + @Override + public void failed(String errorMsg) { + Map resMap = new HashMap(); + resMap.put("accessToken", ""); + result.success(resMap); + } + }); + Intent intent = new Intent(register.activity(), WebViewActivity.class); + intent.putExtra("url", url); + intent.putExtra("arguments", map); + register.activity().startActivity(intent); + } + + /** + * 通过URL方式打开淘宝 + * @param call + * @param result + */ + public void openByUrl(MethodCall call, Result result){ + AlibcShowParams showParams = new AlibcShowParams(); + AlibcTaokeParams taokeParams = new AlibcTaokeParams("","",""); + + showParams.setBackUrl(call.argument(key_BackUrl)); + + ///渠道授权 + if((Boolean) call.argument(login_And_Auth)){ + ///先APP授权 + + if (!AlibcLogin.getInstance().isLogin()) { + + AlibcLogin.getInstance().showLogin(new AlibcLoginCallback() { + @Override + public void onSuccess(int i, String s, String s1) { + Log.d("阿里百川打开WebView","webview"); + register.activity().startActivity(new Intent(register.activity(),WebActivity.class)); + } + + @Override + public void onFailure(int i, String s) { + Log.d("阿里百川授权失败",s); + } + }); + } else { + Log.d("阿里百川打开WebView","webview"); + register.activity().startActivity(new Intent(register.activity(),WebActivity.class)); + } + ///后渠道信息 + return; + } + +// if (call.argument(key_OpenType) != null){ +// System.out.println("openType" + call.argument(key_OpenType)); +// showParams.setOpenType(getOpenType(""+call.argument(key_OpenType))); +// } +// if (call.argument(key_ClientType) != null){ +// System.out.println("clientType " + call.argument(key_ClientType)); +// showParams.setClientType(getClientType(""+call.argument(key_ClientType))); +// } + if (call.argument("taokeParams") != null){ + taokeParams = getTaokeParams(call.argument("taokeParams")); + } +// if ("false".equals(call.argument("isNeedCustomNativeFailMode"))){ +// showParams.setNativeOpenFailedMode(AlibcFailModeType.AlibcNativeFailModeNONE); +// }else if (call.argument(key_NativeFailMode) != null){ +// showParams.setNativeOpenFailedMode(getFailModeType(""+call.argument(key_NativeFailMode))); +// } + + Map trackParams = new HashMap<>(); + String url = call.argument("url"); + // 以显示传入url的方式打开页面(第二个参数是套件名称) + AlibcTrade.openByUrl(register.activity(), "", url, null, + new WebViewClient(), new WebChromeClient(), showParams, + taokeParams, trackParams, new AlibcTradeCallback() { + @Override + public void onTradeSuccess(AlibcTradeResult tradeResult) { + Map results = new HashMap<>(); + if (AlibcResultType.TYPECART == tradeResult.resultType){ + results.put("type", 1); + }else if (AlibcResultType.TYPEPAY == tradeResult.resultType){ + results.put("type", 0); + results.put("payFailedOrders", tradeResult.payResult.payFailedOrders); + results.put("paySuccessOrders", tradeResult.payResult.paySuccessOrders); + } + result.success(PluginResponse.success(results).toMap()); + } + @Override + public void onFailure(int code, String msg) { + result.success(new PluginResponse(Integer.toString(code), msg, null).toMap()); + } + }); + + + } + + /** + * 打开商店 + * @param call + * @param result + */ + public void openShop(MethodCall call, Result result){ + AlibcBasePage page = new AlibcShopPage(call.argument("shopId")); + openByBizCode(page, "shop", call, result); + } + + /** + * 打开购物车 + * @param result + */ + public void openCart(MethodCall call, Result result){ + AlibcBasePage page = new AlibcMyCartsPage(); + openByBizCode(page, "cart",call, result); + } + + /** + * 打开商品详情 + * @param call call.argument["itemID"] 详情id + * @param result + */ + public void openItemDetail(MethodCall call, Result result){ + AlibcBasePage page = new AlibcDetailPage(call.argument("itemID")); + openByBizCode(page, "detail", call, result); + } + + private void openByBizCode(AlibcBasePage page,String type, MethodCall call, Result result){ + AlibcShowParams showParams = new AlibcShowParams(); + AlibcTaokeParams taokeParams = new AlibcTaokeParams("", "", ""); + + showParams.setBackUrl(call.argument(key_BackUrl)); + + if (call.argument(key_OpenType) != null){ + showParams.setOpenType(getOpenType(""+call.argument(key_OpenType))); + } + if (call.argument(key_ClientType) != null){ + showParams.setClientType(getClientType(""+call.argument(key_ClientType))); + } + if (call.argument("taokeParams") != null){ + taokeParams = getTaokeParams(call.argument("taokeParams")); + } + + if ("false".equals(call.argument("isNeedCustomNativeFailMode"))){ + showParams.setNativeOpenFailedMode(AlibcFailModeType.AlibcNativeFailModeNONE); + }else if (call.argument(key_NativeFailMode) != null){ + showParams.setNativeOpenFailedMode(getFailModeType(""+call.argument(key_NativeFailMode))); + } + + Map trackParams = new HashMap<>(); + AlibcTrade.openByBizCode(register.activity(), page, null, new WebViewClient(), + new WebChromeClient(), type, showParams, taokeParams, + trackParams, new AlibcTradeCallback() { + @Override + public void onTradeSuccess(AlibcTradeResult tradeResult) { + Map results = new HashMap<>(); + if (AlibcResultType.TYPECART == tradeResult.resultType){ + results.put("type", 1); + }else if (AlibcResultType.TYPEPAY == tradeResult.resultType){ + results.put("type", 0); + results.put("payFailedOrders", tradeResult.payResult.payFailedOrders); + results.put("paySuccessOrders", tradeResult.payResult.paySuccessOrders); + } + result.success(PluginResponse.success(results).toMap()); + } + @Override + public void onFailure(int code, String msg) { + // 失败回调信息 + result.success(new PluginResponse(Integer.toString(code), msg, null).toMap()); + } + }); + } + + /** + * 设置淘客打点策略 是否异步 + * @param call + */ + public void syncForTaoke(MethodCall call){ + AlibcTradeSDK.setSyncForTaoke(call.argument("isSync")); + } + + /** + * TODO + * @param call + */ + public void useAlipayNative(MethodCall call){ + AlibcTradeSDK.setShouldUseAlipay(call.argument("isNeed")); + } + + +} \ No newline at end of file diff --git a/android/src/main/java/com/wxwx/flutter_alibc/FlutterAlibcPlugin.java b/android/src/main/java/com/wxwx/flutter_alibc/FlutterAlibcPlugin.java new file mode 100644 index 0000000..4a6701d --- /dev/null +++ b/android/src/main/java/com/wxwx/flutter_alibc/FlutterAlibcPlugin.java @@ -0,0 +1,48 @@ +package com.wxwx.flutter_alibc; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.PluginRegistry.Registrar; + +/** FlutterAlibcPlugin */ +public class FlutterAlibcPlugin implements MethodCallHandler { + + private static com.wxwx.flutter_alibc.FlutterAlibcHandle handle; + /** Plugin registration. */ + public static void registerWith(Registrar registrar) { + handle = com.wxwx.flutter_alibc.FlutterAlibcHandle.getInstance(registrar); + final MethodChannel channel = new MethodChannel(registrar.messenger(), "flutter_alibc"); + channel.setMethodCallHandler(new FlutterAlibcPlugin()); + } + + @Override + public void onMethodCall(MethodCall call, Result result) { + if (call.method.equals("getPlatformVersion")) { + result.success("Android " + android.os.Build.VERSION.RELEASE); + } else if (call.method.equals("initAlibc")){ + handle.initAlibc(call, result); + }else if (call.method.equals("openItemDetail")){ + handle.openItemDetail(call, result); + } else if (call.method.equals("loginTaoBao")){ + handle.loginTaoBao(result); + } else if (call.method.equals("taoKeLogin")){ + handle.taoKeLogin(call, result); + } else if (call.method.equals("loginOut")){ + handle.loginOut(result); + }else if (call.method.equals("openByUrl")){ + handle.openByUrl(call, result); + }else if (call.method.equals("openShop")){ + handle.openShop(call, result); + }else if (call.method.equals("openCart")){ + handle.openCart(call, result); + }else if (call.method.equals("syncForTaoke")){ + handle.syncForTaoke(call); + }else if (call.method.equals("useAlipayNative")){ + handle.useAlipayNative(call); + }else { + result.notImplemented(); + } + } +} diff --git a/android/src/main/java/com/wxwx/flutter_alibc/PluginConstants.java b/android/src/main/java/com/wxwx/flutter_alibc/PluginConstants.java new file mode 100644 index 0000000..5789134 --- /dev/null +++ b/android/src/main/java/com/wxwx/flutter_alibc/PluginConstants.java @@ -0,0 +1,29 @@ +package com.wxwx.flutter_alibc; + +import java.lang.annotation.Native; + +/** + * @Author karedem + * @Date 2019/9/10 11:28 + * @Description 常量类 +**/ +public interface PluginConstants { + + String login_And_Auth="auth"; + + String key_OpenType = "openType"; + String key_ClientType = "schemeType"; + String key_BackUrl = "backUrl"; + String key_NativeFailMode = "nativeFailMode"; + + + String Tmall_ClientType = "0"; + String TaoBao_ClientType = "1"; + + String Auto_OpenType = "0"; + String Native_OpenType = "1"; + + String JumpH5_FailMode = "0"; + String JumpDownloadPage_FailMode = "1"; + String None_FailMode = "2"; +} diff --git a/android/src/main/java/com/wxwx/flutter_alibc/PluginResponse.java b/android/src/main/java/com/wxwx/flutter_alibc/PluginResponse.java new file mode 100644 index 0000000..89ea5e2 --- /dev/null +++ b/android/src/main/java/com/wxwx/flutter_alibc/PluginResponse.java @@ -0,0 +1,35 @@ +package com.wxwx.flutter_alibc; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * @Author karedem + * @Date 2019/9/7 19:55 + * @Description 插件 响应返回实体类 +**/ +public class PluginResponse implements Serializable { + + private String errorCode; + private String errorMessage; + private Object data; + + public static PluginResponse success(Object obj){ + return new PluginResponse("0", "成功", obj); + } + + public PluginResponse(String errorCode, String errorMessage, Object data) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + this.data = data; + } + + public Map toMap(){ + HashMap map = new HashMap<>(); + map.put("errorCode", errorCode); + map.put("errorMessage", errorMessage); + map.put("data", data); + return map; + } +} diff --git a/android/src/main/java/com/wxwx/flutter_alibc/PluginUtil.java b/android/src/main/java/com/wxwx/flutter_alibc/PluginUtil.java new file mode 100644 index 0000000..5de3d6b --- /dev/null +++ b/android/src/main/java/com/wxwx/flutter_alibc/PluginUtil.java @@ -0,0 +1,54 @@ +package com.wxwx.flutter_alibc; + +import static com.wxwx.flutter_alibc.PluginConstants.*; +import com.alibaba.baichuan.android.trade.model.OpenType; +import com.alibaba.baichuan.trade.biz.applink.adapter.AlibcFailModeType; +import com.alibaba.baichuan.trade.biz.core.taoke.AlibcTaokeParams; + +import java.util.Map; + +/** + * @Author karedem + * @Date 2019/9/10 11:42 + * @Description 映射返回对应值 +**/ +public class PluginUtil { + + public static OpenType getOpenType(String open){ + if (Auto_OpenType.equals(open)){ + return OpenType.Auto; + }else { + return OpenType.Native; + } + } + + public static String getClientType(String client){ + if (client.equals(Tmall_ClientType)){ + return "tmall"; + }else { + return "taobao"; + } + } + + public static AlibcFailModeType getFailModeType(String mode){ + if (JumpH5_FailMode.equals(mode)){ + return AlibcFailModeType.AlibcNativeFailModeJumpH5; + }else if (JumpDownloadPage_FailMode.equals(mode)){ + return AlibcFailModeType.AlibcNativeFailModeJumpDOWNLOAD; + }else { + return AlibcFailModeType.AlibcNativeFailModeNONE; + } + } + + public static AlibcTaokeParams getTaokeParams(Map taokePar){ + String pid = (String) taokePar.get("pid"); + AlibcTaokeParams taokeParams = new AlibcTaokeParams("", "", ""); + if (pid != null){ + taokeParams.setPid(pid); + } + Object extParams = taokePar.get("extParams"); + //TODO 其他参数待添加 + return taokeParams; + } + +} diff --git a/android/src/main/java/com/wxwx/flutter_alibc/WebActivity.java b/android/src/main/java/com/wxwx/flutter_alibc/WebActivity.java new file mode 100644 index 0000000..c32e488 --- /dev/null +++ b/android/src/main/java/com/wxwx/flutter_alibc/WebActivity.java @@ -0,0 +1,528 @@ +package com.wxwx.flutter_alibc; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.ComponentName; +import android.content.Intent; +import android.graphics.Bitmap; +import android.net.Uri; +import android.net.http.SslError; +import android.os.Bundle; +import android.util.Log; +import android.util.Patterns; +import android.view.View; +import android.webkit.GeolocationPermissions; +import android.webkit.JavascriptInterface; +import android.webkit.SslErrorHandler; +import android.webkit.ValueCallback; +import android.webkit.WebChromeClient; +import android.webkit.WebResourceError; +import android.webkit.WebResourceRequest; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.ImageView; +import android.widget.Toast; + +import com.alibaba.baichuan.android.trade.AlibcTrade; +import com.alibaba.baichuan.android.trade.callback.AlibcTradeCallback; +import com.alibaba.baichuan.android.trade.model.AlibcShowParams; +import com.alibaba.baichuan.trade.biz.context.AlibcTradeResult; +import com.alibaba.baichuan.trade.biz.core.taoke.AlibcTaokeParams; +import com.alibaba.baichuan.trade.biz.login.AlibcLogin; +import com.alibaba.baichuan.trade.biz.login.AlibcLoginCallback; + +import java.util.HashMap; +import java.util.Map; + +public class WebActivity extends Activity { + WebView mainWeb; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_web_bc); + mainWeb = findViewById(R.id.webview_main); + mainWeb.getSettings().setJavaScriptEnabled(true); + mainWeb.getSettings().setDomStorageEnabled(true); + mainWeb.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); + mainWeb.getSettings().setLoadWithOverviewMode(true); + mainWeb.getSettings().setAllowFileAccess(true); + mainWeb.getSettings().setDatabaseEnabled(true); + + + ImageView imageView = findViewById(R.id.go_to_back); + imageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + Map exParams = new HashMap<>();//yhhpass参数 +// AlibcTaokeParams alibcTaokeParams = new AlibcTaokeParams("", "", ""); +// alibcTaokeParams.pid = SPUtils.getPrefString(mActivity, Pkey.pid, ""); +// alibcTaokeParams.adzoneid = SPUtils.getPrefString(mActivity, Pkey.APP_adzoneId, ""); +// alibcTaokeParams.extraParams = new HashMap<>(); +// alibcTaokeParams.extraParams.put("taokeAppkey", SPUtils.getPrefString(mActivity, Pkey.APP_alliance_appkey, "")); + AlibcShowParams showParams = new AlibcShowParams(); + showParams.setBackUrl("alisdk://"); + AlibcTrade.openByUrl(WebActivity.this, "", "http://www.izhim.com/comm/tb_callback.php?_ctrl=domain&domain_state=MTI2&domain_return_url=aHR0cDovLzE5Mi4xNjguMC4xMTM6NTAwMC9hcGkvdjEvdGFvYmFvL2F1dGgvY2FsbGJhY2s%2FdGltZT0xNjAyNDk4MjA3", + mainWeb, new MyBaichuanWebClient(), new MyWebChromeClient(), showParams, + new AlibcTaokeParams("", "", ""), exParams, new AlibcTradeCallback() { + @Override + public void onTradeSuccess(AlibcTradeResult alibcTradeResult) { + + } + + @Override + public void onFailure(int i, String s) { + + } + }); + } + + //用于百川授权的简化的WebClient + @SuppressLint("AddJavascriptInterface") + private class MyBaichuanWebClient extends WebViewClient { + @SuppressLint("AddJavascriptInterface") + @Override + public boolean shouldOverrideUrlLoading(WebView view, final String url) { + + Log.d("百川拦截", url); + //绑定会员关系时获取网页内容关闭网页 + if (url.contains("http://www.izhim.com/comm/tb_callback")&&!url.contains("redirect_uri")) { + Log.d("百川系时获取网页内容关闭网页", url); + mainWeb.addJavascriptInterface(new InJavaScriptLocalObj(), "java_obj"); + } + if (url.contains("oauth.taobao.com/authorize") || url.contains("oauth.m.taobao.com/authorize")) { + + //渠道授权改动测试 + Log.d("百川渠道授权改动测试", url); + Map exParams = new HashMap<>();//yhhpass参数 + AlibcShowParams showParams = new AlibcShowParams(); + showParams.setBackUrl("alisdk://"); + AlibcTrade.openByUrl(WebActivity.this, "", url, + mainWeb, new MyBaichuanWebClient(), new MyWebChromeClient(), showParams, + new AlibcTaokeParams("", "", ""), exParams, new AlibcTradeCallback() { + @Override + public void onTradeSuccess(AlibcTradeResult alibcTradeResult) { + Log.d("cg", alibcTradeResult.toString()); + } + + @Override + public void onFailure(int i, String s) { + Log.d("sb", s); + } + }); + } + return super.shouldOverrideUrlLoading(view, url); + } + + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + // WebLoad.setVisibility(View.GONE); + // mainWeb.setVisibility(View.GONE); + //开始加载设置为透明 + super.onPageStarted(view, url, favicon); + } + + @Override + public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { + super.onReceivedError(view, request, error); + } + + @Override + public void onPageFinished(WebView view, String url) { + // WebLoad.setVisibility(View.GONE); + mainWeb.setVisibility(View.VISIBLE); + // 获取页面内容 + view.loadUrl("javascript:window.java_obj.showSource(" + + "document.documentElement.innerText);"); + + // 获取解析 + view.loadUrl("javascript:window.java_obj.showDescription(" + + "document.querySelector('meta[name=\"share-description\"]').getAttribute('content')" + + ");"); + // quanyikaText(); + super.onPageFinished(view, url); + } + + //处理 [Android]用WebView访问证书有问题的SSL网页 + //http://blog.sina.com.cn/s/blog_4cd978f90102vrxk.html + @Override + public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { + handler.proceed(); + } + + } + + /** + * 绑定渠道 + */ + private final class InJavaScriptLocalObj { + + @JavascriptInterface + public void showSource(final String html) { + //获取网页内容,用于判断是否成功绑定关系id + + try { + if (html.contains("成功")) {//成功 + Toast.makeText(WebActivity.this, "授权成功", Toast.LENGTH_SHORT).show(); + finish(); + } else {//失败 + mainWeb.setAlpha(0); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + @JavascriptInterface + public void showDescription(String str) { + + + } + } + + + public class MyWebChromeClient extends WebChromeClient { + + private CustomViewCallback mCustomViewCallback; + // 横屏时,显示视频的view + private View mCustomView; + + // 点击全屏按钮时,调用的方法 + @Override + public void onShowCustomView(View view, CustomViewCallback callback) { + super.onShowCustomView(view, callback); + //isFullPlayVedio = true; + //如果view 已经存在,则隐藏 + if (mCustomView != null) { + callback.onCustomViewHidden(); + return; + } + + mCustomView = view; + mCustomView.setVisibility(View.VISIBLE); + mCustomViewCallback = callback; + + + } + + // 取消全屏调用的方法 + @Override + public void onHideCustomView() { + super.onHideCustomView(); + + if (mCustomView == null) { + return; + } + mCustomView.setVisibility(View.GONE); + + mCustomView = null; + + try { + mCustomViewCallback.onCustomViewHidden(); + } catch (Exception e) { + } +// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//竖屏 + + + } + + @Override + public void onProgressChanged(WebView view, int newProgress) { + + } + + @Override + public void onReceivedTitle(WebView view, String title) { + super.onReceivedTitle(view, title); +// Logger.wtf("我的url" + view.getUrl()); + String url = view.getUrl(); + if (Patterns.WEB_URL.matcher(title).matches()) { + //网址不显示为标题 + + } else { + + //不是网址 + if (!url.contains("api.ejiayou.com/pages/platform/soulList/index.html")) { + + } + } + } + + @Override + public void onGeolocationPermissionsShowPrompt(final String origin, final GeolocationPermissions.Callback callback) { + + + super.onGeolocationPermissionsShowPrompt(origin, callback); + } + + + // For Android 3.0+ + public void openFileChooser(ValueCallback uploadMsg, String acceptType) { + + + } + + // For Android < 3.0 + public void openFileChooser(ValueCallback uploadMsg) { + openFileChooser(uploadMsg, ""); + } + + // For Android > 4.1.1 + public void openFileChooser(ValueCallback uploadMsg, + String acceptType, String capture) { + + openFileChooser(uploadMsg, acceptType); + } + + // For Android > 5.0 + @Override + public boolean onShowFileChooser(WebView webView, + ValueCallback filePathCallback, + FileChooserParams fileChooserParams) { + + return true; + } + + + } + + @SuppressLint("AddJavascriptInterface") + private class MyWebClient extends WebViewClient { + + @SuppressLint("AddJavascriptInterface") + @Override + public boolean shouldOverrideUrlLoading(WebView view, final String url) { + + if (url.startsWith("tel:")) { + startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); + return true; + } + if (url.startsWith("bdnetdisk:")) { + return true; + } + + + if (url.contains("tmast://")) { + try { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + startActivity(intent); + } catch (Exception e) { + + } + return true; + } + if (url.startsWith("http://ditu.amap.com") || + url.startsWith("https://ditu.amap.com")) { + return true; + } + if (url.contains("oauth.taobao.com/authorize") || url.contains("oauth.m.taobao.com/authorize")) { + +// mainWeb.addJavascriptInterface(new InJavaScriptLocadeUpgralObj(), "java_obj"); + Map exParams = new HashMap<>();//yhhpass参数 +// AlibcTaokeParams alibcTaokeParams = new AlibcTaokeParams("", "", ""); +// alibcTaokeParams.pid = SPUtils.getPrefString(mActivity, Pkey.pid, ""); +// alibcTaokeParams.adzoneid = SPUtils.getPrefString(mActivity, Pkey.APP_adzoneId, ""); +// alibcTaokeParams.extraParams = new HashMap<>(); +// alibcTaokeParams.extraParams.put("taokeAppkey", SPUtils.getPrefString(mActivity, Pkey.APP_alliance_appkey, "")); + AlibcShowParams showParams = new AlibcShowParams(); + showParams.setBackUrl("alisdk://"); + AlibcTrade.openByUrl(WebActivity.this, "", url, mainWeb, new MyBaichuanWebClient(), new MyWebChromeClient(), showParams, + new AlibcTaokeParams("", "", ""), exParams, new AlibcTradeCallback() { + @Override + public void onTradeSuccess(AlibcTradeResult alibcTradeResult) { + + } + + @Override + public void onFailure(int i, String s) { + + } + }); + } + + if (url.contains("tbopen://") || url.contains("tmall://") || url.contains("taobaotravel://")) { + return true; + } + + + if (url.contains("dianping://")) { + return true; + } + if (url.contains("aliim:")) { + return true; + } + if (url.contains("?mod=appapi&act=miandan_course&ctrl=close")) { + finish(); + return true; + } + if (url.contains("vipma.net/quickapp.html?")) { + return true; + } + + + // 如下方案可在非微信内部WebView的H5页面中调出微信支付 + if (url.startsWith("weixin://wap/pay?")) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + + } + return true; + } + if (url.startsWith("weixin://")) { + try { + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + startActivity(intent); + return true; + } catch (Exception e) { + e.printStackTrace(); + + } + return true; + } + if (url.endsWith("native://wechat")) { + Intent intent = new Intent(); + ComponentName cmp = new ComponentName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI"); + intent.setAction(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setComponent(cmp); + startActivity(intent); + return true; + } + if (url.contains("navite://save#")) { + + } + //不拦截的话绑定淘宝关系id的时候会因为下面login.m.taobao.com的拦截而唤醒手淘授权之后导致不能切换帐号 +// if (url.contains("client_id") && url.contains("login.m.taobao.com/logout.htm?")) { +// view.loadUrl(url); +// return true; +// } + if (url.contains("client_id")) { + view.loadUrl(url); + return true; + } +// if (url.contains("login.m.taobao.com")) { +// if (!AlibcLogin.getInstance().isLogin()) { +// AlibcLogin.getInstance().showLogin(new AlibcLoginCallback() { +//// @Override +//// public void onSuccess(int i) { +//// } +// +// @Override +// public void onSuccess(int i, String s, String s1) { +// +// } +// +// @Override +// public void onFailure(int i, String s) { +// } +// }); +// } +// return true; +// } + if (url.contains("maliprod.alipay.com") && !url.contains("confirmGoods.do")) { + AlibcLogin.getInstance().showLogin(new AlibcLoginCallback() { + @Override + public void onSuccess(int i, String s, String s1) { + + } + + @Override + public void onFailure(int i, String s) { + + } + }); + } + + if (url.contains("intent://go/ju/webview?")) { + return true; + } +// if (url.contains("s.click.taobao.com")) { +// Logger.wtf(SPUtils.getPrefString(WebActivity.this, Pkey.IS_OPEN_TAOBAO, "")); +// if (SPUtils.getPrefString(WebActivity.this, Pkey.IS_OPEN_TAOBAO, "").equals("shoutao")) { +// if (!Token.isLogin()) { +// if (isFirst2Login) { +// ActivityJump.toLogin(WebActivity.this); +// } +// isFirst2Login = false; +// finish(); +// } else { +// if (isInstallTaoBao(WebActivity.this)) { +// jump2TaoBao(url); +// finish(); +// } else { +// view.loadUrl(url); +// } +// } +// return true; +// } +// } + + +// if (url.contains("kingcard.dgunicom.com") && url.contains("newMsg") && url.contains("fill.html")) { +// getItf(url); +// } + + +// else { +// Logger.wtf("123"); +// mainWeb.loadUrl(url); +// } + return super.shouldOverrideUrlLoading(view, url); + } + + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + // WebLoad.setVisibility(View.GONE); + //开始加载设置为透明 + super.onPageStarted(view, url, favicon); + } + + @Override + public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { + super.onReceivedError(view, request, error); + } + + @Override + public void onPageFinished(WebView view, String url) { + // WebLoad.setVisibility(View.GONE); +// // 获取页面内容 + view.loadUrl("javascript:window.java_obj.showSource(" + + "document.documentElement.innerText);"); + + // 获取解析 + view.loadUrl("javascript:window.java_obj.showDescription(" + + "document.querySelector('meta[name=\"share-description\"]').getAttribute('content')" + + ");"); + // quanyikaText(); + super.onPageFinished(view, url); + } + + //处理 [Android]用WebView访问证书有问题的SSL网页 + //http://blog.sina.com.cn/s/blog_4cd978f90102vrxk.html + @Override + public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { + handler.proceed(); + } + + } + +} + + diff --git a/android/src/main/java/com/wxwx/flutter_alibc/web/WebViewActivity.java b/android/src/main/java/com/wxwx/flutter_alibc/web/WebViewActivity.java new file mode 100644 index 0000000..ba7e930 --- /dev/null +++ b/android/src/main/java/com/wxwx/flutter_alibc/web/WebViewActivity.java @@ -0,0 +1,143 @@ +package com.wxwx.flutter_alibc.web; +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.util.Log; +import android.webkit.DownloadListener; +import android.webkit.WebChromeClient; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.Toast; + +import com.alibaba.baichuan.android.trade.AlibcTrade; +import com.alibaba.baichuan.android.trade.callback.AlibcTradeCallback; +import com.alibaba.baichuan.android.trade.model.AlibcShowParams; +import com.alibaba.baichuan.android.trade.model.OpenType; +import com.alibaba.baichuan.trade.biz.applink.adapter.AlibcFailModeType; +import com.alibaba.baichuan.trade.biz.context.AlibcTradeResult; +import com.alibaba.baichuan.trade.biz.core.taoke.AlibcTaokeParams; +import com.alibaba.baichuan.trade.common.utils.AlibcLogger; + +import java.util.HashMap; +import java.util.Map; +import static com.wxwx.flutter_alibc.PluginConstants.*; +import static com.wxwx.flutter_alibc.PluginUtil.*; +import com.wxwx.flutter_alibc.R; +import java.net.URLDecoder; + +public class WebViewActivity extends Activity { + + //这个回调最好是非静态的 多线程下会有问题 但是这样比较快 + private static CallBack callBack; + + public static void setCallBack(CallBack callBack){ + WebViewActivity.callBack = callBack; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.webview_activity); + Intent intent = getIntent(); + if (intent != null) { + final String url = intent.getStringExtra("url"); + HashMap arguments = (HashMap) intent.getSerializableExtra("arguments"); + WebView webView = findViewById(R.id.webview); + //启用支持JavaScript + webView.getSettings().setJavaScriptEnabled(true); + //启用支持DOM Storage + webView.getSettings().setDomStorageEnabled(true); + openByUrl(url, webView, arguments); + } + + } + + private String getAccessToken(String url) { + try { + int startIndex = url.indexOf("access_token"); + String subStr = url.substring(startIndex); + String tempUrl = URLDecoder.decode(subStr, "UTF-8"); + int endIndex = tempUrl.indexOf("&"); + subStr = tempUrl.substring(0, endIndex); + startIndex = subStr.indexOf("="); + subStr = subStr.substring(startIndex+1); + return subStr; + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } + + private void openByUrl(String url, WebView webView, HashMap argument) { + + AlibcShowParams showParams = new AlibcShowParams(); + AlibcTaokeParams taokeParams = new AlibcTaokeParams("", "", ""); + showParams.setBackUrl(String.valueOf(argument.get(key_BackUrl))); + + if (argument.get(key_OpenType) != null){ + showParams.setOpenType(getOpenType(String.valueOf(argument.get(key_OpenType)))); + } + if (argument.get(key_ClientType) != null){ + showParams.setClientType(getClientType(String.valueOf(argument.get(key_ClientType)))); + } + if (argument.get("taokeParams") != null){ + taokeParams = getTaokeParams((HashMap)argument.get("taokeParams")); + } + if ("false".equals(argument.get("isNeedCustomNativeFailMode"))){ + showParams.setNativeOpenFailedMode(AlibcFailModeType.AlibcNativeFailModeNONE); + }else if (argument.get(key_NativeFailMode) != null){ + showParams.setNativeOpenFailedMode(getFailModeType(String.valueOf(argument.get(key_NativeFailMode)))); + } + + Map trackParams = new HashMap<>(); + + WebViewClient client = new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + return false; + } + + @Override + public void onLoadResource(WebView view, String url) { + super.onLoadResource(view, url); + //如果包含 + if (url.contains("access_token")){ + String accessToken = getAccessToken(url); + if (callBack != null){ + callBack.success(accessToken); + callBack = null; + } + finish(); + } + } + }; + + AlibcTrade.openByUrl(WebViewActivity.this, "", url, webView, + client, new WebChromeClient(), + showParams, taokeParams, trackParams, new AlibcTradeCallback() { + @Override + public void onTradeSuccess(AlibcTradeResult tradeResult) {}//不会回调 + @Override + public void onFailure(int code, String msg) {}//不会回调 + }); + } + + @Override + protected void onDestroy() { + if (callBack != null){ + callBack.failed("授权失败"); + } + super.onDestroy(); + } + + + + public interface CallBack{ + void success(String accessToken); + + void failed(String errorMsg); + } + +} diff --git a/android/src/main/res/layout/activity_web_bc.xml b/android/src/main/res/layout/activity_web_bc.xml new file mode 100644 index 0000000..db1c55b --- /dev/null +++ b/android/src/main/res/layout/activity_web_bc.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/android/src/main/res/layout/webview_activity.xml b/android/src/main/res/layout/webview_activity.xml new file mode 100644 index 0000000..2ffd027 --- /dev/null +++ b/android/src/main/res/layout/webview_activity.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/example/.flutter-plugins-dependencies b/example/.flutter-plugins-dependencies new file mode 100644 index 0000000..1c2143d --- /dev/null +++ b/example/.flutter-plugins-dependencies @@ -0,0 +1 @@ +{"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"flutter_alibc","dependencies":[]}]} \ No newline at end of file diff --git a/example/.gitignore b/example/.gitignore new file mode 100644 index 0000000..ac4a906 --- /dev/null +++ b/example/.gitignore @@ -0,0 +1,72 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/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/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/example/.metadata b/example/.metadata new file mode 100644 index 0000000..b9689b4 --- /dev/null +++ b/example/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: e4ebcdf6f4facee5779c38a04d91d08dc58ea7a4 + channel: beta + +project_type: app diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..431503c --- /dev/null +++ b/example/README.md @@ -0,0 +1,16 @@ +# flutter_alibc_example + +Demonstrates how to use the flutter_alibc plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle new file mode 100644 index 0000000..543a2ad --- /dev/null +++ b/example/android/app/build.gradle @@ -0,0 +1,77 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "wxwx.com.flutter_alibc_example" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + signingConfigs { + debug { + storeFile file("release.keystore") + storePassword 'cater123' + keyAlias 'release.keystore' + keyPassword 'cater123' + } + release { + storeFile file("release.keystore") + storePassword 'cater123' + keyAlias 'release.keystore' + keyPassword 'cater123' + } + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + implementation 'com.android.support:support-v4:28.0.0' +} diff --git a/example/android/app/release.keystore b/example/android/app/release.keystore new file mode 100644 index 0000000..7343344 Binary files /dev/null and b/example/android/app/release.keystore differ diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..a2dcf18 --- /dev/null +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..46874e7 --- /dev/null +++ b/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + diff --git a/example/android/app/src/main/java/wxwx/com/flutter_alibc_example/MainActivity.java b/example/android/app/src/main/java/wxwx/com/flutter_alibc_example/MainActivity.java new file mode 100644 index 0000000..94ed98d --- /dev/null +++ b/example/android/app/src/main/java/wxwx/com/flutter_alibc_example/MainActivity.java @@ -0,0 +1,13 @@ +package wxwx.com.flutter_alibc_example; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/example/android/app/src/main/res/drawable/launch_background.xml b/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/example/android/app/src/main/res/drawable/yw_1222_baichuan.jpg b/example/android/app/src/main/res/drawable/yw_1222_baichuan.jpg new file mode 100644 index 0000000..0f83041 Binary files /dev/null and b/example/android/app/src/main/res/drawable/yw_1222_baichuan.jpg differ diff --git a/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..db77bb4 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e Binary files /dev/null and b/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..00fa441 --- /dev/null +++ b/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/example/android/app/src/profile/AndroidManifest.xml b/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..a2dcf18 --- /dev/null +++ b/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/example/android/build.gradle b/example/android/build.gradle new file mode 100644 index 0000000..bb8a303 --- /dev/null +++ b/example/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/example/android/gradle.properties b/example/android/gradle.properties new file mode 100644 index 0000000..70030c6 --- /dev/null +++ b/example/android/gradle.properties @@ -0,0 +1,5 @@ +org.gradle.jvmargs=-Xmx1536M + +#android.useAndroidX=false +#android.enableJetifier=true +android.enableR8=true diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..296b146 --- /dev/null +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle new file mode 100644 index 0000000..5a2f14f --- /dev/null +++ b/example/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/example/ios/Flutter/.last_build_id b/example/ios/Flutter/.last_build_id new file mode 100644 index 0000000..ae93b98 --- /dev/null +++ b/example/ios/Flutter/.last_build_id @@ -0,0 +1 @@ +23a60060d9e5b69a910da030e8709ee7 \ No newline at end of file diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..6b4c0f7 --- /dev/null +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/example/ios/Flutter/Debug.xcconfig b/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..e8efba1 --- /dev/null +++ b/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/example/ios/Flutter/Flutter.podspec b/example/ios/Flutter/Flutter.podspec new file mode 100644 index 0000000..5ca3041 --- /dev/null +++ b/example/ios/Flutter/Flutter.podspec @@ -0,0 +1,18 @@ +# +# 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 diff --git a/example/ios/Flutter/Release.xcconfig b/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..399e934 --- /dev/null +++ b/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/example/ios/Flutter/flutter_export_environment.sh b/example/ios/Flutter/flutter_export_environment.sh new file mode 100755 index 0000000..0fea49d --- /dev/null +++ b/example/ios/Flutter/flutter_export_environment.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# This is a generated file; do not edit or check into version control. +export "FLUTTER_ROOT=/Users/fnuser02/flutter" +export "FLUTTER_APPLICATION_PATH=/Users/fnuser02/Documents/fnuoProject/flutter_open/flutter_alibc/example" +export "FLUTTER_TARGET=lib/main.dart" +export "FLUTTER_BUILD_DIR=build" +export "SYMROOT=${SOURCE_ROOT}/../build/ios" +export "FLUTTER_FRAMEWORK_DIR=/Users/fnuser02/flutter/bin/cache/artifacts/engine/ios" +export "FLUTTER_BUILD_NAME=1.0.0" +export "FLUTTER_BUILD_NUMBER=1" diff --git a/example/ios/Podfile b/example/ios/Podfile new file mode 100644 index 0000000..9dd00a4 --- /dev/null +++ b/example/ios/Podfile @@ -0,0 +1,73 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' +source 'https://cdn.cocoapods.org/' +source 'http://repo.baichuan-ios.taobao.com/baichuanSDK/AliBCSpecs.git' +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + end + pods_ary = [] + skip_line_start_symbols = ["#", "/"] + File.foreach(file_abs_path) { |line| + next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } + plugin = line.split(pattern=separator) + if plugin.length == 2 + 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 + +target 'Runner' do + # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock + # referring to absolute paths on developers' machines. + system('rm -rf .symlinks') + system('mkdir -p .symlinks/plugins') + + # Flutter Pods + 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 + +# 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| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end +end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock new file mode 100644 index 0000000..6964737 --- /dev/null +++ b/example/ios/Podfile.lock @@ -0,0 +1,64 @@ +PODS: + - AliAuthSDK (1.1.0.41-bc) + - AlibcTradeSDK (4.0.1.6) + - AliLinkPartnerSDK (4.0.0.24) + - BCUserTrack (5.2.0.18-appkeys): + - UTDID + - Flutter (1.0.0) + - flutter_alibc (0.0.1): + - AliAuthSDK (= 1.1.0.41-bc) + - AlibcTradeSDK (= 4.0.1.6) + - AliLinkPartnerSDK (= 4.0.0.24) + - BCUserTrack (= 5.2.0.18-appkeys) + - Flutter + - mtopSDK (= 3.0.0.3-BC) + - securityGuard (= 5.4.191) + - UTDID (= 1.1.0.16) + - WindVane (= 8.5.0.46-bc11) + - mtopSDK (3.0.0.3-BC) + - securityGuard (5.4.191) + - UTDID (1.1.0.16) + - WindVane (8.5.0.46-bc11): + - WindVane/Basic (= 8.5.0.46-bc11) + - WindVane/Core (= 8.5.0.46-bc11) + - WindVane/WindVane (= 8.5.0.46-bc11) + - WindVane/Basic (8.5.0.46-bc11) + - WindVane/Core (8.5.0.46-bc11) + - WindVane/WindVane (8.5.0.46-bc11) + +DEPENDENCIES: + - Flutter (from `.symlinks/flutter/ios`) + - flutter_alibc (from `.symlinks/plugins/flutter_alibc/ios`) + +SPEC REPOS: + http://repo.baichuan-ios.taobao.com/baichuanSDK/AliBCSpecs.git: + - AliAuthSDK + - AlibcTradeSDK + - AliLinkPartnerSDK + - BCUserTrack + - mtopSDK + - securityGuard + - UTDID + - WindVane + +EXTERNAL SOURCES: + Flutter: + :path: ".symlinks/flutter/ios" + flutter_alibc: + :path: ".symlinks/plugins/flutter_alibc/ios" + +SPEC CHECKSUMS: + AliAuthSDK: 7018e8f3c8be3382e60f69d3b517c7de34c351e0 + AlibcTradeSDK: 9a3e7af6cd648dd1f85684e82694c213fe48dad2 + AliLinkPartnerSDK: c5778cdfdcee7bfe342238d39a77766184d36a46 + BCUserTrack: 49251c6fb7c65cbbc221a492bbd3f3e142f1fb0f + Flutter: 0e3d915762c693b495b44d77113d4970485de6ec + flutter_alibc: 0e2a29e7c1de759672d87a260051240d209964b9 + mtopSDK: d6fdf81730342a69be920b576541c7bb81a683d5 + securityGuard: 9c04c44a3b663f36e15064042abfc107fa07133c + UTDID: c28855683c5ea2e77e597cb14609328f7d470d6e + WindVane: 56e096abae757397ccd3accb66a959f3ffcbf949 + +PODFILE CHECKSUM: f65a7534e3030cd63dfdaf5ac173943dc695fbe8 + +COCOAPODS: 1.9.1 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..eab1d79 --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,643 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1024AFA423235967008B147B /* mtopsdk_configuration.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1024AFA323235967008B147B /* mtopsdk_configuration.plist */; }; + 10AF2D312444309A000BBE1D /* yw_1222_baichuan.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 10AF2D302444309A000BBE1D /* yw_1222_baichuan.jpg */; }; + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 29D91E0DDA39BD518B58A83A /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13B949E8DC4A5D995FB9E354 /* libPods-Runner.a */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1024AF99232357F9008B147B /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; + 1024AF9B23235804008B147B /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; + 1024AF9D2323580E008B147B /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; + 1024AF9F23235865008B147B /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; + 1024AFA123235871008B147B /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; + 1024AFA323235967008B147B /* mtopsdk_configuration.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = mtopsdk_configuration.plist; sourceTree = ""; }; + 10AF2D302444309A000BBE1D /* yw_1222_baichuan.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = yw_1222_baichuan.jpg; sourceTree = SOURCE_ROOT; }; + 13B949E8DC4A5D995FB9E354 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 82A4098269B3611D08C04506 /* 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 = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B764AB2E21DD52B43681DD59 /* 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 = ""; }; + C5A8E9F74491C83DA9777540 /* 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + 29D91E0DDA39BD518B58A83A /* libPods-Runner.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 46E2167EE2EBBCA0A60F4CB6 /* Pods */ = { + isa = PBXGroup; + children = ( + C5A8E9F74491C83DA9777540 /* Pods-Runner.debug.xcconfig */, + 82A4098269B3611D08C04506 /* Pods-Runner.release.xcconfig */, + B764AB2E21DD52B43681DD59 /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 46E2167EE2EBBCA0A60F4CB6 /* Pods */, + 9B3805AA678F1DA4B139770E /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 10AF2D302444309A000BBE1D /* yw_1222_baichuan.jpg */, + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 1024AFA323235967008B147B /* mtopsdk_configuration.plist */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 9B3805AA678F1DA4B139770E /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1024AFA123235871008B147B /* libz.tbd */, + 1024AF9F23235865008B147B /* libc++.tbd */, + 1024AF9D2323580E008B147B /* libsqlite3.tbd */, + 1024AF9B23235804008B147B /* CoreTelephony.framework */, + 1024AF99232357F9008B147B /* CoreMotion.framework */, + 13B949E8DC4A5D995FB9E354 /* libPods-Runner.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 7518D7A0816C434208302B2B /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 0363A6C3197D5F1231140936 /* [CP] Embed Pods Frameworks */, + 2BA3A8E307EB2EEF52011C35 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = 68KMAT999T; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 1024AFA423235967008B147B /* mtopsdk_configuration.plist in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 10AF2D312444309A000BBE1D /* yw_1222_baichuan.jpg in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 0363A6C3197D5F1231140936 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 2BA3A8E307EB2EEF52011C35 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + 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\" thin"; + }; + 7518D7A0816C434208302B2B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 68KMAT999T; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + Flutter, + "-lstdc++", + "-Objc", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.aliTradeSDK.demoxxxxx; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "com.csshotel.revenuereport-appstore"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 68KMAT999T; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + Flutter, + "-lstdc++", + "-Objc", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.aliTradeSDK.demoxxxxx; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "com.csshotel.revenuereport-dev"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 68KMAT999T; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + OTHER_LDFLAGS = ( + "$(inherited)", + "-framework", + Flutter, + "-lstdc++", + "-Objc", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.aliTradeSDK.demoxxxxx; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = "com.csshotel.revenuereport-adhoc"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..1d526a1 --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..a28140c --- /dev/null +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/example/ios/Runner/AppDelegate.h b/example/ios/Runner/AppDelegate.h new file mode 100644 index 0000000..36e21bb --- /dev/null +++ b/example/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/example/ios/Runner/AppDelegate.m b/example/ios/Runner/AppDelegate.m new file mode 100644 index 0000000..ed002fa --- /dev/null +++ b/example/ios/Runner/AppDelegate.m @@ -0,0 +1,30 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application +didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; +// 获取本身vc +// // Override point for customization after application launch. +// self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds]; +// // +// UINavigationController* root = [[UINavigationController alloc]initWithRootViewController:vc]; +// self.window.backgroundColor = [UIColor whiteColor]; +// self.window.rootViewController = root; +// [self.window makeKeyAndVisible]; +// + + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + + +-(FlutterViewController *)getFlutterViewCtrl{ + UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController; + if ([viewController isKindOfClass:[FlutterViewController class]]) { + return (FlutterViewController*)viewController; + } + return nil; +} +@end diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..dc9ada4 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..28c6bf0 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..f091b6b Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..4cde121 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..d0ef06e Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..dcdc230 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..2ccbfd9 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..c8f9ed8 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..75b2d16 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..6a84f41 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..d0e1f58 Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..0bedcf2 --- /dev/null +++ b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..9da19ea Binary files /dev/null and b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner/Base.lproj/Main.storyboard b/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist new file mode 100644 index 0000000..0a0c76b --- /dev/null +++ b/example/ios/Runner/Info.plist @@ -0,0 +1,67 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_alibc_example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + tbopen27827054 + tbopen27563108 + + + + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSApplicationQueriesSchemes + + tbopen + tmall + + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/example/ios/Runner/main.m b/example/ios/Runner/main.m new file mode 100644 index 0000000..dff6597 --- /dev/null +++ b/example/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/example/ios/Runner/mtopsdk_configuration.plist b/example/ios/Runner/mtopsdk_configuration.plist new file mode 100644 index 0000000..c1bc501 --- /dev/null +++ b/example/ios/Runner/mtopsdk_configuration.plist @@ -0,0 +1,8 @@ + + + + + DefaultID + OPEN + + diff --git a/example/ios/yw_1222_baichuan.jpg b/example/ios/yw_1222_baichuan.jpg new file mode 100644 index 0000000..ce73d0c Binary files /dev/null and b/example/ios/yw_1222_baichuan.jpg differ diff --git a/example/lib/main.dart b/example/lib/main.dart new file mode 100644 index 0000000..c9cc764 --- /dev/null +++ b/example/lib/main.dart @@ -0,0 +1,161 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_alibc/alibc_const_key.dart'; +import 'package:flutter_alibc/flutter_alibc.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +class _MyAppState extends State { + String _platformVersion = 'Unknown'; + + @override + void initState() { + super.initState(); + // FlutterAlibc.responseFromShare.listen((data) { + // debugPrint(data); + // }); + initPlatformState(); + } + + // Platform messages are asynchronous, so we initialize in an async method. + Future initPlatformState() async { + String platformVersion; + // Platform messages may fail, so we use a try/catch PlatformException. + try { + platformVersion = await FlutterAlibc.platformVersion; + } on PlatformException { + platformVersion = 'Failed to get platform version.'; + } + + // If the widget was removed from the tree while the asynchronous platform + // message was in flight, we want to discard the reply rather than calling + // setState to update our non-existent appearance. + if (!mounted) return; + + setState(() { + _platformVersion = platformVersion; + }); + + /* try { + var initRes = await FlutterAlibc.initAlibc(); + } on Exception {}*/ + + try { + // var waite3s = await FlutterAlibc.openItemDetail(itemID: "12345"); + var result = await FlutterAlibc.initAlibc(); + print(result); + } on Exception {} + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: const Text('Plugin example app'), + ), + body: Center( + child: Column( + children: [ + FlatButton( + child: Text("初始化阿里百川"), + onPressed: () async { + try { + // var waite3s = await FlutterAlibc.openItemDetail(itemID: "12345"); + // 如果什么都不给 + var result = await FlutterAlibc.initAlibc(); + print(result); + } on Exception {} + }, + ), + FlatButton( + child: Text("登录淘宝"), + onPressed: () async { + var result = await FlutterAlibc.loginTaoBao(); + print( + "登录淘宝 ${result.data.nick} ${result.data.topAccessToken}"); + }, + ), + FlatButton( + child: Text("登出淘宝"), + onPressed: () { + FlutterAlibc.loginOut(); + }, + ), + FlatButton( + child: Text("淘客登录,二次授权"), + onPressed: () async { + var result = await FlutterAlibc.taoKeLogin( + url: + "https://oauth.taobao.com/authorize?response_type=token&client_id=27646673&state=1212&view=wap", + openType: AlibcOpenType.AlibcOpenTypeNative, + isNeedCustomNativeFailMode: true, + nativeFailMode: + AlibcNativeFailMode.AlibcNativeFailModeJumpH5); + print("access token ${result["accessToken"]}"); + }, + ), + FlatButton( + child: Text("唤起淘宝,openByUrl方式"), + onPressed: () async { + var result = await FlutterAlibc.openByUrl( + url: + "https://uland.taobao.com/coupon/edetail?e=0I2EBL%2BTWswGQASttHIRqRXxIesJCFV0jSsDEwaP11URqogtr65NL3IIxArmwXZQtYdj3OrQBBwJkllDQLUC%2B79fwBwwUiqlvyfAqbG%2BQWkG6QT52O7rmXYefz8NXcoYTJnbK5InWzlFfSAQOJJoy8NEaV3mm%2FQSzjZt5gElMznom9kMiklcP0KJ92VgfYGd&traceId=0b0d82cf15669814548736276e3d95&union_lens=lensId:0b0b6466_0c0d_16cd75f7c39_528f&xId=6MboRwsAi2s8Glbqt3lJLAwSlyrPyBLCZ01KOk6QzKCNhw8C6RjXgA1bNbZdKzp30gOqd1J5j1k7ei7HYId1QZ&ut_sk=1.utdid_null_1566981455011.TaoPassword-Outside.taoketop&sp_tk=77+lTU5nMllrdHRqSVLvv6U=", + //backUrl: "tbopen27822502:https://h5.m.taobao.com", + isNeedCustomNativeFailMode: true, + nativeFailMode: + AlibcNativeFailMode.AlibcNativeFailModeJumpH5); + print(result); + }, + ), + FlatButton( + child: Text("唤起淘宝,openItemDetail方式"), + onPressed: () async { + var result = await FlutterAlibc.openItemDetail( + itemID: "575688730394", + schemeType: AlibcSchemeType.AlibcSchemeTaoBao, + isNeedCustomNativeFailMode: true, + nativeFailMode: + AlibcNativeFailMode.AlibcNativeFailModeJumpH5); + print(result); + }, + ), + FlatButton( + child: Text("打开店铺,openShop方式"), + onPressed: () async { + var result = await FlutterAlibc.openShop(shopId: "71955116"); + print(result); + }, + ), + FlatButton( + child: Text("打开购物车,openCart方式"), + onPressed: () async { + var result = await FlutterAlibc.openCart(); + print(result); + }, + ), + FlatButton( + child: Text("允许打点"), + onPressed: () { + FlutterAlibc.syncForTaoke(true); + }, + ), + FlatButton( + child: Text("使用native Alipay"), + onPressed: () { + FlutterAlibc.useAlipayNative(true); + }, + ), + ], + )), + ), + ); + } +} diff --git a/example/pubspec.lock b/example/pubspec.lock new file mode 100644 index 0000000..a517f73 --- /dev/null +++ b/example/pubspec.lock @@ -0,0 +1,202 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.11" + args: + dependency: transitive + description: + name: args + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.5.2" + async: + dependency: transitive + description: + name: async + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.5" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.14.11" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.3" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.1.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_alibc: + dependency: "direct dev" + description: + path: ".." + relative: true + source: path + version: "0.0.15" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + image: + dependency: transitive + description: + name: image + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.4" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.12.6" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.8" + path: + dependency: transitive + description: + name: path + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.6.4" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.8.0+1" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.5" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.5.5" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.5" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.11" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.8" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.5.0" +sdks: + dart: ">=2.4.0 <3.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml new file mode 100644 index 0000000..28dbe07 --- /dev/null +++ b/example/pubspec.yaml @@ -0,0 +1,63 @@ +name: flutter_alibc_example +description: Demonstrates how to use the flutter_alibc plugin. +publish_to: 'none' + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + flutter_alibc: + path: ../ + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # 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 + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart new file mode 100644 index 0000000..2c321b5 --- /dev/null +++ b/example/test/widget_test.dart @@ -0,0 +1,27 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_alibc_example/main.dart'; + +void main() { + testWidgets('Verify Platform version', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that platform version is retrieved. + expect( + find.byWidgetPredicate( + (Widget widget) => widget is Text && + widget.data.startsWith('Running on:'), + ), + findsOneWidget, + ); + }); +} diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..710ec6c --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,36 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/Generated.xcconfig diff --git a/ios/Assets/.gitkeep b/ios/Assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/ios/Classes/FlutterAlibcConstKey/FlutterAlibcConstKey.h b/ios/Classes/FlutterAlibcConstKey/FlutterAlibcConstKey.h new file mode 100644 index 0000000..a262edb --- /dev/null +++ b/ios/Classes/FlutterAlibcConstKey/FlutterAlibcConstKey.h @@ -0,0 +1,14 @@ +// +// FlutterAlibcConstKey.h +// flutter_alibc +// +// Created by 吴兴 on 2019/9/4. +// + +#ifndef FlutterAlibcConstKey_h +#define FlutterAlibcConstKey_h + +static NSString *FlutterAlibcConstKey_ErrorCode = @"errorCode"; +static NSString *FlutterAlibcConstKey_ErrorMessage = @"errorMessage"; +static NSString *FlutterAlibcConstKey_Data = @"data"; +#endif /* FlutterAlibcConstKey_h */ diff --git a/ios/Classes/FlutterAlibcPlugin.h b/ios/Classes/FlutterAlibcPlugin.h new file mode 100644 index 0000000..807d6e7 --- /dev/null +++ b/ios/Classes/FlutterAlibcPlugin.h @@ -0,0 +1,4 @@ +#import + +@interface FlutterAlibcPlugin : NSObject +@end diff --git a/ios/Classes/FlutterAlibcPlugin.m b/ios/Classes/FlutterAlibcPlugin.m new file mode 100644 index 0000000..dbf3cf5 --- /dev/null +++ b/ios/Classes/FlutterAlibcPlugin.m @@ -0,0 +1,86 @@ +#import "FlutterAlibcPlugin.h" +#import "FlutterAlibcHandle.h" +#import + +@interface FlutterAlibcPlugin() +//一个handle服务 +@property(nonatomic,strong)FlutterAlibcHandle *handler; +//一个service服务 +@end + +@implementation FlutterAlibcPlugin ++ (void)registerWithRegistrar:(NSObject*)registrar { + FlutterMethodChannel* channel = [FlutterMethodChannel + methodChannelWithName:@"flutter_alibc" + binaryMessenger:[registrar messenger]]; + FlutterAlibcPlugin* instance = [[FlutterAlibcPlugin alloc] initWithRegistrar:registrar methodChannel:channel]; + [registrar addMethodCallDelegate:instance channel:channel]; + [registrar addApplicationDelegate:instance]; +} + + +- (instancetype)initWithRegistrar:(NSObject *)registrar methodChannel:(FlutterMethodChannel *)flutterMethodChannel{ + self = [super init]; + + if (self) { + self.handler = [[FlutterAlibcHandle alloc]init]; + } + + return self; +} + +- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { + if ([@"getPlatformVersion" isEqualToString:call.method]) { + result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); + }else if ([@"initAlibc" isEqualToString:call.method]){ + [_handler initAlibc:call result:result]; + }else if([@"loginTaoBao" isEqualToString:call.method]){ + [_handler loginTaoBao:call result:result]; + }else if([@"taoKeLogin" isEqualToString:call.method]){ + [_handler taoKeLogin:call result:result]; + }else if([@"loginOut" isEqualToString:call.method]){ + [_handler loginOut]; + }else if([@"openByUrl" isEqualToString:call.method]){ + [_handler openByUrl:call result:result]; + }else if([@"openItemDetail" isEqualToString:call.method]){ + [_handler openItemDetail:call result:result]; + }else if([@"openShop" isEqualToString:call.method]){ + [_handler openShop:call result:result]; + }else if([@"openCart" isEqualToString:call.method]){ + [_handler openCart:call result:result]; + }else if([@"syncForTaoke" isEqualToString:call.method]){ + [_handler syncForTaoke:call result:result]; + }else if([@"useAlipayNative" isEqualToString:call.method]){ + [_handler useAlipayNative:call result:result]; + }else { + result(FlutterMethodNotImplemented); + } +} + + +#pragma mark -- 下面两个为百川处理应用跳转 +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{ + // 如果百川处理过会返回YES + if (![[AlibcTradeSDK sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]) { + return YES; + } + return NO; +} + + +//IOS9.0 系统新的处理openURL 的API +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { + + + if (@available(iOS 9.0, *)) { + __unused BOOL isHandledByALBBSDK=[[AlibcTradeSDK sharedInstance] application:application openURL:url options:options]; + return isHandledByALBBSDK; + } else { + // Fallback on earlier versions + }//处理其他app跳转到自己的app,如果百川处理过会返回YES + + return NO; + + +} +@end diff --git a/ios/Classes/Handle/FlutterAlibcHandle.h b/ios/Classes/Handle/FlutterAlibcHandle.h new file mode 100644 index 0000000..433e3e0 --- /dev/null +++ b/ios/Classes/Handle/FlutterAlibcHandle.h @@ -0,0 +1,99 @@ +/* + * @Description: + * @Author: wuxing + * @Date: 2019-09-02 21:26:27 + * @LastEditors: wuxing + * @LastEditTime: 2019-09-02 22:12:43 + */ +// +// FlutterAlibcHandle.h +// flutter_alibc +// +// Created by 吴兴 on 2019/8/28. +// + +#import +#import +NS_ASSUME_NONNULL_BEGIN + +@interface FlutterAlibcHandle : NSObject +// 初始化 + +/** + 初始化 + + @param call {"version","appName"} + @param result {@"errorCode":"0",@"errorMessage":"success"} + */ +- (void)initAlibc:(FlutterMethodCall *)call result:(FlutterResult)result; + +/** + 登录淘宝 + + @param call <#call description#> + @param result <#result description#> + */ +- (void)loginTaoBao:(FlutterMethodCall *)call result:(FlutterResult)result; + + +/** + 退出淘宝登录 + */ +- (void)loginOut; + + +/// 淘客登录,二次授权 +/// @param call <#call description#> +/// @param result <#result description#> +- (void)taoKeLogin:(FlutterMethodCall *)call result:(FlutterResult)result; +/** + 通过url打开,包括h5,唤起手淘等 + + @param call <#call description#> + @param result <#result description#> + */ +- (void)openByUrl:(FlutterMethodCall *)call result:(FlutterResult)result; + + +/** + 打开商品详情 + + @param call <#call description#> + @param result <#result description#> + */ +- (void)openItemDetail:(FlutterMethodCall *)call result:(FlutterResult)result; + +/** + 打开店铺 + + @param call <#call description#> + @param result <#result description#> + */ +- (void)openShop:(FlutterMethodCall *)call result:(FlutterResult)result; + +/** + 打开购物车 + + @param call <#call description#> + @param result <#result description#> + */ +- (void)openCart:(FlutterMethodCall *)call result:(FlutterResult)result; + +/** + 是否淘宝打点 + + @param call <#call description#> + @param result <#result description#> + */ +- (void)syncForTaoke:(FlutterMethodCall *)call result:(FlutterResult)result; + +/** + 是否使用Native AliPay + + @param call <#call description#> + @param result <#result description#> + */ +- (void)useAlipayNative:(FlutterMethodCall *)call result:(FlutterResult)result; +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Handle/FlutterAlibcHandle.m b/ios/Classes/Handle/FlutterAlibcHandle.m new file mode 100644 index 0000000..4f25645 --- /dev/null +++ b/ios/Classes/Handle/FlutterAlibcHandle.m @@ -0,0 +1,515 @@ +// +// FlutterAlibcHandle.m +// flutter_alibc +// +// Created by 吴兴 on 2019/8/28. +// + +#import "FlutterAlibcHandle.h" +#import "FlutterAlibcTools.h" +#import "FlutterAlibcConstKey.h" +#import +//#import +#import "ALiTradeWebViewController.h" +#import "FlutterWxViewCtrlViewController.h" +#import +#import +@implementation FlutterAlibcHandle +FlutterMethodChannel *_flutterAlibcChannel = nil; + + +- (instancetype)initWithRegistrar:(NSObject *)registrar methodChannel:(FlutterMethodChannel *)flutterMethodChannel { + self = [super init]; + if (self) { + _flutterAlibcChannel = flutterMethodChannel; + } + return self; +} + +#pragma mark- 对flutter暴露的方法 +#pragma mark -- 初始化阿里百川 +- (void)initAlibc:(FlutterMethodCall *)call result:(FlutterResult)result { + // 百川平台基础SDK初始化,加载并初始化各个业务能力插件 + NSString *version = call.arguments[@"version"]; + NSString *appName = call.arguments[@"appName"]; + // 判断是否为空 + if(![FlutterAlibcTools isNil:version]){ + [[AlibcTradeSDK sharedInstance] setIsvVersion:version]; //设置三方App版本,可用于标识App版本 + } + if(![FlutterAlibcTools isNil:appName]){ + [[AlibcTradeSDK sharedInstance] setIsvAppName:appName]; //设置三方App名称,可用于标识App + } + [[AlibcTradeSDK sharedInstance] setDebugLogOpen:YES];//开发阶段打开日志开关,方便排查错误信息 + [[AlibcTradeSDK sharedInstance] setEnv:AlibcEnvironmentRelease];//线上环境 + + + [[AlibcTradeSDK sharedInstance] asyncInitWithSuccess:^{ + // 告诉flutter,初始化完成 + result(@{FlutterAlibcConstKey_ErrorCode:@"0",FlutterAlibcConstKey_ErrorMessage:@"success"}); + } failure:^(NSError *error) { + NSLog(@"Init failed: %@", error.description); + result(@{FlutterAlibcConstKey_ErrorCode:[NSString stringWithFormat: @"%ld", (long)error.code],FlutterAlibcConstKey_ErrorMessage:error.description}); + }]; +} +#pragma mark --淘宝登录 +- (void)loginTaoBao:(FlutterMethodCall *)call result:(FlutterResult)result{ + if(![[ALBBCompatibleSession sharedInstance] isLogin]) { + UIViewController *rootViewController = + [UIApplication sharedApplication].delegate.window.rootViewController; + [[ALBBSDK sharedInstance] setH5Only:NO]; + [[ALBBSDK sharedInstance] auth:rootViewController successCallback:^{ + ALBBUser *userInfo =[[ALBBCompatibleSession sharedInstance] getUser]; + // 登录成功 + result(@{ + FlutterAlibcConstKey_ErrorCode:@"0", + FlutterAlibcConstKey_ErrorMessage:@"success", + FlutterAlibcConstKey_Data:@{ + // 昵称 + @"nick":userInfo.nick, + // 头像地址 + @"avatarUrl":userInfo.avatarUrl, + @"openId":userInfo.openId, + @"openSid":userInfo.openSid, + @"topAccessToken":userInfo.topAccessToken, + @"topAuthCode":userInfo.topAuthCode, + } + }); + } failureCallback:^(NSError *error) { + // 登录失败 + result(@{ + FlutterAlibcConstKey_ErrorCode:[NSString stringWithFormat: @"%ld", (long)error.code], + FlutterAlibcConstKey_ErrorMessage:error.localizedDescription, + FlutterAlibcConstKey_Data:@{} + }); + }]; + + } else { + ALBBUser *userInfo =[[ALBBCompatibleSession sharedInstance] getUser]; + // 登录成功 + result(@{ + FlutterAlibcConstKey_ErrorCode:@"0", + FlutterAlibcConstKey_ErrorMessage:@"success", + FlutterAlibcConstKey_Data:@{ + // 昵称 + @"nick":userInfo.nick, + // 头像地址 + @"avatarUrl":userInfo.avatarUrl, + @"openId":userInfo.openId, + @"openSid":userInfo.openSid, + @"topAccessToken":userInfo.topAccessToken, + @"topAuthCode":userInfo.topAuthCode, + } + }); + } +} +// +//else if([@"useAlipayNative" isEqualToString:call.method]){ +// [_handler useAlipayNative:call result:result]; +//} +#pragma mark --淘客登录 +-(void)taoKeLogin:(FlutterMethodCall *)call result:(FlutterResult)result{ + // 需要获取的数据 + NSNumber *type1 = call.arguments[@"openType"]; + AlibcOpenType openType = [self openType:[type1 intValue]]; + BOOL isNeedCustomNativeFailMode = [call.arguments[@"isNeedCustomNativeFailMode"] boolValue]; + // 不用push了,没有nav,默认都present + // BOOL isNeedPush = [call.arguments[@"isNeedPush"] boolValue]; + BOOL isNeedPush = YES; + NSNumber *failMode = call.arguments[@"nativeFailMode"]; + AlibcNativeFailMode nativeFailMode = [self NativeFailMode:[failMode intValue]]; + NSNumber *schemeType = call.arguments[@"schemeType"]; + NSString *linkKey = [self schemeType:[schemeType intValue]]; + NSString *url = call.arguments[@"url"]; + AlibcTradeTaokeParams *taokeParam = [self getTaokeParams:call]; + NSDictionary *trackParam = call.arguments[@"trackParam"]; + NSString *backUrl = [FlutterAlibcTools changeType:call.arguments[@"backUrl"]]; + // NSString *backUrl = [FlutterAlibcTools nullToNil:call.arguments[@"backUrl"]]; + + UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController; + + + AlibcTradeShowParams* showParam = [[AlibcTradeShowParams alloc] init]; + showParam.openType = openType; + showParam.isNeedCustomNativeFailMode = isNeedCustomNativeFailMode; + showParam.isNeedPush=isNeedPush; + showParam.nativeFailMode=nativeFailMode; + showParam.linkKey=linkKey; + showParam.backUrl= backUrl; + + ALiTradeWebViewController* webviewVC = [[ALiTradeWebViewController alloc] init]; + + NSInteger res = [[AlibcTradeSDK sharedInstance].tradeService + openByUrl:url + identity:@"trade" + webView:webviewVC.webView + parentController:rootViewController + showParams:showParam + taoKeParams:taokeParam + trackParam:trackParam tradeProcessSuccessCallback:^(AlibcTradeResult * _Nullable alibcTradeResult) { + // // 交易成功,判断是付款成功还是加入购物车 + // if(alibcTradeResult.result == AlibcTradeResultTypePaySuccess){ + // // 付款成功 + // result(@{ + // FlutterAlibcConstKey_ErrorCode:@"0", + // FlutterAlibcConstKey_ErrorMessage:@"付款成功", + // FlutterAlibcConstKey_Data:@{ + // @"type":@0, + // @"paySuccessOrders":[alibcTradeResult payResult].paySuccessOrders, + // @"payFailedOrders":[alibcTradeResult payResult].payFailedOrders, + // } + // }); + // }else if(alibcTradeResult.result== AlibcTradeResultTypeAddCard){ + // // 加入购物车 + // result(@{ + // FlutterAlibcConstKey_ErrorCode:@"0", + // FlutterAlibcConstKey_ErrorMessage:@"加入购物车成功", + // FlutterAlibcConstKey_Data:@{ + // @"type":@1, + // } + // }); + // } + } tradeProcessFailedCallback:^(NSError * _Nullable error) { + // result(@{ + // FlutterAlibcConstKey_ErrorCode:[NSString stringWithFormat: @"%ld", (long)error.code], + // FlutterAlibcConstKey_ErrorMessage:[error localizedDescription], + // }); + }]; + + if (res == 1) { + // 新建一个view + FlutterWxViewCtrlViewController *WxVC = [[FlutterWxViewCtrlViewController alloc] init]; + WxVC.vc = webviewVC; + WxVC.accessBlock = ^(NSString * accessToken){ + NSLog(@"accessToken = %@",accessToken); + if (accessToken) { + result(@{ + @"accessToken":accessToken + }); + }else{ + result(@{ + @"accessToken":@"" + }); + } + + }; + UINavigationController *root = [[UINavigationController alloc] initWithRootViewController:WxVC]; + [rootViewController presentViewController:root animated:NO completion:^{ + + }]; + } +} +#pragma mark --退出登录 +- (void)loginOut{ + [[ALBBSDK sharedInstance] logout]; +} +#pragma mark --通过url打开,包括h5,唤起手淘等 +- (void)openByUrl:(FlutterMethodCall *)call result:(FlutterResult)result{ + // 需要获取的数据 + NSNumber *type1 = call.arguments[@"openType"]; + AlibcOpenType openType = [self openType:[type1 intValue]]; + BOOL isNeedCustomNativeFailMode = [call.arguments[@"isNeedCustomNativeFailMode"] boolValue]; + // 不用push了,没有nav,默认都present + // BOOL isNeedPush = [call.arguments[@"isNeedPush"] boolValue]; + BOOL isNeedPush = NO; + NSNumber *failMode = call.arguments[@"nativeFailMode"]; + AlibcNativeFailMode nativeFailMode = [self NativeFailMode:[failMode intValue]]; + NSNumber *schemeType = call.arguments[@"schemeType"]; + NSString *linkKey = [self schemeType:[schemeType intValue]]; + NSString *url = call.arguments[@"url"]; + AlibcTradeTaokeParams *taokeParam = [self getTaokeParams:call]; + NSDictionary *trackParam = call.arguments[@"trackParam"]; + NSString *backUrl = [FlutterAlibcTools changeType:call.arguments[@"backUrl"]]; + // NSString *backUrl = [FlutterAlibcTools nullToNil:call.arguments[@"backUrl"]]; + + UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController; + + + AlibcTradeShowParams* showParam = [[AlibcTradeShowParams alloc] init]; + showParam.openType = openType; + showParam.isNeedCustomNativeFailMode = isNeedCustomNativeFailMode; + showParam.isNeedPush=isNeedPush; + showParam.nativeFailMode=nativeFailMode; + showParam.linkKey=linkKey; + showParam.backUrl= backUrl; + [[AlibcTradeSDK sharedInstance].tradeService openByUrl:url identity:@"trade" webView:nil parentController:rootViewController showParams:showParam taoKeParams:taokeParam trackParam:trackParam tradeProcessSuccessCallback:^(AlibcTradeResult * _Nullable alibcTradeResult) { + // 交易成功,判断是付款成功还是加入购物车 + if(alibcTradeResult.result == AlibcTradeResultTypePaySuccess){ + // 付款成功 + result(@{ + FlutterAlibcConstKey_ErrorCode:@"0", + FlutterAlibcConstKey_ErrorMessage:@"付款成功", + FlutterAlibcConstKey_Data:@{ + @"type":@0, + @"paySuccessOrders":[alibcTradeResult payResult].paySuccessOrders, + @"payFailedOrders":[alibcTradeResult payResult].payFailedOrders, + } + }); + }else if(alibcTradeResult.result== AlibcTradeResultTypeAddCard){ + // 加入购物车 + result(@{ + FlutterAlibcConstKey_ErrorCode:@"0", + FlutterAlibcConstKey_ErrorMessage:@"加入购物车成功", + FlutterAlibcConstKey_Data:@{ + @"type":@1, + } + }); + } + } tradeProcessFailedCallback:^(NSError * _Nullable error) { + result(@{ + FlutterAlibcConstKey_ErrorCode:[NSString stringWithFormat: @"%ld", (long)error.code], + FlutterAlibcConstKey_ErrorMessage:[error localizedDescription], + // android没有,直接去掉 + // FlutterAlibcConstKey_Data:@{ + // @"orderIdList":[[error userInfo] objectForKey:@"orderIdList"], + // } + }); + }]; +} +#pragma mark --打开商品详情 +- (void)openItemDetail:(FlutterMethodCall *)call result:(FlutterResult)result{ + NSString *itemID = call.arguments[@"itemID"]; + id page = [AlibcTradePageFactory itemDetailPage:itemID]; + [self OpenPageByNewWay:page BizCode:@"detail" Call:call callback:result]; +} +#pragma mark --打开店铺 +- (void)openShop:(FlutterMethodCall *)call result:(FlutterResult)result{ + NSString *shopId = call.arguments[@"shopId"]; + id page = [AlibcTradePageFactory shopPage:shopId]; + [self OpenPageByNewWay:page BizCode:@"shop" Call:call callback:result]; +} +#pragma mark --打开我的购物车 +- (void)openCart:(FlutterMethodCall *)call result:(FlutterResult)result{ + id page = [AlibcTradePageFactory myCartsPage]; + [self OpenPageByNewWay:page BizCode:@"cart" Call:call callback:result]; +} + +#pragma mark --淘客打点 +- (void)syncForTaoke:(FlutterMethodCall *)call result:(FlutterResult)result{ + BOOL isSync = [call.arguments[@"isSync"] boolValue]; + [[AlibcTradeSDK sharedInstance] setIsSyncForTaoke:isSync]; +} +#pragma mark --设置是否需要 Native AliPay 接口 +- (void)useAlipayNative:(FlutterMethodCall *)call result:(FlutterResult)result{ + BOOL isNeed = [call.arguments[@"isNeed"] boolValue]; + [[AlibcTradeSDK sharedInstance] setShouldUseAlizfNative:isNeed]; +} +#pragma mark - 不对flutter暴露 +#pragma mark --打开page +- (void)OpenPageByNewWay:(id)page BizCode:(NSString *)bizCode Call:(FlutterMethodCall *)call callback:(FlutterResult)callback{ + AlibcTradeShowParams* showParam = [[AlibcTradeShowParams alloc] init]; + NSNumber *type1 = call.arguments[@"openType"]; + AlibcOpenType openType = [self openType:[type1 intValue]]; + BOOL isNeedCustomNativeFailMode = [call.arguments[@"isNeedCustomNativeFailMode"] boolValue]; + // 不用push了,没有nav,默认都present + // BOOL isNeedPush = [call.arguments[@"isNeedPush"] boolValue]; + BOOL isNeedPush = NO; + // 不用绑定了,默认为没有,有的话flutter太难搞了 + // BOOL isBindWebview = [call.arguments[@"isBindWebview"] boolValue]; + NSNumber *failMode = call.arguments[@"nativeFailMode"]; + AlibcNativeFailMode nativeFailMode = [self NativeFailMode:[failMode intValue]]; + NSNumber *schemeType = call.arguments[@"schemeType"]; + NSString *linkKey = [self schemeType:[schemeType intValue]]; + AlibcTradeTaokeParams *taokeParam = [self getTaokeParams:call]; + NSDictionary *trackParam = [FlutterAlibcTools nullToNil:call.arguments[@"trackParam"]]; + + NSString *backUrl = [FlutterAlibcTools changeType:call.arguments[@"backUrl"]]; + // 判断 + + UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController; + + showParam.openType = openType; + showParam.isNeedPush = isNeedPush; + showParam.nativeFailMode = nativeFailMode; + showParam.isNeedCustomNativeFailMode = isNeedCustomNativeFailMode; + showParam.linkKey = linkKey; + showParam.backUrl = backUrl; + + + // if (isBindWebview) { + // ALiTradeWebViewController *viewCtrl = [[ALiTradeWebViewController alloc]init]; + // NSInteger res = [[AlibcTradeSDK sharedInstance].tradeService openByBizCode:bizCode page:page webView:view.webView parentController:view showParams:showParam taoKeParams:[self taokeParam] trackParam:[self customParam] tradeProcessSuccessCallback:self.onTradeSuccess tradeProcessFaelseiledCallback:self.onTradeFailure]; + // }else{ + // if (isNeedPush) { + // [[AlibcTradeSDK sharedInstance].tradeService openByBizCode:bizCode page:page webView:nil parentController:rootViewController showParams:showParam taoKeParams:taokeParam trackParam:trackParam tradeProcessSuccessCallback:^(AlibcTradeResult * _Nullable result) { + //// 交易成功,判断是付款成功还是加入购物车 + // if(result.result == AlibcTradeResultTypePaySuccess){ + //// 付款成功 + // callback(@{ + // FlutterAlibcConstKey_ErrorCode:@"0", + // FlutterAlibcConstKey_ErrorMessage:@"付款成功", + // FlutterAlibcConstKey_Data:@{ + // @"type":@0, + // @"paySuccessOrders":[result payResult].paySuccessOrders, + // @"payFailedOrders":[result payResult].payFailedOrders, + // } + // }); + // }else if(result.result== AlibcTradeResultTypeAddCard){ + //// 加入购物车 + // callback(@{ + // FlutterAlibcConstKey_ErrorCode:@"0", + // FlutterAlibcConstKey_ErrorMessage:@"付款成功", + // FlutterAlibcConstKey_Data:@{ + // @"type":@1, + // } + // }); + // } + // } tradeProcessFailedCallback:^(NSError * _Nullable error) { + //// 退出交易流程 + // callback(@{ + // FlutterAlibcConstKey_ErrorCode:[NSString stringWithFormat: @"%ld", (long)error.code], + // FlutterAlibcConstKey_ErrorMessage:[error localizedDescription], + // FlutterAlibcConstKey_Data:@{ + // @"orderIdList":[[error userInfo] objectForKey:@"orderIdList"], + // } + // }); + // }]; + // }else{ + [[AlibcTradeSDK sharedInstance].tradeService openByBizCode:bizCode page:page webView:nil parentController:rootViewController showParams:showParam taoKeParams:taokeParam trackParam:trackParam tradeProcessSuccessCallback:^(AlibcTradeResult * _Nullable result) { + // 交易成功,判断是付款成功还是加入购物车 + if(result.result == AlibcTradeResultTypePaySuccess){ + // 付款成功 + callback(@{ + FlutterAlibcConstKey_ErrorCode:@"0", + FlutterAlibcConstKey_ErrorMessage:@"付款成功", + FlutterAlibcConstKey_Data:@{ + @"type":@0, + @"paySuccessOrders":[result payResult].paySuccessOrders, + @"payFailedOrders":[result payResult].payFailedOrders, + } + }); + }else if(result.result== AlibcTradeResultTypeAddCard){ + // 加入购物车 + callback(@{ + FlutterAlibcConstKey_ErrorCode:@"0", + FlutterAlibcConstKey_ErrorMessage:@"加入购物车成功", + FlutterAlibcConstKey_Data:@{ + @"type":@1, + } + }); + } + } tradeProcessFailedCallback:^(NSError * _Nullable error) { + // 退出交易流程 + callback(@{ + FlutterAlibcConstKey_ErrorCode:[NSString stringWithFormat: @"%ld", (long)error.code], + FlutterAlibcConstKey_ErrorMessage:[error localizedDescription], + // Android没有,所以去掉 + // FlutterAlibcConstKey_Data:@{ + // @"orderIdList":[[error userInfo] objectForKey:@"orderIdList"], + // } + }); + }]; + // } + //} +} +#pragma mark --设置淘客参数 +- (AlibcTradeTaokeParams *)getTaokeParams:(FlutterMethodCall *)call{ + AlibcTradeTaokeParams *taoke = [[AlibcTradeTaokeParams alloc] init]; + if (call.arguments[@"taoKeParams"] == nil || [call.arguments[@"taoKeParams"] isKindOfClass:[NSNull class]]) { + return nil; + } + NSDictionary *taoKeParams = call.arguments[@"taoKeParams"]; + taoke.adzoneId = (taoKeParams[@"adzoneId"] == (id) [NSNull null]) ? nil : taoKeParams[@"adzoneId"]; + taoke.pid = (taoKeParams[@"pid"] == (id) [NSNull null]) ? nil : taoKeParams[@"pid"]; + //有adzoneId则pid失效 + taoke.unionId = (taoKeParams[@"unionId"] == (id) [NSNull null]) ? nil : taoKeParams[@"unionId"]; + taoke.subPid = (taoKeParams[@"subPid"] == (id) [NSNull null]) ? nil : taoKeParams[@"subPid"]; + // 必须是dic + taoke.extParams = (taoKeParams[@"extParams"] == (id) [NSNull null]) ? nil : taoKeParams[@"extParams"]; + + // 判断这玩意是什么格式,dic就直接赋值,jsoÏn需要转dic + // if ([extParams isKindOfClass:[NSDictionary class]]) { + // taoke.extParams = extParams; + // }else{ + // 解析字符串 + // taoke.extParams = [FlutterAlibcTools dictionaryWithJsonString:extParams]; + // } + + return taoke; +} +#pragma mark - 转换 +#pragma mark --唤起端失败的策略转换 +-(AlibcNativeFailMode )NativeFailMode:(int)mode{ + AlibcNativeFailMode openType=AlibcNativeFailModeJumpH5; + switch (mode) { + case 0: + openType=AlibcNativeFailModeJumpH5; + break; + case 1: + openType=AlibcNativeFailModeJumpDownloadPage; + break; + case 2: + openType=AlibcNativeFailModeNone; + break; + default: + break; + } + return openType; + +} +//唤起类型 +- (AlibcOpenType)openType:(int)mode{ + + AlibcOpenType openType=AlibcOpenTypeAuto; + switch (mode) { + case 0: + openType=AlibcOpenTypeAuto; + break; + case 1: + openType=AlibcOpenTypeNative; + break; + default: + break; + } + return openType; +} + +//打开类型 +-(NSString*)schemeType:(int)mode{ + NSString *linkKey=@"tmall"; + switch (mode) { + case 0: + linkKey=@"tmall"; + break; + case 1: + linkKey=@"taobao"; + break; + default: + break; + } + return linkKey; +} + + + + + + + + + + + + +/** + 可设置的参数 + 1.是否同步淘客打点 + 2.是否使用Native支付宝 + 3.是否使用淘客参数(是,需要设置如下参数) + adzoneId + pid + //有adzoneId则pid失效 + unionId + subPid + extParams{ + sellerId + taokeAppkey + } + 4.页面打开方式 + 是否唤端 Auto/Native + 唤起目标应用 淘宝/天猫 + 是否以push的方式打开页面 + 是否绑定webview + 是否自定义唤端失败策略(若是:H5,DownLoad,None) + 5.跟踪参数 customParams自定义 + */ +@end diff --git a/ios/Classes/Tools/FlutterAlibcTools.h b/ios/Classes/Tools/FlutterAlibcTools.h new file mode 100644 index 0000000..a1193c4 --- /dev/null +++ b/ios/Classes/Tools/FlutterAlibcTools.h @@ -0,0 +1,23 @@ +// +// FlutterAlibcTools.h +// flutter_alibc +// +// Created by 吴兴 on 2019/8/29. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface FlutterAlibcTools : NSObject +//判断String是否为空 ++ (BOOL)isNil:(NSString *)string; +//Json转Dic ++ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString; +//判断是不是null,是就转nil ++ (id)nullToNil:(id)obj; +//改变类型 ++(id)changeType:(id)myObj; +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/Tools/FlutterAlibcTools.m b/ios/Classes/Tools/FlutterAlibcTools.m new file mode 100644 index 0000000..ffe0557 --- /dev/null +++ b/ios/Classes/Tools/FlutterAlibcTools.m @@ -0,0 +1,116 @@ +// +// FlutterAlibcTools.m +// flutter_alibc +// +// Created by 吴兴 on 2019/8/29. +// + +#import "FlutterAlibcTools.h" + +@implementation FlutterAlibcTools + ++ (BOOL)isNil:(NSString *)string { + if (string == nil) { + return YES; + } + + if ([string isKindOfClass:[NSNull class]]) { + return YES; + } + return [[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length] == 0; +} + ++ (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString{ + if (jsonString == nil) { + return nil; + } + + NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; + NSError *err; + NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData + options:NSJSONReadingMutableContainers + error:&err]; + if(err) + { + NSLog(@"json解析失败:%@",err); + return nil; + } + return dic; +} + ++ (id)nullToNil:(id)obj{ + if ([obj isKindOfClass:[NSNull class]]) { + return nil; + } + return obj; +} + + +#pragma mark - 公有方法,直接使用 +//类型识别:将所有的NSNull类型转化成@"" ++(id)changeType:(id)myObj +{ + if ([myObj isKindOfClass:[NSDictionary class]]) + { + return [self nullDic:myObj]; + } + else if([myObj isKindOfClass:[NSArray class]]) + { + return [self nullArr:myObj]; + } + else if([myObj isKindOfClass:[NSString class]]) + { + return [self stringToString:myObj]; + } + else if([myObj isKindOfClass:[NSNull class]]) + { + return [self nullToString]; + } + else + { + return myObj; + } +} + +#pragma mark - 私有方法 +//将NSDictionary中的Null类型的项目转化成@"" ++(NSDictionary *)nullDic:(NSDictionary *)myDic +{ + NSArray *keyArr = [myDic allKeys]; + NSMutableDictionary *resDic = [[NSMutableDictionary alloc]init]; + for (int i = 0; i < keyArr.count; i ++) + { + id obj = [myDic objectForKey:keyArr[i]]; + obj = [self changeType:obj]; + [resDic setObject:obj forKey:keyArr[i]]; + } + return resDic; +} + +//将NSArray中的Null类型的项目转化成@"" ++(NSArray *)nullArr:(NSArray *)myArr +{ + NSMutableArray *resArr = [[NSMutableArray alloc] init]; + for (int i = 0; i < myArr.count; i ++) + { + id obj = myArr[i]; + obj = [self changeType:obj]; + [resArr addObject:obj]; + } + return resArr; +} + +//将NSString类型的原路返回 ++(NSString *)stringToString:(NSString *)string +{ + return string; +} + +//将Null类型的项目转化成@"" ++(NSString *)nullToString +{ +// return @""; + return @""; +} + +@end diff --git a/ios/Classes/WKWebView/ALiTradeWebViewController.h b/ios/Classes/WKWebView/ALiTradeWebViewController.h new file mode 100644 index 0000000..f05156d --- /dev/null +++ b/ios/Classes/WKWebView/ALiTradeWebViewController.h @@ -0,0 +1,23 @@ +// +// ALiTradeWantViewController.h +// ALiSDKAPIDemo +// +// Created by com.alibaba on 16/6/1. +// Copyright © 2016年 alibaba. All rights reserved. +// + +#ifndef ALiTradeWantViewController_h +#define ALiTradeWantViewController_h + +#import +#import + +@interface ALiTradeWebViewController : UIViewController +@property (nonatomic, copy) NSString *openUrl; +@property (strong, nonatomic) WKWebView *webView; + +-(WKWebView *)getWebView; + +@end + +#endif /* ALiTradeWantViewController_h */ diff --git a/ios/Classes/WKWebView/ALiTradeWebViewController.m b/ios/Classes/WKWebView/ALiTradeWebViewController.m new file mode 100644 index 0000000..902ec6c --- /dev/null +++ b/ios/Classes/WKWebView/ALiTradeWebViewController.m @@ -0,0 +1,89 @@ +// +// ALiTradeWantViewController.m +// ALiSDKAPIDemo +// +// Created by com.alibaba on 16/6/1. +// Copyright © 2016年 alibaba. All rights reserved. +// + +#import +#import "ALiTradeWebViewController.h" +#import + +//#import "ALiCartService.h" + +@interface ALiTradeWebViewController() + +@end + +@implementation ALiTradeWebViewController +- (instancetype)init +{ + self = [super init]; + if (self) { + _webView = [[WKWebView alloc]initWithFrame:self.view.bounds]; + _webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _webView.scrollView.scrollEnabled = YES; +// _webView.navigationDelegate = self; + _webView.navigationDelegate = self; + _webView.UIDelegate = self; + [_webView addObserver:self forKeyPath:@"URL" options:NSKeyValueObservingOptionNew context:nil]; + [self.view addSubview:_webView]; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.title=@"淘你喜欢"; + + + [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) + forBarMetrics:UIBarMetricsDefault]; +} +-(void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context{ + + NSLog(@"url == %@",_webView.URL.absoluteString); + NSString *urlStr = _webView.URL.absoluteString; + NSRange range; + range = [urlStr rangeOfString:@"access_token"]; + if (range.location != NSNotFound) { + NSString *accessString = [urlStr substringFromIndex:range.location]; + // 截止到& + NSRange range2 = [accessString rangeOfString: @"&"]; + + NSString *access_token_string = [accessString substringWithRange:NSMakeRange(0,range2.location)]; + NSArray *array = [access_token_string componentsSeparatedByString:@"="]; + NSString *access_token = array[1]; + NSLog(@"%@",access_token); + // 跳转回去 + [[NSNotificationCenter defaultCenter] postNotificationName:@"getAccessToken" object:access_token]; + [self.navigationController popViewControllerAnimated:YES]; + }else{ + NSLog(@"Not Found"); + } +} + +-(void)dealloc +{ + NSLog(@"dealloc view"); + [_webView removeObserver:self forKeyPath:@"URL"]; + _webView = nil; + +} + +-(void)setOpenUrl:(NSString *)openUrl { + [_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:openUrl]]]; +} + +-(WKWebView *)getWebView{ + return _webView; +} + +#pragma mark - WKNavigationDelegate +- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { +// 重定向 + decisionHandler(WKNavigationActionPolicyAllow); +} +@end diff --git a/ios/Classes/WKWebView/FlutterWxViewCtrlViewController.h b/ios/Classes/WKWebView/FlutterWxViewCtrlViewController.h new file mode 100644 index 0000000..9ee5aa8 --- /dev/null +++ b/ios/Classes/WKWebView/FlutterWxViewCtrlViewController.h @@ -0,0 +1,19 @@ +// +// FlutterWxViewCtrlViewController.h +// flutter_alibc +// +// Created by 吴兴 on 2019/10/22. +// + +#import +#import "ALiTradeWebViewController.h" +NS_ASSUME_NONNULL_BEGIN +typedef void (^AccessTokenBlock) (NSString *accessToken); +@interface FlutterWxViewCtrlViewController : UIViewController + +@property(nonatomic,strong)ALiTradeWebViewController *vc; +@property(nonatomic,copy) AccessTokenBlock accessBlock; +@property(nonatomic,copy) NSString *accessToken; +@end + +NS_ASSUME_NONNULL_END diff --git a/ios/Classes/WKWebView/FlutterWxViewCtrlViewController.m b/ios/Classes/WKWebView/FlutterWxViewCtrlViewController.m new file mode 100644 index 0000000..1053b62 --- /dev/null +++ b/ios/Classes/WKWebView/FlutterWxViewCtrlViewController.m @@ -0,0 +1,61 @@ +// +// FlutterWxViewCtrlViewController.m +// flutter_alibc +// +// Created by 吴兴 on 2019/10/22. +// + +#import "FlutterWxViewCtrlViewController.h" + +@interface FlutterWxViewCtrlViewController () +@property(nonatomic,assign)int num; +@end + +@implementation FlutterWxViewCtrlViewController +- (instancetype)init +{ + self = [super init]; + if (self) { + self.num = 0; + } + return self; +} +- (void)viewDidLoad { + [super viewDidLoad]; + self.view.backgroundColor = [UIColor whiteColor]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getAccessToken:) name:@"getAccessToken" object:nil]; +// 跳转到别的页面 + [self.navigationController pushViewController:self.vc animated:YES]; + // Do any additional setup after loading the view. +} + +- (void)viewDidAppear:(BOOL)animated{ + self.num = self.num + 1; + if (self.num == 2) { + NSLog(@"该关闭了"); + [self.navigationController dismissViewControllerAnimated:YES completion:^{ + NSLog(@"执行dismiss回调"); + + }]; + } +} +- (void)getAccessToken:(NSNotification *) notification { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + NSLog(@"写入accessToken"); + self.accessToken = notification.object; +} +- (void)dealloc{ + NSLog(@"dealloc执行"); + self.accessBlock(self.accessToken); +} +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/ios/flutter_alibc.podspec b/ios/flutter_alibc.podspec new file mode 100644 index 0000000..c3b0e98 --- /dev/null +++ b/ios/flutter_alibc.podspec @@ -0,0 +1,36 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'flutter_alibc' + s.version = '0.0.1' + s.summary = '阿里百川' + s.description = <<-DESC +阿里百川 + DESC + s.homepage = 'http://example.com' + s.license = { :file => '../LICENSE' } + s.author = { 'Your Company' => 'email@example.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + s.dependency 'AlibcTradeSDK','4.0.1.6' + s.dependency 'AliAuthSDK','1.1.0.41-bc' + s.dependency 'mtopSDK','3.0.0.3-BC' + s.dependency 'securityGuard','5.4.191' + s.dependency 'AliLinkPartnerSDK','4.0.0.24' + s.dependency 'BCUserTrack','5.2.0.18-appkeys' + s.dependency 'UTDID','1.1.0.16' + s.dependency 'WindVane','8.5.0.46-bc11' + + # s.vendored_frameworks ="AliBaichuan/Frameworks/*.framework" + # s.resource = "AliBaichuan/Resources/*.bundle" + + s.frameworks = "CoreTelephony","CoreMotion","UIKit","Foundation" + s.libraries = "z","c++","sqlite3.0" + + s.ios.deployment_target = '8.0' + s.static_framework = true +end + diff --git a/lib/albc_tools.dart b/lib/albc_tools.dart new file mode 100644 index 0000000..78554bf --- /dev/null +++ b/lib/albc_tools.dart @@ -0,0 +1,62 @@ +/// + /// @Description: 工具类 + /// @Author: wuxing + /// @Date: 2019-09-06 22:51:22 + /// @LastEditors: wuxing + /// @LastEditTime: 2019-09-06 22:52:48 + /// + +import 'alibc_const_key.dart'; +import 'alibc_model.dart'; + +class AlibcTools { + // -------------------------------------------// +// --------这里是工具类,不要从这获取-------------// +// -------------------------------------------// + + // 获取返回数据 + static TradeResult getTradeResult(Map result) { + // 如果失败 + if (result[AlibcConstKey.errorCode] != "0") { + return TradeResult( + result[AlibcConstKey.errorCode], + result[AlibcConstKey.errorMessage], + ); + } + + // 判断类型 + if (result[AlibcConstKey.data]["type"] == + TradeResultType.AlibcTradeResultTypePaySuccess) { + // 付款成功 + return TradeResult( + result[AlibcConstKey.errorCode], result[AlibcConstKey.errorMessage], + type: TradeResultType.AlibcTradeResultTypePaySuccess, + payResult: PayResult( + result[AlibcConstKey.data]["paySuccessOrders"], + result[AlibcConstKey.data]["payFailedOrders"], + )); + } else { + // 添加购物车成功 + return TradeResult( + result[AlibcConstKey.errorCode], + result[AlibcConstKey.errorMessage], + type: TradeResultType.AlibcTradeResultTypeAddCard, + ); + } + } + +// 设置淘宝客数据 + static Map getTaokeMap(TaokeParams taokeParams) { + Map taoKe; + if (taokeParams != null) { + taoKe = { + "adzoneId": taokeParams.adzoneId ?? "", + "pid": taokeParams.pid ?? "", + "unionId": taokeParams.unionId ?? "", + "subPid": taokeParams.subPid ?? "", + "extParams": taokeParams.extParams ?? {} + }; + } + return taoKe; + } +} diff --git a/lib/alibc_const_key.dart b/lib/alibc_const_key.dart new file mode 100644 index 0000000..c0f8a3d --- /dev/null +++ b/lib/alibc_const_key.dart @@ -0,0 +1,47 @@ + /// + /// @Author: 无星 + /// @Date: 2019-08-30 15:55:44 + /// @Last Modified by: 无星 + /// @Last Modified time: 2019-08-30 17:17:07 + /// + +import 'package:flutter/foundation.dart'; + +class AlibcConstKey { + // 错误码 + static String errorCode = "errorCode"; + // 错误信息 + static String errorMessage = "errorMessage"; + // 平台,iOS为iOS,Android为Android + static String platform = "platform"; + // result + static String data = "data"; + + static String platform_ios = "iOS"; + static String platform_andriod = "andriod"; +} + +/// 成功支付 +/// 成功添加到购物车 +enum TradeResultType { + AlibcTradeResultTypePaySuccess, + AlibcTradeResultTypeAddCard +} + +/// 智能判断 +/// 强制拉端(手淘/天猫) +enum AlibcOpenType { AlibcOpenTypeAuto, AlibcOpenTypeNative } + +// 拉起手淘失败后的处理策略 + +// - AlibcNativeFailModeJumpH5: 当拉起手淘/天猫失败, 则在 webview 中跳转对应 H5 页面; 默认选项 +// - AlibcNativeFailModeJumpDownloadPage: 当拉起手淘/天猫失败, 则跳转对应 App 下载页面 +// - AlibcNativeFailModeNone: 当拉起手淘/天猫失败, 不做额外操作 +enum AlibcNativeFailMode { + AlibcNativeFailModeJumpH5, + AlibcNativeFailModeJumpDownloadPage, + AlibcNativeFailModeNone +} +// 天猫 +// 淘宝 +enum AlibcSchemeType { AlibcSchemeTmall, AlibcSchemeTaoBao } diff --git a/lib/alibc_model.dart b/lib/alibc_model.dart new file mode 100644 index 0000000..b831a5e --- /dev/null +++ b/lib/alibc_model.dart @@ -0,0 +1,134 @@ +// 初始化阿里百川的model +import 'alibc_const_key.dart'; + +class InitModel { + // 错误码 + final String errorCode; + // 错误信息 + final String errorMessage; + + InitModel(this.errorCode, this.errorMessage); +} + +class LoginModel { + // 错误码 + final String errorCode; + // 错误信息 + final String errorMessage; + + UserModel data; + + LoginModel(this.errorCode, this.errorMessage, {this.data}); +} + +// 用户信息 +class UserModel { + // 用户昵称 + final String nick; + // 头像地址 + final String avatarUrl; + final String openId; + final String openSid; + final String topAccessToken; + final String topAuthCode; + UserModel(this.nick, this.avatarUrl, this.openId, this.openSid, + this.topAccessToken, this.topAuthCode); +} + +// 淘宝客的参数 +class TaokeParams { + //有adzoneId则pid失效 + String adzoneId; + String pid; + String unionId; + String subPid; + Map extParams; + TaokeParams( + {this.adzoneId, this.pid, this.unionId, this.subPid, this.extParams}); +} + +// url打开或者page打开等的数据 +class TradeResult { + // 错误码,0为成功,非0为失败 + final String errorCode; + // 错误信息 + final String errorMessage; + + TradeResultType type; + + PayResult payResult; + // AddCardResult addCardResult; + // Android没有,所以去掉 + // TradeFailResult tradeFailResult; + + TradeResult( + this.errorCode, + this.errorMessage, { + this.type, + this.payResult, + // this.tradeFailResult, + }); +} + +// 付款成功的result +class PayResult { + // 支付成功的订单 + final List paySuccessOrders; + // 支付失败的订单 + final List payFailedOrders; + + PayResult(this.paySuccessOrders, this.payFailedOrders); +} + +// 添加购物车成功的result +// 因为没什么好返回的,所以不写 +// class AddCardResult {} + +// 失败,Android没有,所以去掉 +// class TradeFailResult { +// // 失败的订单list +// final List orderIdList; + +// TradeFailResult(this.orderIdList); +// } + +// class TaoKeParams { +// // 淘客ID +// final String pid; +// // 不知道什么id +// final String subPid; +// // 不知道什么id +// final String unionId; + +// TaoKeParams(this.pid, this.subPid, this.unionId); +// } + +// class TradeResult { +// // 是否成功 +// final int openResultCode; +// // 平台 +// final String platform; +// // // 是否成功 +// // final bool isSuccessful; +// // errorCode +// final int errorCode; +// // 错误信息 +// final String errorMessage; +// // 打开配型 +// final TradeResultType tradeResultType; +// // 成功付款商品 +// final List paySuccessOrders; +// // 付款失败商品 +// final List payFailedOrders; + +// TradeResult({ +// this.openResultCode, +// this.platform, +// // this.isSuccessful, +// this.errorCode, +// this.errorMessage, +// this.tradeResultType, +// this.paySuccessOrders, +// this.payFailedOrders +// }); +// } diff --git a/lib/flutter_alibc.dart b/lib/flutter_alibc.dart new file mode 100644 index 0000000..e5ef406 --- /dev/null +++ b/lib/flutter_alibc.dart @@ -0,0 +1,264 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_alibc/albc_tools.dart'; +import 'package:flutter_alibc/alibc_const_key.dart'; +import 'package:flutter_alibc/alibc_model.dart'; + +class FlutterAlibc { + // static StreamController _responseTaoKeLoginController = new StreamController.broadcast(); + // static Stream get responseFromShare => + // _responseTaoKeLoginController.stream; + + // static Future _handler(MethodCall methodCall) { + // if ("taoKeLogin" == methodCall.method) { + // _responseTaoKeLoginController.sink.add(methodCall.arguments); + // } + // return Future.value(true); + // } + + // 通信的桥接类 + static final MethodChannel _channel = const MethodChannel("flutter_alibc"); + // ..setMethodCallHandler(_handler); + + static Future get platformVersion async { + final String version = await _channel.invokeMethod('getPlatformVersion'); + return version; + } + + ///初始化 + ///version:当前app版本 + ///appName:当前app名称 + ///result:{ + /// errorCode, //0为初始化成功,其他为失败 + /// errorMessage, //message + ///} + static Future initAlibc({String version, String appName}) async { + Map result = await _channel + .invokeMethod("initAlibc", {"version": version, "appName": appName}); + return InitModel( + result[AlibcConstKey.errorCode], result[AlibcConstKey.errorMessage]); + } + + /// + /// @description: 登录淘宝 + /// + /// @return: 成功则返回的data为用户信息,失败则没有data + /// + static Future loginTaoBao() async { + Map result = await _channel.invokeMethod("loginTaoBao"); + // 判断成功还是失败 + if (result[AlibcConstKey.errorCode] != "0") { + return LoginModel( + result[AlibcConstKey.errorCode], + result[AlibcConstKey.errorMessage], + ); + } + return LoginModel( + result[AlibcConstKey.errorCode], result[AlibcConstKey.errorMessage], + data: UserModel( + result[AlibcConstKey.data]["nick"], + result[AlibcConstKey.data]["avatarUrl"], + result[AlibcConstKey.data]["openId"], + result[AlibcConstKey.data]["openSid"], + result[AlibcConstKey.data]["topAccessToken"], + result[AlibcConstKey.data]["topAuthCode"])); + } + + /// + /// @description: 退出淘宝登录 + /// @param {type} + /// @return: + /// + static loginOut() { + _channel.invokeMethod("loginOut"); + } + + /// + /// @description: 渠道授权,获取access_token + /// @param {type} + /// @return: + /// Map + static Future> taoKeLogin({ + @required String url, + AlibcOpenType openType = AlibcOpenType.AlibcOpenTypeAuto, + bool isNeedCustomNativeFailMode = false, + AlibcNativeFailMode nativeFailMode = + AlibcNativeFailMode.AlibcNativeFailModeNone, + AlibcSchemeType schemeType = AlibcSchemeType.AlibcSchemeTaoBao, + TaokeParams taokeParams, + String backUrl, + }) async { + Map taoKe = AlibcTools.getTaokeMap(taokeParams); + Map result = await _channel.invokeMethod("taoKeLogin", { + "url": url, + "openType": openType.index, + "isNeedCustomNativeFailMode": isNeedCustomNativeFailMode, + "nativeFailMode": nativeFailMode.index, + "schemeType": schemeType.index, + "taokeParams": taoKe, + "backUrl": backUrl + }); + + return result; + } + + /// + /// @description: 通过url打开,包括h5,唤起手淘等 + /// @param + /// url:目标url + /// openType:打开类型 + /// isNeedCustomNativeFailMode:是否需要设置唤端失败策略 + /// nativeFailMode:唤端失败策略 + /// schemeType:唤起哪个端 + /// taokeParams:淘客数据 + /// backUrl: 跳转回来的url + /// @return: + /// + static Future openByUrl({ + @required String url, + AlibcOpenType openType = AlibcOpenType.AlibcOpenTypeAuto, + bool isNeedCustomNativeFailMode = false, + AlibcNativeFailMode nativeFailMode = + AlibcNativeFailMode.AlibcNativeFailModeNone, + AlibcSchemeType schemeType = AlibcSchemeType.AlibcSchemeTmall, + TaokeParams taokeParams, + String backUrl, + bool isAuth=false + }) async { + Map taoKe = AlibcTools.getTaokeMap(taokeParams); + Map result = await _channel.invokeMethod("openByUrl", { + "url": url, + "openType": openType.index, + "isNeedCustomNativeFailMode": isNeedCustomNativeFailMode, + "nativeFailMode": nativeFailMode.index, + "schemeType": schemeType.index, + "taokeParams": taoKe, + "backUrl": backUrl, + "auth":isAuth + }); + + TradeResult tradeResult = AlibcTools.getTradeResult(result); + return tradeResult; + } + + /// + /// @description: 打开商品详情 + /// @param + /// 同上 + /// itemID 商品id,可以是真实的也可以是混淆的 + /// isNeedPush iOS独占 + /// @return: + /// + static Future openItemDetail({ + @required String itemID, + // iOS独占 + // bool isNeedPush = false, + AlibcOpenType openType = AlibcOpenType.AlibcOpenTypeAuto, + bool isNeedCustomNativeFailMode = false, + AlibcNativeFailMode nativeFailMode = + AlibcNativeFailMode.AlibcNativeFailModeNone, + AlibcSchemeType schemeType = AlibcSchemeType.AlibcSchemeTmall, + TaokeParams taokeParams, + // 额外需要追踪的业务数据 + Map trackParam, + String backUrl, + }) async { + Map taoKe = AlibcTools.getTaokeMap(taokeParams); + Map result = await _channel.invokeMethod("openItemDetail", { + "itemID": itemID, + // "isNeedPush": isNeedPush, + "openType": openType.index, + "isNeedCustomNativeFailMode": isNeedCustomNativeFailMode, + "nativeFailMode": nativeFailMode.index, + "schemeType": schemeType.index, + "taokeParams": taoKe, + "trackParam": trackParam, + "backUrl": backUrl + }); + TradeResult tradeResult = AlibcTools.getTradeResult(result); + return tradeResult; + } + + /// + /// @description: 打开店铺 + /// @param {type} + /// shopId 店铺id + /// @return: + /// + static Future openShop({ + @required String shopId, + // iOS独占 + // bool isNeedPush = false, + AlibcOpenType openType = AlibcOpenType.AlibcOpenTypeAuto, + bool isNeedCustomNativeFailMode = false, + AlibcNativeFailMode nativeFailMode = + AlibcNativeFailMode.AlibcNativeFailModeNone, + AlibcSchemeType schemeType = AlibcSchemeType.AlibcSchemeTmall, + TaokeParams taokeParams, + // 额外需要追踪的业务数据 + Map trackParam, + String backUrl, + }) async { + Map taoKe = AlibcTools.getTaokeMap(taokeParams); + + Map result = await _channel.invokeMethod("openShop", { + "shopId": shopId, + // "isNeedPush": isNeedPush, + "openType": openType.index, + "isNeedCustomNativeFailMode": isNeedCustomNativeFailMode, + "nativeFailMode": nativeFailMode.index, + "schemeType": schemeType.index, + "taokeParams": taoKe, + "trackParam": trackParam, + "backUrl": backUrl + }); + TradeResult tradeResult = AlibcTools.getTradeResult(result); + return tradeResult; + } + + /// + /// @description: 打开购物车 + /// @param {type} + /// @return: + /// + static Future openCart({ + // iOS独占 + // bool isNeedPush = false, + AlibcOpenType openType = AlibcOpenType.AlibcOpenTypeAuto, + bool isNeedCustomNativeFailMode = false, + AlibcNativeFailMode nativeFailMode = + AlibcNativeFailMode.AlibcNativeFailModeNone, + AlibcSchemeType schemeType = AlibcSchemeType.AlibcSchemeTmall, + TaokeParams taokeParams, + // 额外需要追踪的业务数据 + Map trackParam, + String backUrl, + }) async { + Map taoKe = AlibcTools.getTaokeMap(taokeParams); + + Map result = await _channel.invokeMethod("openCart", { + // "isNeedPush": isNeedPush, + "openType": openType.index, + "isNeedCustomNativeFailMode": isNeedCustomNativeFailMode, + "nativeFailMode": nativeFailMode.index, + "schemeType": schemeType.index, + "taokeParams": taoKe, + "trackParam": trackParam, + "backUrl": backUrl + }); + TradeResult tradeResult = AlibcTools.getTradeResult(result); + return tradeResult; + } + + // 是否需要设置打点 + static syncForTaoke(bool isSync) { + _channel.invokeMethod("syncForTaoke", {"isSync": isSync}); + } + + // 是否需要 Native AliPay 接口 + static useAlipayNative(bool isNeed) { + _channel.invokeMethod("useAlipayNative", {"isNeed": isNeed}); + } +} diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..c57bb09 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,188 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.11" + args: + dependency: transitive + description: + name: args + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.5.2" + async: + dependency: transitive + description: + name: async + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.5" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.14.11" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.3" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + image: + dependency: transitive + description: + name: image + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.4" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.12.6" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.8" + path: + dependency: transitive + description: + name: path + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.6.4" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.8.0+1" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.5" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.5.5" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.5" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.11" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.8" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.5.0" +sdks: + dart: ">=2.4.0 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..f5b58f8 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,58 @@ +name: flutter_alibc +description: flutter_alibc,flutter版本的阿里百川,android V4.0.0.8 ios V4.0.1。更新日期:2020-4-13 +version: 0.0.15 +author: wx +homepage: https://github.com/FlutterTaoBaoKe/flutter_alibc.git + +environment: + sdk: '>=2.1.0 <3.0.0' + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # This section identifies this Flutter project as a plugin project. + # The androidPackage and pluginClass identifiers should not ordinarily + # be modified. They are used by the tooling to maintain consistency when + # adding or updating assets for this project. + plugin: + androidPackage: com.wxwx.flutter_alibc + pluginClass: FlutterAlibcPlugin + # To add assets to your plugin package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.dev/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + # To add custom fonts to your plugin package, add a fonts section here, + # 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 + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.dev/custom-fonts/#from-packages diff --git a/test/flutter_alibc_test.dart b/test/flutter_alibc_test.dart new file mode 100644 index 0000000..6c1c791 --- /dev/null +++ b/test/flutter_alibc_test.dart @@ -0,0 +1,21 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter_alibc/flutter_alibc.dart'; + +void main() { + const MethodChannel channel = MethodChannel('flutter_alibc'); + + setUp(() { + channel.setMockMethodCallHandler((MethodCall methodCall) async { + return '42'; + }); + }); + + tearDown(() { + channel.setMockMethodCallHandler(null); + }); + + test('getPlatformVersion', () async { + expect(await FlutterAlibc.platformVersion, '42'); + }); +}