提交 82f72e78 authored 作者: JarvanMo's avatar JarvanMo

introduce v4

上级 00231ca2
...@@ -16,14 +16,14 @@ RUN sudo apt-get update && sudo apt-get install -y google-cloud-sdk && \ ...@@ -16,14 +16,14 @@ RUN sudo apt-get update && sudo apt-get install -y google-cloud-sdk && \
gcloud config set component_manager/disable_update_check true gcloud config set component_manager/disable_update_check true
RUN yes | sdkmanager \ RUN yes | sdkmanager \
"platforms;android-29" \ "platforms;android-33" \
"build-tools;29.0.2" \ "build-tools;33.0.2" \
"extras;google;m2repository" \ "extras;google;m2repository" \
"extras;android;m2repository" "extras;android;m2repository"
RUN yes | sdkmanager \ RUN yes | sdkmanager \
"platforms;android-30" \ "platforms;android-32" \
"build-tools;28.0.3" \ "build-tools;33.0.2" \
"extras;google;m2repository" \ "extras;google;m2repository" \
"extras;android;m2repository" "extras;android;m2repository"
......
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
...@@ -6,3 +6,4 @@ ...@@ -6,3 +6,4 @@
.DS_Store .DS_Store
/build /build
/captures /captures
.cxx
...@@ -9,12 +9,12 @@ buildscript { ...@@ -9,12 +9,12 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.1.2' classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
rootProject.allprojects { allprojects {
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
...@@ -25,26 +25,38 @@ apply plugin: 'com.android.library' ...@@ -25,26 +25,38 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
android { android {
namespace "com.jarvan.fluwx"
compileSdkVersion 31 compileSdkVersion 31
sourceSets { sourceSets {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
test.java.srcDirs += 'src/test/kotlin'
} }
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
consumerProguardFiles 'consumer-proguard-rules.txt' consumerProguardFiles 'consumer-proguard-rules.txt'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
lintOptions {
disable 'InvalidPackage' dependencies {
api 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.24'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'id.zelory:compressor:3.0.1'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
testImplementation 'org.jetbrains.kotlin:kotlin-test'
testImplementation 'org.mockito:mockito-core:5.0.0'
} }
}
dependencies { testOptions {
api 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.24' unitTests.all {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' useJUnitPlatform()
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
implementation 'id.zelory:compressor:3.0.1' testLogging {
implementation 'com.squareup.okhttp3:okhttp:4.9.1' events "passed", "skipped", "failed", "standardOut", "standardError"
testImplementation 'junit:junit:4.13.2' outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
} }
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="com.jarvan.fluwx">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
...@@ -14,8 +13,8 @@ ...@@ -14,8 +13,8 @@
<application> <application>
<activity <activity
android:name=".wxapi.FluwxWXEntryActivity" android:name=".wxapi.FluwxWXEntryActivity"
android:launchMode="singleTask"
android:exported="false" android:exported="false"
android:launchMode="singleTask"
android:taskAffinity="${applicationId}" android:taskAffinity="${applicationId}"
android:theme="@style/DisablePreviewTheme" /> android:theme="@style/DisablePreviewTheme" />
...@@ -25,13 +24,13 @@ ...@@ -25,13 +24,13 @@
android:launchMode="singleTop" android:launchMode="singleTop"
android:targetActivity="com.jarvan.fluwx.wxapi.FluwxWXEntryActivity" android:targetActivity="com.jarvan.fluwx.wxapi.FluwxWXEntryActivity"
android:taskAffinity="${applicationId}" android:taskAffinity="${applicationId}"
android:theme="@style/DisablePreviewTheme"/> android:theme="@style/DisablePreviewTheme" />
<activity-alias <activity-alias
android:name="${applicationId}.wxapi.WXPayEntryActivity" android:name="${applicationId}.wxapi.WXPayEntryActivity"
android:exported="true" android:exported="true"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:targetActivity="com.jarvan.fluwx.wxapi.FluwxWXEntryActivity" android:targetActivity="com.jarvan.fluwx.wxapi.FluwxWXEntryActivity"
android:theme="@style/DisablePreviewTheme"/> android:theme="@style/DisablePreviewTheme" />
<provider <provider
android:name="com.jarvan.fluwx.FluwxFileProvider" android:name="com.jarvan.fluwx.FluwxFileProvider"
......
package com.jarvan.fluwx
class FluwxTest {
fun test(){}
}
\ No newline at end of file
package com.jarvan.fluwx
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import kotlin.test.Test
import org.mockito.Mockito
/*
* This demonstrates a simple unit test of the Kotlin portion of this plugin's implementation.
*
* Once you have built the plugin's example app, you can run these tests from the command
* line by running `./gradlew testDebugUnitTest` in the `example/android/` directory, or
* you can run them directly from IDEs that support JUnit such as Android Studio.
*/
internal class FluwxPluginTest {
@Test
fun onMethodCall_getPlatformVersion_returnsExpectedValue() {
val plugin = FluwxPlugin()
val call = MethodCall("getPlatformVersion", null)
val mockResult: MethodChannel.Result = Mockito.mock(MethodChannel.Result::class.java)
plugin.onMethodCall(call, mockResult)
Mockito.verify(mockResult).success("Android " + android.os.Build.VERSION.RELEASE)
}
}
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
.buildlog/ .buildlog/
.history .history
.svn/ .svn/
**/Podfile.lock migrate_working_dir/
# IntelliJ related # IntelliJ related
*.iml *.iml
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
# Flutter/Dart/Pub related # Flutter/Dart/Pub related
**/doc/api/ **/doc/api/
**/ios/Flutter/.last_build_id **/ios/Flutter/.last_build_id
**/ios/Flutter/flutter_export_environment.sh
.dart_tool/ .dart_tool/
.flutter-plugins .flutter-plugins
.flutter-plugins-dependencies .flutter-plugins-dependencies
...@@ -33,11 +32,13 @@ ...@@ -33,11 +32,13 @@
.pub/ .pub/
/build/ /build/
# Web related
lib/generated_plugin_registrant.dart
# Symbolication related # Symbolication related
app.*.symbols app.*.symbols
# Obfuscation related # Obfuscation related
app.*.map.json app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
# 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: 0b8abb4724aa590dd0f429683339b1e045a1594d
channel: stable
project_type: app
...@@ -8,9 +8,9 @@ This project is a starting point for a Flutter application. ...@@ -8,9 +8,9 @@ This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project: 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) - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter, view our For help getting started with Flutter development, view the
[online documentation](https://flutter.dev/docs), which offers tutorials, [online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference. samples, guidance on mobile development, and a full API reference.
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
gradle-wrapper.jar gradle-wrapper.jar
**.classpath
**.project
**.settings
/.gradle /.gradle
/captures/ /captures/
/gradlew /gradlew
/gradlew.bat /gradlew.bat
/local.properties /local.properties
GeneratedPluginRegistrant.java GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties() def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties') def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) { if (localPropertiesFile.exists()) {
...@@ -6,12 +12,6 @@ if (localPropertiesFile.exists()) { ...@@ -6,12 +12,6 @@ if (localPropertiesFile.exists()) {
} }
} }
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') def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) { if (flutterVersionCode == null) {
flutterVersionCode = '1' flutterVersionCode = '1'
...@@ -22,32 +22,27 @@ if (flutterVersionName == null) { ...@@ -22,32 +22,27 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0' flutterVersionName = '1.0'
} }
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android { android {
compileSdkVersion 31 namespace "com.jarvan.fluwx_example"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
sourceSets { sourceSets {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
} }
lintOptions {
disable 'InvalidPackage'
}
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "net.sourceforge.simcpux" applicationId "net.sourceforge.simcpux"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 31 targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
flavorDimensions "branch"
buildTypes { buildTypes {
release { release {
// TODO: Add your own signing config for the release build. // TODO: Add your own signing config for the release build.
...@@ -73,7 +68,4 @@ flutter { ...@@ -73,7 +68,4 @@ flutter {
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
} }
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="com.jarvan.fluwx_example">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that <!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method. calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide In most cases you can leave this as-is, but you if you want to provide
...@@ -28,9 +27,9 @@ ...@@ -28,9 +27,9 @@
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:exported="true"
android:hardwareAccelerated="true" android:hardwareAccelerated="true"
android:launchMode="singleTop" android:launchMode="singleTop"
android:exported="true"
android:theme="@style/LaunchTheme" android:theme="@style/LaunchTheme"
android:windowSoftInputMode="adjustResize"> android:windowSoftInputMode="adjustResize">
<intent-filter> <intent-filter>
......
...@@ -5,7 +5,6 @@ import android.os.Bundle ...@@ -5,7 +5,6 @@ import android.os.Bundle
import com.jarvan.fluwx.handlers.FluwxRequestHandler import com.jarvan.fluwx.handlers.FluwxRequestHandler
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() { class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar"> <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when <!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame --> the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item> <item name="android:windowBackground">@drawable/launch_background</item>
</style> </style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources> </resources>
...@@ -6,7 +6,7 @@ buildscript { ...@@ -6,7 +6,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.1.2' classpath 'com.android.tools.build:gradle:7.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
...@@ -26,6 +26,6 @@ subprojects { ...@@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app') project.evaluationDependsOn(':app')
} }
task clean(type: Delete) { tasks.register("clean", Delete) {
delete rootProject.buildDir delete rootProject.buildDir
} }
org.gradle.jvmargs=-Xmx1536M org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
\ No newline at end of file
...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
include ':app' pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
def plugins = new Properties() plugins {
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
if (pluginsFile.exists()) { }
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
} }
plugins.each { name, path -> include ":app"
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name" apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle"
project(":$name").projectDir = pluginDirectory
}
// This is a basic Flutter integration test.
//
// Since integration tests run in a full Flutter application, they can interact
// with the host side of a plugin implementation, unlike Dart unit tests.
//
// For more information about Flutter integration tests, please see
// https://docs.flutter.dev/cookbook/testing/integration/introduction
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:fluwx/fluwx.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('getPlatformVersion test', (WidgetTester tester) async {
});
}
**/dgph
*.mode1v3 *.mode1v3
*.mode2v3 *.mode2v3
*.moved-aside *.moved-aside
...@@ -11,7 +12,6 @@ ...@@ -11,7 +12,6 @@
Icon? Icon?
**/Pods/ **/Pods/
**/.symlinks/ **/.symlinks/
Podfile.lock
profile profile
xcuserdata xcuserdata
**/.generated/ **/.generated/
...@@ -19,6 +19,7 @@ Flutter/App.framework ...@@ -19,6 +19,7 @@ Flutter/App.framework
Flutter/Flutter.framework Flutter/Flutter.framework
Flutter/Flutter.podspec Flutter/Flutter.podspec
Flutter/Generated.xcconfig Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx Flutter/app.flx
Flutter/app.zip Flutter/app.zip
Flutter/flutter_assets/ Flutter/flutter_assets/
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>en</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>App</string> <string>App</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
......
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig" #include "Generated.xcconfig"
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig" #include "Generated.xcconfig"
...@@ -29,6 +29,9 @@ flutter_ios_podfile_setup ...@@ -29,6 +29,9 @@ flutter_ios_podfile_setup
target 'Runner' do target 'Runner' do
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
target 'RunnerTests' do
inherit! :search_paths
end
end end
post_install do |installer| post_install do |installer|
......
...@@ -8,15 +8,27 @@ ...@@ -8,15 +8,27 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C80F4294D02FB00263BE5 /* RunnerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 331C80F3294D02FB00263BE5 /* RunnerTests.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
62B88C18565D88C02906C10C /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27C08EA6C421C7E89069DE6B /* libPods-Runner.a */; }; 5255F9316848A30ED1F84FF5 /* libPods-RunnerTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 61BB2832514DC5AC842E583C /* libPods-RunnerTests.a */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
F3F2D014A64FDD073F05B4CA /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F1790AB3CDE0ED1C0E115C2 /* libPods-Runner.a */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
331C80F5294D02FB00263BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = { 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase; isa = PBXCopyFilesBuildPhase;
...@@ -31,11 +43,17 @@ ...@@ -31,11 +43,17 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
1201E93D5A4AF06F8B2154F7 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
27C08EA6C421C7E89069DE6B /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 1F1790AB3CDE0ED1C0E115C2 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
32AE9497AA826921991B27BF /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; 331C80F1294D02FB00263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
331C80F3294D02FB00263BE5 /* RunnerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RunnerTests.m; sourceTree = "<group>"; };
3796AEEE99D23C2985F27594 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
3CDE7FB3ADAC9EC781FA9BD4 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
517551098246B7C71A7D63D8 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
61BB2832514DC5AC842E583C /* libPods-RunnerTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RunnerTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
...@@ -47,38 +65,36 @@ ...@@ -47,38 +65,36 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9E479F6222F46DD1BF9F2E3E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; A9DDFA5760AD388C7AE67D68 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
D9FC4FD7820D62136E2C7EAB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; F071110615569824B74AF901 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
331C80EE294D02FB00263BE5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
5255F9316848A30ED1F84FF5 /* libPods-RunnerTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EB1CF9000F007C117D /* Frameworks */ = { 97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
62B88C18565D88C02906C10C /* libPods-Runner.a in Frameworks */, F3F2D014A64FDD073F05B4CA /* libPods-Runner.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
3510C167085BA3D3F8540F37 /* Pods */ = { 331C80F2294D02FB00263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
9E479F6222F46DD1BF9F2E3E /* Pods-Runner.debug.xcconfig */,
32AE9497AA826921991B27BF /* Pods-Runner.release.xcconfig */,
D9FC4FD7820D62136E2C7EAB /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
8513A54653CE3C4FB2C564F0 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
27C08EA6C421C7E89069DE6B /* libPods-Runner.a */, 331C80F3294D02FB00263BE5 /* RunnerTests.m */,
); );
name = Frameworks; path = RunnerTests;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
...@@ -97,9 +113,10 @@ ...@@ -97,9 +113,10 @@
children = ( children = (
9740EEB11CF90186004384FC /* Flutter */, 9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
331C80F2294D02FB00263BE5 /* RunnerTests */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
3510C167085BA3D3F8540F37 /* Pods */, B7024FD9E7130F00288DF469 /* Pods */,
8513A54653CE3C4FB2C564F0 /* Frameworks */, C05958523A4B26DE07C628DD /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
...@@ -107,6 +124,7 @@ ...@@ -107,6 +124,7 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
97C146EE1CF9000F007C117D /* Runner.app */, 97C146EE1CF9000F007C117D /* Runner.app */,
331C80F1294D02FB00263BE5 /* RunnerTests.xctest */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
...@@ -135,14 +153,56 @@ ...@@ -135,14 +153,56 @@
name = "Supporting Files"; name = "Supporting Files";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
B7024FD9E7130F00288DF469 /* Pods */ = {
isa = PBXGroup;
children = (
F071110615569824B74AF901 /* Pods-Runner.debug.xcconfig */,
3796AEEE99D23C2985F27594 /* Pods-Runner.release.xcconfig */,
517551098246B7C71A7D63D8 /* Pods-Runner.profile.xcconfig */,
1201E93D5A4AF06F8B2154F7 /* Pods-RunnerTests.debug.xcconfig */,
A9DDFA5760AD388C7AE67D68 /* Pods-RunnerTests.release.xcconfig */,
3CDE7FB3ADAC9EC781FA9BD4 /* Pods-RunnerTests.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
C05958523A4B26DE07C628DD /* Frameworks */ = {
isa = PBXGroup;
children = (
1F1790AB3CDE0ED1C0E115C2 /* libPods-Runner.a */,
61BB2832514DC5AC842E583C /* libPods-RunnerTests.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
331C80F0294D02FB00263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C80F7294D02FB00263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
A4A7D39886C9A1DA97227C83 /* [CP] Check Pods Manifest.lock */,
331C80ED294D02FB00263BE5 /* Sources */,
331C80EE294D02FB00263BE5 /* Frameworks */,
331C80EF294D02FB00263BE5 /* Resources */,
);
buildRules = (
);
dependencies = (
331C80F6294D02FB00263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C80F1294D02FB00263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = { 97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
E2E8F9B5C8F1E9545B8C092B /* [CP] Check Pods Manifest.lock */, 6284E94FC7A5514593210205 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
...@@ -166,15 +226,19 @@ ...@@ -166,15 +226,19 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1300; LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "The Chromium Authors"; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
331C80F0294D02FB00263BE5 = {
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1; CreatedOnToolsVersion = 7.3.1;
}; };
}; };
}; };
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 3.2"; compatibilityVersion = "Xcode 9.3";
developmentRegion = en; developmentRegion = en;
hasScannedForEncodings = 0; hasScannedForEncodings = 0;
knownRegions = ( knownRegions = (
...@@ -187,11 +251,19 @@ ...@@ -187,11 +251,19 @@
projectRoot = ""; projectRoot = "";
targets = ( targets = (
97C146ED1CF9000F007C117D /* Runner */, 97C146ED1CF9000F007C117D /* Runner */,
331C80F0294D02FB00263BE5 /* RunnerTests */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
331C80EF294D02FB00263BE5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = { 97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
...@@ -213,6 +285,7 @@ ...@@ -213,6 +285,7 @@
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
); );
name = "Thin Binary"; name = "Thin Binary";
outputPaths = ( outputPaths = (
...@@ -221,6 +294,28 @@ ...@@ -221,6 +294,28 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
}; };
6284E94FC7A5514593210205 /* [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 */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1; alwaysOutOfDate = 1;
...@@ -236,7 +331,7 @@ ...@@ -236,7 +331,7 @@
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
E2E8F9B5C8F1E9545B8C092B /* [CP] Check Pods Manifest.lock */ = { A4A7D39886C9A1DA97227C83 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
...@@ -251,7 +346,7 @@ ...@@ -251,7 +346,7 @@
outputFileListPaths = ( outputFileListPaths = (
); );
outputPaths = ( outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
...@@ -261,6 +356,14 @@ ...@@ -261,6 +356,14 @@
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */
331C80ED294D02FB00263BE5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C80F4294D02FB00263BE5 /* RunnerTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = { 97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
...@@ -273,6 +376,14 @@ ...@@ -273,6 +376,14 @@
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
331C80F6294D02FB00263BE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C80F5294D02FB00263BE5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */ /* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = { 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup; isa = PBXVariantGroup;
...@@ -316,7 +427,6 @@ ...@@ -316,7 +427,6 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
...@@ -335,7 +445,7 @@ ...@@ -335,7 +445,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
...@@ -350,23 +460,61 @@ ...@@ -350,23 +460,61 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 8JJXUFV6F7;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.jarvan.fluwxExample1; PRODUCT_BUNDLE_IDENTIFIER = com.jarvan.fluwxExample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
name = Profile; name = Profile;
}; };
331C80F8294D02FB00263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 1201E93D5A4AF06F8B2154F7 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.jarvan.fluwxExample.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C80F9294D02FB00263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = A9DDFA5760AD388C7AE67D68 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.jarvan.fluwxExample.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C80FA294D02FB00263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 3CDE7FB3ADAC9EC781FA9BD4 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.jarvan.fluwxExample.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = { 97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
...@@ -390,7 +538,6 @@ ...@@ -390,7 +538,6 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
...@@ -415,7 +562,7 @@ ...@@ -415,7 +562,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
...@@ -446,7 +593,6 @@ ...@@ -446,7 +593,6 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
...@@ -465,7 +611,7 @@ ...@@ -465,7 +611,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
...@@ -480,18 +626,14 @@ ...@@ -480,18 +626,14 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 8JJXUFV6F7;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.jarvan.fluwxExample1; PRODUCT_BUNDLE_IDENTIFIER = com.jarvan.fluwxExample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
...@@ -503,18 +645,14 @@ ...@@ -503,18 +645,14 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 8JJXUFV6F7;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "@executable_path/Frameworks",
); );
PRODUCT_BUNDLE_IDENTIFIER = com.jarvan.fluwxExample1; PRODUCT_BUNDLE_IDENTIFIER = com.jarvan.fluwxExample;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic"; VERSIONING_SYSTEM = "apple-generic";
}; };
...@@ -523,6 +661,16 @@ ...@@ -523,6 +661,16 @@
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
331C80F7294D02FB00263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
331C80F8294D02FB00263BE5 /* Debug */,
331C80F9294D02FB00263BE5 /* Release */,
331C80FA294D02FB00263BE5 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
......
...@@ -37,6 +37,17 @@ ...@@ -37,6 +37,17 @@
</BuildableReference> </BuildableReference>
</MacroExpansion> </MacroExpansion>
<Testables> <Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C80F0294D02FB00263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables> </Testables>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
<dict> <dict>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Fluwx</string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string> <string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key> <key>CFBundleIdentifier</key>
...@@ -18,22 +20,8 @@ ...@@ -18,22 +20,8 @@
<string>$(FLUTTER_BUILD_NAME)</string> <string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>wxd930ea5d5a258f4f</string>
</dict>
</array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string> <string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>weixin</string>
<string>weixinULAPI</string>
</array>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
......
...@@ -26,6 +26,8 @@ class MyApp extends StatefulWidget { ...@@ -26,6 +26,8 @@ class MyApp extends StatefulWidget {
} }
class _MyAppState extends State<MyApp> { class _MyAppState extends State<MyApp> {
Fluwx fluwx = Fluwx();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
...@@ -33,14 +35,14 @@ class _MyAppState extends State<MyApp> { ...@@ -33,14 +35,14 @@ class _MyAppState extends State<MyApp> {
} }
_initFluwx() async { _initFluwx() async {
await registerWxApi( await fluwx.registerWxApi(
appId: 'wxd930ea5d5a258f4f', appId: 'wxd930ea5d5a258f4f',
doOnAndroid: true, doOnAndroid: true,
doOnIOS: true, doOnIOS: true,
universalLink: 'https://your.univerallink.com/link/', universalLink: 'https://your.univerallink.com/link/',
); );
var result = await isWeChatInstalled; var result = await fluwx.isWeChatInstalled;
print('is installed $result'); debugPrint('is installed $result');
} }
// Platform messages are asynchronous, so we initialize in an async method. // Platform messages are asynchronous, so we initialize in an async method.
...@@ -51,20 +53,20 @@ class _MyAppState extends State<MyApp> { ...@@ -51,20 +53,20 @@ class _MyAppState extends State<MyApp> {
return MaterialApp( return MaterialApp(
routes: <String, WidgetBuilder>{ routes: <String, WidgetBuilder>{
'shareText': (context) => ShareTextPage(), 'shareText': (context) => ShareTextPage(),
'shareImage': (context) => ShareImagePage(), 'shareImage': (context) => const ShareImagePage(),
'shareWebPage': (context) => ShareWebPagePage(), 'shareWebPage': (context) => const ShareWebPagePage(),
'shareMusic': (context) => ShareMusicPage(), 'shareMusic': (context) => const ShareMusicPage(),
'shareVideo': (context) => ShareVideoPage(), 'shareVideo': (context) => const ShareVideoPage(),
'sendAuth': (context) => SendAuthPage(), 'sendAuth': (context) => const SendAuthPage(),
'shareMiniProgram': (context) => ShareMiniProgramPage(), 'shareMiniProgram': (context) => ShareMiniProgramPage(),
'pay': (context) => PayPage(), 'pay': (context) => const PayPage(),
'launchMiniProgram': (context) => LaunchMiniProgramPage(), 'launchMiniProgram': (context) => const LaunchMiniProgramPage(),
'subscribeMessage': (ctx) => SubscribeMessagePage(), 'subscribeMessage': (ctx) => const SubscribeMessagePage(),
'AuthByQRCode': (ctx) => AuthByQRCodePage(), 'AuthByQRCode': (ctx) => const AuthByQRCodePage(),
'AutoDeduct': (ctx) => SignAutoDeductPage(), 'AutoDeduct': (ctx) => const SignAutoDeductPage(),
}, },
home: Scaffold( home: Scaffold(
appBar: AppBar(title: const Text('Plugin example app')), appBar: AppBar(title: const Text('Fluwx sample')),
body: ShareSelectorPage(), body: ShareSelectorPage(),
), ),
); );
...@@ -72,6 +74,10 @@ class _MyAppState extends State<MyApp> { ...@@ -72,6 +74,10 @@ class _MyAppState extends State<MyApp> {
} }
class ShareSelectorPage extends StatelessWidget { class ShareSelectorPage extends StatelessWidget {
final Fluwx fluwx = Fluwx();
ShareSelectorPage({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Center( return Center(
...@@ -81,8 +87,8 @@ class ShareSelectorPage extends StatelessWidget { ...@@ -81,8 +87,8 @@ class ShareSelectorPage extends StatelessWidget {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: OutlinedButton( child: OutlinedButton(
onPressed: () async { onPressed: () async {
String? extMsg = await getExtMsg(); String? extMsg = await fluwx.getExtMsg();
print('extMsg:$extMsg\n'); debugPrint('extMsg:$extMsg\n');
}, },
child: const Text('Get ExtMessage'), child: const Text('Get ExtMessage'),
), ),
...@@ -91,8 +97,9 @@ class ShareSelectorPage extends StatelessWidget { ...@@ -91,8 +97,9 @@ class ShareSelectorPage extends StatelessWidget {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: OutlinedButton( child: OutlinedButton(
onPressed: () async { onPressed: () async {
bool? success = await startLog(logLevel: WXLogLevel.NORMAL); bool? success =
print('startLog:$success\n'); await fluwx.startLog(logLevel: WXLogLevel.normal);
debugPrint('startLog:$success\n');
}, },
child: const Text('start log'), child: const Text('start log'),
), ),
...@@ -101,8 +108,8 @@ class ShareSelectorPage extends StatelessWidget { ...@@ -101,8 +108,8 @@ class ShareSelectorPage extends StatelessWidget {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: OutlinedButton( child: OutlinedButton(
onPressed: () async { onPressed: () async {
dynamic success = await stopLog(); dynamic success = await fluwx.stopLog();
print('stopLog:$success\n'); debugPrint('stopLog:$success\n');
}, },
child: const Text('stop log'), child: const Text('stop log'),
), ),
...@@ -219,7 +226,7 @@ class ShareSelectorPage extends StatelessWidget { ...@@ -219,7 +226,7 @@ class ShareSelectorPage extends StatelessWidget {
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: OutlinedButton( child: OutlinedButton(
onPressed: () { onPressed: () {
openWeChatApp(); fluwx.openWeChatApp();
}, },
child: const Text('Open WeChat App'), child: const Text('Open WeChat App'),
), ),
......
...@@ -6,11 +6,11 @@ class AuthByQRCodePage extends StatefulWidget { ...@@ -6,11 +6,11 @@ class AuthByQRCodePage extends StatefulWidget {
const AuthByQRCodePage({Key? key}) : super(key: key); const AuthByQRCodePage({Key? key}) : super(key: key);
@override @override
_AuthByQRCodePageState createState() => _AuthByQRCodePageState(); State<AuthByQRCodePage> createState() => _AuthByQRCodePageState();
} }
class _AuthByQRCodePageState extends State<AuthByQRCodePage> { class _AuthByQRCodePageState extends State<AuthByQRCodePage> {
String _status = 'status'; final String _status = 'status';
Uint8List? _image; Uint8List? _image;
@override @override
......
...@@ -5,30 +5,35 @@ class LaunchMiniProgramPage extends StatefulWidget { ...@@ -5,30 +5,35 @@ class LaunchMiniProgramPage extends StatefulWidget {
const LaunchMiniProgramPage({Key? key}) : super(key: key); const LaunchMiniProgramPage({Key? key}) : super(key: key);
@override @override
_LaunchMiniProgramPageState createState() => _LaunchMiniProgramPageState(); State<LaunchMiniProgramPage> createState() => _LaunchMiniProgramPageState();
} }
class _LaunchMiniProgramPageState extends State<LaunchMiniProgramPage> { class _LaunchMiniProgramPageState extends State<LaunchMiniProgramPage> {
String? _result = '无'; String? _result = '无';
final Fluwx fluwx = Fluwx();
late Function(WeChatResponse) responseListener;
@override
void dispose() {
super.dispose();
_result = null;
fluwx.unsubscribeResponse(responseListener);
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
weChatResponseEventHandler.listen((res) { responseListener = (response) {
if (res is WeChatLaunchMiniProgramResponse) { if (response is WeChatLaunchMiniProgramResponse) {
if (mounted) { if (mounted) {
setState(() { setState(() {
_result = 'isSuccessful:${res.isSuccessful}'; _result = 'isSuccessful:${response.isSuccessful}';
}); });
} }
} }
}); };
}
@override fluwx.subscribeResponse(responseListener);
void dispose() {
super.dispose();
_result = null;
} }
@override @override
...@@ -41,7 +46,7 @@ class _LaunchMiniProgramPageState extends State<LaunchMiniProgramPage> { ...@@ -41,7 +46,7 @@ class _LaunchMiniProgramPageState extends State<LaunchMiniProgramPage> {
children: <Widget>[ children: <Widget>[
OutlinedButton( OutlinedButton(
onPressed: () { onPressed: () {
launchWeChatMiniProgram(username: 'gh_d43f693ca31f'); fluwx.launchMiniProgram(username: 'gh_d43f693ca31f');
}, },
child: const Text('Launch MiniProgrom'), child: const Text('Launch MiniProgrom'),
), ),
......
...@@ -2,34 +2,38 @@ import 'dart:convert'; ...@@ -2,34 +2,38 @@ import 'dart:convert';
import 'dart:io' as H; import 'dart:io' as H;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluwx/fluwx.dart' as fluwx; import 'package:fluwx/fluwx.dart';
class PayPage extends StatefulWidget { class PayPage extends StatefulWidget {
const PayPage({Key? key}) : super(key: key); const PayPage({Key? key}) : super(key: key);
@override @override
_PayPageState createState() => _PayPageState(); State<PayPage> createState() => _PayPageState();
} }
class _PayPageState extends State<PayPage> { class _PayPageState extends State<PayPage> {
String _url = 'https://wxpay.wxutil.com/pub_v2/app/app_pay.php'; final Fluwx fluwx = Fluwx();
final String _url = 'https://wxpay.wxutil.com/pub_v2/app/app_pay.php';
String _result = '无'; String _result = '无';
late Function(WeChatResponse) responseListener;
@override
void dispose() {
super.dispose();
fluwx.unsubscribeResponse(responseListener);
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
fluwx.weChatResponseEventHandler.listen((res) { responseListener = (response) {
if (res is fluwx.WeChatPaymentResponse) { if (response is WeChatPaymentResponse) {
setState(() { setState(() {
_result = 'pay :${res.isSuccessful}'; _result = 'pay :${response.isSuccessful}';
}); });
} }
}); };
// fluwx.responseFromPayment.listen((data) { fluwx.subscribeResponse(responseListener);
// setState(() {
// _result = '${data.errCode}';
// });
// });
} }
@override @override
...@@ -46,18 +50,18 @@ class _PayPageState extends State<PayPage> { ...@@ -46,18 +50,18 @@ class _PayPageState extends State<PayPage> {
}; };
var request = await h.getUrl(Uri.parse(_url)); var request = await h.getUrl(Uri.parse(_url));
var response = await request.close(); var response = await request.close();
var data = await Utf8Decoder().bind(response).join(); var data = await const Utf8Decoder().bind(response).join();
Map<String, dynamic> result = json.decode(data); Map<String, dynamic> result = json.decode(data);
print(result['appid']); debugPrint(result['appid']);
print(result['timestamp']); debugPrint(result['timestamp']);
fluwx fluwx
.payWithWeChat( .pay(
appId: result['appid'].toString(), appId: result['appid'].toString(),
partnerId: result['partnerid'].toString(), partnerId: result['partnerid'].toString(),
prepayId: result['prepayid'].toString(), prepayId: result['prepayid'].toString(),
packageValue: result['package'].toString(), packageValue: result['package'].toString(),
nonceStr: result['noncestr'].toString(), nonceStr: result['noncestr'].toString(),
timeStamp: result['timestamp'], timestamp: result['timestamp'],
sign: result['sign'].toString(), sign: result['sign'].toString(),
) )
.then((data) { .then((data) {
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluwx/fluwx.dart' as fluwx; import 'package:fluwx/fluwx.dart';
class SendAuthPage extends StatefulWidget { class SendAuthPage extends StatefulWidget {
const SendAuthPage({Key? key}) : super(key: key); const SendAuthPage({Key? key}) : super(key: key);
@override @override
_SendAuthPageState createState() => _SendAuthPageState(); State<SendAuthPage> createState() => _SendAuthPageState();
} }
class _SendAuthPageState extends State<SendAuthPage> { class _SendAuthPageState extends State<SendAuthPage> {
String? _result = '无'; String? _result = '无';
Fluwx fluwx = Fluwx();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
fluwx.weChatResponseEventHandler.distinct((a, b) => a == b).listen((res) { fluwx.subscribeResponse((response) {
if (res is fluwx.WeChatAuthResponse) { if (response is WeChatAuthResponse) {
setState(() { setState(() {
_result = 'state :${res.state} \n code:${res.code}'; _result = 'state :${response.state} \n code:${response.code}';
}); });
} }
}); });
...@@ -38,7 +39,7 @@ class _SendAuthPageState extends State<SendAuthPage> { ...@@ -38,7 +39,7 @@ class _SendAuthPageState extends State<SendAuthPage> {
OutlinedButton( OutlinedButton(
onPressed: () { onPressed: () {
fluwx fluwx
.sendWeChatAuth( .sendAuth(
scope: 'snsapi_userinfo', scope: 'snsapi_userinfo',
state: 'wechat_sdk_demo_test', state: 'wechat_sdk_demo_test',
) )
......
...@@ -5,20 +5,21 @@ class ShareImagePage extends StatefulWidget { ...@@ -5,20 +5,21 @@ class ShareImagePage extends StatefulWidget {
const ShareImagePage({Key? key}) : super(key: key); const ShareImagePage({Key? key}) : super(key: key);
@override @override
_ShareImagePageState createState() => _ShareImagePageState(); State<ShareImagePage> createState() => _ShareImagePageState();
} }
class _ShareImagePageState extends State<ShareImagePage> { class _ShareImagePageState extends State<ShareImagePage> {
WeChatScene scene = WeChatScene.SESSION; WeChatScene scene = WeChatScene.session;
String _response = ''; String _response = '';
WeChatImage? source; WeChatImage? source;
WeChatImage? thumbnail; WeChatImage? thumbnail;
Fluwx fluwx = Fluwx();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
weChatResponseEventHandler.listen((res) { fluwx.subscribeResponse((res) {
if (res is WeChatShareResponse) { if (res is WeChatShareResponse) {
setState(() { setState(() {
_response = 'state :${res.isSuccessful}'; _response = 'state :${res.isSuccessful}';
...@@ -34,7 +35,7 @@ class _ShareImagePageState extends State<ShareImagePage> { ...@@ -34,7 +35,7 @@ class _ShareImagePageState extends State<ShareImagePage> {
title: const Text('shareImage'), title: const Text('shareImage'),
actions: <Widget>[ actions: <Widget>[
IconButton( IconButton(
icon: Icon(Icons.share, color: Colors.white), icon: const Icon(Icons.share, color: Colors.white),
onPressed: _shareImage, onPressed: _shareImage,
), ),
], ],
...@@ -44,7 +45,7 @@ class _ShareImagePageState extends State<ShareImagePage> { ...@@ -44,7 +45,7 @@ class _ShareImagePageState extends State<ShareImagePage> {
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
TextField( TextField(
decoration: InputDecoration(labelText: '图片地址(仅限网络)'), decoration: const InputDecoration(labelText: '图片地址(仅限网络)'),
controller: TextEditingController( controller: TextEditingController(
text: 'https://timgsa.baidu.com/timg' text: 'https://timgsa.baidu.com/timg'
'?image' '?image'
...@@ -73,7 +74,7 @@ class _ShareImagePageState extends State<ShareImagePage> { ...@@ -73,7 +74,7 @@ class _ShareImagePageState extends State<ShareImagePage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.SESSION, value: WeChatScene.session,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -85,7 +86,7 @@ class _ShareImagePageState extends State<ShareImagePage> { ...@@ -85,7 +86,7 @@ class _ShareImagePageState extends State<ShareImagePage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.TIMELINE, value: WeChatScene.timeline,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -97,7 +98,7 @@ class _ShareImagePageState extends State<ShareImagePage> { ...@@ -97,7 +98,7 @@ class _ShareImagePageState extends State<ShareImagePage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.FAVORITE, value: WeChatScene.favorite,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -116,7 +117,7 @@ class _ShareImagePageState extends State<ShareImagePage> { ...@@ -116,7 +117,7 @@ class _ShareImagePageState extends State<ShareImagePage> {
} }
void _shareImage() { void _shareImage() {
shareToWeChat(WeChatShareImageModel(source!, thumbnail: thumbnail)); fluwx.share(WeChatShareImageModel(source!, thumbnail: thumbnail));
} }
void handleRadioValueChanged(WeChatScene scene) { void handleRadioValueChanged(WeChatScene scene) {
......
...@@ -2,12 +2,14 @@ import 'package:flutter/material.dart'; ...@@ -2,12 +2,14 @@ import 'package:flutter/material.dart';
import 'package:fluwx/fluwx.dart'; import 'package:fluwx/fluwx.dart';
class ShareMiniProgramPage extends StatefulWidget { class ShareMiniProgramPage extends StatefulWidget {
const ShareMiniProgramPage({Key? key}) : super(key: key);
@override @override
_ShareMiniProgramPageState createState() => _ShareMiniProgramPageState(); State<ShareMiniProgramPage> createState() => _ShareMiniProgramPageState();
} }
class _ShareMiniProgramPageState extends State<ShareMiniProgramPage> { class _ShareMiniProgramPageState extends State<ShareMiniProgramPage> {
WeChatScene scene = WeChatScene.SESSION; WeChatScene scene = WeChatScene.session;
String _webPageUrl = 'http://www.qq.com'; String _webPageUrl = 'http://www.qq.com';
String _thumbnail = 'https://timgsa.baidu.com/timg' String _thumbnail = 'https://timgsa.baidu.com/timg'
'?image' '?image'
...@@ -22,6 +24,8 @@ class _ShareMiniProgramPageState extends State<ShareMiniProgramPage> { ...@@ -22,6 +24,8 @@ class _ShareMiniProgramPageState extends State<ShareMiniProgramPage> {
String _path = '/pages/media'; String _path = '/pages/media';
String _description = 'Fluwx'; String _description = 'Fluwx';
Fluwx fluwx = Fluwx();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
...@@ -29,7 +33,7 @@ class _ShareMiniProgramPageState extends State<ShareMiniProgramPage> { ...@@ -29,7 +33,7 @@ class _ShareMiniProgramPageState extends State<ShareMiniProgramPage> {
title: const Text('ShareMiniProgram'), title: const Text('ShareMiniProgram'),
actions: <Widget>[ actions: <Widget>[
IconButton( IconButton(
icon: Icon(Icons.share, color: Colors.white), icon: const Icon(Icons.share, color: Colors.white),
onPressed: _share, onPressed: _share,
), ),
], ],
...@@ -95,6 +99,6 @@ class _ShareMiniProgramPageState extends State<ShareMiniProgramPage> { ...@@ -95,6 +99,6 @@ class _ShareMiniProgramPageState extends State<ShareMiniProgramPage> {
description: _description, description: _description,
thumbnail: WeChatImage.network(_thumbnail), thumbnail: WeChatImage.network(_thumbnail),
); );
shareToWeChat(model); fluwx.share(model);
} }
} }
...@@ -5,7 +5,7 @@ class ShareMusicPage extends StatefulWidget { ...@@ -5,7 +5,7 @@ class ShareMusicPage extends StatefulWidget {
const ShareMusicPage({Key? key}) : super(key: key); const ShareMusicPage({Key? key}) : super(key: key);
@override @override
_ShareMusicPageState createState() => _ShareMusicPageState(); State<ShareMusicPage> createState() => _ShareMusicPageState();
} }
class _ShareMusicPageState extends State<ShareMusicPage> { class _ShareMusicPageState extends State<ShareMusicPage> {
...@@ -15,7 +15,8 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -15,7 +15,8 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
String _title = 'Beyond'; String _title = 'Beyond';
String _description = 'A Popular Rock Band From China'; String _description = 'A Popular Rock Band From China';
String _thumnail = 'images/logo.png'; String _thumnail = 'images/logo.png';
WeChatScene scene = WeChatScene.SESSION; WeChatScene scene = WeChatScene.session;
Fluwx _fluwx = Fluwx();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -24,7 +25,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -24,7 +25,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
title: const Text('ShareMusicPage'), title: const Text('ShareMusicPage'),
actions: <Widget>[ actions: <Widget>[
IconButton( IconButton(
icon: Icon(Icons.share, color: Colors.white), icon: const Icon(Icons.share, color: Colors.white),
onPressed: _share, onPressed: _share,
), ),
], ],
...@@ -41,21 +42,22 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -41,21 +42,22 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
onChanged: (str) { onChanged: (str) {
_musicUrl = str; _musicUrl = str;
}, },
decoration: InputDecoration(labelText: 'music url'), decoration: const InputDecoration(labelText: 'music url'),
), ),
TextField( TextField(
controller: TextEditingController(text: 'http://www.qq.com'), controller: TextEditingController(text: 'http://www.qq.com'),
onChanged: (str) { onChanged: (str) {
_musicLowBandUrl = str; _musicLowBandUrl = str;
}, },
decoration: InputDecoration(labelText: 'music low band url'), decoration:
const InputDecoration(labelText: 'music low band url'),
), ),
TextField( TextField(
controller: TextEditingController(text: 'Beyond'), controller: TextEditingController(text: 'Beyond'),
onChanged: (str) { onChanged: (str) {
_title = str; _title = str;
}, },
decoration: InputDecoration(labelText: 'title'), decoration: const InputDecoration(labelText: 'title'),
), ),
TextField( TextField(
controller: TextEditingController( controller: TextEditingController(
...@@ -64,14 +66,14 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -64,14 +66,14 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
onChanged: (str) { onChanged: (str) {
_description = str; _description = str;
}, },
decoration: InputDecoration(labelText: 'description'), decoration: const InputDecoration(labelText: 'description'),
), ),
TextField( TextField(
controller: TextEditingController(text: 'images/logo.png'), controller: TextEditingController(text: 'images/logo.png'),
onChanged: (str) { onChanged: (str) {
_thumnail = str; _thumnail = str;
}, },
decoration: InputDecoration(labelText: 'thumbnail'), decoration: const InputDecoration(labelText: 'thumbnail'),
), ),
Row( Row(
children: <Widget>[ children: <Widget>[
...@@ -79,7 +81,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -79,7 +81,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.SESSION, value: WeChatScene.session,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -91,7 +93,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -91,7 +93,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.TIMELINE, value: WeChatScene.timeline,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -103,7 +105,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -103,7 +105,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.FAVORITE, value: WeChatScene.favorite,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -130,7 +132,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> { ...@@ -130,7 +132,7 @@ class _ShareMusicPageState extends State<ShareMusicPage> {
thumbnail: WeChatImage.network(_thumnail), thumbnail: WeChatImage.network(_thumnail),
); );
shareToWeChat(model); _fluwx.share(model);
} }
void handleRadioValueChanged(WeChatScene scene) { void handleRadioValueChanged(WeChatScene scene) {
......
...@@ -2,13 +2,16 @@ import 'package:flutter/material.dart'; ...@@ -2,13 +2,16 @@ import 'package:flutter/material.dart';
import 'package:fluwx/fluwx.dart'; import 'package:fluwx/fluwx.dart';
class ShareTextPage extends StatefulWidget { class ShareTextPage extends StatefulWidget {
const ShareTextPage({Key? key}) : super(key: key);
@override @override
_ShareTextPageState createState() => _ShareTextPageState(); State<ShareTextPage> createState() => _ShareTextPageState();
} }
class _ShareTextPageState extends State<ShareTextPage> { class _ShareTextPageState extends State<ShareTextPage> {
String _text = 'share text from fluwx'; String _text = 'share text from fluwx';
WeChatScene scene = WeChatScene.SESSION; WeChatScene scene = WeChatScene.session;
Fluwx fluwx = Fluwx();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -31,7 +34,7 @@ class _ShareTextPageState extends State<ShareTextPage> { ...@@ -31,7 +34,7 @@ class _ShareTextPageState extends State<ShareTextPage> {
onChanged: (str) { onChanged: (str) {
_text = str; _text = str;
}, },
decoration: InputDecoration(labelText: 'TextToShare'), decoration: const InputDecoration(labelText: 'TextToShare'),
), ),
Row( Row(
children: <Widget>[ children: <Widget>[
...@@ -39,7 +42,7 @@ class _ShareTextPageState extends State<ShareTextPage> { ...@@ -39,7 +42,7 @@ class _ShareTextPageState extends State<ShareTextPage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.SESSION, value: WeChatScene.session,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -51,7 +54,7 @@ class _ShareTextPageState extends State<ShareTextPage> { ...@@ -51,7 +54,7 @@ class _ShareTextPageState extends State<ShareTextPage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.TIMELINE, value: WeChatScene.timeline,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -63,7 +66,7 @@ class _ShareTextPageState extends State<ShareTextPage> { ...@@ -63,7 +66,7 @@ class _ShareTextPageState extends State<ShareTextPage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.FAVORITE, value: WeChatScene.favorite,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -81,9 +84,7 @@ class _ShareTextPageState extends State<ShareTextPage> { ...@@ -81,9 +84,7 @@ class _ShareTextPageState extends State<ShareTextPage> {
} }
void _shareText() { void _shareText() {
shareToWeChat(WeChatShareTextModel(_text, scene: scene)).then((data) { fluwx.share(WeChatShareTextModel(_text, scene: scene));
print('-->$data');
});
} }
void handleRadioValueChanged(WeChatScene scene) { void handleRadioValueChanged(WeChatScene scene) {
......
...@@ -5,16 +5,18 @@ class ShareVideoPage extends StatefulWidget { ...@@ -5,16 +5,18 @@ class ShareVideoPage extends StatefulWidget {
const ShareVideoPage({Key? key}) : super(key: key); const ShareVideoPage({Key? key}) : super(key: key);
@override @override
_ShareMusicPageState createState() => _ShareMusicPageState(); State<ShareVideoPage> createState() => _ShareVideoPageState();
} }
class _ShareMusicPageState extends State<ShareVideoPage> { class _ShareVideoPageState extends State<ShareVideoPage> {
String _videoUrl = 'http://www.qq.com'; String _videoUrl = 'http://www.qq.com';
String _videoLowBandUrl = 'http://www.qq.com'; String _videoLowBandUrl = 'http://www.qq.com';
String _title = 'Beyond'; String _title = 'Beyond';
String _description = 'A Popular Rock Band From China'; String _description = 'A Popular Rock Band From China';
String _thumnail = 'images/logo.png'; String _thumnail = 'images/logo.png';
WeChatScene scene = WeChatScene.SESSION; WeChatScene scene = WeChatScene.session;
Fluwx fluwx = Fluwx();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -23,7 +25,7 @@ class _ShareMusicPageState extends State<ShareVideoPage> { ...@@ -23,7 +25,7 @@ class _ShareMusicPageState extends State<ShareVideoPage> {
title: const Text('ShareVideoPage'), title: const Text('ShareVideoPage'),
actions: <Widget>[ actions: <Widget>[
IconButton( IconButton(
icon: Icon(Icons.share, color: Colors.white), icon: const Icon(Icons.share, color: Colors.white),
onPressed: _share, onPressed: _share,
), ),
], ],
...@@ -40,21 +42,22 @@ class _ShareMusicPageState extends State<ShareVideoPage> { ...@@ -40,21 +42,22 @@ class _ShareMusicPageState extends State<ShareVideoPage> {
onChanged: (str) { onChanged: (str) {
_videoUrl = str; _videoUrl = str;
}, },
decoration: InputDecoration(labelText: 'video url'), decoration: const InputDecoration(labelText: 'video url'),
), ),
TextField( TextField(
controller: TextEditingController(text: 'http://www.qq.com'), controller: TextEditingController(text: 'http://www.qq.com'),
onChanged: (str) { onChanged: (str) {
_videoLowBandUrl = str; _videoLowBandUrl = str;
}, },
decoration: InputDecoration(labelText: 'video low band url'), decoration:
const InputDecoration(labelText: 'video low band url'),
), ),
TextField( TextField(
controller: TextEditingController(text: 'Beyond'), controller: TextEditingController(text: 'Beyond'),
onChanged: (str) { onChanged: (str) {
_title = str; _title = str;
}, },
decoration: InputDecoration(labelText: 'title'), decoration: const InputDecoration(labelText: 'title'),
), ),
TextField( TextField(
controller: controller:
...@@ -62,14 +65,14 @@ class _ShareMusicPageState extends State<ShareVideoPage> { ...@@ -62,14 +65,14 @@ class _ShareMusicPageState extends State<ShareVideoPage> {
onChanged: (str) { onChanged: (str) {
_description = str; _description = str;
}, },
decoration: InputDecoration(labelText: 'description'), decoration: const InputDecoration(labelText: 'description'),
), ),
TextField( TextField(
controller: TextEditingController(text: 'images/logo.png'), controller: TextEditingController(text: 'images/logo.png'),
onChanged: (str) { onChanged: (str) {
_thumnail = str; _thumnail = str;
}, },
decoration: InputDecoration(labelText: 'thumbnail'), decoration: const InputDecoration(labelText: 'thumbnail'),
), ),
Row( Row(
children: <Widget>[ children: <Widget>[
...@@ -77,7 +80,7 @@ class _ShareMusicPageState extends State<ShareVideoPage> { ...@@ -77,7 +80,7 @@ class _ShareMusicPageState extends State<ShareVideoPage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.SESSION, value: WeChatScene.session,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -89,7 +92,7 @@ class _ShareMusicPageState extends State<ShareVideoPage> { ...@@ -89,7 +92,7 @@ class _ShareMusicPageState extends State<ShareVideoPage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.TIMELINE, value: WeChatScene.timeline,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -101,7 +104,7 @@ class _ShareMusicPageState extends State<ShareVideoPage> { ...@@ -101,7 +104,7 @@ class _ShareMusicPageState extends State<ShareVideoPage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.FAVORITE, value: WeChatScene.favorite,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -124,10 +127,10 @@ class _ShareMusicPageState extends State<ShareVideoPage> { ...@@ -124,10 +127,10 @@ class _ShareMusicPageState extends State<ShareVideoPage> {
videoLowBandUrl: _videoLowBandUrl, videoLowBandUrl: _videoLowBandUrl,
thumbnail: WeChatImage.network(_thumnail), thumbnail: WeChatImage.network(_thumnail),
description: _description, description: _description,
scene: this.scene, scene: scene,
title: _title, title: _title,
); );
shareToWeChat(model); fluwx.share(model);
} }
void handleRadioValueChanged(WeChatScene scene) { void handleRadioValueChanged(WeChatScene scene) {
......
...@@ -12,7 +12,9 @@ class ShareWebPagePageState extends State<ShareWebPagePage> { ...@@ -12,7 +12,9 @@ class ShareWebPagePageState extends State<ShareWebPagePage> {
String _url = 'share text from fluwx'; String _url = 'share text from fluwx';
String _title = 'Fluwx'; String _title = 'Fluwx';
String _thumnail = 'images/logo.png'; String _thumnail = 'images/logo.png';
WeChatScene scene = WeChatScene.SESSION; WeChatScene scene = WeChatScene.session;
Fluwx fluwx = Fluwx();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
...@@ -21,7 +23,7 @@ class ShareWebPagePageState extends State<ShareWebPagePage> { ...@@ -21,7 +23,7 @@ class ShareWebPagePageState extends State<ShareWebPagePage> {
title: const Text('ShareWebPage'), title: const Text('ShareWebPage'),
actions: <Widget>[ actions: <Widget>[
IconButton( IconButton(
icon: Icon(Icons.share, color: Colors.white), icon: const Icon(Icons.share, color: Colors.white),
onPressed: _share, onPressed: _share,
), ),
], ],
...@@ -37,21 +39,21 @@ class ShareWebPagePageState extends State<ShareWebPagePage> { ...@@ -37,21 +39,21 @@ class ShareWebPagePageState extends State<ShareWebPagePage> {
onChanged: (str) { onChanged: (str) {
_url = str; _url = str;
}, },
decoration: InputDecoration(labelText: 'web page'), decoration: const InputDecoration(labelText: 'web page'),
), ),
TextField( TextField(
controller: TextEditingController(text: 'Fluwx'), controller: TextEditingController(text: 'Fluwx'),
onChanged: (str) { onChanged: (str) {
_title = str; _title = str;
}, },
decoration: InputDecoration(labelText: 'thumbnail'), decoration: const InputDecoration(labelText: 'thumbnail'),
), ),
TextField( TextField(
controller: TextEditingController(text: 'images/logo.png'), controller: TextEditingController(text: 'images/logo.png'),
onChanged: (str) { onChanged: (str) {
_thumnail = str; _thumnail = str;
}, },
decoration: InputDecoration(labelText: 'thumbnail'), decoration: const InputDecoration(labelText: 'thumbnail'),
), ),
Row( Row(
children: <Widget>[ children: <Widget>[
...@@ -59,7 +61,7 @@ class ShareWebPagePageState extends State<ShareWebPagePage> { ...@@ -59,7 +61,7 @@ class ShareWebPagePageState extends State<ShareWebPagePage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.SESSION, value: WeChatScene.session,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -71,7 +73,7 @@ class ShareWebPagePageState extends State<ShareWebPagePage> { ...@@ -71,7 +73,7 @@ class ShareWebPagePageState extends State<ShareWebPagePage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.TIMELINE, value: WeChatScene.timeline,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -83,7 +85,7 @@ class ShareWebPagePageState extends State<ShareWebPagePage> { ...@@ -83,7 +85,7 @@ class ShareWebPagePageState extends State<ShareWebPagePage> {
Row( Row(
children: <Widget>[ children: <Widget>[
Radio<WeChatScene>( Radio<WeChatScene>(
value: WeChatScene.FAVORITE, value: WeChatScene.favorite,
groupValue: scene, groupValue: scene,
onChanged: (v) { onChanged: (v) {
if (v != null) handleRadioValueChanged(v); if (v != null) handleRadioValueChanged(v);
...@@ -107,7 +109,7 @@ class ShareWebPagePageState extends State<ShareWebPagePage> { ...@@ -107,7 +109,7 @@ class ShareWebPagePageState extends State<ShareWebPagePage> {
thumbnail: WeChatImage.network(_thumnail), thumbnail: WeChatImage.network(_thumnail),
scene: scene, scene: scene,
); );
shareToWeChat(model); fluwx.share(model);
} }
void handleRadioValueChanged(WeChatScene scene) { void handleRadioValueChanged(WeChatScene scene) {
......
...@@ -6,10 +6,9 @@ class SignAutoDeductPage extends StatefulWidget { ...@@ -6,10 +6,9 @@ class SignAutoDeductPage extends StatefulWidget {
const SignAutoDeductPage({Key? key}) : super(key: key); const SignAutoDeductPage({Key? key}) : super(key: key);
@override @override
_SignAutoDeductPageState createState() => _SignAutoDeductPageState(); State<SignAutoDeductPage> createState() => _SignAutoDeductPageState();
} }
/// see wechat [document](https://pay.weixin.qq.com/wiki/doc/api/pap.php?chapter=18_5&index=2)
class _SignAutoDeductPageState extends State<SignAutoDeductPage> { class _SignAutoDeductPageState extends State<SignAutoDeductPage> {
TextEditingController appId = TextEditingController appId =
TextEditingController(text: 'wx316f9c82e99ac105'); TextEditingController(text: 'wx316f9c82e99ac105');
...@@ -25,10 +24,12 @@ class _SignAutoDeductPageState extends State<SignAutoDeductPage> { ...@@ -25,10 +24,12 @@ class _SignAutoDeductPageState extends State<SignAutoDeductPage> {
TextEditingController timestamp = TextEditingController(text: ''); TextEditingController timestamp = TextEditingController(text: '');
TextEditingController returnApp = TextEditingController(text: '3'); TextEditingController returnApp = TextEditingController(text: '3');
Fluwx fluwx = Fluwx();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
weChatResponseEventHandler.listen((resp) { fluwx.subscribeResponse((resp) {
print('resp = ${resp.isSuccessful}'); print('resp = ${resp.isSuccessful}');
}); });
} }
...@@ -54,61 +55,59 @@ class _SignAutoDeductPageState extends State<SignAutoDeductPage> { ...@@ -54,61 +55,59 @@ class _SignAutoDeductPageState extends State<SignAutoDeductPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text('SubscribeMessagePage'), title: const Text('SubscribeMessagePage'),
), ),
body: Container( body: ListView(
child: ListView( children: <Widget>[
children: <Widget>[ _buildTextField(
_buildTextField( title: 'appId',
title: 'appId', textEditController: appId,
textEditController: appId, ),
), _buildTextField(
_buildTextField( title: 'mchId',
title: 'mchId', textEditController: mchId,
textEditController: mchId, ),
), _buildTextField(
_buildTextField( title: 'planId',
title: 'planId', textEditController: planId,
textEditController: planId, ),
), _buildTextField(
_buildTextField( title: 'contractCode',
title: 'contractCode', textEditController: contractCode,
textEditController: contractCode, ),
), _buildTextField(
_buildTextField( title: 'requestSerial',
title: 'requestSerial', textEditController: requestSerial,
textEditController: requestSerial, ),
), _buildTextField(
_buildTextField( title: 'contractDisplayAccount',
title: 'contractDisplayAccount', textEditController: contractDisplayAccount,
textEditController: contractDisplayAccount, ),
), _buildTextField(
_buildTextField( title: 'notifyUrl',
title: 'notifyUrl', textEditController: notifyUrl,
textEditController: notifyUrl, ),
), _buildTextField(
_buildTextField( title: 'version',
title: 'version', textEditController: version,
textEditController: version, ),
), _buildTextField(
_buildTextField( title: 'sign',
title: 'sign', textEditController: sign,
textEditController: sign, ),
), _buildTextField(
_buildTextField( title: 'timestamp',
title: 'timestamp', textEditController: timestamp,
textEditController: timestamp, ),
), _buildTextField(
_buildTextField( title: 'returnApp',
title: 'returnApp', textEditController: returnApp,
textEditController: returnApp, ),
), CupertinoButton(
CupertinoButton( child: Text('request once sign auto-deduct message'),
child: Text('request once sign auto-deduct message'), onPressed: _signAutoDeduct,
onPressed: _signAutoDeduct, ),
), ],
],
),
), ),
); );
} }
...@@ -124,7 +123,7 @@ class _SignAutoDeductPageState extends State<SignAutoDeductPage> { ...@@ -124,7 +123,7 @@ class _SignAutoDeductPageState extends State<SignAutoDeductPage> {
} }
void _signAutoDeduct() { void _signAutoDeduct() {
autoDeDuctWeChat( fluwx.autoDeDuct(
appId: appId.text, appId: appId.text,
mchId: mchId.text, mchId: mchId.text,
planId: planId.text, planId: planId.text,
......
...@@ -5,7 +5,7 @@ class SubscribeMessagePage extends StatefulWidget { ...@@ -5,7 +5,7 @@ class SubscribeMessagePage extends StatefulWidget {
const SubscribeMessagePage({Key? key}) : super(key: key); const SubscribeMessagePage({Key? key}) : super(key: key);
@override @override
_SubscribeMessagePageState createState() => _SubscribeMessagePageState(); State<SubscribeMessagePage> createState() => _SubscribeMessagePageState();
} }
/// see wechat [document](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1500434436_aWfqW&token=&lang=zh_CN) /// see wechat [document](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1500434436_aWfqW&token=&lang=zh_CN)
...@@ -16,12 +16,13 @@ class _SubscribeMessagePageState extends State<SubscribeMessagePage> { ...@@ -16,12 +16,13 @@ class _SubscribeMessagePageState extends State<SubscribeMessagePage> {
TextEditingController templateId = TextEditingController( TextEditingController templateId = TextEditingController(
text: 'cm_vM2k3IjHcYbkGUeAfL6Fja_7Pgv4Hx_q4tA253Ss'); text: 'cm_vM2k3IjHcYbkGUeAfL6Fja_7Pgv4Hx_q4tA253Ss');
TextEditingController reserved = TextEditingController(text: '123'); TextEditingController reserved = TextEditingController(text: '123');
Fluwx fluwx = Fluwx();
@override @override
void initState() { void initState() {
super.initState(); super.initState();
weChatResponseEventHandler.listen((resp) { fluwx.subscribeResponse((resp) {
print('resp = $resp'); debugPrint('resp = $resp');
}); });
} }
...@@ -80,7 +81,7 @@ class _SubscribeMessagePageState extends State<SubscribeMessagePage> { ...@@ -80,7 +81,7 @@ class _SubscribeMessagePageState extends State<SubscribeMessagePage> {
} }
void _requestSubMsg() { void _requestSubMsg() {
subscribeWeChatMsg( fluwx.subscribeMsg(
appId: appId.text, appId: appId.text,
scene: int.tryParse(scene.text) ?? 1, scene: int.tryParse(scene.text) ?? 1,
templateId: templateId.text, templateId: templateId.text,
......
name: fluwx_example name: fluwx_example
description: Demonstrates how to use the fluwx plugin. description: Demonstrates how to use the fluwx plugin.
publish_to: 'none' # The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment: environment:
sdk: ">=2.12.4 <3.0.0" sdk: '>=3.1.0-26.0.dev <4.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
characters: ^1.2.0
fluwx:
# When depending on this package from a real application you should use:
# fluwx: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.1+1 cupertino_icons: ^1.0.2
dev_dependencies: dev_dependencies:
integration_test:
sdk: flutter
flutter_test: flutter_test:
sdk: flutter sdk: flutter
fluwx: # The "flutter_lints" package below contains a set of recommended lints to
path: ../ # encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter. # The following section is specific to Flutter packages.
flutter: flutter:
# The following line ensures that the Material Icons font is # The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in # included with your application, so that you can use the icons in
# the material Icons class. # the material Icons class.
uses-material-design: true uses-material-design: true
assets:
- images/logo.png
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
# assets: assets:
# - images/a_dot_burr.jpeg - images/logo.png
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware. # https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see # For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages # https://flutter.dev/assets-and-images/#from-packages
......
// This is a basic Flutter widget test. // This is a basic Flutter widget test.
// //
// To perform an interaction with a widget in your test, use the WidgetTester // 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 // utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget // 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. // 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_test/flutter_test.dart';
import 'package:fluwx_example/main.dart'; import 'package:fluwx_example/main.dart';
...@@ -12,15 +13,15 @@ import 'package:fluwx_example/main.dart'; ...@@ -12,15 +13,15 @@ import 'package:fluwx_example/main.dart';
void main() { void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async { testWidgets('Verify Platform version', (WidgetTester tester) async {
// Build our app and trigger a frame. // Build our app and trigger a frame.
await tester.pumpWidget(MyApp()); await tester.pumpWidget(const MyApp());
// Verify that platform version is retrieved. // Verify that platform version is retrieved.
// expect( expect(
// find.byWidgetPredicate( find.byWidgetPredicate(
// (Widget widget) => widget is Text && (Widget widget) => widget is Text &&
// widget.data.startsWith('Running on:'), widget.data!.startsWith('Running on:'),
// ), ),
// findsOneWidget, findsOneWidget,
// ); );
}); });
} }
...@@ -34,6 +34,5 @@ Icon? ...@@ -34,6 +34,5 @@ Icon?
.tags* .tags*
/Flutter/Generated.xcconfig /Flutter/Generated.xcconfig
/Flutter/flutter_export_environment.sh /Flutter/ephemeral/
/Flutter/flutter_export_environment.sh
.gradle \ No newline at end of file
\ No newline at end of file
# #
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint fluwx.podspec' to validate before publishing. # Run `pod lib lint fluwx.podspec` to validate before publishing.
# #
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'fluwx' s.name = 'fluwx'
s.version = '0.0.1' s.version = '0.0.1'
s.summary = 'A new Flutter plugin for Wechat SDK.' s.summary = 'The capability of implementing WeChat SDKs in Flutter. With Fluwx, developers can use WeChatSDK easily, such as sharing, payment, lanuch mini program and etc.'
s.description = <<-DESC s.description = <<-DESC
A new Flutter plugin for Wechat SDK. The capability of implementing WeChat SDKs in Flutter. With Fluwx, developers can use WeChatSDK easily, such as sharing, payment, lanuch mini program and etc.
DESC DESC
s.homepage = 'https://github.com/OpenFlutter/fluwx' s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' } s.license = { :file => '../LICENSE' }
s.author = { 'JarvanMo' => 'jarvan.mo@gmail.com' } s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' } s.source = { :path => '.' }
s.source_files = 'Classes/**/*' s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/public/*.h' s.public_header_files = 'Classes/**/*.h'
s.static_framework = true
s.dependency 'Flutter' s.dependency 'Flutter'
# s.dependency 'WechatOpenSDK', '1.8.7.1' s.platform = :ios, '12.0'
# s.dependency 'OpenWeChatSDK','~> 1.9.9'
s.dependency 'WechatOpenSDK-XCFramework','~> 2.0.2' s.dependency 'WechatOpenSDK-XCFramework','~> 2.0.2'
# s.xcconfig = { 'HEADER_SEARCH_PATHS' => "${PODS_ROOT}/Headers/Public/#{s.name}" }
s.frameworks = ["SystemConfiguration", "CoreTelephony","WebKit"]
s.libraries = ["z", "sqlite3.0", "c++"]
s.preserve_paths = 'Lib/*.a'
s.vendored_libraries = "**/*.a"
s.ios.deployment_target = '12.0'
# Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. # Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
end end
/*
* Copyright (c) 2023. OpenFlutter Project
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/// Fluwx is a powerful plugin for WeChatSDK. /// Fluwx is a powerful plugin for WeChatSDK.
/// easy to use. /// easy to use.
/// ///
/// A open sou;rce project authorized by [OpenFlutter](https://github.com/OpenFlutter). /// A open sou;rce project authorized by [OpenFlutter](https://github.com/OpenFlutter).
library fluwx; library fluwx;
export 'src/fluwx_iml.dart'; export 'src/fluwx.dart';
export 'src/response/wechat_response.dart'; export 'src/response/wechat_response.dart';
export 'src/share/share_models.dart'; export 'src/share/share_models.dart';
export 'src/wechat_enums.dart'; export 'src/wechat_enums.dart';
......
/*
* Copyright (c) 2023. OpenFlutter Project
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
import 'dart:async';
import 'method_channel/fluwx_platform_interface.dart';
import 'response/wechat_response.dart';
import 'share/share_models.dart';
import 'wechat_enums.dart';
class Fluwx {
final List<Function(WeChatResponse response)> _responseListeners = [];
Fluwx() {
FluwxPlatform.instance.responseEventHandler.listen((event) {
for (var listener in _responseListeners) {
listener(event);
}
});
}
Future<bool> get isWeChatInstalled =>
FluwxPlatform.instance.isWeChatInstalled;
Future<bool> openWeChatApp() async {
return FluwxPlatform.instance.openWeChatApp();
}
Future<bool> registerWxApi({
required String appId,
bool doOnIOS = true,
bool doOnAndroid = true,
String? universalLink,
}) async {
return FluwxPlatform.instance.registerWxApi(
appId: appId,
doOnAndroid: doOnAndroid,
doOnIOS: doOnIOS,
universalLink: universalLink);
}
Future<bool?> startLog({WXLogLevel logLevel = WXLogLevel.unspecific}) {
return FluwxPlatform.instance.startLog(logLevel: logLevel);
}
Future<bool?> stopLog() {
return FluwxPlatform.instance.stopLog();
}
Future<bool> share(WeChatShareModel what) async {
return FluwxPlatform.instance.share(what);
}
Future<bool> sendAuth(
{required String scope,
String state = 'state',
bool nonAutomatic = false}) async {
return FluwxPlatform.instance
.sendAuth(scope: scope, nonAutomatic: nonAutomatic);
}
Future<bool> subscribeMsg({
required String appId,
required int scene,
required String templateId,
String? reserved,
}) async {
return FluwxPlatform.instance.subscribeMsg(
appId: appId, scene: scene, templateId: templateId, reserved: reserved);
}
Future<bool> autoDeDuct({
required String appId,
required String mchId,
required String planId,
required String contractCode,
required String requestSerial,
required String contractDisplayAccount,
required String notifyUrl,
required String version,
required String sign,
required String timestamp,
String returnApp = '3',
int businessType = 12,
}) async {
return FluwxPlatform.instance.autoDeDuct(
appId: appId,
mchId: mchId,
planId: planId,
contractCode: contractCode,
requestSerial: requestSerial,
contractDisplayAccount: contractDisplayAccount,
notifyUrl: notifyUrl,
version: version,
sign: sign,
timestamp: timestamp,
returnApp: returnApp,
businessType: businessType);
}
Future<bool> autoDeductV2(
Map<String, String> queryInfo, {
int businessType = 12,
}) async {
return FluwxPlatform.instance.autoDeductV2(queryInfo, businessType: 12);
}
Future<bool> authByQRCode({
required String appId,
required String scope,
required String nonceStr,
required String timestamp,
required String signature,
String? schemeData,
}) async {
return FluwxPlatform.instance.authByQRCode(
appId: appId,
scope: scope,
nonceStr: nonceStr,
timestamp: timestamp,
signature: signature,
schemeData: schemeData);
}
/// IOS only
Future<bool> authByPhoneLogin({
required String scope,
String state = 'state',
}) async {
return FluwxPlatform.instance.authByPhoneLogin(scope: scope, state: state);
}
Future<bool> openCustomerServiceChat(
{required String url, required String corpId}) async {
return await FluwxPlatform.instance
.openCustomerServiceChat(url: url, corpId: corpId);
}
/// see * https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter6_2_1.shtml
Future<bool> openBusinessView(
{required String businessType, required String query}) async {
return await FluwxPlatform.instance
.openBusinessView(businessType: businessType, query: query);
}
Future<bool> checkSupportOpenBusinessView() async {
return await FluwxPlatform.instance.checkSupportOpenBusinessView();
}
Future<bool> openInvoice(
{required String appId,
required String cardType,
String locationId = "",
String cardId = "",
String canMultiSelect = "1"}) async {
return FluwxPlatform.instance.openInvoice(
appId: appId,
cardType: cardType,
locationId: locationId,
cardId: cardId,
canMultiSelect: canMultiSelect);
}
Future launchMiniProgram({
required String username,
String? path,
WXMiniProgramType miniProgramType = WXMiniProgramType.release,
}) async {
return FluwxPlatform.instance.launchMiniProgram(
username: username, path: path, miniProgramType: miniProgramType);
}
Future<String?> getExtMsg() async {
return FluwxPlatform.instance.getExtMsg();
}
Future<bool> pay({
required String appId,
required String partnerId,
required String prepayId,
required String packageValue,
required String nonceStr,
required int timestamp,
required String sign,
String? signType,
String? extData,
}) async {
return FluwxPlatform.instance.pay(
appId: appId,
partnerId: partnerId,
prepayId: prepayId,
packageValue: packageValue,
nonceStr: nonceStr,
timestamp: timestamp,
sign: sign,
signType: signType,
extData: extData);
}
Future<bool> payWithHongKongWallet({required String prepayId}) async {
return FluwxPlatform.instance.payWithHongKongWallet(prepayId: prepayId);
}
subscribeResponse(Function(WeChatResponse response) listener) {
_responseListeners.add(listener);
}
unsubscribeResponse(Function(WeChatResponse response) listener) {
_responseListeners.remove(listener);
}
}
/*
* Copyright (c) 2020. OpenFlutter Project
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:fluwx/fluwx.dart';
const Map<Type, String> _shareModelMethodMapper = {
WeChatShareTextModel: 'shareText',
WeChatShareImageModel: 'shareImage',
WeChatShareMusicModel: 'shareMusic',
WeChatShareVideoModel: 'shareVideo',
WeChatShareWebPageModel: 'shareWebPage',
WeChatShareMiniProgramModel: 'shareMiniProgram',
WeChatShareFileModel: 'shareFile',
};
MethodChannel _channel = MethodChannel('com.jarvanmo/fluwx')
..setMethodCallHandler(_methodHandler);
StreamController<BaseWeChatResponse> _weChatResponseEventHandlerController =
StreamController.broadcast();
/// Response answers from WeChat after sharing, payment etc.
Stream<BaseWeChatResponse> get weChatResponseEventHandler =>
_weChatResponseEventHandlerController.stream;
/// [true] if WeChat installed, otherwise [false].
/// Please add WeChat to the white list in order use this method on IOS.
Future<bool> get isWeChatInstalled async {
return await _channel.invokeMethod('isWeChatInstalled');
}
///just open WeChat, noting to do.
Future<bool> openWeChatApp() async {
return await _channel.invokeMethod('openWXApp');
}
/// It's ok if you register multi times.
/// [appId] is not necessary.
/// if [doOnIOS] is true ,fluwx will register WXApi on iOS.
/// if [doOnAndroid] is true, fluwx will register WXApi on Android.
/// [universalLink] is required if you want to register on iOS.
Future<bool> registerWxApi({
required String appId,
bool doOnIOS = true,
bool doOnAndroid = true,
String? universalLink,
}) async {
if (doOnIOS && Platform.isIOS) {
if (universalLink == null ||
universalLink.trim().isEmpty ||
!universalLink.startsWith('https')) {
throw ArgumentError.value(
universalLink,
"You're trying to use illegal universal link, see "
'https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html '
'for more detail',
);
}
}
return await _channel.invokeMethod('registerApp', {
'appId': appId,
'iOS': doOnIOS,
'android': doOnAndroid,
'universalLink': universalLink
});
}
// Get ext Message
Future<String?> getExtMsg() {
return _channel.invokeMethod('getExtMsg');
}
/// start Log
/// defalult [WXLogLevel.DETAIL]
Future<bool?> startLog({WXLogLevel logLevel = WXLogLevel.DETAIL}) async {
return await _channel
.invokeMethod('startLog', {'logLevel': logLevel.toNativeInt()});
}
/// stop log
Future<bool?> stopLog() async {
return await _channel.invokeMethod('stopLog');
}
/// Share your requests to WeChat.
/// This depends on the actual type of [model].
/// see [_shareModelMethodMapper] for detail.
Future<bool> shareToWeChat(WeChatShareBaseModel model) async {
if (_shareModelMethodMapper.containsKey(model.runtimeType)) {
final methodChannel = _shareModelMethodMapper[model.runtimeType];
if (methodChannel == null) {
throw ArgumentError.value(
'${model.runtimeType} method channel not found',
);
}
return await _channel.invokeMethod(methodChannel, model.toMap());
}
return Future.error('no method mapper found[${model.runtimeType}]');
}
/// The WeChat-Login is under Auth-2.0
/// This method login with native WeChat app.
/// For users without WeChat app, please use [authByQRCode] instead
/// This method only supports getting AuthCode,this is first step to login with WeChat
/// Once AuthCode got, you need to request Access_Token
/// For more information please visit:
/// * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=
Future<bool> sendWeChatAuth(
{required String scope,
String state = 'state',
bool nonAutomatic = false}) async {
assert(scope.trim().isNotEmpty);
return await _channel.invokeMethod(
'sendAuth',
{'scope': scope, 'state': state, 'nonAutomatic': nonAutomatic},
);
}
/// open mini-program
/// see [WXMiniProgramType]
Future<bool> launchWeChatMiniProgram({
required String username,
String? path,
WXMiniProgramType miniProgramType = WXMiniProgramType.RELEASE,
}) async {
assert(username.trim().isNotEmpty);
return await _channel.invokeMethod('launchMiniProgram', {
'userName': username,
'path': path,
'miniProgramType': miniProgramType.toNativeInt()
});
}
/// request payment with WeChat.
/// Read the official document for more detail.
/// [timeStamp] is int because [timeStamp] will be mapped to Unit32.
Future<bool> payWithWeChat({
required String appId,
required String partnerId,
required String prepayId,
required String packageValue,
required String nonceStr,
required int timeStamp,
required String sign,
String? signType,
String? extData,
}) async {
return await _channel.invokeMethod('payWithFluwx', {
'appId': appId,
'partnerId': partnerId,
'prepayId': prepayId,
'packageValue': packageValue,
'nonceStr': nonceStr,
'timeStamp': timeStamp,
'sign': sign,
'signType': signType,
'extData': extData,
});
}
/// request Hong Kong Wallet payment with WeChat.
/// Read the official document for more detail.
Future<bool> payWithWeChatHongKongWallet({required String prepayId}) async {
return await _channel.invokeMethod('payWithHongKongWallet', {
'prepayId': prepayId,
});
}
/// subscribe WeChat message
Future<bool> subscribeWeChatMsg({
required String appId,
required int scene,
required String templateId,
String? reserved,
}) async {
return await _channel.invokeMethod(
'subscribeMsg',
{
'appId': appId,
'scene': scene,
'templateId': templateId,
'reserved': reserved,
},
);
}
/// please read official docs.
Future<bool> autoDeDuctWeChat({
required String appId,
required String mchId,
required String planId,
required String contractCode,
required String requestSerial,
required String contractDisplayAccount,
required String notifyUrl,
required String version,
required String sign,
required String timestamp,
String returnApp = '3',
int businessType = 12,
}) async {
return await _channel.invokeMethod('autoDeduct', {
'appid': appId,
'mch_id': mchId,
'plan_id': planId,
'contract_code': contractCode,
'request_serial': requestSerial,
'contract_display_account': contractDisplayAccount,
'notify_url': notifyUrl,
'version': version,
'sign': sign,
'timestamp': timestamp,
'return_app': returnApp,
'businessType': businessType
});
}
/// please read * [official docs](https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter3_2.shtml).
Future<bool> autoDeductWeChatV2(
Map<String, String> queryInfo, {
int businessType = 12,
}) async {
return await _channel.invokeMethod(
'autoDeductV2', {'queryInfo': queryInfo, 'businessType': businessType});
}
/// Sometimes WeChat is not installed on users's devices.However we can
/// request a QRCode so that we can get AuthCode by scanning the QRCode
/// All required params must not be null or empty
/// [schemeData] only works on iOS
/// see * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=215238808828h4XN&token=&lang=zh_CN
Future<bool> authWeChatByQRCode({
required String appId,
required String scope,
required String nonceStr,
required String timeStamp,
required String signature,
String? schemeData,
}) async {
assert(appId.isNotEmpty);
assert(scope.isNotEmpty);
assert(nonceStr.isNotEmpty);
assert(timeStamp.isNotEmpty);
assert(signature.isNotEmpty);
return await _channel.invokeMethod('authByQRCode', {
'appId': appId,
'scope': scope,
'nonceStr': nonceStr,
'timeStamp': timeStamp,
'signature': signature,
'schemeData': schemeData
});
}
/// stop [authWeChatByQRCode]
Future<bool> stopWeChatAuthByQRCode() async {
return await _channel.invokeMethod('stopAuthByQRCode');
}
Future _methodHandler(MethodCall methodCall) {
final response = BaseWeChatResponse.create(
methodCall.method,
methodCall.arguments,
);
_weChatResponseEventHandlerController.add(response);
return Future.value();
}
/// IOS only
Future<bool> authWeChatByPhoneLogin({
required String scope,
String state = 'state',
}) async {
return await _channel.invokeMethod(
'authByPhoneLogin',
{'scope': scope, 'state': state},
);
}
Future<bool> openWeChatCustomerServiceChat(
{required String url, required String corpId}) async {
return await _channel.invokeMethod(
"openWeChatCustomerServiceChat", {"corpId": corpId, "url": url});
}
/// see * https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter6_2_1.shtml
Future<bool> openWeChatBusinessView(
{required String businessType, required String query}) async {
return await _channel.invokeMethod(
"openBusinessView", {"businessType": businessType, "query": query});
}
Future<bool> checkSupportOpenBusinessView() async {
return await _channel.invokeMethod("checkSupportOpenBusinessView");
}
Future<bool> openWeChatInvoice(
{required String appId,
required String cardType,
String locationId = "",
String cardId = "",
String canMultiSelect = "1"}) async {
return await _channel.invokeMethod("openWeChatInvoice", {
"appId": appId,
"cardType": cardType,
"locationId": locationId,
"cardId": cardId,
"canMultiSelect": canMultiSelect
});
}
/* /*
* Copyright (c) 2020. OpenFlutter Project * Copyright (c) 2023. OpenFlutter Project
* *
* Licensed to the Apache Software Foundation (ASF) under one or more contributor * Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for * license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this * additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the "License"); you may not * file to you under the Apache License, Version 2.0 (the 'License'); you may not
* use this file except in compliance with the License. You may obtain a copy of * use this file except in compliance with the License. You may obtain a copy of
* the License at * the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
import 'package:flutter_test/flutter_test.dart';
import 'package:fluwx/src/share/share_models.dart';
import 'package:fluwx/src/wechat_enums.dart';
void main() { // In order to *not* need this ignore, consider extracting the "web" version
test('create WeChatTextModel', () { // of your plugin as a separate package, instead of inlining it in the same
var model = WeChatShareTextModel('text', scene: WeChatScene.FAVORITE); // package as the core of your plugin.
expect(model.source, 'text'); // ignore: avoid_web_libraries_in_flutter
expect(model.scene, WeChatScene.FAVORITE); import 'dart:html' as html show window;
});
test('WeChatTextModel toMap', () { import 'package:flutter_web_plugins/flutter_web_plugins.dart';
var map = WeChatShareTextModel('text', scene: WeChatScene.FAVORITE).toMap();
expect(map['source'], 'text'); import 'method_channel/fluwx_platform_interface.dart';
expect(map['scene'], 2);
}); /// A web implementation of the FluwxPlatform of the Fluwx plugin.
class FluwxWeb extends FluwxPlatform {
/// Constructs a FluwxWeb
FluwxWeb();
static void registerWith(Registrar registrar) {
FluwxPlatform.instance = FluwxWeb();
}
} }
/*
* Copyright (c) 2023. OpenFlutter Project
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the 'License'); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import '../response/wechat_response.dart';
import '../share/share_models.dart';
import '../wechat_enums.dart';
import 'fluwx_platform_interface.dart';
/// An implementation of [FluwxPlatform] that uses method channels.
class MethodChannelFluwx extends FluwxPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
final methodChannel = const MethodChannel('com.jarvanmo/fluwx');
MethodChannelFluwx() {
methodChannel.setMethodCallHandler(_methodHandler);
}
final Map<Type, String> _shareModelMethodMapper = {
WeChatShareTextModel: 'shareText',
WeChatShareImageModel: 'shareImage',
WeChatShareMusicModel: 'shareMusic',
WeChatShareVideoModel: 'shareVideo',
WeChatShareWebPageModel: 'shareWebPage',
WeChatShareMiniProgramModel: 'shareMiniProgram',
WeChatShareFileModel: 'shareFile',
};
final StreamController<WeChatResponse> _responseEventHandler =
StreamController.broadcast();
/// Response answers from WeChat after sharing, payment etc.
@override
Stream<WeChatResponse> get responseEventHandler =>
_responseEventHandler.stream;
Future _methodHandler(MethodCall methodCall) {
final response = WeChatResponse.create(
methodCall.method,
methodCall.arguments,
);
_responseEventHandler.add(response);
return Future.value();
}
/// [true] if WeChat installed, otherwise [false].
/// Please add WeChat to the white list in order use this method on IOS.
@override
Future<bool> get isWeChatInstalled async {
return await methodChannel.invokeMethod('isWeChatInstalled');
}
/// Just open WeChat, noting to do.
@override
Future<bool> openWeChatApp() async {
return await methodChannel.invokeMethod('openWXApp');
}
/// It's ok if you register multi times.
/// [appId] is not necessary.
/// if [doOnIOS] is true ,fluwx will register WXApi on iOS.
/// if [doOnAndroid] is true, fluwx will register WXApi on Android.
/// [universalLink] is required if you want to register on iOS.
@override
Future<bool> registerWxApi({
required String appId,
bool doOnIOS = true,
bool doOnAndroid = true,
String? universalLink,
}) async {
if (doOnIOS && Platform.isIOS) {
if (universalLink == null ||
universalLink.trim().isEmpty ||
!universalLink.startsWith('https')) {
throw ArgumentError.value(
universalLink,
"You're trying to use illegal universal link, see "
'https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html '
'for more detail',
);
}
}
return await methodChannel.invokeMethod('registerApp', {
'appId': appId,
'iOS': doOnIOS,
'android': doOnAndroid,
'universalLink': universalLink
});
}
/// Get ext Message
@override
Future<String?> getExtMsg() {
return methodChannel.invokeMethod('getExtMsg');
}
/// start Log
/// default [WXLogLevel.unspecific]
@override
Future<bool?> startLog({WXLogLevel logLevel = WXLogLevel.unspecific}) async {
return await methodChannel
.invokeMethod('startLog', {'logLevel': logLevel.level});
}
/// stop log
@override
Future<bool?> stopLog() async {
return await methodChannel.invokeMethod('stopLog');
}
/// Share your requests to WeChat.
/// This depends on the actual type of [what].
/// see [_shareModelMethodMapper] for detail.
@override
Future<bool> share(WeChatShareModel what) async {
if (_shareModelMethodMapper.containsKey(what.runtimeType)) {
final channelName = _shareModelMethodMapper[what.runtimeType];
if (channelName == null) {
throw ArgumentError.value(
'${what.runtimeType} method channel not found',
);
}
return await methodChannel.invokeMethod(channelName, what.toMap());
}
return Future.error('no method mapper found[${what.runtimeType}]');
}
/// The WeChat-Login is under Auth-2.0
/// This method login with native WeChat app.
/// For users without WeChat app, please use [authByQRCode] instead
/// This method only supports getting AuthCode,this is first step to login with WeChat
/// Once AuthCode got, you need to request Access_Token
/// For more information please visit:
/// * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=
@override
Future<bool> sendAuth(
{required String scope,
String state = 'state',
bool nonAutomatic = false}) async {
assert(scope.trim().isNotEmpty);
return await methodChannel.invokeMethod(
'sendAuth',
{'scope': scope, 'state': state, 'nonAutomatic': nonAutomatic},
);
}
/// open mini-program
/// see [WXMiniProgramType]
@override
Future<bool> launchMiniProgram({
required String username,
String? path,
WXMiniProgramType miniProgramType = WXMiniProgramType.release,
}) async {
assert(username.trim().isNotEmpty);
return await methodChannel.invokeMethod('launchMiniProgram', {
'userName': username,
'path': path,
'miniProgramType': miniProgramType.value
});
}
/// request payment with WeChat.
/// Read the official document for more detail.
/// [timestamp] is int because [timestamp] will be mapped to Unit32.
@override
Future<bool> pay({
required String appId,
required String partnerId,
required String prepayId,
required String packageValue,
required String nonceStr,
required int timestamp,
required String sign,
String? signType,
String? extData,
}) async {
return await methodChannel.invokeMethod('payWithFluwx', {
'appId': appId,
'partnerId': partnerId,
'prepayId': prepayId,
'packageValue': packageValue,
'nonceStr': nonceStr,
'timeStamp': timestamp,
'sign': sign,
'signType': signType,
'extData': extData,
});
}
/// request Hong Kong Wallet payment with WeChat.
/// Read the official document for more detail.
@override
Future<bool> payWithHongKongWallet({required String prepayId}) async {
return await methodChannel.invokeMethod('payWithHongKongWallet', {
'prepayId': prepayId,
});
}
/// subscribe WeChat message
@override
Future<bool> subscribeMsg({
required String appId,
required int scene,
required String templateId,
String? reserved,
}) async {
return await methodChannel.invokeMethod(
'subscribeMsg',
{
'appId': appId,
'scene': scene,
'templateId': templateId,
'reserved': reserved,
},
);
}
/// please read official docs.
@override
Future<bool> autoDeDuct({
required String appId,
required String mchId,
required String planId,
required String contractCode,
required String requestSerial,
required String contractDisplayAccount,
required String notifyUrl,
required String version,
required String sign,
required String timestamp,
String returnApp = '3',
int businessType = 12,
}) async {
return await methodChannel.invokeMethod('autoDeduct', {
'appid': appId,
'mch_id': mchId,
'plan_id': planId,
'contract_code': contractCode,
'request_serial': requestSerial,
'contract_display_account': contractDisplayAccount,
'notify_url': notifyUrl,
'version': version,
'sign': sign,
'timestamp': timestamp,
'return_app': returnApp,
'businessType': businessType
}) ??
false;
}
/// please read * [official docs](https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/papay/chapter3_2.shtml).
@override
Future<bool> autoDeductV2(
Map<String, String> queryInfo, {
int businessType = 12,
}) async {
return await methodChannel.invokeMethod('autoDeductV2',
{'queryInfo': queryInfo, 'businessType': businessType}) ??
false;
}
/// Sometimes WeChat is not installed on users's devices.However we can
/// request a QRCode so that we can get AuthCode by scanning the QRCode
/// All required params must not be null or empty
/// [schemeData] only works on iOS
/// see * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=215238808828h4XN&token=&lang=zh_CN
@override
Future<bool> authByQRCode({
required String appId,
required String scope,
required String nonceStr,
required String timestamp,
required String signature,
String? schemeData,
}) async {
assert(appId.isNotEmpty);
assert(scope.isNotEmpty);
assert(nonceStr.isNotEmpty);
assert(timestamp.isNotEmpty);
assert(signature.isNotEmpty);
return await methodChannel.invokeMethod('authByQRCode', {
'appId': appId,
'scope': scope,
'nonceStr': nonceStr,
'timeStamp': timestamp,
'signature': signature,
'schemeData': schemeData
});
}
/// stop [authWeChatByQRCode]
@override
Future<bool> stopWeChatAuthByQRCode() async {
return await methodChannel.invokeMethod('stopAuthByQRCode');
}
/// IOS only
@override
Future<bool> authByPhoneLogin({
required String scope,
String state = 'state',
}) async {
return await methodChannel.invokeMethod(
'authByPhoneLogin',
{'scope': scope, 'state': state},
);
}
@override
Future<bool> openCustomerServiceChat(
{required String url, required String corpId}) async {
return await methodChannel.invokeMethod(
"openWeChatCustomerServiceChat", {"corpId": corpId, "url": url});
}
/// see * https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter6_2_1.shtml
@override
Future<bool> openBusinessView(
{required String businessType, required String query}) async {
return await methodChannel.invokeMethod(
"openBusinessView", {"businessType": businessType, "query": query});
}
@override
Future<bool> checkSupportOpenBusinessView() async {
return await methodChannel.invokeMethod("checkSupportOpenBusinessView");
}
@override
Future<bool> openInvoice(
{required String appId,
required String cardType,
String locationId = "",
String cardId = "",
String canMultiSelect = "1"}) async {
return await methodChannel.invokeMethod("openWeChatInvoice", {
"appId": appId,
"cardType": cardType,
"locationId": locationId,
"cardId": cardId,
"canMultiSelect": canMultiSelect
});
}
}
/*
* Copyright (c) 2023. OpenFlutter Project
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the 'License'); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
import 'package:fluwx/fluwx.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'fluwx_method_channel.dart';
abstract class FluwxPlatform extends PlatformInterface {
/// Constructs a FluwxPlatform.
FluwxPlatform() : super(token: _token);
static final Object _token = Object();
static FluwxPlatform _instance = MethodChannelFluwx();
/// The default instance of [FluwxPlatform] to use.
///
/// Defaults to [MethodChannelFluwx].
static FluwxPlatform get instance => _instance;
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [FluwxPlatform] when
/// they register themselves.
static set instance(FluwxPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
Stream<WeChatResponse> get responseEventHandler {
throw UnimplementedError('responseEventHandler has not been implemented.');
}
Future<bool> get isWeChatInstalled {
throw UnimplementedError('isWeChatInstalled has not been implemented.');
}
Future<bool> openWeChatApp() {
throw UnimplementedError('openWeChatApp() has not been implemented.');
}
Future<bool> registerWxApi({
required String appId,
bool doOnIOS = true,
bool doOnAndroid = true,
String? universalLink,
}) {
throw UnimplementedError('registerWxApi() has not been implemented.');
}
Future<String?> getExtMsg() {
throw UnimplementedError('getExtMsg() has not been implemented.');
}
Future<bool?> startLog({WXLogLevel logLevel = WXLogLevel.unspecific}) {
throw UnimplementedError('startLog() has not been implemented.');
}
Future<bool?> stopLog() {
throw UnimplementedError('stopLog() has not been implemented.');
}
Future<bool> share(WeChatShareModel what) {
throw UnimplementedError('share() has not been implemented.');
}
Future<bool> sendAuth(
{required String scope,
String state = 'state',
bool nonAutomatic = false}) {
throw UnimplementedError('sendAuth() has not been implemented.');
}
Future<bool> authByPhoneLogin({
required String scope,
String state = 'state',
}) async {
throw UnimplementedError('authByPhoneLogin() has not been implemented.');
}
Future<bool> authByQRCode({
required String appId,
required String scope,
required String nonceStr,
required String timestamp,
required String signature,
String? schemeData,
}) async {
throw UnimplementedError('authByQRCode() has not been implemented.');
}
Future<bool> stopWeChatAuthByQRCode() async {
throw UnimplementedError(
'stopWeChatAuthByQRCode() has not been implemented.');
}
Future<bool> launchMiniProgram({
required String username,
String? path,
WXMiniProgramType miniProgramType = WXMiniProgramType.release,
}) {
throw UnimplementedError('launchMiniProgram() has not been implemented.');
}
Future<bool> pay({
required String appId,
required String partnerId,
required String prepayId,
required String packageValue,
required String nonceStr,
required int timestamp,
required String sign,
String? signType,
String? extData,
}) {
throw UnimplementedError('pay() has not been implemented.');
}
Future<bool> payWithHongKongWallet({required String prepayId}) async {
throw UnimplementedError(
'payWithHongKongWallet() has not been implemented.');
}
Future<bool> subscribeMsg({
required String appId,
required int scene,
required String templateId,
String? reserved,
}) async {
throw UnimplementedError('subscribeWeChatMsg() has not been implemented.');
}
Future<bool> autoDeDuct({
required String appId,
required String mchId,
required String planId,
required String contractCode,
required String requestSerial,
required String contractDisplayAccount,
required String notifyUrl,
required String version,
required String sign,
required String timestamp,
String returnApp = '3',
int businessType = 12,
}) async {
throw UnimplementedError('autoDeDuct() has not been implemented.');
}
Future<bool> autoDeductV2(
Map<String, String> queryInfo, {
int businessType = 12,
}) async {
throw UnimplementedError('autoDeductV2() has not been implemented.');
}
Future<bool> openCustomerServiceChat(
{required String url, required String corpId}) {
throw UnimplementedError(
'openCustomerServiceChat() has not been implemented.');
}
Future<bool> openBusinessView(
{required String businessType, required String query}) async {
throw UnimplementedError('openBusinessView() has not been implemented.');
}
Future<bool> checkSupportOpenBusinessView() async {
throw UnimplementedError(
'checkSupportOpenBusinessView() has not been implemented.');
}
Future<bool> openInvoice(
{required String appId,
required String cardType,
String locationId = "",
String cardId = "",
String canMultiSelect = "1"}) async {
throw UnimplementedError('openInvoice() has not been implemented.');
}
}
...@@ -22,7 +22,7 @@ import 'dart:typed_data'; ...@@ -22,7 +22,7 @@ import 'dart:typed_data';
const String _errCode = 'errCode'; const String _errCode = 'errCode';
const String _errStr = 'errStr'; const String _errStr = 'errStr';
typedef BaseWeChatResponse _WeChatResponseInvoker(Map argument); typedef _WeChatResponseInvoker = WeChatResponse Function(Map argument);
Map<String, _WeChatResponseInvoker> _nameAndResponseMapper = { Map<String, _WeChatResponseInvoker> _nameAndResponseMapper = {
'onShareResponse': (Map argument) => WeChatShareResponse.fromMap(argument), 'onShareResponse': (Map argument) => WeChatShareResponse.fromMap(argument),
...@@ -50,11 +50,11 @@ Map<String, _WeChatResponseInvoker> _nameAndResponseMapper = { ...@@ -50,11 +50,11 @@ Map<String, _WeChatResponseInvoker> _nameAndResponseMapper = {
WeChatOpenInvoiceResponse.fromMap(argument), WeChatOpenInvoiceResponse.fromMap(argument),
}; };
class BaseWeChatResponse { sealed class WeChatResponse {
BaseWeChatResponse._(this.errCode, this.errStr); WeChatResponse._(this.errCode, this.errStr);
/// Create response from the response pool. /// Create response from the response pool.
factory BaseWeChatResponse.create(String name, Map argument) { factory WeChatResponse.create(String name, Map argument) {
var result = _nameAndResponseMapper[name]; var result = _nameAndResponseMapper[name];
if (result == null) { if (result == null) {
throw ArgumentError("Can't found instance of $name"); throw ArgumentError("Can't found instance of $name");
...@@ -68,14 +68,15 @@ class BaseWeChatResponse { ...@@ -68,14 +68,15 @@ class BaseWeChatResponse {
bool get isSuccessful => errCode == 0; bool get isSuccessful => errCode == 0;
} }
class WeChatOpenInvoiceResponse extends BaseWeChatResponse { class WeChatOpenInvoiceResponse extends WeChatResponse {
String? cardItemList; String? cardItemList;
WeChatOpenInvoiceResponse.fromMap(Map map) WeChatOpenInvoiceResponse.fromMap(Map map)
: cardItemList = map["cardItemList"], : cardItemList = map["cardItemList"],
super._(map[_errCode], map[_errStr]); super._(map[_errCode], map[_errStr]);
} }
class WeChatShareResponse extends BaseWeChatResponse { class WeChatShareResponse extends WeChatResponse {
WeChatShareResponse.fromMap(Map map) WeChatShareResponse.fromMap(Map map)
: type = map['type'], : type = map['type'],
super._(map[_errCode], map[_errStr]); super._(map[_errCode], map[_errStr]);
...@@ -83,7 +84,7 @@ class WeChatShareResponse extends BaseWeChatResponse { ...@@ -83,7 +84,7 @@ class WeChatShareResponse extends BaseWeChatResponse {
final int type; final int type;
} }
class WeChatAuthResponse extends BaseWeChatResponse { class WeChatAuthResponse extends WeChatResponse {
WeChatAuthResponse.fromMap(Map map) WeChatAuthResponse.fromMap(Map map)
: type = map['type'], : type = map['type'],
country = map['country'], country = map['country'],
...@@ -115,7 +116,7 @@ class WeChatAuthResponse extends BaseWeChatResponse { ...@@ -115,7 +116,7 @@ class WeChatAuthResponse extends BaseWeChatResponse {
1432; 1432;
} }
class WeChatLaunchMiniProgramResponse extends BaseWeChatResponse { class WeChatLaunchMiniProgramResponse extends WeChatResponse {
WeChatLaunchMiniProgramResponse.fromMap(Map map) WeChatLaunchMiniProgramResponse.fromMap(Map map)
: type = map['type'], : type = map['type'],
extMsg = map['extMsg'], extMsg = map['extMsg'],
...@@ -125,7 +126,7 @@ class WeChatLaunchMiniProgramResponse extends BaseWeChatResponse { ...@@ -125,7 +126,7 @@ class WeChatLaunchMiniProgramResponse extends BaseWeChatResponse {
final String? extMsg; final String? extMsg;
} }
class WeChatPaymentResponse extends BaseWeChatResponse { class WeChatPaymentResponse extends WeChatResponse {
WeChatPaymentResponse.fromMap(Map map) WeChatPaymentResponse.fromMap(Map map)
: type = map['type'], : type = map['type'],
extData = map['extData'], extData = map['extData'],
...@@ -135,7 +136,7 @@ class WeChatPaymentResponse extends BaseWeChatResponse { ...@@ -135,7 +136,7 @@ class WeChatPaymentResponse extends BaseWeChatResponse {
final String? extData; final String? extData;
} }
class WeChatOpenCustomerServiceChatResponse extends BaseWeChatResponse { class WeChatOpenCustomerServiceChatResponse extends WeChatResponse {
WeChatOpenCustomerServiceChatResponse.fromMap(Map map) WeChatOpenCustomerServiceChatResponse.fromMap(Map map)
: extMsg = map['extMsg'], : extMsg = map['extMsg'],
super._(map[_errCode], map[_errStr]); super._(map[_errCode], map[_errStr]);
...@@ -143,7 +144,7 @@ class WeChatOpenCustomerServiceChatResponse extends BaseWeChatResponse { ...@@ -143,7 +144,7 @@ class WeChatOpenCustomerServiceChatResponse extends BaseWeChatResponse {
final String? extMsg; final String? extMsg;
} }
class WeChatOpenBusinessViewResponse extends BaseWeChatResponse { class WeChatOpenBusinessViewResponse extends WeChatResponse {
final String? extMsg; final String? extMsg;
final String? openid; final String? openid;
final String? businessType; final String? businessType;
...@@ -157,7 +158,7 @@ class WeChatOpenBusinessViewResponse extends BaseWeChatResponse { ...@@ -157,7 +158,7 @@ class WeChatOpenBusinessViewResponse extends BaseWeChatResponse {
super._(map[_errCode], map[_errStr]); super._(map[_errCode], map[_errStr]);
} }
class WeChatSubscribeMsgResponse extends BaseWeChatResponse { class WeChatSubscribeMsgResponse extends WeChatResponse {
WeChatSubscribeMsgResponse.fromMap(Map map) WeChatSubscribeMsgResponse.fromMap(Map map)
: openid = map['openid'], : openid = map['openid'],
templateId = map['templateId'], templateId = map['templateId'],
...@@ -173,25 +174,23 @@ class WeChatSubscribeMsgResponse extends BaseWeChatResponse { ...@@ -173,25 +174,23 @@ class WeChatSubscribeMsgResponse extends BaseWeChatResponse {
final int scene; final int scene;
} }
class WeChatOpenBusinessWebviewResponse extends BaseWeChatResponse { class WeChatOpenBusinessWebviewResponse extends WeChatResponse {
WeChatOpenBusinessWebviewResponse.fromMap(Map map) WeChatOpenBusinessWebviewResponse.fromMap(Map map)
: type = map['type'], : type = map['type'],
errCode = map[_errCode],
businessType = map['businessType'], businessType = map['businessType'],
resultInfo = map['resultInfo'], resultInfo = map['resultInfo'],
super._(map[_errCode], map[_errStr]); super._(map[_errCode], map[_errStr]);
final int? type; final int? type;
final int errCode;
final int? businessType; final int? businessType;
final String resultInfo; final String resultInfo;
} }
class WeChatAuthByQRCodeFinishedResponse extends BaseWeChatResponse { class WeChatAuthByQRCodeFinishedResponse extends WeChatResponse {
WeChatAuthByQRCodeFinishedResponse.fromMap(Map map) WeChatAuthByQRCodeFinishedResponse.fromMap(Map map)
: authCode = map['authCode'], : authCode = map['authCode'],
qrCodeErrorCode = (_authByQRCodeErrorCodes[_errCode] ?? qrCodeErrorCode = (_authByQRCodeErrorCodes[_errCode] ??
AuthByQRCodeErrorCode.UNKNOWN), AuthByQRCodeErrorCode.unknown),
super._(map[_errCode], map[_errStr]); super._(map[_errCode], map[_errStr]);
final String? authCode; final String? authCode;
...@@ -199,7 +198,7 @@ class WeChatAuthByQRCodeFinishedResponse extends BaseWeChatResponse { ...@@ -199,7 +198,7 @@ class WeChatAuthByQRCodeFinishedResponse extends BaseWeChatResponse {
} }
///[qrCode] in memory. ///[qrCode] in memory.
class WeChatAuthGotQRCodeResponse extends BaseWeChatResponse { class WeChatAuthGotQRCodeResponse extends WeChatResponse {
WeChatAuthGotQRCodeResponse.fromMap(Map map) WeChatAuthGotQRCodeResponse.fromMap(Map map)
: qrCode = map['qrCode'], : qrCode = map['qrCode'],
super._(map[_errCode], map[_errStr]); super._(map[_errCode], map[_errStr]);
...@@ -207,13 +206,13 @@ class WeChatAuthGotQRCodeResponse extends BaseWeChatResponse { ...@@ -207,13 +206,13 @@ class WeChatAuthGotQRCodeResponse extends BaseWeChatResponse {
final Uint8List? qrCode; final Uint8List? qrCode;
} }
class WeChatQRCodeScannedResponse extends BaseWeChatResponse { class WeChatQRCodeScannedResponse extends WeChatResponse {
WeChatQRCodeScannedResponse.fromMap(Map map) WeChatQRCodeScannedResponse.fromMap(Map map)
: super._(map[_errCode], map[_errStr]); : super._(map[_errCode], map[_errStr]);
} }
// 获取微信打开App时携带的参数 // 获取微信打开App时携带的参数
class WeChatShowMessageFromWXRequest extends BaseWeChatResponse { class WeChatShowMessageFromWXRequest extends WeChatResponse {
WeChatShowMessageFromWXRequest.fromMap(Map map) WeChatShowMessageFromWXRequest.fromMap(Map map)
: extMsg = map['extMsg'], : extMsg = map['extMsg'],
super._(0, ''); super._(0, '');
...@@ -222,21 +221,21 @@ class WeChatShowMessageFromWXRequest extends BaseWeChatResponse { ...@@ -222,21 +221,21 @@ class WeChatShowMessageFromWXRequest extends BaseWeChatResponse {
} }
enum AuthByQRCodeErrorCode { enum AuthByQRCodeErrorCode {
OK, // WechatAuth_Err_OK(0) ok, // WechatAuth_Err_OK(0)
NORMAL_ERR, // WechatAuth_Err_NormalErr(-1) normalErr, // WechatAuth_Err_NormalErr(-1)
NETWORK_ERR, // WechatAuth_Err_NetworkErr(-2) networkErr, // WechatAuth_Err_NetworkErr(-2)
JSON_DECODE_ERR, // WechatAuth_Err_JsonDecodeErr(-3), WechatAuth_Err_GetQrcodeFailed on iOS jsonDecodeErr, // WechatAuth_Err_JsonDecodeErr(-3), WechatAuth_Err_GetQrcodeFailed on iOS
CANCEL, // WechatAuth_Err_Cancel(-4) cancel, // WechatAuth_Err_Cancel(-4)
TIMEOUT, // WechatAuth_Err_Timeout(-5) timeout, // WechatAuth_Err_Timeout(-5)
AUTH_STOPPED, // WechatAuth_Err_Auth_Stopped(-6), Android only authStopped, // WechatAuth_Err_Auth_Stopped(-6), Android only
UNKNOWN unknown
} }
const Map<int, AuthByQRCodeErrorCode> _authByQRCodeErrorCodes = { const Map<int, AuthByQRCodeErrorCode> _authByQRCodeErrorCodes = {
0: AuthByQRCodeErrorCode.OK, 0: AuthByQRCodeErrorCode.ok,
-1: AuthByQRCodeErrorCode.NORMAL_ERR, -1: AuthByQRCodeErrorCode.normalErr,
-2: AuthByQRCodeErrorCode.NETWORK_ERR, -2: AuthByQRCodeErrorCode.networkErr,
-3: AuthByQRCodeErrorCode.JSON_DECODE_ERR, -3: AuthByQRCodeErrorCode.jsonDecodeErr,
-4: AuthByQRCodeErrorCode.CANCEL, -4: AuthByQRCodeErrorCode.cancel,
-5: AuthByQRCodeErrorCode.AUTH_STOPPED -5: AuthByQRCodeErrorCode.authStopped
}; };
/* /*
* Copyright (c) 2020. OpenFlutter Project * Copyright (c) 2023. OpenFlutter Project
* *
* Licensed to the Apache Software Foundation (ASF) under one or more contributor * Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for * license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this * additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the "License"); you may not * file to you under the Apache License, Version 2.0 (the "License"); you may not
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
import 'package:fluwx/fluwx.dart'; import 'package:fluwx/fluwx.dart';
const String _scene = "scene"; const String _scene = "scene";
...@@ -29,24 +30,24 @@ const String _messageAction = "messageAction"; ...@@ -29,24 +30,24 @@ const String _messageAction = "messageAction";
const String _compressThumbnail = "compressThumbnail"; const String _compressThumbnail = "compressThumbnail";
const String _msgSignature = "msgSignature"; const String _msgSignature = "msgSignature";
mixin WeChatShareBaseModel { sealed class WeChatShareModel {
Map toMap(); Map<String, dynamic> toMap();
} }
/// [source] the text you want to send to WeChat /// [source] the text you want to send to WeChat
/// [scene] the target you want to send /// [scene] the target you want to send
class WeChatShareTextModel implements WeChatShareBaseModel { class WeChatShareTextModel extends WeChatShareModel {
WeChatShareTextModel( WeChatShareTextModel(
this.source, { this.source, {
this.scene = WeChatScene.SESSION, this.scene = WeChatScene.session,
this.mediaTagName, this.mediaTagName,
this.messageAction, this.messageAction,
this.messageExt, this.messageExt,
this.msgSignature, this.msgSignature,
String? description, String? description,
String? title, String? title,
}) : this.title = title ?? source, }) : title = title ?? source,
this.description = description ?? source; description = description ?? source;
final String source; final String source;
final WeChatScene scene; final WeChatScene scene;
...@@ -58,7 +59,7 @@ class WeChatShareTextModel implements WeChatShareBaseModel { ...@@ -58,7 +59,7 @@ class WeChatShareTextModel implements WeChatShareBaseModel {
final String? msgSignature; final String? msgSignature;
@override @override
Map toMap() { Map<String, dynamic> toMap() {
return { return {
_scene: scene.index, _scene: scene.index,
_source: source, _source: source,
...@@ -75,10 +76,10 @@ class WeChatShareTextModel implements WeChatShareBaseModel { ...@@ -75,10 +76,10 @@ class WeChatShareTextModel implements WeChatShareBaseModel {
/// the default value is [MINI_PROGRAM_TYPE_RELEASE] /// the default value is [MINI_PROGRAM_TYPE_RELEASE]
/// [hdImagePath] only works on iOS, not sure the relationship /// [hdImagePath] only works on iOS, not sure the relationship
/// between [thumbnail] and [hdImagePath]. /// between [thumbnail] and [hdImagePath].
class WeChatShareMiniProgramModel implements WeChatShareBaseModel { class WeChatShareMiniProgramModel extends WeChatShareModel {
WeChatShareMiniProgramModel( WeChatShareMiniProgramModel(
{required this.webPageUrl, {required this.webPageUrl,
this.miniProgramType = WXMiniProgramType.RELEASE, this.miniProgramType = WXMiniProgramType.release,
required this.userName, required this.userName,
this.path = "/", this.path = "/",
this.title, this.title,
...@@ -111,10 +112,10 @@ class WeChatShareMiniProgramModel implements WeChatShareBaseModel { ...@@ -111,10 +112,10 @@ class WeChatShareMiniProgramModel implements WeChatShareBaseModel {
final String? msgSignature; final String? msgSignature;
@override @override
Map toMap() { Map<String, dynamic> toMap() {
return { return {
'webPageUrl': webPageUrl, 'webPageUrl': webPageUrl,
"miniProgramType": miniProgramType.toNativeInt(), "miniProgramType": miniProgramType.value,
"userName": userName, "userName": userName,
"path": path, "path": path,
"title": title, "title": title,
...@@ -133,11 +134,11 @@ class WeChatShareMiniProgramModel implements WeChatShareBaseModel { ...@@ -133,11 +134,11 @@ class WeChatShareMiniProgramModel implements WeChatShareBaseModel {
/// [source] the image you want to send to WeChat /// [source] the image you want to send to WeChat
/// [scene] the target you want to send /// [scene] the target you want to send
/// [thumbnail] the preview of your image, will be created from [scene] if null. /// [thumbnail] the preview of your image, will be created from [scene] if null.
class WeChatShareImageModel implements WeChatShareBaseModel { class WeChatShareImageModel extends WeChatShareModel {
WeChatShareImageModel(this.source, WeChatShareImageModel(this.source,
{WeChatImage? thumbnail, {WeChatImage? thumbnail,
this.title, this.title,
this.scene = WeChatScene.SESSION, this.scene = WeChatScene.session,
this.description, this.description,
this.mediaTagName, this.mediaTagName,
this.messageAction, this.messageAction,
...@@ -158,7 +159,7 @@ class WeChatShareImageModel implements WeChatShareBaseModel { ...@@ -158,7 +159,7 @@ class WeChatShareImageModel implements WeChatShareBaseModel {
final String? msgSignature; final String? msgSignature;
@override @override
Map toMap() { Map<String, dynamic> toMap() {
return { return {
_scene: scene.index, _scene: scene.index,
_source: source.toMap(), _source: source.toMap(),
...@@ -175,7 +176,7 @@ class WeChatShareImageModel implements WeChatShareBaseModel { ...@@ -175,7 +176,7 @@ class WeChatShareImageModel implements WeChatShareBaseModel {
/// if [musicUrl] and [musicLowBandUrl] are both provided, /// if [musicUrl] and [musicLowBandUrl] are both provided,
/// only [musicUrl] will be used. /// only [musicUrl] will be used.
class WeChatShareMusicModel implements WeChatShareBaseModel { class WeChatShareMusicModel extends WeChatShareModel {
WeChatShareMusicModel( WeChatShareMusicModel(
{this.musicUrl, {this.musicUrl,
this.musicLowBandUrl, this.musicLowBandUrl,
...@@ -187,7 +188,7 @@ class WeChatShareMusicModel implements WeChatShareBaseModel { ...@@ -187,7 +188,7 @@ class WeChatShareMusicModel implements WeChatShareBaseModel {
this.mediaTagName, this.mediaTagName,
this.messageAction, this.messageAction,
this.messageExt, this.messageExt,
this.scene = WeChatScene.SESSION, this.scene = WeChatScene.session,
this.compressThumbnail = true, this.compressThumbnail = true,
this.msgSignature}) this.msgSignature})
: assert(musicUrl != null || musicLowBandUrl != null); : assert(musicUrl != null || musicLowBandUrl != null);
...@@ -207,7 +208,7 @@ class WeChatShareMusicModel implements WeChatShareBaseModel { ...@@ -207,7 +208,7 @@ class WeChatShareMusicModel implements WeChatShareBaseModel {
final String? msgSignature; final String? msgSignature;
@override @override
Map toMap() { Map<String, dynamic> toMap() {
return { return {
_scene: scene.index, _scene: scene.index,
"musicUrl": musicUrl, "musicUrl": musicUrl,
...@@ -227,9 +228,9 @@ class WeChatShareMusicModel implements WeChatShareBaseModel { ...@@ -227,9 +228,9 @@ class WeChatShareMusicModel implements WeChatShareBaseModel {
/// if [videoUrl] and [videoLowBandUrl] are both provided, /// if [videoUrl] and [videoLowBandUrl] are both provided,
/// only [videoUrl] will be used. /// only [videoUrl] will be used.
class WeChatShareVideoModel implements WeChatShareBaseModel { class WeChatShareVideoModel extends WeChatShareModel {
WeChatShareVideoModel( WeChatShareVideoModel(
{this.scene = WeChatScene.SESSION, {this.scene = WeChatScene.session,
this.videoUrl, this.videoUrl,
this.videoLowBandUrl, this.videoLowBandUrl,
this.title = "", this.title = "",
...@@ -256,7 +257,7 @@ class WeChatShareVideoModel implements WeChatShareBaseModel { ...@@ -256,7 +257,7 @@ class WeChatShareVideoModel implements WeChatShareBaseModel {
final String? msgSignature; final String? msgSignature;
@override @override
Map toMap() { Map<String, dynamic> toMap() {
return { return {
_scene: scene.index, _scene: scene.index,
"videoUrl": videoUrl, "videoUrl": videoUrl,
...@@ -274,13 +275,13 @@ class WeChatShareVideoModel implements WeChatShareBaseModel { ...@@ -274,13 +275,13 @@ class WeChatShareVideoModel implements WeChatShareBaseModel {
/// [webPage] url you want to send to wechat /// [webPage] url you want to send to wechat
/// [thumbnail] logo of your website /// [thumbnail] logo of your website
class WeChatShareWebPageModel implements WeChatShareBaseModel { class WeChatShareWebPageModel extends WeChatShareModel {
WeChatShareWebPageModel( WeChatShareWebPageModel(
this.webPage, { this.webPage, {
this.title = "", this.title = "",
String? description, String? description,
this.thumbnail, this.thumbnail,
this.scene = WeChatScene.SESSION, this.scene = WeChatScene.session,
this.mediaTagName, this.mediaTagName,
this.messageAction, this.messageAction,
this.messageExt, this.messageExt,
...@@ -301,7 +302,7 @@ class WeChatShareWebPageModel implements WeChatShareBaseModel { ...@@ -301,7 +302,7 @@ class WeChatShareWebPageModel implements WeChatShareBaseModel {
final String? msgSignature; final String? msgSignature;
@override @override
Map toMap() { Map<String, dynamic> toMap() {
return { return {
_scene: scene.index, _scene: scene.index,
"webPage": webPage, "webPage": webPage,
...@@ -319,13 +320,13 @@ class WeChatShareWebPageModel implements WeChatShareBaseModel { ...@@ -319,13 +320,13 @@ class WeChatShareWebPageModel implements WeChatShareBaseModel {
/// [source] the file you want to share, [source.suffix] is necessary on iOS. /// [source] the file you want to share, [source.suffix] is necessary on iOS.
/// [scene] can't be [WeChatScene.TIMELINE], otherwise, sharing nothing. /// [scene] can't be [WeChatScene.TIMELINE], otherwise, sharing nothing.
/// send files to WeChat /// send files to WeChat
class WeChatShareFileModel implements WeChatShareBaseModel { class WeChatShareFileModel extends WeChatShareModel {
WeChatShareFileModel( WeChatShareFileModel(
this.source, { this.source, {
this.title = "", this.title = "",
this.description = "", this.description = "",
this.thumbnail, this.thumbnail,
this.scene = WeChatScene.SESSION, this.scene = WeChatScene.session,
this.mediaTagName, this.mediaTagName,
this.messageAction, this.messageAction,
this.messageExt, this.messageExt,
...@@ -345,7 +346,7 @@ class WeChatShareFileModel implements WeChatShareBaseModel { ...@@ -345,7 +346,7 @@ class WeChatShareFileModel implements WeChatShareBaseModel {
final String? msgSignature; final String? msgSignature;
@override @override
Map toMap() { Map<String, dynamic> toMap() {
return { return {
_scene: scene.index, _scene: scene.index,
_source: source.toMap(), _source: source.toMap(),
......
/* /*
* Copyright (c) 2020. OpenFlutter Project * Copyright (c) 2023. OpenFlutter Project
* *
* Licensed to the Apache Software Foundation (ASF) under one or more contributor * Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for * license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this * additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the "License"); you may not * file to you under the Apache License, Version 2.0 (the "License"); you may not
...@@ -17,44 +17,29 @@ ...@@ -17,44 +17,29 @@
* the License. * the License.
*/ */
/// [WXMiniProgramType.RELEASE]正式版 /// [WXMiniProgramType.release]正式版
/// [WXMiniProgramType.TEST]测试版 /// [WXMiniProgramType.test]测试版
/// [WXMiniProgramType.PREVIEW]预览版 /// [WXMiniProgramType.preview]预览版
enum WXMiniProgramType { RELEASE, TEST, PREVIEW } enum WXMiniProgramType {
release(0),
/// [WeChatScene.SESSION]会话 test(1),
/// [WeChatScene.TIMELINE]朋友圈 preview(2);
/// [WeChatScene.FAVORITE]收藏 final int value;
enum WeChatScene { SESSION, TIMELINE, FAVORITE } const WXMiniProgramType(this.value);
extension MiniProgramTypeExtensions on WXMiniProgramType {
int toNativeInt() {
switch (this) {
case WXMiniProgramType.PREVIEW:
return 2;
case WXMiniProgramType.TEST:
return 1;
case WXMiniProgramType.RELEASE:
return 0;
default:
return 0;
}
}
} }
/// [WeChatScene.session]会话
/// [WeChatScene.timeline]朋友圈
/// [WeChatScene.favorite]收藏
enum WeChatScene { session, timeline, favorite }
/// 打印日常的日志 /// 打印日常的日志
/// 打印详细的日志 /// 打印详细的日志
enum WXLogLevel { NORMAL, DETAIL } enum WXLogLevel {
normal(1),
unspecific(0);
final int level;
extension LogLevelExtensions on WXLogLevel { const WXLogLevel(this.level);
int toNativeInt() {
switch (this) {
case WXLogLevel.DETAIL:
return 1;
case WXLogLevel.NORMAL:
return 0;
default:
return 0;
}
}
} }
/* /*
* Copyright (c) 2020. OpenFlutter Project * Copyright (c) 2023. OpenFlutter Project
* *
* Licensed to the Apache Software Foundation (ASF) under one or more contributor * Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for * license agreements. See the NOTICE file distributed with this work for
...@@ -47,37 +47,33 @@ class WeChatImage extends WeChatFile { ...@@ -47,37 +47,33 @@ class WeChatImage extends WeChatFile {
class WeChatFile { class WeChatFile {
/// [source] must begin with http or https /// [source] must begin with http or https
WeChatFile.network( WeChatFile.network(
String source, { String this.source, {
String? suffix, String? suffix,
}) : assert(source.startsWith('http')), }) : assert(source.startsWith('http')),
source = source, schema = FileSchema.network,
schema = FileSchema.NETWORK,
suffix = source.readSuffix(suffix, defaultSuffixTxt); suffix = source.readSuffix(suffix, defaultSuffixTxt);
///[source] path of the image, like '/asset/image.pdf?package=flutter', ///[source] path of the image, like '/asset/image.pdf?package=flutter',
///the query param package in [source] only available when you want to specify the package of image ///the query param package in [source] only available when you want to specify the package of image
WeChatFile.asset( WeChatFile.asset(
String source, { String this.source, {
String? suffix, String? suffix,
}) : assert(source.trim().isNotEmpty), }) : assert(source.trim().isNotEmpty),
this.source = source, schema = FileSchema.asset,
this.schema = FileSchema.ASSET, suffix = source.readSuffix(suffix, defaultSuffixTxt);
this.suffix = source.readSuffix(suffix, defaultSuffixTxt);
WeChatFile.file( WeChatFile.file(
File source, { File source, {
String suffix = defaultSuffixTxt, String suffix = defaultSuffixTxt,
}) : source = source.path, }) : source = source.path,
schema = FileSchema.FILE, schema = FileSchema.file,
suffix = source.path.readSuffix(suffix, defaultSuffixTxt); suffix = source.path.readSuffix(suffix, defaultSuffixTxt);
WeChatFile.binary( WeChatFile.binary(
Uint8List source, { Uint8List this.source, {
String suffix = defaultSuffixTxt, this.suffix = defaultSuffixTxt,
}) : assert(suffix.trim().isNotEmpty), }) : assert(suffix.trim().isNotEmpty),
source = source, schema = FileSchema.binary;
schema = FileSchema.BINARY,
suffix = suffix;
final dynamic source; final dynamic source;
final FileSchema schema; final FileSchema schema;
...@@ -88,11 +84,11 @@ class WeChatFile { ...@@ -88,11 +84,11 @@ class WeChatFile {
/// Types of image, usually there are for types listed below. /// Types of image, usually there are for types listed below.
/// ///
/// [NETWORK] is online images. /// [network] is online images.
/// [ASSET] is flutter asset image. /// [asset] is flutter asset image.
/// [BINARY] is binary image, shall be be [Uint8List] /// [binary] is binary image, shall be be [Uint8List]
/// [FILE] is local file, usually not comes from flutter asset. /// [file] is local file, usually not comes from flutter asset.
enum FileSchema { NETWORK, ASSET, FILE, BINARY } enum FileSchema { network, asset, file, binary }
extension _FileSuffix on String { extension _FileSuffix on String {
/// returns [suffix] if [suffix] not blank. /// returns [suffix] if [suffix] not blank.
......
name: fluwx name: fluwx
description: The capability of implementing WeChat SDKs in Flutter. With Fluwx, developers can use WeChatSDK easily, such as sharing, payment, lanuch mini program and etc. description: The capability of implementing WeChat SDKs in Flutter. With Fluwx, developers can use WeChatSDK easily, such as sharing, payment, lanuch mini program and etc.
version: 3.13.1 version: 0.0.1
homepage: https://github.com/JarvanMo/fluwx homepage:
environment: environment:
sdk: ">=2.12.0 <3.0.0" sdk: '>=3.1.0-26.0.dev <4.0.0'
flutter: ">=1.12.0" flutter: ">=3.3.0"
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
flutter_web_plugins:
sdk: flutter
plugin_platform_interface: ^2.0.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter. # The following section is specific to Flutter packages.
flutter: flutter:
# This section identifies this Flutter project as a plugin project. # This section identifies this Flutter project as a plugin project.
# The androidPackage and pluginClass identifiers should not ordinarily # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
# be modified. They are used by the tooling to maintain consistency when # which should be registered in the plugin registry. This is required for
# using method channels.
# The Android 'package' specifies package in which the registered class is.
# This is required for using method channels on Android.
# The 'ffiPlugin' specifies that native code should be built and bundled.
# This is required for using `dart:ffi`.
# All these are used by the tooling to maintain consistency when
# adding or updating assets for this project. # adding or updating assets for this project.
plugin: plugin:
platforms: platforms:
...@@ -31,17 +41,20 @@ flutter: ...@@ -31,17 +41,20 @@ flutter:
pluginClass: FluwxPlugin pluginClass: FluwxPlugin
ios: ios:
pluginClass: FluwxPlugin pluginClass: FluwxPlugin
web:
pluginClass: FluwxWeb
fileName: fluwx_web.dart
# To add assets to your plugin package, add an assets section, like this: # To add assets to your plugin package, add an assets section, like this:
# assets: # assets:
# - images/a_dot_burr.jpeg # - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg # - images/a_dot_ham.jpeg
# #
# For details regarding assets in packages, see # For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages # https://flutter.dev/assets-and-images/#from-packages
# #
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware. # https://flutter.dev/assets-and-images/#resolution-aware
# To add custom fonts to your plugin package, add a fonts section here, # 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 # in this "flutter" section. Each entry in this list should have a
......
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fluwx/fluwx.dart' as fluwx;
void main() {
const MethodChannel channel = MethodChannel('com.jarvanmo/fluwx');
TestWidgetsFlutterBinding.ensureInitialized();
setUp(() {
channel.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'registerApp') {
if (methodCall.arguments['appId'] == 'wx13124324324') {
return Future.value(true);
} else {
return Future.value(false);
}
} else if (methodCall.method == 'shareText') {
channel.invokeMethod(
'onShareResponse',
{'type': 1, 'errCode': 1, 'errStr': 'hehe'},
);
return Future.value(true);
} else if (methodCall.method == 'shareImage') {
channel.invokeMethod(
'onShareResponse',
{'type': 1, 'errCode': 0, 'errStr': ''},
);
return Future.value(true);
}
return '42';
});
});
tearDown(() {
channel.setMockMethodCallHandler(null);
});
group('register', () {
test('success', () async {
expect(await fluwx.registerWxApi(appId: 'wx13124324324'), true);
});
test('failed', () async {
expect(await fluwx.registerWxApi(appId: 'wx131256'), false);
});
});
group('share', () {
test('text', () async {
expect(
await fluwx.shareToWeChat(fluwx.WeChatShareTextModel('text')),
true,
);
});
test('shareImage', () async {
expect(
await fluwx.shareToWeChat(
fluwx.WeChatShareImageModel(
fluwx.WeChatImage.network('http://flutter.dev'),
),
),
true,
);
});
});
group('learn', () {
test('description', () async {
print('argumentsss');
});
});
}
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fluwx/src/method_channel/fluwx_method_channel.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
MethodChannelFluwx platform = MethodChannelFluwx();
const MethodChannel channel = MethodChannel('fluwx');
setUp(() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(
channel,
(MethodCall methodCall) async {
return '42';
},
);
});
tearDown(() {
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(channel, null);
});
test('getPlatformVersion', () async {
});
}
import 'package:flutter_test/flutter_test.dart';
import 'package:fluwx/fluwx.dart';
import 'package:fluwx/src/method_channel/fluwx_method_channel.dart';
import 'package:fluwx/src/method_channel/fluwx_platform_interface.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
class MockFluwxPlatform
with MockPlatformInterfaceMixin
implements FluwxPlatform {
@override
Future<bool> authByPhoneLogin(
{required String scope, String state = 'state'}) {
// TODO: implement authByPhoneLogin
throw UnimplementedError();
}
@override
Future<bool> authByQRCode(
{required String appId,
required String scope,
required String nonceStr,
required String timestamp,
required String signature,
String? schemeData}) {
// TODO: implement authByQRCode
throw UnimplementedError();
}
@override
Future<bool> autoDeDuct(
{required String appId,
required String mchId,
required String planId,
required String contractCode,
required String requestSerial,
required String contractDisplayAccount,
required String notifyUrl,
required String version,
required String sign,
required String timestamp,
String returnApp = '3',
int businessType = 12}) {
// TODO: implement autoDeDuct
throw UnimplementedError();
}
@override
Future<bool> autoDeductV2(Map<String, String> queryInfo,
{int businessType = 12}) {
// TODO: implement autoDeductV2
throw UnimplementedError();
}
@override
Future<bool> checkSupportOpenBusinessView() {
// TODO: implement checkSupportOpenBusinessView
throw UnimplementedError();
}
@override
Future<String?> getExtMsg() {
// TODO: implement getExtMsg
throw UnimplementedError();
}
@override
Future<bool> get isWeChatInstalled => Future.value(false);
@override
Future<bool> launchMiniProgram(
{required String username,
String? path,
WXMiniProgramType miniProgramType = WXMiniProgramType.release}) {
// TODO: implement launchMiniProgram
throw UnimplementedError();
}
@override
Future<bool> openBusinessView(
{required String businessType, required String query}) {
// TODO: implement openBusinessView
throw UnimplementedError();
}
@override
Future<bool> openCustomerServiceChat(
{required String url, required String corpId}) {
// TODO: implement openCustomerServiceChat
throw UnimplementedError();
}
@override
Future<bool> openInvoice(
{required String appId,
required String cardType,
String locationId = "",
String cardId = "",
String canMultiSelect = "1"}) {
// TODO: implement openInvoice
throw UnimplementedError();
}
@override
Future<bool> openWeChatApp() {
// TODO: implement openWeChatApp
throw UnimplementedError();
}
@override
Future<bool> pay(
{required String appId,
required String partnerId,
required String prepayId,
required String packageValue,
required String nonceStr,
required int timestamp,
required String sign,
String? signType,
String? extData}) {
// TODO: implement pay
throw UnimplementedError();
}
@override
Future<bool> payWithHongKongWallet({required String prepayId}) {
// TODO: implement payWithHongKongWallet
throw UnimplementedError();
}
@override
Future<bool> registerWxApi(
{required String appId,
bool doOnIOS = true,
bool doOnAndroid = true,
String? universalLink}) {
// TODO: implement registerWxApi
throw UnimplementedError();
}
@override
Future<bool> sendAuth(
{required String scope,
String state = 'state',
bool nonAutomatic = false}) {
// TODO: implement sendAuth
throw UnimplementedError();
}
@override
Future<bool> share(WeChatShareModel what) {
// TODO: implement share
throw UnimplementedError();
}
@override
Future<bool?> startLog({WXLogLevel logLevel = WXLogLevel.unspecific}) {
// TODO: implement startLog
throw UnimplementedError();
}
@override
Future<bool?> stopLog() {
// TODO: implement stopLog
throw UnimplementedError();
}
@override
Future<bool> stopWeChatAuthByQRCode() {
// TODO: implement stopWeChatAuthByQRCode
throw UnimplementedError();
}
@override
Future<bool> subscribeMsg(
{required String appId,
required int scene,
required String templateId,
String? reserved}) {
// TODO: implement subscribeMsg
throw UnimplementedError();
}
@override
// TODO: implement responseEventHandler
Stream<WeChatResponse> get responseEventHandler => throw UnimplementedError();
}
void main() {
final FluwxPlatform initialPlatform = FluwxPlatform.instance;
test('$MethodChannelFluwx is the default instance', () {
expect(initialPlatform, isInstanceOf<MethodChannelFluwx>());
});
test('isWeChatInstalled', () async {
Fluwx fluwxPlugin = Fluwx();
MockFluwxPlatform fakePlatform = MockFluwxPlatform();
FluwxPlatform.instance = fakePlatform;
expect(await fluwxPlugin.isWeChatInstalled, false);
});
}
/*
* Copyright (c) 2020. OpenFlutter Project
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
import 'package:flutter_test/flutter_test.dart';
import 'package:fluwx/fluwx.dart';
void main() {
group('create response', () {
test('WeChatShareResponse', () {
var response = BaseWeChatResponse.create(
'onShareResponse',
{'type': 1, 'errCode': 1, 'errStr': 'hehe'},
);
expect(response is WeChatShareResponse, true);
var casted = response as WeChatShareResponse;
expect(casted.type, 1);
expect(casted.errCode, 1);
expect(casted.errStr, 'hehe');
});
test('WeChatAuthResponse', () {
var response = BaseWeChatResponse.create('onAuthResponse', {
'type': 1,
'errCode': 1,
'errStr': 'hehe',
'country': 'cn',
'lang': 'lang',
'code': 'code',
'state': 'ok'
});
expect(response is WeChatAuthResponse, true);
var casted = response as WeChatAuthResponse;
expect(casted.type, 1);
expect(casted.errCode, 1);
expect(casted.errStr, 'hehe');
expect(casted.country, 'cn');
expect(casted.lang, 'lang');
expect(casted.code, 'code');
expect(casted.state, 'ok');
});
test('onLaunchMiniProgramResponse', () {
var response = BaseWeChatResponse.create(
'onLaunchMiniProgramResponse',
{'type': 1, 'errCode': 1, 'errStr': 'hehe', 'extMsg': 'extMsg'},
);
expect(response is WeChatLaunchMiniProgramResponse, true);
var casted = response as WeChatLaunchMiniProgramResponse;
expect(casted.type, 1);
expect(casted.errCode, 1);
expect(casted.errStr, 'hehe');
expect(casted.extMsg, 'extMsg');
});
test('WeChatPaymentResponse', () {
var response = BaseWeChatResponse.create(
'onPayResponse',
{'type': 1, 'errCode': 1, 'errStr': 'hehe', 'extData': 'extData'},
);
expect(response is WeChatPaymentResponse, true);
var casted = response as WeChatPaymentResponse;
expect(casted.type, 1);
expect(casted.errCode, 1);
expect(casted.errStr, 'hehe');
expect(casted.extData, 'extData');
});
test('WeChatSubscribeMsgResponse', () {
var response = BaseWeChatResponse.create('onSubscribeMsgResp', {
'type': 1,
'errCode': 1,
'errStr': 'hehe',
'openid': '425235131',
'templateId': '4252345',
'action': 'action',
'reserved': 'reserved',
'scene': 1
});
expect(response is WeChatSubscribeMsgResponse, true);
var casted = response as WeChatSubscribeMsgResponse;
expect(casted.errCode, 1);
expect(casted.errStr, 'hehe');
expect(casted.openid, '425235131');
expect(casted.templateId, '4252345');
expect(casted.action, 'action');
expect(casted.reserved, 'reserved');
expect(casted.scene, 1);
});
test('WeChatAutoDeductResponse', () {
var response = BaseWeChatResponse.create('onAutoDeductResponse', {
'type': 1,
'errCode': 0,
'errStr': 'hehe',
'businessType': 2,
'resultInfo': 'resultInfo'
});
expect(response is WeChatOpenBusinessWebviewResponse, true);
var casted = response as WeChatOpenBusinessWebviewResponse;
assert(casted.isSuccessful);
expect(casted.type, 1);
expect(casted.errCode, 0);
expect(casted.errStr, 'hehe');
expect(casted.resultInfo, 'resultInfo');
expect(casted.businessType, 2);
});
});
}
/*
* Copyright (c) 2020. OpenFlutter Project
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
import 'package:flutter_test/flutter_test.dart';
import 'package:fluwx/fluwx.dart';
void main() {
test('test create WeChatShareImageModel with thumbnail', () {
var image = WeChatImage.network('http://openflutter.dev/fluwx.png');
var thumbnail = WeChatImage.network('http://openflutter.dev/fluwx.png');
var model = WeChatShareImageModel(
image,
scene: WeChatScene.FAVORITE,
thumbnail: thumbnail,
);
expect(model.source, image);
expect(model.scene, WeChatScene.FAVORITE);
expect(model.thumbnail, thumbnail);
});
test('test create WeChatShareImageModel without thumbnail', () {
var image = WeChatImage.network('http://openflutter.dev/fluwx.png');
var model = WeChatShareImageModel(image, scene: WeChatScene.FAVORITE);
expect(model.source, image);
expect(model.scene, WeChatScene.FAVORITE);
expect(model.thumbnail, image);
});
test('test WeChatShareImageModel toMap', () {
var image = WeChatImage.network('http://openflutter.dev/fluwx.png');
var thumbnail = WeChatImage.network('http://openflutter.dev/fluwx.png');
var map = WeChatShareImageModel(
image,
scene: WeChatScene.FAVORITE,
thumbnail: thumbnail,
).toMap();
assert(map['thumbnail'] != null);
expect(map['thumbnail']['source'], 'http://openflutter.dev/fluwx.png');
});
}
/*
* Copyright (c) 2020. OpenFlutter Project
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
import 'package:flutter_test/flutter_test.dart';
import 'package:fluwx/fluwx.dart';
void main() {
group("construct", () {
test("non default values", () {
var thumbnail = WeChatImage.network("http://openflutter.dev/fluwx.png");
var model = WeChatShareMiniProgramModel(
webPageUrl: "http://openflutter.dev",
miniProgramType: WXMiniProgramType.PREVIEW,
withShareTicket: true,
thumbnail: thumbnail,
userName: "userName",
path: "path",
hdImagePath: thumbnail);
expect(model.webPageUrl, "http://openflutter.dev");
expect(model.miniProgramType, WXMiniProgramType.PREVIEW);
expect(model.thumbnail, thumbnail);
expect(model.hdImagePath, thumbnail);
expect(model.path, "path");
expect(model.userName, "userName");
});
test("default values", () {
var thumbnail = WeChatImage.network("http://openflutter.dev/fluwx.png");
var model = WeChatShareMiniProgramModel(
webPageUrl: "http://openflutter.dev",
userName: "userName",
thumbnail: thumbnail);
expect(model.webPageUrl, "http://openflutter.dev");
expect(model.miniProgramType, WXMiniProgramType.RELEASE);
expect(model.thumbnail, null);
expect(model.path, "/");
expect(model.userName, "userName");
});
});
group("toMap", () {
test("with thumbnail", () {
var thumbnail = WeChatImage.network("http://openflutter.dev/fluwx.png");
var map = WeChatShareMiniProgramModel(
webPageUrl: "http://openflutter.dev",
miniProgramType: WXMiniProgramType.PREVIEW,
withShareTicket: true,
thumbnail: thumbnail,
userName: "userName",
path: "path")
.toMap();
expect(map["webPageUrl"], "http://openflutter.dev");
expect(map["miniProgramType"], 2);
expect(map["thumbnail"]["source"], "http://openflutter.dev/fluwx.png");
expect(map["path"], "path");
expect(map["userName"], "userName");
});
test("without thumbnail", () {
var thumbnail = WeChatImage.network("http://openflutter.dev/fluwx.png");
var map = WeChatShareMiniProgramModel(
webPageUrl: "http://openflutter.dev",
miniProgramType: WXMiniProgramType.PREVIEW,
withShareTicket: true,
thumbnail: thumbnail,
userName: "userName",
path: "path")
.toMap();
expect(map["webPageUrl"], "http://openflutter.dev");
expect(map["miniProgramType"], 2);
expect(map["thumbnail"], null);
expect(map["path"], "path");
expect(map["userName"], "userName");
});
});
}
/*
* Copyright (c) 2020. OpenFlutter Project
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. The ASF licenses this
* file to you under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
import 'package:flutter_test/flutter_test.dart';
import 'package:fluwx/src/wechat_file.dart';
void main() {
test('test WeChatImage.fromNetwork', () {
var withSuffixImage = WeChatImage.network(
'http://image.openflutter.dev/fluwx.png',
);
expect(withSuffixImage.source, 'http://image.openflutter.dev/fluwx.png');
expect(withSuffixImage.suffix, '.png');
expect(FileSchema.NETWORK, withSuffixImage.schema);
var withNoSuffixNoUrlSuffixImage = WeChatImage.network(
'http://image.openflutter.dev/fluwx',
);
expect(
'http://image.openflutter.dev/fluwx',
withNoSuffixNoUrlSuffixImage.source,
);
expect(withNoSuffixNoUrlSuffixImage.suffix, '.jpeg');
expect(FileSchema.NETWORK, withSuffixImage.schema);
var withSpecifiedSuffixImage = WeChatImage.network(
'http://image.openflutter.dev/fluwx.jpeg',
suffix: '.png',
);
expect(
withSpecifiedSuffixImage.source,
'http://image.openflutter.dev/fluwx.jpeg',
);
expect(withSpecifiedSuffixImage.suffix, '.png');
expect(withSpecifiedSuffixImage.schema, FileSchema.NETWORK);
});
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论