From 51d09fcea7af16880398799e84b87c935e875eac Mon Sep 17 00:00:00 2001 From: v7lin Date: Tue, 17 May 2022 16:24:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=87=E7=BA=A7Flutter=203.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/FUNDING.yml | 12 - .github/workflows/build.yml | 18 +- .github/workflows/publish.yml | 4 +- .github/workflows/publish_manually.yml | 4 +- .gitignore | 53 +- .metadata | 27 +- CHANGELOG.md | 5 + analysis_options.yaml | 142 +++-- android/.gitignore | 1 + android/build.gradle | 14 +- android/gradle.properties | 3 - .../gradle/wrapper/gradle-wrapper.properties | 5 - .../wechat_kit/WechatCallbackActivity.java | 0 .../v7lin/wechat_kit/WechatKitPlugin.java | 413 +++++------- example/.gitignore | 2 +- example/.metadata | 10 - example/README.md | 8 +- example/android/.gitignore | 2 + example/android/app/build.gradle | 9 +- .../android/app/src/debug/AndroidManifest.xml | 3 +- .../android/app/src/main/AndroidManifest.xml | 7 +- .../res/drawable-v21/launch_background.xml | 12 + .../app/src/main/res/values-night/styles.xml | 18 + .../app/src/main/res/values/styles.xml | 12 +- .../app/src/profile/AndroidManifest.xml | 3 +- example/android/build.gradle | 2 +- example/android/gradle.properties | 1 - .../gradle/wrapper/gradle-wrapper.properties | 3 +- example/android/settings.gradle | 4 - example/ios/.gitignore | 2 + example/ios/Flutter/AppFrameworkInfo.plist | 2 +- example/ios/Flutter/Debug.xcconfig | 2 +- example/ios/Flutter/Release.xcconfig | 2 +- example/ios/Podfile.lock | 46 ++ example/ios/Runner.xcodeproj/project.pbxproj | 66 +- .../xcshareddata/IDEWorkspaceChecks.plist} | 6 +- .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 8 +- .../xcshareddata/WorkspaceSettings.xcsettings | 8 + example/ios/Runner/Info.plist | 4 + example/lib/main.dart | 157 ++--- example/pubspec.lock | 399 ++++++++++++ example/pubspec.yaml | 71 ++- example/test/widget_test.dart | 12 +- ios/.gitignore | 1 + ios/Classes/WechatKitPlugin.m | 399 +++++------- ios/wechat_kit.podspec | 10 +- lib/src/wechat.dart | 600 +++++------------- lib/src/wechat_constant.dart | 16 +- lib/src/wechat_kit_method_channel.dart | 549 ++++++++++++++++ lib/src/wechat_kit_platform_interface.dart | 247 +++++++ lib/wechat_kit.dart | 0 pubspec.yaml | 30 +- test/wechat_kit_method_channel_test.dart | 27 + test/wechat_kit_test.dart | 138 ---- test/wechat_test.dart | 273 ++++++++ 56 files changed, 2426 insertions(+), 1454 deletions(-) delete mode 100644 .github/FUNDING.yml delete mode 100644 android/gradle.properties delete mode 100644 android/gradle/wrapper/gradle-wrapper.properties mode change 100755 => 100644 android/src/main/java/io/github/v7lin/wechat_kit/WechatCallbackActivity.java delete mode 100644 example/.metadata create mode 100644 example/android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 example/android/app/src/main/res/values-night/styles.xml create mode 100644 example/ios/Podfile.lock rename example/ios/{Runner/Runner.entitlements => Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist} (62%) create mode 100644 example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 example/pubspec.lock mode change 100755 => 100644 lib/src/wechat.dart create mode 100644 lib/src/wechat_kit_method_channel.dart create mode 100644 lib/src/wechat_kit_platform_interface.dart mode change 100755 => 100644 lib/wechat_kit.dart create mode 100644 test/wechat_kit_method_channel_test.dart delete mode 100644 test/wechat_kit_test.dart create mode 100644 test/wechat_test.dart diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 18322f7..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: https://v7lin.github.io/docsify/#/navbar/sponsor # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d285774..331fd9d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,10 +10,12 @@ jobs: matrix: os: [macos-latest] steps: - - uses: actions/checkout@v1 - - uses: actions/setup-java@v1 + - uses: actions/checkout@v2 + - uses: actions/setup-java@v2 with: - java-version: '8.x' + distribution: 'temurin' + java-version: '11' + cache: 'gradle' - uses: subosito/flutter-action@v1 with: channel: 'stable' @@ -32,10 +34,12 @@ jobs: matrix: os: [ubuntu-latest] steps: - - uses: actions/checkout@v1 - - uses: actions/setup-java@v1 + - uses: actions/checkout@v2 + - uses: actions/setup-java@v2 with: - java-version: '8.x' + distribution: 'temurin' + java-version: '11' + cache: 'gradle' - uses: subosito/flutter-action@v1 with: channel: 'stable' @@ -45,5 +49,5 @@ jobs: - run: flutter format --dry-run --set-exit-if-changed . - run: flutter pub publish --dry-run - run: flutter analyze lib example/lib - - run: sudo echo "y" | sudo $ANDROID_HOME/tools/bin/sdkmanager "ndk;20.0.5594570" + - run: sudo echo "y" | sudo $ANDROID_HOME/tools/bin/sdkmanager "ndk;21.1.6352462" - run: cd example; flutter build apk --debug diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index eeeadb3..187bfab 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,8 +9,8 @@ jobs: name: Publish runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: sakebook/actions-flutter-pub-publisher@v1.3.0 + - uses: actions/checkout@v2 + - uses: sakebook/actions-flutter-pub-publisher@v1.4.0 with: credential: ${{ secrets.CREDENTIAL_JSON }} flutter_package: true diff --git a/.github/workflows/publish_manually.yml b/.github/workflows/publish_manually.yml index 1c51463..fb0aadf 100644 --- a/.github/workflows/publish_manually.yml +++ b/.github/workflows/publish_manually.yml @@ -7,8 +7,8 @@ jobs: name: Publish Manually runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: sakebook/actions-flutter-pub-publisher@v1.3.0 + - uses: actions/checkout@v2 + - uses: sakebook/actions-flutter-pub-publisher@v1.4.0 with: credential: ${{ secrets.CREDENTIAL_JSON }} flutter_package: true diff --git a/.gitignore b/.gitignore index 57a0334..96486fd 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ .buildlog/ .history .svn/ +migrate_working_dir/ # IntelliJ related *.iml @@ -21,57 +22,9 @@ #.vscode/ # Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock **/doc/api/ .dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies .packages -.pub-cache/ -.pub/ build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Flutter.podspec -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages -*.lock -.env diff --git a/.metadata b/.metadata index 53b454c..5bfec1b 100644 --- a/.metadata +++ b/.metadata @@ -1,10 +1,33 @@ # 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. +# This file should be version controlled. version: - revision: b041144f833e05cf463b8887fa12efdec9493488 + revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 channel: stable project_type: plugin + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 + base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 + - platform: android + create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 + base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 + - platform: ios + create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 + base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d46f7b..3f850d6 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.0.0 + +* 升级 Flutter 3.0 +* break change: 官方标准化插件 + ## 3.2.0 * 合并 pay 和 no_pay diff --git a/analysis_options.yaml b/analysis_options.yaml index 0afdb32..2e4f838 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -5,38 +5,42 @@ # # For a list of lints, see: http://dart-lang.github.io/linter/lints/ # See the configuration guide for more -# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer +# https://github.com/dart-lang/sdk/tree/main/pkg/analyzer#configuring-the-analyzer # # There are other similar analysis options files in the flutter repos, # which should be kept in sync with this file: # # - analysis_options.yaml (this file) -# - packages/flutter/lib/analysis_options_user.yaml # - https://github.com/flutter/plugins/blob/master/analysis_options.yaml # - https://github.com/flutter/engine/blob/master/analysis_options.yaml +# - https://github.com/flutter/packages/blob/master/analysis_options.yaml # # This file contains the analysis options used by Flutter tools, such as IntelliJ, # Android Studio, and the `flutter analyze` command. analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: false + language: + strict-raw-types: true errors: # treat missing required parameters as a warning (not a hint) missing_required_param: warning # treat missing returns as a warning (not a hint) missing_return: warning - # allow having TODOs in the code + # allow having TODO comments in the code todo: ignore # allow self-reference to deprecated members (we do this because otherwise we have # to annotate every member in every test, assert, etc, when we deprecate something) deprecated_member_use_from_same_package: ignore - # Ignore analyzer hints for updating pubspecs when using Future or - # Stream and not importing dart:async - # Please see https://github.com/flutter/flutter/pull/24528 for details. - sdk_version_async_exported_from_core: ignore + # TODO(ianh): https://github.com/flutter/flutter/issues/74381 + # Clean up existing unnecessary imports, and remove line to ignore. + unnecessary_import: ignore + # Turned off until null-safe rollout is complete. + unnecessary_null_comparison: ignore exclude: + - "bin/cache/**" + # Ignore protoc generated files + - "dev/conductor/lib/proto/*" + # - "lib/*.g.dart" - "lib/**/*.g.dart" @@ -50,65 +54,71 @@ linter: # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 - always_require_non_null_named_parameters - always_specify_types - - always_use_package_imports # we do this commonly + # - always_use_package_imports # we do this commonly - annotate_overrides # - avoid_annotating_with_dynamic # conflicts with always_specify_types - # - avoid_as # required for implicit-casts: true - avoid_bool_literals_in_conditional_expressions - # - avoid_catches_without_on_clauses # we do this commonly - # - avoid_catching_errors # we do this commonly + # - avoid_catches_without_on_clauses # blocked on https://github.com/dart-lang/linter/issues/3023 + # - avoid_catching_errors # blocked on https://github.com/dart-lang/linter/issues/3023 - avoid_classes_with_only_static_members - # - avoid_double_and_int_checks # only useful when targeting JS runtime + - avoid_double_and_int_checks + - avoid_dynamic_calls - avoid_empty_else - avoid_equals_and_hash_code_on_mutable_classes - # - avoid_escaping_inner_quotes # not yet tested + - avoid_escaping_inner_quotes - avoid_field_initializers_in_const_classes + # - avoid_final_parameters # incompatible with prefer_final_parameters - avoid_function_literals_in_foreach_calls - # - avoid_implementing_value_types # not yet tested + - avoid_implementing_value_types - avoid_init_to_null - # - avoid_js_rounded_ints # only useful when targeting JS runtime + - avoid_js_rounded_ints + # - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to - avoid_null_checks_in_equality_operators - # - avoid_positional_boolean_parameters # not yet tested - # - avoid_print # not yet tested + # - avoid_positional_boolean_parameters # would have been nice to enable this but by now there's too many places that break it + - avoid_print # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) - # - avoid_redundant_argument_values # not yet tested + - avoid_redundant_argument_values - avoid_relative_lib_imports - avoid_renaming_method_parameters - avoid_return_types_on_setters - # - avoid_returning_null # there are plenty of valid reasons to return null - # - avoid_returning_null_for_future # not yet tested + # - avoid_returning_null # still violated by some pre-nnbd code that we haven't yet migrated + - avoid_returning_null_for_future - avoid_returning_null_for_void - # - avoid_returning_this # there are plenty of valid reasons to return this - # - avoid_setters_without_getters # not yet tested + # - avoid_returning_this # there are enough valid reasons to return `this` that this lint ends up with too many false positives + - avoid_setters_without_getters - avoid_shadowing_type_parameters - avoid_single_cascade_in_expression_statements - avoid_slow_async_io - # - avoid_type_to_string # we do this commonly + - avoid_type_to_string - avoid_types_as_parameter_names # - avoid_types_on_closure_parameters # conflicts with always_specify_types - # - avoid_unnecessary_containers # not yet tested + - avoid_unnecessary_containers - avoid_unused_constructor_parameters - avoid_void_async - # - avoid_web_libraries_in_flutter # not yet tested + # - avoid_web_libraries_in_flutter # we use web libraries in web-specific code, and our tests prevent us from using them elsewhere - await_only_futures - camel_case_extensions - camel_case_types - cancel_subscriptions - # - cascade_invocations # not yet tested + # - cascade_invocations # doesn't match the typical style of this repo - cast_nullable_to_non_nullable # - close_sinks # not reliable enough - # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 + # - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142 + # - conditional_uri_does_not_exist # not yet tested # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 - control_flow_in_finally # - curly_braces_in_flow_control_structures # not required by flutter style - # - diagnostic_describe_all_properties # not yet tested + - depend_on_referenced_packages + - deprecated_consistency + # - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib) - directives_ordering - # - do_not_use_environment # we do this commonly + # - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic - empty_catches - empty_constructor_bodies - empty_statements + - eol_at_end_of_file - exhaustive_cases - - file_names # not yet tested + - file_names - flutter_style_todos - hash_and_equals - implementation_imports @@ -118,24 +128,28 @@ linter: - leading_newlines_in_multiline_strings - library_names - library_prefixes + - library_private_types_in_public_api # - lines_longer_than_80_chars # not required by flutter style - list_remove_unrelated_type - # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 - # - missing_whitespace_between_adjacent_strings # not yet tested + # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/linter/issues/453 + - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - # - no_default_cases # too many false positives + - no_default_cases - no_duplicate_case_values + - no_leading_underscores_for_library_prefixes + - no_leading_underscores_for_local_identifiers - no_logic_in_create_state # - no_runtimeType_toString # ok in tests; we enable this only in packages/ - non_constant_identifier_names + - noop_primitive_operations - null_check_on_nullable_type_parameter - # - null_closures # not required by flutter style + - null_closures # - omit_local_variable_types # opposite of always_specify_types # - one_member_abstracts # too many false positives - # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 + - only_throw_errors # this does get disabled in a few places where we have legacy code that uses strings et al - overridden_fields - package_api_docs - # - package_names # non conforming packages in sdk + - package_names - package_prefixed_library_names # - parameter_assignments # we do this commonly - prefer_adjacent_string_concatenation @@ -143,10 +157,10 @@ linter: # - prefer_asserts_with_message # not required by flutter style - prefer_collection_literals - prefer_conditional_assignment - - prefer_const_constructors + # - prefer_const_constructors - prefer_const_constructors_in_immutables - prefer_const_declarations - - prefer_const_literals_to_create_immutables + # - prefer_const_literals_to_create_immutables # - prefer_constructors_over_static_methods # far too many false positives - prefer_contains # - prefer_double_quotes # opposite of prefer_single_quotes @@ -155,33 +169,38 @@ linter: - prefer_final_fields - prefer_final_in_for_each - prefer_final_locals + # - prefer_final_parameters # we should enable this one day when it can be auto-fixed (https://github.com/dart-lang/linter/issues/3104), see also parameter_assignments - prefer_for_elements_to_map_fromIterable - prefer_foreach - # - prefer_function_declarations_over_variables # not yet tested + - prefer_function_declarations_over_variables - prefer_generic_function_type_aliases - prefer_if_elements_to_conditional_expressions - prefer_if_null_operators - prefer_initializing_formals - prefer_inlined_adds - # - prefer_int_literals # not yet tested - # - prefer_interpolation_to_compose_strings # not yet tested + # - prefer_int_literals # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#use-double-literals-for-double-constants + - prefer_interpolation_to_compose_strings - prefer_is_empty - prefer_is_not_empty - prefer_is_not_operator - prefer_iterable_whereType - # - prefer_mixin # https://github.com/dart-lang/language/issues/32 - # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 - # - prefer_relative_imports # not yet tested + # - prefer_mixin # Has false positives, see https://github.com/dart-lang/linter/issues/3018 + # - prefer_null_aware_method_calls # "call()" is confusing to people new to the language since it's not documented anywhere + - prefer_null_aware_operators + # - prefer_relative_imports - prefer_single_quotes - prefer_spread_collections - prefer_typing_uninitialized_variables - prefer_void_to_null - # - provide_deprecation_message # not yet tested + - provide_deprecation_message # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml - recursive_getters - # - sized_box_for_whitespace # not yet tested + # - require_trailing_commas # blocked on https://github.com/dart-lang/sdk/issues/47441 + - secure_pubspec_urls + - sized_box_for_whitespace + # - sized_box_shrink_expand # not yet tested - slash_for_doc_comments - # - sort_child_properties_last # not yet tested + - sort_child_properties_last - sort_constructors_first # - sort_pub_dependencies # prevents separating pinned transitive dependencies - sort_unnamed_constructors_first @@ -190,36 +209,43 @@ linter: - tighten_type_of_initializing_formals # - type_annotate_public_apis # subset of always_specify_types - type_init_formals - - unawaited_futures # too many false positives - # - unnecessary_await_in_return # not yet tested + # - unawaited_futures # too many false positives, especially with the way AnimationController works + - unnecessary_await_in_return - unnecessary_brace_in_string_interps - unnecessary_const + - unnecessary_constructor_name # - unnecessary_final # conflicts with prefer_final_locals - unnecessary_getters_setters # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 + - unnecessary_late - unnecessary_new - unnecessary_null_aware_assignments - # - unnecessary_null_checks # not yet tested + - unnecessary_null_checks - unnecessary_null_in_if_null_operators - unnecessary_nullable_for_final_variable_declarations - unnecessary_overrides - unnecessary_parenthesis - # - unnecessary_raw_strings # not yet tested + # - unnecessary_raw_strings # what's "necessary" is a matter of opinion; consistency across strings can help readability more than this lint - unnecessary_statements - unnecessary_string_escapes - unnecessary_string_interpolations - unnecessary_this - unrelated_type_equality_checks - # - unsafe_html # not yet tested + - unsafe_html + - use_build_context_synchronously + # - use_decorated_box # not yet tested - use_full_hex_values_for_flutter_colors - # - use_function_type_syntax_for_parameters # not yet tested + - use_function_type_syntax_for_parameters + - use_if_null_to_convert_nulls_to_bools - use_is_even_rather_than_modulo - # - use_key_in_widget_constructors # not yet tested + - use_key_in_widget_constructors - use_late_for_private_fields_and_variables + - use_named_constants - use_raw_strings - use_rethrow_when_possible - # - use_setters_to_change_properties # not yet tested + - use_setters_to_change_properties # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 + - use_test_throws_matchers # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review - valid_regexps - void_checks diff --git a/android/.gitignore b/android/.gitignore index c6cbe56..161bdcd 100644 --- a/android/.gitignore +++ b/android/.gitignore @@ -6,3 +6,4 @@ .DS_Store /build /captures +.cxx diff --git a/android/build.gradle b/android/build.gradle index f365c04..a0060ab 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ group 'io.github.v7lin.wechat_kit' -version '3.2.0' +version '4.0.0' buildscript { repositories { @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.1.2' } } @@ -24,6 +24,11 @@ apply plugin: 'com.android.library' android { compileSdkVersion 31 + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + resourcePrefix 'wechat_kit' defaultConfig { @@ -33,10 +38,6 @@ android { consumerProguardFiles 'consumer-rules.pro' } - lintOptions { - disable 'InvalidPackage' - } - flavorDimensions 'vendor' productFlavors { @@ -53,4 +54,3 @@ dependencies { // vendorImplementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.8.0' } - diff --git a/android/gradle.properties b/android/gradle.properties deleted file mode 100644 index 94adc3a..0000000 --- a/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.useAndroidX=true -android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 3c9d085..0000000 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/android/src/main/java/io/github/v7lin/wechat_kit/WechatCallbackActivity.java b/android/src/main/java/io/github/v7lin/wechat_kit/WechatCallbackActivity.java old mode 100755 new mode 100644 diff --git a/android/src/main/java/io/github/v7lin/wechat_kit/WechatKitPlugin.java b/android/src/main/java/io/github/v7lin/wechat_kit/WechatKitPlugin.java index 06d4b21..e24b9d9 100644 --- a/android/src/main/java/io/github/v7lin/wechat_kit/WechatKitPlugin.java +++ b/android/src/main/java/io/github/v7lin/wechat_kit/WechatKitPlugin.java @@ -22,9 +22,9 @@ import com.tencent.mm.opensdk.modelbiz.OpenRankList; import com.tencent.mm.opensdk.modelbiz.OpenWebview; import com.tencent.mm.opensdk.modelbiz.SubscribeMessage; import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram; +import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView; import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessWebview; import com.tencent.mm.opensdk.modelbiz.WXOpenCustomerServiceChat; -import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView; import com.tencent.mm.opensdk.modelmsg.LaunchFromWX; import com.tencent.mm.opensdk.modelmsg.SendAuth; import com.tencent.mm.opensdk.modelmsg.SendMessageToWX; @@ -61,116 +61,7 @@ import io.flutter.plugin.common.PluginRegistry; /** * WechatKitPlugin */ -public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, PluginRegistry.NewIntentListener, MethodCallHandler { - - // - - private static final String METHOD_REGISTERAPP = "registerApp"; - private static final String METHOD_HANDLEINITIALWXREQ = "handleInitialWXReq"; - private static final String METHOD_ISINSTALLED = "isInstalled"; - private static final String METHOD_ISSUPPORTAPI = "isSupportApi"; - private static final String METHOD_ISSUPPORTSTATEAPI = "isSupportStateAPI"; - private static final String METHOD_OPENWECHAT = "openWechat"; - private static final String METHOD_AUTH = "auth"; - private static final String METHOD_STARTQRAUTH = "startQrauth"; - private static final String METHOD_STOPQRAUTH = "stopQrauth"; - private static final String METHOD_OPENURL = "openUrl"; - private static final String METHOD_OPENRANKLIST = "openRankList"; - private static final String METHOD_SHARETEXT = "shareText"; - private static final String METHOD_SHAREIMAGE = "shareImage"; - private static final String METHOD_SHAREFILE = "shareFile"; - private static final String METHOD_SHAREEMOJI = "shareEmoji"; - private static final String METHOD_SHAREMUSIC = "shareMusic"; - private static final String METHOD_SHAREVIDEO = "shareVideo"; - private static final String METHOD_SHAREWEBPAGE = "shareWebpage"; - private static final String METHOD_SHAREMINIPROGRAM = "shareMiniProgram"; - private static final String METHOD_SUBSCRIBEMSG = "subscribeMsg"; - private static final String METHOD_LAUNCHMINIPROGRAM = "launchMiniProgram"; - private static final String METHOD_OPENCUSTOMERSERVICECHAT = "openCustomerServiceChat"; - private static final String METHOD_OPENBUSINESSVIEW = "openBusinessView"; - private static final String METHOD_OPENBUSINESSWEBVIEW = "openBusinessWebview"; - private static final String METHOD_PAY = "pay"; - - private static final String METHOD_ONLAUNCHFROMWXREQ = "onLaunchFromWXReq"; - private static final String METHOD_ONSHOWMESSAGEFROMWXREQ = "onShowMessageFromWXReq"; - - private static final String METHOD_ONAUTHRESP = "onAuthResp"; - private static final String METHOD_ONOPENURLRESP = "onOpenUrlResp"; - private static final String METHOD_ONSHAREMSGRESP = "onShareMsgResp"; - private static final String METHOD_ONSUBSCRIBEMSGRESP = "onSubscribeMsgResp"; - private static final String METHOD_ONLAUNCHMINIPROGRAMRESP = "onLaunchMiniProgramResp"; - private static final String METHOD_ONOPENCUSTOMERSERVICECHATRESP = "onOpenCustomerServiceChatResp"; - private static final String METHOD_ONOPENBUSINESSVIEWRESP = "onOpenBusinessViewResp"; - private static final String METHOD_ONOPENBUSINESSWEBVIEWRESP = "onOpenBusinessWebviewResp"; - private static final String METHOD_ONPAYRESP = "onPayResp"; - private static final String METHOD_ONAUTHGOTQRCODE = "onAuthGotQrcode"; - private static final String METHOD_ONAUTHQRCODESCANNED = "onAuthQrcodeScanned"; - private static final String METHOD_ONAUTHFINISH = "onAuthFinish"; - - private static final String ARGUMENT_KEY_APPID = "appId"; - // private static final String ARGUMENT_KEY_UNIVERSALLINK = "universalLink"; - private static final String ARGUMENT_KEY_SCOPE = "scope"; - private static final String ARGUMENT_KEY_STATE = "state"; - private static final String ARGUMENT_KEY_NONCESTR = "noncestr"; - private static final String ARGUMENT_KEY_TIMESTAMP = "timestamp"; - private static final String ARGUMENT_KEY_SIGNATURE = "signature"; - private static final String ARGUMENT_KEY_URL = "url"; - private static final String ARGUMENT_KEY_QUERY = "query"; - private static final String ARGUMENT_KEY_USERNAME = "username"; - private static final String ARGUMENT_KEY_SCENE = "scene"; - private static final String ARGUMENT_KEY_TEXT = "text"; - private static final String ARGUMENT_KEY_TITLE = "title"; - private static final String ARGUMENT_KEY_DESCRIPTION = "description"; - private static final String ARGUMENT_KEY_THUMBDATA = "thumbData"; - private static final String ARGUMENT_KEY_IMAGEDATA = "imageData"; - private static final String ARGUMENT_KEY_IMAGEURI = "imageUri"; - private static final String ARGUMENT_KEY_EMOJIDATA = "emojiData"; - private static final String ARGUMENT_KEY_EMOJIURI = "emojiUri"; - private static final String ARGUMENT_KEY_FILEDATA = "fileData"; - private static final String ARGUMENT_KEY_FILEURI = "fileUri"; - // private static final String ARGUMENT_KEY_FILEEXTENSION = "fileExtension"; - private static final String ARGUMENT_KEY_MUSICURL = "musicUrl"; - private static final String ARGUMENT_KEY_MUSICDATAURL = "musicDataUrl"; - private static final String ARGUMENT_KEY_MUSICLOWBANDURL = "musicLowBandUrl"; - private static final String ARGUMENT_KEY_MUSICLOWBANDDATAURL = "musicLowBandDataUrl"; - private static final String ARGUMENT_KEY_VIDEOURL = "videoUrl"; - private static final String ARGUMENT_KEY_VIDEOLOWBANDURL = "videoLowBandUrl"; - private static final String ARGUMENT_KEY_WEBPAGEURL = "webpageUrl"; - private static final String ARGUMENT_KEY_PATH = "path"; - private static final String ARGUMENT_KEY_HDIMAGEDATA = "hdImageData"; - private static final String ARGUMENT_KEY_WITHSHARETICKET = "withShareTicket"; - private static final String ARGUMENT_KEY_TYPE = "type"; - private static final String ARGUMENT_KEY_DISABLEFORWARD = "disableForward"; - private static final String ARGUMENT_KEY_TEMPLATEID = "templateId"; - private static final String ARGUMENT_KEY_RESERVED = "reserved"; - private static final String ARGUMENT_KEY_CORPID = "corpId"; - private static final String ARGUMENT_KEY_BUSINESSTYPE = "businessType"; - private static final String ARGUMENT_KEY_QUERYINFO = "queryInfo"; - private static final String ARGUMENT_KEY_PARTNERID = "partnerId"; - private static final String ARGUMENT_KEY_PREPAYID = "prepayId"; - private static final String ARGUMENT_KEY_PACKAGE = "package"; - private static final String ARGUMENT_KEY_SIGN = "sign"; - private static final String ARGUMENT_KEY_EXTINFO = "extInfo"; - - private static final String ARGUMENT_KEY_RESULT_ERRORCODE = "errorCode"; - private static final String ARGUMENT_KEY_RESULT_ERRORMSG = "errorMsg"; - private static final String ARGUMENT_KEY_RESULT_CODE = "code"; - private static final String ARGUMENT_KEY_RESULT_STATE = "state"; - private static final String ARGUMENT_KEY_RESULT_LANG = "lang"; - private static final String ARGUMENT_KEY_RESULT_COUNTRY = "country"; - private static final String ARGUMENT_KEY_RESULT_TEMPLATEID = "templateId"; - private static final String ARGUMENT_KEY_RESULT_SCENE = "scene"; - private static final String ARGUMENT_KEY_RESULT_ACTION = "action"; - private static final String ARGUMENT_KEY_RESULT_RESERVED = "reserved"; - private static final String ARGUMENT_KEY_RESULT_EXTMSG = "extMsg"; - private static final String ARGUMENT_KEY_RESULT_BUSINESSTYPE = "businessType"; - private static final String ARGUMENT_KEY_RESULT_RESULTINFO = "resultInfo"; - private static final String ARGUMENT_KEY_RESULT_MESSAGEACTION = "messageAction"; - private static final String ARGUMENT_KEY_RESULT_MESSAGEEXT = "messageExt"; - private static final String ARGUMENT_KEY_RESULT_RETURNKEY = "returnKey"; - private static final String ARGUMENT_KEY_RESULT_IMAGEDATA = "imageData"; - private static final String ARGUMENT_KEY_RESULT_AUTHCODE = "authCode"; - +public class WechatKitPlugin implements FlutterPlugin, ActivityAware, PluginRegistry.NewIntentListener, MethodCallHandler { /// The MethodChannel that will the communication between Flutter and native Android /// /// This local reference serves to register the plugin with the Flutter Engine and unregister it @@ -190,7 +81,6 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { channel = new MethodChannel(binding.getBinaryMessenger(), "v7lin.github.io/wechat_kit"); channel.setMethodCallHandler(this); - applicationContext = binding.getApplicationContext(); } @@ -199,7 +89,6 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { channel.setMethodCallHandler(null); channel = null; - applicationContext = null; } @@ -230,7 +119,7 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug // --- NewIntentListener @Override - public boolean onNewIntent(Intent intent) { + public boolean onNewIntent(@NonNull Intent intent) { final Intent resp = WechatCallbackActivity.extraCallback(intent); if (resp != null) { if (iwxapi != null) { @@ -246,22 +135,22 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug public void onReq(BaseReq req) { final Map map = new HashMap<>(); if (req instanceof LaunchFromWX.Req) { - LaunchFromWX.Req launchFromWXReq = (LaunchFromWX.Req) req; - map.put(ARGUMENT_KEY_RESULT_MESSAGEACTION, launchFromWXReq.messageAction); - map.put(ARGUMENT_KEY_RESULT_MESSAGEEXT, launchFromWXReq.messageExt); - map.put(ARGUMENT_KEY_RESULT_LANG, launchFromWXReq.lang); - map.put(ARGUMENT_KEY_RESULT_COUNTRY, launchFromWXReq.country); + final LaunchFromWX.Req launchFromWXReq = (LaunchFromWX.Req) req; + map.put("messageAction", launchFromWXReq.messageAction); + map.put("messageExt", launchFromWXReq.messageExt); + map.put("lang", launchFromWXReq.lang); + map.put("country", launchFromWXReq.country); if (channel != null) { - channel.invokeMethod(METHOD_ONLAUNCHFROMWXREQ, map); + channel.invokeMethod("onLaunchFromWXReq", map); } } else if (req instanceof ShowMessageFromWX.Req) { - ShowMessageFromWX.Req showMessageFromWXReq = (ShowMessageFromWX.Req) req; - map.put(ARGUMENT_KEY_RESULT_MESSAGEACTION, showMessageFromWXReq.message.messageAction); - map.put(ARGUMENT_KEY_RESULT_MESSAGEEXT, showMessageFromWXReq.message.messageExt); - map.put(ARGUMENT_KEY_RESULT_LANG, showMessageFromWXReq.lang); - map.put(ARGUMENT_KEY_RESULT_COUNTRY, showMessageFromWXReq.country); + final ShowMessageFromWX.Req showMessageFromWXReq = (ShowMessageFromWX.Req) req; + map.put("messageAction", showMessageFromWXReq.message.messageAction); + map.put("messageExt", showMessageFromWXReq.message.messageExt); + map.put("lang", showMessageFromWXReq.lang); + map.put("country", showMessageFromWXReq.country); if (channel != null) { - channel.invokeMethod(METHOD_ONSHOWMESSAGEFROMWXREQ, map); + channel.invokeMethod("onShowMessageFromWXReq", map); } } } @@ -269,81 +158,81 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug @Override public void onResp(BaseResp resp) { final Map map = new HashMap<>(); - map.put(ARGUMENT_KEY_RESULT_ERRORCODE, resp.errCode); - map.put(ARGUMENT_KEY_RESULT_ERRORMSG, resp.errStr); + map.put("errorCode", resp.errCode); + map.put("errorMsg", resp.errStr); if (resp instanceof SendAuth.Resp) { // 授权 if (resp.errCode == BaseResp.ErrCode.ERR_OK) { - SendAuth.Resp authResp = (SendAuth.Resp) resp; - map.put(ARGUMENT_KEY_RESULT_CODE, authResp.code); - map.put(ARGUMENT_KEY_RESULT_STATE, authResp.state); - map.put(ARGUMENT_KEY_RESULT_LANG, authResp.lang); - map.put(ARGUMENT_KEY_RESULT_COUNTRY, authResp.country); + final SendAuth.Resp authResp = (SendAuth.Resp) resp; + map.put("code", authResp.code); + map.put("state", authResp.state); + map.put("lang", authResp.lang); + map.put("country", authResp.country); } if (channel != null) { - channel.invokeMethod(METHOD_ONAUTHRESP, map); + channel.invokeMethod("onAuthResp", map); } } else if (resp instanceof OpenWebview.Resp) { // 浏览器 if (channel != null) { - channel.invokeMethod(METHOD_ONOPENURLRESP, map); + channel.invokeMethod("onOpenUrlResp", map); } } else if (resp instanceof SendMessageToWX.Resp) { // 分享 if (channel != null) { - channel.invokeMethod(METHOD_ONSHAREMSGRESP, map); + channel.invokeMethod("onShareMsgResp", map); } } else if (resp instanceof SubscribeMessage.Resp) { // 一次性订阅消息 if (resp.errCode == BaseResp.ErrCode.ERR_OK) { - SubscribeMessage.Resp subscribeMsgResp = (SubscribeMessage.Resp) resp; - map.put(ARGUMENT_KEY_RESULT_TEMPLATEID, subscribeMsgResp.templateID); - map.put(ARGUMENT_KEY_RESULT_SCENE, subscribeMsgResp.scene); - map.put(ARGUMENT_KEY_RESULT_ACTION, subscribeMsgResp.action); - map.put(ARGUMENT_KEY_RESULT_RESERVED, subscribeMsgResp.reserved); + final SubscribeMessage.Resp subscribeMsgResp = (SubscribeMessage.Resp) resp; + map.put("templateId", subscribeMsgResp.templateID); + map.put("scene", subscribeMsgResp.scene); + map.put("action", subscribeMsgResp.action); + map.put("reserved", subscribeMsgResp.reserved); } if (channel != null) { - channel.invokeMethod(METHOD_ONSUBSCRIBEMSGRESP, map); + channel.invokeMethod("onSubscribeMsgResp", map); } } else if (resp instanceof WXLaunchMiniProgram.Resp) { // 打开小程序 if (resp.errCode == BaseResp.ErrCode.ERR_OK) { - WXLaunchMiniProgram.Resp launchMiniProgramResp = (WXLaunchMiniProgram.Resp) resp; - map.put(ARGUMENT_KEY_RESULT_EXTMSG, launchMiniProgramResp.extMsg); + final WXLaunchMiniProgram.Resp launchMiniProgramResp = (WXLaunchMiniProgram.Resp) resp; + map.put("extMsg", launchMiniProgramResp.extMsg); } if (channel != null) { - channel.invokeMethod(METHOD_ONLAUNCHMINIPROGRAMRESP, map); + channel.invokeMethod("onLaunchMiniProgramResp", map); } } else if (resp instanceof WXOpenCustomerServiceChat.Resp) { if (channel != null) { - channel.invokeMethod(METHOD_ONOPENCUSTOMERSERVICECHATRESP, map); + channel.invokeMethod("onOpenCustomerServiceChatResp", map); } } else if (resp instanceof WXOpenBusinessView.Resp) { if (resp.errCode == BaseResp.ErrCode.ERR_OK) { - WXOpenBusinessView.Resp openBusinessViewResp = (WXOpenBusinessView.Resp) resp; - map.put(ARGUMENT_KEY_RESULT_BUSINESSTYPE, openBusinessViewResp.businessType); - map.put(ARGUMENT_KEY_RESULT_EXTMSG, openBusinessViewResp.extMsg); + final WXOpenBusinessView.Resp openBusinessViewResp = (WXOpenBusinessView.Resp) resp; + map.put("businessType", openBusinessViewResp.businessType); + map.put("extMsg", openBusinessViewResp.extMsg); } if (channel != null) { - channel.invokeMethod(METHOD_ONOPENBUSINESSVIEWRESP, map); + channel.invokeMethod("onOpenBusinessViewResp", map); } } else if (resp instanceof WXOpenBusinessWebview.Resp) { if (resp.errCode == BaseResp.ErrCode.ERR_OK) { - WXOpenBusinessWebview.Resp openBusinessWebviewResp = (WXOpenBusinessWebview.Resp) resp; - map.put(ARGUMENT_KEY_RESULT_BUSINESSTYPE, openBusinessWebviewResp.businessType); - map.put(ARGUMENT_KEY_RESULT_RESULTINFO, openBusinessWebviewResp.resultInfo); + final WXOpenBusinessWebview.Resp openBusinessWebviewResp = (WXOpenBusinessWebview.Resp) resp; + map.put("businessType", openBusinessWebviewResp.businessType); + map.put("resultInfo", openBusinessWebviewResp.resultInfo); } if (channel != null) { - channel.invokeMethod(METHOD_ONOPENBUSINESSWEBVIEWRESP, map); + channel.invokeMethod("onOpenBusinessWebviewResp", map); } } else if (resp instanceof PayResp) { // 支付 if (resp.errCode == BaseResp.ErrCode.ERR_OK) { - PayResp payResp = (PayResp) resp; - map.put(ARGUMENT_KEY_RESULT_RETURNKEY, payResp.returnKey); + final PayResp payResp = (PayResp) resp; + map.put("returnKey", payResp.returnKey); } if (channel != null) { - channel.invokeMethod(METHOD_ONPAYRESP, map); + channel.invokeMethod("onPayResp", map); } } } @@ -353,48 +242,48 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug @Override public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { - if (METHOD_REGISTERAPP.equals(call.method)) { + if ("registerApp".equals(call.method)) { registerApp(call, result); - } else if (METHOD_HANDLEINITIALWXREQ.equals(call.method)) { + } else if ("handleInitialWXReq".equals(call.method)) { handleInitialWXReq(call, result); - } else if (METHOD_ISINSTALLED.equals(call.method)) { + } else if ("isInstalled".equals(call.method)) { result.success(iwxapi != null && iwxapi.isWXAppInstalled()); - } else if (METHOD_ISSUPPORTAPI.equals(call.method)) { + } else if ("isSupportApi".equals(call.method)) { result.success(iwxapi != null && iwxapi.getWXAppSupportAPI() >= Build.OPENID_SUPPORTED_SDK_INT); - } else if (METHOD_ISSUPPORTSTATEAPI.equals(call.method)) { + } else if ("isSupportStateApi".equals(call.method)) { result.success(iwxapi != null && iwxapi.getWXAppSupportAPI() >= Build.SUPPORTED_SEND_TO_STATUS); - } else if (METHOD_OPENWECHAT.equals(call.method)) { + } else if ("openWechat".equals(call.method)) { result.success(iwxapi != null && iwxapi.openWXApp()); - } else if (METHOD_AUTH.equals(call.method)) { + } else if ("auth".equals(call.method)) { handleAuthCall(call, result); - } else if (METHOD_STARTQRAUTH.equals(call.method) || - METHOD_STOPQRAUTH.equals(call.method)) { + } else if ("startQrauth".equals(call.method) || + "stopQrauth".equals(call.method)) { handleQRAuthCall(call, result); - } else if (METHOD_OPENURL.equals(call.method)) { + } else if ("openUrl".equals(call.method)) { handleOpenUrlCall(call, result); - } else if (METHOD_OPENRANKLIST.equals(call.method)) { + } else if ("openRankList".equals(call.method)) { handleOpenRankListCall(call, result); - } else if (METHOD_SHARETEXT.equals(call.method)) { + } else if ("shareText".equals(call.method)) { handleShareTextCall(call, result); - } else if (METHOD_SHAREIMAGE.equals(call.method) || - METHOD_SHAREFILE.equals(call.method) || - METHOD_SHAREEMOJI.equals(call.method) || - METHOD_SHAREMUSIC.equals(call.method) || - METHOD_SHAREVIDEO.equals(call.method) || - METHOD_SHAREWEBPAGE.equals(call.method) || - METHOD_SHAREMINIPROGRAM.equals(call.method)) { + } else if ("shareImage".equals(call.method) || + "shareFile".equals(call.method) || + "shareEmoji".equals(call.method) || + "shareMusic".equals(call.method) || + "shareVideo".equals(call.method) || + "shareWebpage".equals(call.method) || + "shareMiniProgram".equals(call.method)) { handleShareMediaCall(call, result); - } else if (METHOD_SUBSCRIBEMSG.equals(call.method)) { + } else if ("subscribeMsg".equals(call.method)) { handleSubscribeMsgCall(call, result); - } else if (METHOD_LAUNCHMINIPROGRAM.equals(call.method)) { + } else if ("launchMiniProgram".equals(call.method)) { handleLaunchMiniProgramCall(call, result); - } else if (METHOD_OPENCUSTOMERSERVICECHAT.equals(call.method)) { + } else if ("openCustomerServiceChat".equals(call.method)) { handleOpenCustomerServiceChat(call, result); - } else if (METHOD_OPENBUSINESSVIEW.equals(call.method)) { + } else if ("openBusinessView".equals(call.method)) { handleOpenBusinessView(call, result); - } else if (METHOD_OPENBUSINESSWEBVIEW.equals(call.method)) { + } else if ("openBusinessWebview".equals(call.method)) { handleOpenBusinessWebview(call, result); - } else if (METHOD_PAY.equals(call.method)) { + } else if ("pay".equals(call.method)) { handlePayCall(call, result); } else { result.notImplemented(); @@ -402,8 +291,8 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug } private void registerApp(@NonNull MethodCall call, @NonNull Result result) { - final String appId = call.argument(ARGUMENT_KEY_APPID); -// final String universalLink = call.argument(ARGUMENT_KEY_UNIVERSALLINK); + final String appId = call.argument("appId"); +// final String universalLink = call.argument("universalLink"); iwxapi = WXAPIFactory.createWXAPI(applicationContext, appId); iwxapi.registerApp(appId); result.success(null); @@ -428,8 +317,8 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug private void handleAuthCall(@NonNull MethodCall call, @NonNull Result result) { final SendAuth.Req req = new SendAuth.Req(); - req.scope = call.argument(ARGUMENT_KEY_SCOPE); - req.state = call.argument(ARGUMENT_KEY_STATE); + req.scope = call.argument("scope"); + req.state = call.argument("state"); if (iwxapi != null) { iwxapi.sendReq(req); } @@ -437,14 +326,14 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug } private void handleQRAuthCall(@NonNull MethodCall call, @NonNull Result result) { - if (METHOD_STARTQRAUTH.equals(call.method)) { - final String appId = call.argument(ARGUMENT_KEY_APPID); - final String scope = call.argument(ARGUMENT_KEY_SCOPE); - final String noncestr = call.argument(ARGUMENT_KEY_NONCESTR); - final String timestamp = call.argument(ARGUMENT_KEY_TIMESTAMP); - final String signature = call.argument(ARGUMENT_KEY_SIGNATURE); + if ("startQrauth".equals(call.method)) { + final String appId = call.argument("appId"); + final String scope = call.argument("scope"); + final String noncestr = call.argument("noncestr"); + final String timestamp = call.argument("timestamp"); + final String signature = call.argument("signature"); qrauth.auth(appId, scope, noncestr, timestamp, signature, qrauthListener); - } else if (METHOD_STOPQRAUTH.equals(call.method)) { + } else if ("stopQrauth".equals(call.method)) { qrauth.stopAuth(); } result.success(null); @@ -454,33 +343,33 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug @Override public void onAuthGotQrcode(@Deprecated String qrcodeImgPath, byte[] imgBuf) { final Map map = new HashMap<>(); - map.put(ARGUMENT_KEY_RESULT_IMAGEDATA, imgBuf); + map.put("imageData", imgBuf); if (channel != null) { - channel.invokeMethod(METHOD_ONAUTHGOTQRCODE, map); + channel.invokeMethod("onAuthGotQrcode", map); } } @Override public void onQrcodeScanned() { if (channel != null) { - channel.invokeMethod(METHOD_ONAUTHQRCODESCANNED, null); + channel.invokeMethod("onAuthQrcodeScanned", null); } } @Override public void onAuthFinish(OAuthErrCode errCode, String authCode) { final Map map = new HashMap<>(); - map.put(ARGUMENT_KEY_RESULT_ERRORCODE, errCode.getCode()); - map.put(ARGUMENT_KEY_RESULT_AUTHCODE, authCode); + map.put("errorCode", errCode.getCode()); + map.put("authCode", authCode); if (channel != null) { - channel.invokeMethod(METHOD_ONAUTHFINISH, map); + channel.invokeMethod("onAuthFinish", map); } } }; private void handleOpenUrlCall(@NonNull MethodCall call, @NonNull Result result) { final OpenWebview.Req req = new OpenWebview.Req(); - req.url = call.argument(ARGUMENT_KEY_URL); + req.url = call.argument("url"); if (iwxapi != null) { iwxapi.sendReq(req); } @@ -498,11 +387,11 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug private void handleShareTextCall(@NonNull MethodCall call, @NonNull Result result) { final SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = call.method + ": " + System.currentTimeMillis(); - req.scene = call.argument(ARGUMENT_KEY_SCENE); - String text = call.argument(ARGUMENT_KEY_TEXT); - WXMediaMessage message = new WXMediaMessage(); + req.scene = call.argument("scene"); + final String text = call.argument("text"); + final WXMediaMessage message = new WXMediaMessage(); message.description = text.length() <= 1024 ? text : text.substring(0, 1024);// 必选项,否则无法分享 - WXTextObject object = new WXTextObject(); + final WXTextObject object = new WXTextObject(); object.text = text; message.mediaObject = object; req.message = message; @@ -515,67 +404,67 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug private void handleShareMediaCall(@NonNull MethodCall call, @NonNull Result result) { final SendMessageToWX.Req req = new SendMessageToWX.Req(); req.transaction = call.method + ": " + System.currentTimeMillis(); - req.scene = call.argument(ARGUMENT_KEY_SCENE); + req.scene = call.argument("scene"); final WXMediaMessage message = new WXMediaMessage(); - message.title = call.argument(ARGUMENT_KEY_TITLE); - message.description = call.argument(ARGUMENT_KEY_DESCRIPTION); - message.thumbData = call.argument(ARGUMENT_KEY_THUMBDATA); - if (METHOD_SHAREIMAGE.equals(call.method)) { + message.title = call.argument("title"); + message.description = call.argument("description"); + message.thumbData = call.argument("thumbData"); + if ("shareImage".equals(call.method)) { final WXImageObject object = new WXImageObject(); - if (call.hasArgument(ARGUMENT_KEY_IMAGEDATA)) { - object.imageData = call.argument(ARGUMENT_KEY_IMAGEDATA); - } else if (call.hasArgument(ARGUMENT_KEY_IMAGEURI)) { - String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI); + if (call.hasArgument("imageData")) { + object.imageData = call.argument("imageData"); + } else if (call.hasArgument("imageUri")) { + final String imageUri = call.argument("imageUri"); object.imagePath = getShareFilePath(imageUri);//Uri.parse(imageUri).getPath(); } message.mediaObject = object; - } else if (METHOD_SHAREFILE.equals(call.method)) { + } else if ("shareFile".equals(call.method)) { final WXFileObject object = new WXFileObject(); - if (call.hasArgument(ARGUMENT_KEY_FILEDATA)) { - object.fileData = call.argument(ARGUMENT_KEY_FILEDATA); - } else if (call.hasArgument(ARGUMENT_KEY_FILEURI)) { - String fileUri = call.argument(ARGUMENT_KEY_FILEURI); + if (call.hasArgument("fileData")) { + object.fileData = call.argument("fileData"); + } else if (call.hasArgument("fileUri")) { + final String fileUri = call.argument("fileUri"); object.filePath = getShareFilePath(fileUri);//Uri.parse(fileUri).getPath(); } -// String fileExtension = call.argument(ARGUMENT_KEY_FILEEXTENSION); +// final String fileExtension = call.argument("fileExtension"); message.mediaObject = object; - } else if (METHOD_SHAREEMOJI.equals(call.method)) { + } else if ("shareEmoji".equals(call.method)) { final WXEmojiObject object = new WXEmojiObject(); - if (call.hasArgument(ARGUMENT_KEY_EMOJIDATA)) { - object.emojiData = call.argument(ARGUMENT_KEY_EMOJIDATA); - } else if (call.hasArgument(ARGUMENT_KEY_EMOJIURI)) { - String emojiUri = call.argument(ARGUMENT_KEY_EMOJIURI); + if (call.hasArgument("emojiData")) { + object.emojiData = call.argument("emojiData"); + } else if (call.hasArgument("emojiUri")) { + final String emojiUri = call.argument("emojiUri"); object.emojiPath = getShareFilePath(emojiUri);//Uri.parse(emojiUri).getPath(); } message.mediaObject = object; - } else if (METHOD_SHAREMUSIC.equals(call.method)) { + } else if ("shareMusic".equals(call.method)) { final WXMusicObject object = new WXMusicObject(); - object.musicUrl = call.argument(ARGUMENT_KEY_MUSICURL); - object.musicDataUrl = call.argument(ARGUMENT_KEY_MUSICDATAURL); - object.musicLowBandUrl = call.argument(ARGUMENT_KEY_MUSICLOWBANDURL); - object.musicLowBandDataUrl = call.argument(ARGUMENT_KEY_MUSICLOWBANDDATAURL); + object.musicUrl = call.argument("musicUrl"); + object.musicDataUrl = call.argument("musicDataUrl"); + object.musicLowBandUrl = call.argument("musicLowBandUrl"); + object.musicLowBandDataUrl = call.argument("musicLowBandDataUrl"); message.mediaObject = object; - } else if (METHOD_SHAREVIDEO.equals(call.method)) { + } else if ("shareVideo".equals(call.method)) { final WXVideoObject object = new WXVideoObject(); - object.videoUrl = call.argument(ARGUMENT_KEY_VIDEOURL); - object.videoLowBandUrl = call.argument(ARGUMENT_KEY_VIDEOLOWBANDURL); + object.videoUrl = call.argument("videoUrl"); + object.videoLowBandUrl = call.argument("videoLowBandUrl"); message.mediaObject = object; - } else if (METHOD_SHAREWEBPAGE.equals(call.method)) { + } else if ("shareWebpage".equals(call.method)) { final WXWebpageObject object = new WXWebpageObject(); - object.webpageUrl = call.argument(ARGUMENT_KEY_WEBPAGEURL); + object.webpageUrl = call.argument("webpageUrl"); message.mediaObject = object; - } else if (METHOD_SHAREMINIPROGRAM.equals(call.method)) { + } else if ("shareMiniProgram".equals(call.method)) { final WXMiniProgramObject object = new WXMiniProgramObject(); - object.webpageUrl = call.argument(ARGUMENT_KEY_WEBPAGEURL); - object.userName = call.argument(ARGUMENT_KEY_USERNAME); - object.path = call.argument(ARGUMENT_KEY_PATH); - byte[] hdImageData = call.argument(ARGUMENT_KEY_HDIMAGEDATA); + object.webpageUrl = call.argument("webpageUrl"); + object.userName = call.argument("username"); + object.path = call.argument("path"); + final byte[] hdImageData = call.argument("hdImageData"); if (hdImageData != null) { message.thumbData = hdImageData; } - object.withShareTicket = call.argument(ARGUMENT_KEY_WITHSHARETICKET); - object.miniprogramType = call.argument(ARGUMENT_KEY_TYPE); - boolean disableforward = call.argument(ARGUMENT_KEY_DISABLEFORWARD); + object.withShareTicket = call.argument("withShareTicket"); + object.miniprogramType = call.argument("type"); + final boolean disableforward = call.argument("disableForward"); object.disableforward = disableforward ? 1 : 0; message.mediaObject = object; } @@ -588,9 +477,9 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug private void handleSubscribeMsgCall(@NonNull MethodCall call, @NonNull Result result) { final SubscribeMessage.Req req = new SubscribeMessage.Req(); - req.scene = call.argument(ARGUMENT_KEY_SCENE); - req.templateID = call.argument(ARGUMENT_KEY_TEMPLATEID); - req.reserved = call.argument(ARGUMENT_KEY_RESERVED); + req.scene = call.argument("scene"); + req.templateID = call.argument("templateId"); + req.reserved = call.argument("reserved"); if (iwxapi != null) { iwxapi.sendReq(req); } @@ -599,9 +488,9 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug private void handleLaunchMiniProgramCall(@NonNull MethodCall call, @NonNull Result result) { final WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req(); - req.userName = call.argument(ARGUMENT_KEY_USERNAME); - req.path = call.argument(ARGUMENT_KEY_PATH); - req.miniprogramType = call.argument(ARGUMENT_KEY_TYPE); + req.userName = call.argument("username"); + req.path = call.argument("path"); + req.miniprogramType = call.argument("type"); if (iwxapi != null) { iwxapi.sendReq(req); } @@ -610,8 +499,8 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug private void handleOpenCustomerServiceChat(@NonNull MethodCall call, @NonNull Result result) { final WXOpenCustomerServiceChat.Req req = new WXOpenCustomerServiceChat.Req(); - req.corpId = call.argument(ARGUMENT_KEY_CORPID); - req.url = call.argument(ARGUMENT_KEY_URL); + req.corpId = call.argument("corpId"); + req.url = call.argument("url"); if (iwxapi != null) { iwxapi.sendReq(req); } @@ -620,9 +509,9 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug private void handleOpenBusinessView(@NonNull MethodCall call, @NonNull Result result) { final WXOpenBusinessView.Req req = new WXOpenBusinessView.Req(); - req.businessType = call.argument(ARGUMENT_KEY_BUSINESSTYPE); - req.query = call.argument(ARGUMENT_KEY_QUERY); - req.extInfo = call.argument(ARGUMENT_KEY_EXTINFO); + req.businessType = call.argument("businessType"); + req.query = call.argument("query"); + req.extInfo = call.argument("extInfo"); if (iwxapi != null) { iwxapi.sendReq(req); } @@ -631,8 +520,8 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug private void handleOpenBusinessWebview(@NonNull MethodCall call, @NonNull Result result) { final WXOpenBusinessWebview.Req req = new WXOpenBusinessWebview.Req(); - req.businessType = call.argument(ARGUMENT_KEY_BUSINESSTYPE); - req.queryInfo = call.argument(ARGUMENT_KEY_QUERYINFO); + req.businessType = call.argument("businessType"); + req.queryInfo = call.argument("queryInfo"); if (iwxapi != null) { iwxapi.sendReq(req); } @@ -641,13 +530,13 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug private void handlePayCall(@NonNull MethodCall call, @NonNull Result result) { final PayReq req = new PayReq(); - req.appId = call.argument(ARGUMENT_KEY_APPID); - req.partnerId = call.argument(ARGUMENT_KEY_PARTNERID); - req.prepayId = call.argument(ARGUMENT_KEY_PREPAYID); - req.nonceStr = call.argument(ARGUMENT_KEY_NONCESTR); - req.timeStamp = call.argument(ARGUMENT_KEY_TIMESTAMP); - req.packageValue = call.argument(ARGUMENT_KEY_PACKAGE); - req.sign = call.argument(ARGUMENT_KEY_SIGN); + req.appId = call.argument("appId"); + req.partnerId = call.argument("partnerId"); + req.prepayId = call.argument("prepayId"); + req.nonceStr = call.argument("noncestr"); + req.timeStamp = call.argument("timestamp"); + req.packageValue = call.argument("package"); + req.sign = call.argument("sign"); if (iwxapi != null) { iwxapi.sendReq(req); } diff --git a/example/.gitignore b/example/.gitignore index ef1b609..a8e938c 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -8,6 +8,7 @@ .buildlog/ .history .svn/ +migrate_working_dir/ # IntelliJ related *.iml @@ -23,7 +24,6 @@ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id -**/ios/Podfile.lock .dart_tool/ .flutter-plugins .flutter-plugins-dependencies diff --git a/example/.metadata b/example/.metadata deleted file mode 100644 index 7c361dd..0000000 --- a/example/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# 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: b041144f833e05cf463b8887fa12efdec9493488 - channel: stable - -project_type: app diff --git a/example/README.md b/example/README.md index 95924f9..9eb3b3d 100644 --- a/example/README.md +++ b/example/README.md @@ -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: -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, samples, guidance on mobile development, and a full API reference. diff --git a/example/android/.gitignore b/example/android/.gitignore index 0a741cb..6f56801 100644 --- a/example/android/.gitignore +++ b/example/android/.gitignore @@ -9,3 +9,5 @@ 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 diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 780a809..358ed7f 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -27,13 +27,18 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion flutter.compileSdkVersion + ndkVersion flutter.ndkVersion - lintOptions { - disable 'InvalidPackage' + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "io.github.v7lin.wechat_kit_example" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. minSdkVersion flutter.minSdkVersion targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml index 9014c83..452b694 100644 --- a/example/android/app/src/debug/AndroidManifest.xml +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,7 @@ - diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index db24305..d336609 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,11 +1,6 @@ - - + + + + + + + diff --git a/example/android/app/src/main/res/values-night/styles.xml b/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml index 1f83a33..cb1ef88 100644 --- a/example/android/app/src/main/res/values/styles.xml +++ b/example/android/app/src/main/res/values/styles.xml @@ -1,18 +1,18 @@ - - - diff --git a/example/android/app/src/profile/AndroidManifest.xml b/example/android/app/src/profile/AndroidManifest.xml index 9014c83..452b694 100644 --- a/example/android/app/src/profile/AndroidManifest.xml +++ b/example/android/app/src/profile/AndroidManifest.xml @@ -1,6 +1,7 @@ - diff --git a/example/android/build.gradle b/example/android/build.gradle index 4256f91..83ae220 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 38c8d45..94adc3a 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1,4 +1,3 @@ org.gradle.jvmargs=-Xmx1536M -android.enableR8=true android.useAndroidX=true android.enableJetifier=true diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 3c9d085..cc5527d 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip diff --git a/example/android/settings.gradle b/example/android/settings.gradle index d3b6a40..44e62bc 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -1,7 +1,3 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") diff --git a/example/ios/.gitignore b/example/ios/.gitignore index e96ef60..7a7f987 100644 --- a/example/ios/.gitignore +++ b/example/ios/.gitignore @@ -1,3 +1,4 @@ +**/dgph *.mode1v3 *.mode2v3 *.moved-aside @@ -18,6 +19,7 @@ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig +Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ diff --git a/example/ios/Flutter/AppFrameworkInfo.plist b/example/ios/Flutter/AppFrameworkInfo.plist index f2872cf..8d4492f 100644 --- a/example/ios/Flutter/AppFrameworkInfo.plist +++ b/example/ios/Flutter/AppFrameworkInfo.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) + en CFBundleExecutable App CFBundleIdentifier diff --git a/example/ios/Flutter/Debug.xcconfig b/example/ios/Flutter/Debug.xcconfig index e8efba1..ec97fc6 100644 --- a/example/ios/Flutter/Debug.xcconfig +++ b/example/ios/Flutter/Debug.xcconfig @@ -1,2 +1,2 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/example/ios/Flutter/Release.xcconfig b/example/ios/Flutter/Release.xcconfig index 399e934..c4855bf 100644 --- a/example/ios/Flutter/Release.xcconfig +++ b/example/ios/Flutter/Release.xcconfig @@ -1,2 +1,2 @@ -#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock new file mode 100644 index 0000000..5b4770e --- /dev/null +++ b/example/ios/Podfile.lock @@ -0,0 +1,46 @@ +PODS: + - Flutter (1.0.0) + - FMDB (2.7.5): + - FMDB/standard (= 2.7.5) + - FMDB/standard (2.7.5) + - path_provider_ios (0.0.1): + - Flutter + - sqflite (0.0.2): + - Flutter + - FMDB (>= 2.7.5) + - wechat_kit (4.0.0): + - Flutter + - wechat_kit/pay (= 4.0.0) + - wechat_kit/pay (4.0.0): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) + - sqflite (from `.symlinks/plugins/sqflite/ios`) + - wechat_kit (from `.symlinks/plugins/wechat_kit/ios`) + +SPEC REPOS: + trunk: + - FMDB + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + path_provider_ios: + :path: ".symlinks/plugins/path_provider_ios/ios" + sqflite: + :path: ".symlinks/plugins/sqflite/ios" + wechat_kit: + :path: ".symlinks/plugins/wechat_kit/ios" + +SPEC CHECKSUMS: + Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 + sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 + wechat_kit: 334889808fcf75d434d9de87e058c691143d431e + +PODFILE CHECKSUM: caccac501e88af75e8ed5a7a9625762fb5755e27 + +COCOAPODS: 1.11.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index ff1a916..1486f70 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,12 +3,12 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ - 0A009A3402DAC340BC01BA13 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C744CCEB00ABFCFE847E0995 /* libPods-Runner.a */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3A1FC0E9553EF41840956751 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 16A3C53D588E3E40E8CBC6EC /* libPods-Runner.a */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; @@ -33,9 +33,9 @@ /* Begin PBXFileReference section */ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2A9F683624AF2A723305BFBA /* 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 = ""; }; - 33B35D8048C5A0A7E7E26649 /* 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 = ""; }; + 16A3C53D588E3E40E8CBC6EC /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 5B47FD60C153DCE48E1A0D15 /* 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 = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -47,8 +47,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - C744CCEB00ABFCFE847E0995 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - CB8B4ED2736FBA3973EE42E5 /* 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 = ""; }; + DA21A54319640BE724F39D26 /* 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 = ""; }; + FF329184F9C54092DB9EFEF8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -56,27 +56,28 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0A009A3402DAC340BC01BA13 /* libPods-Runner.a in Frameworks */, + 3A1FC0E9553EF41840956751 /* libPods-Runner.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 46D9C1E399B6A633AF01F6AD /* Pods */ = { + 04696AED717245F295202B26 /* Pods */ = { isa = PBXGroup; children = ( - CB8B4ED2736FBA3973EE42E5 /* Pods-Runner.debug.xcconfig */, - 33B35D8048C5A0A7E7E26649 /* Pods-Runner.release.xcconfig */, - 2A9F683624AF2A723305BFBA /* Pods-Runner.profile.xcconfig */, + FF329184F9C54092DB9EFEF8 /* Pods-Runner.debug.xcconfig */, + DA21A54319640BE724F39D26 /* Pods-Runner.release.xcconfig */, + 5B47FD60C153DCE48E1A0D15 /* Pods-Runner.profile.xcconfig */, ); + name = Pods; path = Pods; sourceTree = ""; }; - 57BC2D71F0F7DCD915E8F520 /* Frameworks */ = { + 136B8F9608382F11455A7715 /* Frameworks */ = { isa = PBXGroup; children = ( - C744CCEB00ABFCFE847E0995 /* libPods-Runner.a */, + 16A3C53D588E3E40E8CBC6EC /* libPods-Runner.a */, ); name = Frameworks; sourceTree = ""; @@ -98,8 +99,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, - 46D9C1E399B6A633AF01F6AD /* Pods */, - 57BC2D71F0F7DCD915E8F520 /* Frameworks */, + 04696AED717245F295202B26 /* Pods */, + 136B8F9608382F11455A7715 /* Frameworks */, ); sourceTree = ""; }; @@ -142,7 +143,7 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 75534BAC7D3BD2B24D40A95E /* [CP] Check Pods Manifest.lock */, + 6496D2B4FC35C84E9DFEE6A4 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, @@ -218,9 +219,9 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 75534BAC7D3BD2B24D40A95E /* [CP] Check Pods Manifest.lock */ = { + 6496D2B4FC35C84E9DFEE6A4 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -254,7 +255,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n"; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; /* End PBXShellScriptBuildPhase section */ @@ -349,20 +350,11 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 78W43A3TE2; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.wechatKitExample; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; @@ -482,20 +474,11 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 78W43A3TE2; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.wechatKitExample; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; @@ -510,20 +493,11 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; DEVELOPMENT_TEAM = 78W43A3TE2; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.wechatKitExample; PRODUCT_NAME = "$(TARGET_NAME)"; VERSIONING_SYSTEM = "apple-generic"; diff --git a/example/ios/Runner/Runner.entitlements b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 62% rename from example/ios/Runner/Runner.entitlements rename to example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist index 3d3306d..18d9810 100644 --- a/example/ios/Runner/Runner.entitlements +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -2,9 +2,7 @@ - com.apple.developer.associated-domains - - applinks:app.666sdk.com - + IDEDidComputeMac32BitWarning + diff --git a/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 3db53b6..c87d15a 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -27,8 +27,6 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> - - - - + + - - + + + + PreviewsEnabled + + + diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index 05400fe..b880fb3 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -4,6 +4,8 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Wechat Kit CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -60,5 +62,7 @@ UIViewControllerBasedStatusBarAppearance + CADisableMinimumFrameDurationOnPhone + diff --git a/example/lib/main.dart b/example/lib/main.dart index 4f3dd68..4144794 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,8 +1,9 @@ import 'dart:async'; -import 'dart:io'; import 'dart:typed_data'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/file.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:image/image.dart' as image; import 'package:path/path.dart' as path; @@ -16,15 +17,14 @@ const String WECHAT_APPSECRET = 'your wechat appSecret'; const String WECHAT_MINIAPPID = 'your wechat miniAppId'; void main() { - WidgetsFlutterBinding.ensureInitialized(); - Wechat.instance.registerApp( - appId: WECHAT_APPID, - universalLink: WECHAT_UNIVERSAL_LINK, - ); runApp(MyApp()); } class MyApp extends StatelessWidget { + const MyApp({ + super.key, + }); + @override Widget build(BuildContext context) { return MaterialApp( @@ -34,6 +34,10 @@ class MyApp extends StatelessWidget { } class Home extends StatefulWidget { + const Home({ + super.key, + }); + @override State createState() { return _HomeState(); @@ -48,7 +52,7 @@ class _HomeState extends State { @override void initState() { super.initState(); - _respSubs = Wechat.instance.respStream().listen(_listenResp); + _respSubs = Wechat.respStream().listen(_listenResp); } void _listenResp(BaseResp resp) { @@ -78,91 +82,95 @@ class _HomeState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Wechat Kit Demo'), + title: Text('Wechat Kit Demo'), ), body: ListView( children: [ ListTile( - title: const Text('微信回调 - 冷启'), + title: Text('注册APP'), onTap: () async { - await Wechat.instance.handleInitialWXReq(); + await Wechat.registerApp( + appId: WECHAT_APPID, + universalLink: WECHAT_UNIVERSAL_LINK, + ); + _showTips('注册APP', '注册成功'); }, ), ListTile( - title: const Text('环境检查'), + title: Text('微信回调 - 冷启'), onTap: () async { - final String content = - 'wechat: ${await Wechat.instance.isInstalled()} - ${await Wechat.instance.isSupportApi()}'; + await Wechat.handleInitialWXReq(); + }, + ), + ListTile( + title: Text('环境检查'), + onTap: () async { + final String content = 'wechat: ${await Wechat.isInstalled()} - ${await Wechat.isSupportApi()}'; _showTips('环境检查', content); }, ), ListTile( - title: const Text('登录'), + title: Text('登录'), onTap: () { - Wechat.instance.auth( + Wechat.auth( scope: [WechatScope.SNSAPI_USERINFO], state: 'auth', ); }, ), ListTile( - title: const Text('扫码登录'), + title: Text('扫码登录'), onTap: () { Navigator.of(context).push(MaterialPageRoute( - builder: (BuildContext context) => const Qrauth(), + builder: (BuildContext context) => Qrauth(), )); }, ), ListTile( - title: const Text('获取用户信息'), + title: Text('获取用户信息'), onTap: () async { if (_authResp != null && _authResp!.isSuccessful) { - final WechatAccessTokenResp accessTokenResp = - await WechatExtension.getAccessTokenUnionID( + final WechatAccessTokenResp accessTokenResp = await WechatExtension.getAccessTokenUnionID( appId: WECHAT_APPID, appSecret: WECHAT_APPSECRET, code: _authResp!.code!, ); if (accessTokenResp.isSuccessful) { - final WechatUserInfoResp userInfoResp = - await WechatExtension.getUserInfoUnionID( + final WechatUserInfoResp userInfoResp = await WechatExtension.getUserInfoUnionID( openId: accessTokenResp.openid!, accessToken: accessTokenResp.accessToken!, ); if (userInfoResp.isSuccessful) { - _showTips('用户信息', - '${userInfoResp.nickname} - ${userInfoResp.sex}'); + _showTips('用户信息', '${userInfoResp.nickname} - ${userInfoResp.sex}'); } } } }, ), ListTile( - title: const Text('文字分享'), + title: Text('文字分享'), onTap: () { - Wechat.instance.shareText( + Wechat.shareText( scene: WechatScene.TIMELINE, text: 'Share Text', ); }, ), ListTile( - title: const Text('图片分享'), + title: Text('图片分享'), onTap: () async { - final File file = await DefaultCacheManager().getSingleFile( - 'https://www.baidu.com/img/bd_logo1.png?where=super'); - await Wechat.instance.shareImage( + final File file = await DefaultCacheManager().getSingleFile('https://www.baidu.com/img/bd_logo1.png?where=super'); + await Wechat.shareImage( scene: WechatScene.SESSION, imageUri: Uri.file(file.path), ); }, ), ListTile( - title: const Text('文件分享'), + title: Text('文件分享'), onTap: () async { - final File file = await DefaultCacheManager().getSingleFile( - 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'); - await Wechat.instance.shareFile( + final File file = await DefaultCacheManager().getSingleFile('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'); + await Wechat.shareFile( scene: WechatScene.SESSION, title: '测试文件', fileUri: Uri.file(file.path), @@ -171,18 +179,15 @@ class _HomeState extends State { }, ), ListTile( - title: const Text('Emoji分享'), + title: Text('Emoji分享'), onTap: () async { - final File file = await DefaultCacheManager().getSingleFile( - 'https://n.sinaimg.cn/tech/transform/695/w467h228/20191119/bf27-iipztfe9404360.gif'); - final image.Image thumbnail = - image.decodeImage(file.readAsBytesSync())!; + final File file = await DefaultCacheManager().getSingleFile('https://n.sinaimg.cn/tech/transform/695/w467h228/20191119/bf27-iipztfe9404360.gif'); + final image.Image thumbnail = image.decodeImage(file.readAsBytesSync())!; Uint8List thumbData = thumbnail.getBytes(); if (thumbData.length > 32 * 1024) { - thumbData = Uint8List.fromList(image.encodeJpg(thumbnail, - quality: 100 * 32 * 1024 ~/ thumbData.length)); + thumbData = Uint8List.fromList(image.encodeJpg(thumbnail, quality: 100 * 32 * 1024 ~/ thumbData.length)); } - await Wechat.instance.shareEmoji( + await Wechat.shareEmoji( scene: WechatScene.SESSION, thumbData: thumbData, emojiUri: Uri.file(file.path), @@ -190,19 +195,19 @@ class _HomeState extends State { }, ), ListTile( - title: const Text('网页分享'), + title: Text('网页分享'), onTap: () { - Wechat.instance.shareWebpage( + Wechat.shareWebpage( scene: WechatScene.TIMELINE, webpageUrl: 'https://www.baidu.com', ); }, ), ListTile( - title: const Text('支付'), + title: Text('支付'), onTap: () { // 微信 Demo 例子:https://wxpay.wxutil.com/pub_v2/app/app_pay.php - Wechat.instance.pay( + Wechat.pay( appId: WECHAT_APPID, partnerId: '商户号', prepayId: '预支付交易会话ID', @@ -214,12 +219,12 @@ class _HomeState extends State { }, ), ListTile( - title: const Text('拉起小程序'), + title: Text('拉起小程序'), onTap: () { - Wechat.instance.launchMiniProgram( + Wechat.launchMiniProgram( userName: WECHAT_MINIAPPID, path: 'page/page/index?uid=123', - type: WechatMiniProgram.preview, + type: WechatMiniProgram.PREVIEW, ); }, ), @@ -243,8 +248,8 @@ class _HomeState extends State { class Qrauth extends StatefulWidget { const Qrauth({ - Key? key, - }) : super(key: key); + super.key, + }); @override State createState() { @@ -260,8 +265,7 @@ class _QrauthState extends State { @override void initState() { super.initState(); - _qrauthRespSubs = - Wechat.instance.qrauthRespStream().listen(_listenQrauthResp); + _qrauthRespSubs = Wechat.qrauthRespStream().listen(_listenQrauthResp); } void _listenQrauthResp(QrauthResp resp) { @@ -270,9 +274,13 @@ class _QrauthState extends State { _qrcode = resp.imageData; }); } else if (resp is QrcodeScannedResp) { - print('QrcodeScanned'); + if (kDebugMode) { + print('QrcodeScanned'); + } } else if (resp is FinishResp) { - print('resp: ${resp.errorCode} - ${resp.authCode}'); + if (kDebugMode) { + print('resp: ${resp.errorCode} - ${resp.authCode}'); + } } } @@ -286,44 +294,45 @@ class _QrauthState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('Qrauth'), + title: Text('Qrauth'), actions: [ TextButton( onPressed: () async { - final WechatAccessTokenResp accessToken = - await WechatExtension.getAccessToken( + final WechatAccessTokenResp accessToken = await WechatExtension.getAccessToken( appId: WECHAT_APPID, appSecret: WECHAT_APPSECRET, ); - print( - 'accessToken: ${accessToken.errorCode} - ' - '${accessToken.errorMsg} - ' - '${accessToken.accessToken}', - ); + if (kDebugMode) { + print( + 'accessToken: ${accessToken.errorCode} - ' + '${accessToken.errorMsg} - ' + '${accessToken.accessToken}', + ); + } final WechatTicketResp ticket = await WechatExtension.getTicket( accessToken: accessToken.accessToken!, ); - print( - 'accessToken: ${ticket.errorCode} - ' - '${ticket.errorMsg} - ' - '${ticket.ticket}', - ); - await Wechat.instance.startQrauth( + if (kDebugMode) { + print( + 'accessToken: ${ticket.errorCode} - ' + '${ticket.errorMsg} - ' + '${ticket.ticket}', + ); + } + await Wechat.startQrauth( appId: WECHAT_APPID, scope: [WechatScope.SNSAPI_USERINFO], - noncestr: const Uuid().v1().toString().replaceAll('-', ''), + noncestr: Uuid().v1().replaceAll('-', ''), ticket: ticket.ticket!, ); }, - child: const Text('got qr code'), + child: Text('got qr code'), ), ], ), body: GestureDetector( child: Center( - child: _qrcode != null - ? Image.memory(_qrcode!) - : const Text('got qr code'), + child: _qrcode != null ? Image.memory(_qrcode!) : Text('got qr code'), ), ), ); diff --git a/example/pubspec.lock b/example/pubspec.lock new file mode 100644 index 0000000..e345131 --- /dev/null +++ b/example/pubspec.lock @@ -0,0 +1,399 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + archive: + dependency: transitive + description: + name: archive + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.0" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.8.2" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.1" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_cache_manager: + dependency: "direct main" + description: + name: flutter_cache_manager + url: "https://pub.dartlang.org" + source: hosted + version: "3.3.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + image: + dependency: "direct main" + description: + name: image + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.3" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.0" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.0" + path: + dependency: "direct main" + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.1" + path_provider: + dependency: transitive + description: + name: path_provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.10" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.14" + path_provider_ios: + dependency: transitive + description: + name: path_provider_ios + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.6" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.11.1" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" + rxdart: + dependency: transitive + description: + name: rxdart + url: "https://pub.dartlang.org" + source: hosted + version: "0.27.3" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.2" + sqflite: + dependency: transitive + description: + name: sqflite + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2+1" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1+1" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0+2" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.9" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.1" + uuid: + dependency: "direct main" + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + wechat_kit: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "4.0.0" + wechat_kit_extension: + dependency: "direct main" + description: + name: wechat_kit_extension + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0+1" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "2.6.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+1" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "5.4.1" +sdks: + dart: ">=2.17.0 <3.0.0" + flutter: ">=2.8.1" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 1e61c68..1ee1eac 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,11 +1,21 @@ name: wechat_kit_example description: Demonstrates how to use the wechat_kit 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 + version: 1.0.0+100 environment: - sdk: ">=2.12.0 <3.0.0" + sdk: ">=2.17.0 <3.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: flutter: sdk: flutter @@ -15,16 +25,69 @@ dependencies: # wechat_kit: ^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. + # the parent directory to use the current plugin's version. path: ../ - wechat_kit_extension: ^1.0.0 + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + + path: ^1.8.1 image: ^3.0.1 flutter_cache_manager: ^3.1.2 + uuid: ^3.0.6 + wechat_kit_extension: ^1.0.0 + dev_dependencies: flutter_test: sdk: flutter + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^2.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 570e0e4..19850bf 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -1,8 +1,16 @@ // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll +// 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 // tree, read text, and verify that the values of widget properties are correct. -void main() {} +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:wechat_kit_example/main.dart'; + +void main() { + testWidgets('smoke test', (WidgetTester tester) async { + }); +} diff --git a/ios/.gitignore b/ios/.gitignore index aa479fd..0c88507 100644 --- a/ios/.gitignore +++ b/ios/.gitignore @@ -34,4 +34,5 @@ Icon? .tags* /Flutter/Generated.xcconfig +/Flutter/ephemeral/ /Flutter/flutter_export_environment.sh \ No newline at end of file diff --git a/ios/Classes/WechatKitPlugin.m b/ios/Classes/WechatKitPlugin.m index 9957597..efa4bc4 100644 --- a/ios/Classes/WechatKitPlugin.m +++ b/ios/Classes/WechatKitPlugin.m @@ -7,7 +7,7 @@ #import #endif -typedef void(^WechatKitWXReqRunnable)(void); +typedef void (^WechatKitWXReqRunnable)(void); @interface WechatKitPlugin () @@ -30,121 +30,6 @@ typedef void(^WechatKitWXReqRunnable)(void); [registrar addMethodCallDelegate:instance channel:channel]; } -static NSString *const METHOD_REGISTERAPP = @"registerApp"; -static NSString *const METHOD_HANDLEINITIALWXREQ = @"handleInitialWXReq"; -static NSString *const METHOD_ISINSTALLED = @"isInstalled"; -static NSString *const METHOD_ISSUPPORTAPI = @"isSupportApi"; -static NSString *const METHOD_ISSUPPORTSTATEAPI = @"isSupportStateAPI"; -static NSString *const METHOD_OPENWECHAT = @"openWechat"; -static NSString *const METHOD_AUTH = @"auth"; -static NSString *const METHOD_STARTQRAUTH = @"startQrauth"; -static NSString *const METHOD_STOPQRAUTH = @"stopQrauth"; -static NSString *const METHOD_OPENURL = @"openUrl"; -static NSString *const METHOD_OPENRANKLIST = @"openRankList"; -static NSString *const METHOD_SHARETEXT = @"shareText"; -static NSString *const METHOD_SHAREIMAGE = @"shareImage"; -static NSString *const METHOD_SHAREFILE = @"shareFile"; -static NSString *const METHOD_SHAREEMOJI = @"shareEmoji"; -static NSString *const METHOD_SHAREMUSIC = @"shareMusic"; -static NSString *const METHOD_SHAREVIDEO = @"shareVideo"; -static NSString *const METHOD_SHAREWEBPAGE = @"shareWebpage"; -static NSString *const METHOD_SHAREMINIPROGRAM = @"shareMiniProgram"; -static NSString *const METHOD_SUBSCRIBEMSG = @"subscribeMsg"; -static NSString *const METHOD_LAUNCHMINIPROGRAM = @"launchMiniProgram"; -static NSString *const METHOD_OPENCUSTOMERSERVICECHAT = @"openCustomerServiceChat"; -static NSString *const METHOD_OPENBUSINESSVIEW = @"openBusinessView"; -static NSString *const METHOD_OPENBUSINESSWEBVIEW = @"openBusinessWebview"; -#ifndef NO_PAY -static NSString *const METHOD_PAY = @"pay"; -#endif - -static NSString *const METHOD_ONLAUNCHFROMWXREQ = @"onLaunchFromWXReq"; -static NSString *const METHOD_ONSHOWMESSAGEFROMWXREQ = @"onShowMessageFromWXReq"; - -static NSString *const METHOD_ONAUTHRESP = @"onAuthResp"; -static NSString *const METHOD_ONOPENURLRESP = @"onOpenUrlResp"; -static NSString *const METHOD_ONSHAREMSGRESP = @"onShareMsgResp"; -static NSString *const METHOD_ONSUBSCRIBEMSGRESP = @"onSubscribeMsgResp"; -static NSString *const METHOD_ONLAUNCHMINIPROGRAMRESP = @"onLaunchMiniProgramResp"; -static NSString *const METHOD_ONOPENCUSTOMERSERVICECHATRESP = @"onOpenCustomerServiceChatResp"; -static NSString *const METHOD_ONOPENBUSINESSVIEWRESP = @"onOpenBusinessViewResp"; -static NSString *const METHOD_ONOPENBUSINESSWEBVIEWRESP = @"onOpenBusinessWebviewResp"; -#ifndef NO_PAY -static NSString *const METHOD_ONPAYRESP = @"onPayResp"; -#endif -static NSString *const METHOD_ONAUTHGOTQRCODE = @"onAuthGotQrcode"; -static NSString *const METHOD_ONAUTHQRCODESCANNED = @"onAuthQrcodeScanned"; -static NSString *const METHOD_ONAUTHFINISH = @"onAuthFinish"; - -static NSString *const ARGUMENT_KEY_APPID = @"appId"; -static NSString *const ARGUMENT_KEY_UNIVERSALLINK = @"universalLink"; -static NSString *const ARGUMENT_KEY_SCOPE = @"scope"; -static NSString *const ARGUMENT_KEY_STATE = @"state"; -static NSString *const ARGUMENT_KEY_NONCESTR = @"noncestr"; -static NSString *const ARGUMENT_KEY_TIMESTAMP = @"timestamp"; -static NSString *const ARGUMENT_KEY_SIGNATURE = @"signature"; -static NSString *const ARGUMENT_KEY_URL = @"url"; -static NSString *const ARGUMENT_KEY_QUERY = @"query"; -static NSString *const ARGUMENT_KEY_USERNAME = @"username"; -static NSString *const ARGUMENT_KEY_SCENE = @"scene"; -static NSString *const ARGUMENT_KEY_TEXT = @"text"; -static NSString *const ARGUMENT_KEY_TITLE = @"title"; -static NSString *const ARGUMENT_KEY_DESCRIPTION = @"description"; -static NSString *const ARGUMENT_KEY_THUMBDATA = @"thumbData"; -static NSString *const ARGUMENT_KEY_IMAGEDATA = @"imageData"; -static NSString *const ARGUMENT_KEY_IMAGEURI = @"imageUri"; -static NSString *const ARGUMENT_KEY_FILEDATA = @"fileData"; -static NSString *const ARGUMENT_KEY_FILEURI = @"fileUri"; -static NSString *const ARGUMENT_KEY_FILEEXTENSION = @"fileExtension"; -static NSString *const ARGUMENT_KEY_EMOJIDATA = @"emojiData"; -static NSString *const ARGUMENT_KEY_EMOJIURI = @"emojiUri"; -static NSString *const ARGUMENT_KEY_MUSICURL = @"musicUrl"; -static NSString *const ARGUMENT_KEY_MUSICDATAURL = @"musicDataUrl"; -static NSString *const ARGUMENT_KEY_MUSICLOWBANDURL = @"musicLowBandUrl"; -static NSString *const ARGUMENT_KEY_MUSICLOWBANDDATAURL = - @"musicLowBandDataUrl"; -static NSString *const ARGUMENT_KEY_VIDEOURL = @"videoUrl"; -static NSString *const ARGUMENT_KEY_VIDEOLOWBANDURL = @"videoLowBandUrl"; -static NSString *const ARGUMENT_KEY_WEBPAGEURL = @"webpageUrl"; -static NSString *const ARGUMENT_KEY_PATH = @"path"; -static NSString *const ARGUMENT_KEY_HDIMAGEDATA = @"hdImageData"; -static NSString *const ARGUMENT_KEY_WITHSHARETICKET = @"withShareTicket"; -static NSString *const ARGUMENT_KEY_TYPE = @"type"; -static NSString *const ARGUMENT_KEY_DISABLEFORWARD = @"disableForward"; -static NSString *const ARGUMENT_KEY_TEMPLATEID = @"templateId"; -static NSString *const ARGUMENT_KEY_RESERVED = @"reserved"; -static NSString *const ARGUMENT_KEY_CORPID = @"corpId"; -static NSString *const ARGUMENT_KEY_BUSINESSTYPE = @"businessType"; -static NSString *const ARGUMENT_KEY_QUERYINFO = @"queryInfo"; -#ifndef NO_PAY -static NSString *const ARGUMENT_KEY_PARTNERID = @"partnerId"; -static NSString *const ARGUMENT_KEY_PREPAYID = @"prepayId"; -// static NSString *const ARGUMENT_KEY_NONCESTR = @"noncestr"; -// static NSString *const ARGUMENT_KEY_TIMESTAMP = @"timestamp"; -static NSString *const ARGUMENT_KEY_PACKAGE = @"package"; -static NSString *const ARGUMENT_KEY_SIGN = @"sign"; -#endif -static NSString *const ARGUMENT_KEY_EXTINFO = @"extInfo"; - -static NSString *const ARGUMENT_KEY_RESULT_ERRORCODE = @"errorCode"; -static NSString *const ARGUMENT_KEY_RESULT_ERRORMSG = @"errorMsg"; -static NSString *const ARGUMENT_KEY_RESULT_CODE = @"code"; -static NSString *const ARGUMENT_KEY_RESULT_STATE = @"state"; -static NSString *const ARGUMENT_KEY_RESULT_LANG = @"lang"; -static NSString *const ARGUMENT_KEY_RESULT_COUNTRY = @"country"; -static NSString *const ARGUMENT_KEY_RESULT_TEMPLATEID = @"templateId"; -static NSString *const ARGUMENT_KEY_RESULT_SCENE = @"scene"; -static NSString *const ARGUMENT_KEY_RESULT_ACTION = @"action"; -static NSString *const ARGUMENT_KEY_RESULT_RESERVED = @"reserved"; -static NSString *const ARGUMENT_KEY_RESULT_EXTMSG = @"extMsg"; -static NSString *const ARGUMENT_KEY_RESULT_BUSINESSTYPE = @"businessType"; -static NSString *const ARGUMENT_KEY_RESULT_RESULTINFO = @"resultInfo"; -static NSString *const ARGUMENT_KEY_RESULT_MESSAGEACTION = @"messageAction"; -static NSString *const ARGUMENT_KEY_RESULT_MESSAGEEXT = @"messageExt"; -static NSString *const ARGUMENT_KEY_RESULT_RETURNKEY = @"returnKey"; -static NSString *const ARGUMENT_KEY_RESULT_IMAGEDATA = @"imageData"; -static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - - (instancetype)initWithChannel:(FlutterMethodChannel *)channel { self = [super init]; if (self) { @@ -159,13 +44,13 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result { - if ([METHOD_REGISTERAPP isEqualToString:call.method]) { - NSString *appId = call.arguments[ARGUMENT_KEY_APPID]; - NSString *universalLink = call.arguments[ARGUMENT_KEY_UNIVERSALLINK]; + if ([@"registerApp" isEqualToString:call.method]) { + NSString *appId = call.arguments[@"appId"]; + NSString *universalLink = call.arguments[@"universalLink"]; [WXApi registerApp:appId universalLink:universalLink]; _isRunning = YES; result(nil); - } else if ([METHOD_HANDLEINITIALWXREQ isEqualToString:call.method]) { + } else if ([@"handleInitialWXReq" isEqualToString:call.method]) { if (!_handleInitialWXReqFlag) { _handleInitialWXReqFlag = YES; if (_initialWXReqRunnable != nil) { @@ -176,48 +61,48 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; } else { result([FlutterError errorWithCode:@"FAILED" message:nil details:nil]); } - } else if ([METHOD_ISINSTALLED isEqualToString:call.method]) { + } else if ([@"isInstalled" isEqualToString:call.method]) { result([NSNumber numberWithBool:[WXApi isWXAppInstalled]]); - } else if ([METHOD_ISSUPPORTAPI isEqualToString:call.method]) { + } else if ([@"isSupportApi" isEqualToString:call.method]) { result([NSNumber numberWithBool:[WXApi isWXAppSupportApi]]); - } else if ([METHOD_ISSUPPORTSTATEAPI isEqualToString:call.method]) { + } else if ([@"isSupportStateApi" isEqualToString:call.method]) { result([NSNumber numberWithBool:[WXApi isWXAppSupportStateAPI]]); - } else if ([METHOD_OPENWECHAT isEqualToString:call.method]) { + } else if ([@"openWechat" isEqualToString:call.method]) { result([NSNumber numberWithBool:[WXApi openWXApp]]); - } else if ([METHOD_AUTH isEqualToString:call.method]) { + } else if ([@"auth" isEqualToString:call.method]) { [self handleAuthCall:call result:result]; } else if ([@"sendAuth" isEqualToString:call.method]) { [self handleSendAuthCall:call result:result]; - }else if ([METHOD_STARTQRAUTH isEqualToString:call.method] || - [METHOD_STOPQRAUTH isEqualToString:call.method]) { + } else if ([@"startQrauth" isEqualToString:call.method] || + [@"stopQrauth" isEqualToString:call.method]) { [self handleQRAuthCall:call result:result]; - } else if ([METHOD_OPENURL isEqualToString:call.method]) { + } else if ([@"openUrl" isEqualToString:call.method]) { [self handleOpenUrlCall:call result:result]; - } else if ([METHOD_OPENRANKLIST isEqualToString:call.method]) { + } else if ([@"openRankList" isEqualToString:call.method]) { [self handleOpenRankListCall:call result:result]; - } else if ([METHOD_SHARETEXT isEqualToString:call.method]) { + } else if ([@"shareText" isEqualToString:call.method]) { [self handleShareTextCall:call result:result]; - } else if ([METHOD_SHAREIMAGE isEqualToString:call.method] || - [METHOD_SHAREFILE isEqualToString:call.method] || - [METHOD_SHAREEMOJI isEqualToString:call.method] || - [METHOD_SHAREMUSIC isEqualToString:call.method] || - [METHOD_SHAREVIDEO isEqualToString:call.method] || - [METHOD_SHAREWEBPAGE isEqualToString:call.method] || - [METHOD_SHAREMINIPROGRAM isEqualToString:call.method]) { + } else if ([@"shareImage" isEqualToString:call.method] || + [@"shareFile" isEqualToString:call.method] || + [@"shareEmoji" isEqualToString:call.method] || + [@"shareMusic" isEqualToString:call.method] || + [@"shareVideo" isEqualToString:call.method] || + [@"shareWebpage" isEqualToString:call.method] || + [@"shareMiniProgram" isEqualToString:call.method]) { [self handleShareMediaCall:call result:result]; - } else if ([METHOD_SUBSCRIBEMSG isEqualToString:call.method]) { + } else if ([@"subscribeMsg" isEqualToString:call.method]) { [self handleSubscribeMsgCall:call result:result]; - } else if ([METHOD_LAUNCHMINIPROGRAM isEqualToString:call.method]) { + } else if ([@"launchMiniProgram" isEqualToString:call.method]) { [self handleLaunchMiniProgramCall:call result:result]; - } else if ([METHOD_OPENCUSTOMERSERVICECHAT isEqualToString:call.method]) { - [self handleOpenCustomerServiceChatCall: call result:result]; - } else if ([METHOD_OPENBUSINESSVIEW isEqualToString:call.method]) { - [self handleOpenBusinessViewCall: call result:result]; - } else if ([METHOD_OPENBUSINESSWEBVIEW isEqualToString:call.method]) { + } else if ([@"openCustomerServiceChat" isEqualToString:call.method]) { + [self handleOpenCustomerServiceChatCall:call result:result]; + } else if ([@"openBusinessView" isEqualToString:call.method]) { + [self handleOpenBusinessViewCall:call result:result]; + } else if ([@"openBusinessWebview" isEqualToString:call.method]) { [self handleOpenBusinessWebviewCall:call result:result]; } #ifndef NO_PAY - else if ([METHOD_PAY isEqualToString:call.method]) { + else if ([@"pay" isEqualToString:call.method]) { [self handlePayCall:call result:result]; } #endif @@ -228,8 +113,8 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)handleAuthCall:(FlutterMethodCall *)call result:(FlutterResult)result { SendAuthReq *req = [[SendAuthReq alloc] init]; - req.scope = call.arguments[ARGUMENT_KEY_SCOPE]; - req.state = call.arguments[ARGUMENT_KEY_STATE]; + req.scope = call.arguments[@"scope"]; + req.state = call.arguments[@"state"]; [WXApi sendReq:req completion:^(BOOL success){ // do nothing @@ -239,33 +124,33 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)handleSendAuthCall:(FlutterMethodCall *)call result:(FlutterResult)result { SendAuthReq *req = [[SendAuthReq alloc] init]; - req.scope = call.arguments[ARGUMENT_KEY_SCOPE]; - req.state = call.arguments[ARGUMENT_KEY_STATE]; + req.scope = call.arguments[@"scope"]; + req.state = call.arguments[@"state"]; UIViewController *viewController = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; [WXApi sendAuthReq:req viewController:viewController delegate:self - completion:^(BOOL success) { - // do nothing - }]; + completion:^(BOOL success){ + // do nothing + }]; result(nil); } - (void)handleQRAuthCall:(FlutterMethodCall *)call result:(FlutterResult)result { - if ([METHOD_STARTQRAUTH isEqualToString:call.method]) { - NSString *appId = call.arguments[ARGUMENT_KEY_APPID]; - NSString *scope = call.arguments[ARGUMENT_KEY_SCOPE]; - NSString *noncestr = call.arguments[ARGUMENT_KEY_NONCESTR]; - NSString *timestamp = call.arguments[ARGUMENT_KEY_TIMESTAMP]; - NSString *signature = call.arguments[ARGUMENT_KEY_SIGNATURE]; + if ([@"startQrauth" isEqualToString:call.method]) { + NSString *appId = call.arguments[@"appId"]; + NSString *scope = call.arguments[@"scope"]; + NSString *noncestr = call.arguments[@"noncestr"]; + NSString *timestamp = call.arguments[@"timestamp"]; + NSString *signature = call.arguments[@"signature"]; [_qrauth Auth:appId nonceStr:noncestr timeStamp:timestamp scope:scope signature:signature schemeData:nil]; - } else if ([METHOD_STOPQRAUTH isEqualToString:call.method]) { + } else if ([@"stopQrauth" isEqualToString:call.method]) { [_qrauth StopAuth]; } result(nil); @@ -274,7 +159,7 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)handleOpenUrlCall:(FlutterMethodCall *)call result:(FlutterResult)result { OpenWebviewReq *req = [[OpenWebviewReq alloc] init]; - req.url = call.arguments[ARGUMENT_KEY_URL]; + req.url = call.arguments[@"url"]; [WXApi sendReq:req completion:^(BOOL success){ // do nothing @@ -295,10 +180,10 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)handleShareTextCall:(FlutterMethodCall *)call result:(FlutterResult)result { SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; - NSNumber *scene = call.arguments[ARGUMENT_KEY_SCENE]; + NSNumber *scene = call.arguments[@"scene"]; req.scene = [scene intValue]; req.bText = YES; - req.text = call.arguments[ARGUMENT_KEY_TEXT]; + req.text = call.arguments[@"text"]; [WXApi sendReq:req completion:^(BOOL success){ // do nothing @@ -309,84 +194,84 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)handleShareMediaCall:(FlutterMethodCall *)call result:(FlutterResult)result { SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init]; - NSNumber *scene = call.arguments[ARGUMENT_KEY_SCENE]; + NSNumber *scene = call.arguments[@"scene"]; req.scene = [scene intValue]; req.bText = NO; WXMediaMessage *message = [WXMediaMessage message]; - message.title = call.arguments[ARGUMENT_KEY_TITLE]; - message.description = call.arguments[ARGUMENT_KEY_DESCRIPTION]; - FlutterStandardTypedData *thumbData = call.arguments[ARGUMENT_KEY_THUMBDATA]; + message.title = call.arguments[@"title"]; + message.description = call.arguments[@"description"]; + FlutterStandardTypedData *thumbData = call.arguments[@"thumbData"]; if (thumbData != nil) { message.thumbData = thumbData.data; } - if ([METHOD_SHAREIMAGE isEqualToString:call.method]) { + if ([@"shareImage" isEqualToString:call.method]) { WXImageObject *mediaObject = [WXImageObject object]; FlutterStandardTypedData *imageData = - call.arguments[ARGUMENT_KEY_IMAGEDATA]; + call.arguments[@"imageData"]; if (imageData != nil) { mediaObject.imageData = imageData.data; } else { - NSString *imageUri = call.arguments[ARGUMENT_KEY_IMAGEURI]; + NSString *imageUri = call.arguments[@"imageUri"]; NSURL *imageUrl = [NSURL URLWithString:imageUri]; mediaObject.imageData = [NSData dataWithContentsOfFile:imageUrl.path]; } message.mediaObject = mediaObject; - } else if ([METHOD_SHAREFILE isEqualToString:call.method]) { + } else if ([@"shareFile" isEqualToString:call.method]) { WXFileObject *mediaObject = [WXFileObject object]; - FlutterStandardTypedData *fileData = call.arguments[ARGUMENT_KEY_FILEDATA]; + FlutterStandardTypedData *fileData = call.arguments[@"fileData"]; if (fileData != nil) { mediaObject.fileData = fileData.data; } else { - NSString *fileUri = call.arguments[ARGUMENT_KEY_FILEURI]; + NSString *fileUri = call.arguments[@"fileUri"]; NSURL *fileUrl = [NSURL URLWithString:fileUri]; mediaObject.fileData = [NSData dataWithContentsOfFile:fileUrl.path]; } - mediaObject.fileExtension = call.arguments[ARGUMENT_KEY_FILEEXTENSION]; + mediaObject.fileExtension = call.arguments[@"fileExtension"]; message.mediaObject = mediaObject; - } else if ([METHOD_SHAREEMOJI isEqualToString:call.method]) { + } else if ([@"shareEmoji" isEqualToString:call.method]) { WXEmoticonObject *mediaObject = [WXEmoticonObject object]; FlutterStandardTypedData *emojiData = - call.arguments[ARGUMENT_KEY_EMOJIDATA]; + call.arguments[@"emojiData"]; if (emojiData != nil) { mediaObject.emoticonData = emojiData.data; } else { - NSString *emojiUri = call.arguments[ARGUMENT_KEY_EMOJIURI]; + NSString *emojiUri = call.arguments[@"emojiUri"]; NSURL *emojiUrl = [NSURL URLWithString:emojiUri]; mediaObject.emoticonData = [NSData dataWithContentsOfFile:emojiUrl.path]; } message.mediaObject = mediaObject; - } else if ([METHOD_SHAREMUSIC isEqualToString:call.method]) { + } else if ([@"shareMusic" isEqualToString:call.method]) { WXMusicObject *mediaObject = [WXMusicObject object]; - mediaObject.musicUrl = call.arguments[ARGUMENT_KEY_MUSICURL]; - mediaObject.musicDataUrl = call.arguments[ARGUMENT_KEY_MUSICDATAURL]; - mediaObject.musicLowBandUrl = call.arguments[ARGUMENT_KEY_MUSICLOWBANDURL]; + mediaObject.musicUrl = call.arguments[@"musicUrl"]; + mediaObject.musicDataUrl = call.arguments[@"musicDataUrl"]; + mediaObject.musicLowBandUrl = call.arguments[@"musicLowBandUrl"]; mediaObject.musicLowBandDataUrl = - call.arguments[ARGUMENT_KEY_MUSICLOWBANDDATAURL]; + call.arguments[@"musicLowBandDataUrl"]; message.mediaObject = mediaObject; - } else if ([METHOD_SHAREVIDEO isEqualToString:call.method]) { + } else if ([@"shareVideo" isEqualToString:call.method]) { WXVideoObject *mediaObject = [WXVideoObject object]; - mediaObject.videoUrl = call.arguments[ARGUMENT_KEY_VIDEOURL]; - mediaObject.videoLowBandUrl = call.arguments[ARGUMENT_KEY_VIDEOLOWBANDURL]; + mediaObject.videoUrl = call.arguments[@"videoUrl"]; + mediaObject.videoLowBandUrl = call.arguments[@"videoLowBandUrl"]; message.mediaObject = mediaObject; - } else if ([METHOD_SHAREWEBPAGE isEqualToString:call.method]) { + } else if ([@"shareWebpage" isEqualToString:call.method]) { WXWebpageObject *mediaObject = [WXWebpageObject object]; - mediaObject.webpageUrl = call.arguments[ARGUMENT_KEY_WEBPAGEURL]; + mediaObject.webpageUrl = call.arguments[@"webpageUrl"]; message.mediaObject = mediaObject; - } else if ([METHOD_SHAREMINIPROGRAM isEqualToString:call.method]) { + } else if ([@"shareMiniProgram" isEqualToString:call.method]) { WXMiniProgramObject *mediaObject = [WXMiniProgramObject object]; - mediaObject.webpageUrl = call.arguments[ARGUMENT_KEY_WEBPAGEURL]; - mediaObject.userName = call.arguments[ARGUMENT_KEY_USERNAME]; - mediaObject.path = call.arguments[ARGUMENT_KEY_PATH]; + mediaObject.webpageUrl = call.arguments[@"webpageUrl"]; + mediaObject.userName = call.arguments[@"username"]; + mediaObject.path = call.arguments[@"path"]; FlutterStandardTypedData *hdImageData = - call.arguments[ARGUMENT_KEY_HDIMAGEDATA]; + call.arguments[@"hdImageData"]; if (hdImageData != nil) { mediaObject.hdImageData = hdImageData.data; } - NSNumber *withShareTicket = call.arguments[ARGUMENT_KEY_WITHSHARETICKET]; + NSNumber *withShareTicket = call.arguments[@"withShareTicket"]; mediaObject.withShareTicket = withShareTicket.boolValue; - NSNumber *miniProgramType = call.arguments[ARGUMENT_KEY_TYPE]; + NSNumber *miniProgramType = call.arguments[@"type"]; mediaObject.miniProgramType = miniProgramType.unsignedIntegerValue; - NSNumber *disableForward = call.arguments[ARGUMENT_KEY_DISABLEFORWARD]; + NSNumber *disableForward = call.arguments[@"disableForward"]; mediaObject.disableForward = disableForward.boolValue; message.mediaObject = mediaObject; } @@ -401,14 +286,14 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)handleSubscribeMsgCall:(FlutterMethodCall *)call result:(FlutterResult)result { WXSubscribeMsgReq *req = [[WXSubscribeMsgReq alloc] init]; - NSNumber *scene = call.arguments[ARGUMENT_KEY_SCENE]; + NSNumber *scene = call.arguments[@"scene"]; #if __LP64__ req.scene = [scene unsignedIntValue]; #else req.scene = [scene unsignedLongValue]; #endif - req.templateId = call.arguments[ARGUMENT_KEY_TEMPLATEID]; - req.reserved = call.arguments[ARGUMENT_KEY_RESERVED]; + req.templateId = call.arguments[@"templateId"]; + req.reserved = call.arguments[@"reserved"]; [WXApi sendReq:req completion:^(BOOL success){ // do nothing @@ -419,9 +304,9 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)handleLaunchMiniProgramCall:(FlutterMethodCall *)call result:(FlutterResult)result { WXLaunchMiniProgramReq *req = [[WXLaunchMiniProgramReq alloc] init]; - req.userName = call.arguments[ARGUMENT_KEY_USERNAME]; - req.path = call.arguments[ARGUMENT_KEY_PATH]; - NSNumber *miniProgramType = call.arguments[ARGUMENT_KEY_TYPE]; + req.userName = call.arguments[@"username"]; + req.path = call.arguments[@"path"]; + NSNumber *miniProgramType = call.arguments[@"type"]; req.miniProgramType = miniProgramType.unsignedIntegerValue; [WXApi sendReq:req completion:^(BOOL success){ @@ -433,8 +318,8 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)handleOpenCustomerServiceChatCall:(FlutterMethodCall *)call result:(FlutterResult)result { WXOpenCustomerServiceReq *req = [[WXOpenCustomerServiceReq alloc] init]; - req.corpid = call.arguments[ARGUMENT_KEY_CORPID]; - req.url = call.arguments[ARGUMENT_KEY_URL]; + req.corpid = call.arguments[@"corpId"]; + req.url = call.arguments[@"url"]; [WXApi sendReq:req completion:^(BOOL success){ // do nothing @@ -445,9 +330,9 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)handleOpenBusinessViewCall:(FlutterMethodCall *)call result:(FlutterResult)result { WXOpenBusinessViewReq *req = [[WXOpenBusinessViewReq alloc] init]; - req.businessType = call.arguments[ARGUMENT_KEY_BUSINESSTYPE]; - req.query = call.arguments[ARGUMENT_KEY_QUERY]; - req.extInfo = call.arguments[ARGUMENT_KEY_EXTINFO]; + req.businessType = call.arguments[@"businessType"]; + req.query = call.arguments[@"query"]; + req.extInfo = call.arguments[@"extInfo"]; [WXApi sendReq:req completion:^(BOOL success){ // do nothing @@ -456,28 +341,28 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; } - (void)handleOpenBusinessWebviewCall:(FlutterMethodCall *)call - result:(FlutterResult)result { + result:(FlutterResult)result { WXOpenBusinessWebViewReq *req = [[WXOpenBusinessWebViewReq alloc] init]; - NSNumber *businessType = call.arguments[ARGUMENT_KEY_BUSINESSTYPE]; + NSNumber *businessType = call.arguments[@"businessType"]; #if __LP64__ req.businessType = [businessType unsignedIntValue]; #else req.businessType = [businessType unsignedLongValue]; #endif - req.queryInfoDic = call.arguments[ARGUMENT_KEY_QUERYINFO]; + req.queryInfoDic = call.arguments[@"queryInfo"]; result(nil); } #ifndef NO_PAY - (void)handlePayCall:(FlutterMethodCall *)call result:(FlutterResult)result { PayReq *req = [[PayReq alloc] init]; - req.partnerId = call.arguments[ARGUMENT_KEY_PARTNERID]; - req.prepayId = call.arguments[ARGUMENT_KEY_PREPAYID]; - req.nonceStr = call.arguments[ARGUMENT_KEY_NONCESTR]; - NSString *timeStamp = call.arguments[ARGUMENT_KEY_TIMESTAMP]; + req.partnerId = call.arguments[@"partnerId"]; + req.prepayId = call.arguments[@"prepayId"]; + req.nonceStr = call.arguments[@"noncestr"]; + NSString *timeStamp = call.arguments[@"timestamp"]; req.timeStamp = [timeStamp intValue]; - req.package = call.arguments[ARGUMENT_KEY_PACKAGE]; - req.sign = call.arguments[ARGUMENT_KEY_SIGN]; + req.package = call.arguments[@"package"]; + req.sign = call.arguments[@"sign"]; [WXApi sendReq:req completion:^(BOOL success){ // do nothing @@ -518,32 +403,32 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; if ([req isKindOfClass:[LaunchFromWXReq class]]) { LaunchFromWXReq *launchFromWXReq = (LaunchFromWXReq *)req; - [dictionary setValue:launchFromWXReq.message.messageAction forKey:ARGUMENT_KEY_RESULT_MESSAGEACTION]; - [dictionary setValue:launchFromWXReq.message.messageExt forKey:ARGUMENT_KEY_RESULT_MESSAGEEXT]; - [dictionary setValue:launchFromWXReq.lang forKey:ARGUMENT_KEY_RESULT_LANG]; - [dictionary setValue:launchFromWXReq.country forKey:ARGUMENT_KEY_RESULT_COUNTRY]; + [dictionary setValue:launchFromWXReq.message.messageAction forKey:@"messageAction"]; + [dictionary setValue:launchFromWXReq.message.messageExt forKey:@"messageExt"]; + [dictionary setValue:launchFromWXReq.lang forKey:@"lang"]; + [dictionary setValue:launchFromWXReq.country forKey:@"country"]; if (_isRunning) { - [_channel invokeMethod:METHOD_ONLAUNCHFROMWXREQ arguments:dictionary]; + [_channel invokeMethod:@"onLaunchFromWXReq" arguments:dictionary]; } else { __weak typeof(self) weakSelf = self; _initialWXReqRunnable = ^() { __strong typeof(weakSelf) strongSelf = weakSelf; - [strongSelf -> _channel invokeMethod:METHOD_ONLAUNCHFROMWXREQ arguments:dictionary]; + [strongSelf->_channel invokeMethod:@"onLaunchFromWXReq" arguments:dictionary]; }; } } else if ([req isKindOfClass:[ShowMessageFromWXReq class]]) { ShowMessageFromWXReq *showMessageFromWXReq = (ShowMessageFromWXReq *)req; - [dictionary setValue:showMessageFromWXReq.message.messageAction forKey:ARGUMENT_KEY_RESULT_MESSAGEACTION]; - [dictionary setValue:showMessageFromWXReq.message.messageExt forKey:ARGUMENT_KEY_RESULT_MESSAGEEXT]; - [dictionary setValue:showMessageFromWXReq.lang forKey:ARGUMENT_KEY_RESULT_LANG]; - [dictionary setValue:showMessageFromWXReq.country forKey:ARGUMENT_KEY_RESULT_COUNTRY]; + [dictionary setValue:showMessageFromWXReq.message.messageAction forKey:@"messageAction"]; + [dictionary setValue:showMessageFromWXReq.message.messageExt forKey:@"messageExt"]; + [dictionary setValue:showMessageFromWXReq.lang forKey:@"lang"]; + [dictionary setValue:showMessageFromWXReq.country forKey:@"country"]; if (_isRunning) { - [_channel invokeMethod:METHOD_ONSHOWMESSAGEFROMWXREQ arguments:dictionary]; + [_channel invokeMethod:@"onShowMessageFromWXReq" arguments:dictionary]; } else { __weak typeof(self) weakSelf = self; _initialWXReqRunnable = ^() { __strong typeof(weakSelf) strongSelf = weakSelf; - [strongSelf -> _channel invokeMethod:METHOD_ONSHOWMESSAGEFROMWXREQ arguments:dictionary]; + [strongSelf->_channel invokeMethod:@"onShowMessageFromWXReq" arguments:dictionary]; }; } } @@ -552,75 +437,75 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; - (void)onResp:(BaseResp *)resp { NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; [dictionary setValue:[NSNumber numberWithInt:resp.errCode] - forKey:ARGUMENT_KEY_RESULT_ERRORCODE]; + forKey:@"errorCode"]; if (resp.errStr != nil) { - [dictionary setValue:resp.errStr forKey:ARGUMENT_KEY_RESULT_ERRORMSG]; + [dictionary setValue:resp.errStr forKey:@"errorMsg"]; } if ([resp isKindOfClass:[SendAuthResp class]]) { // 授权 if (resp.errCode == WXSuccess) { SendAuthResp *authResp = (SendAuthResp *)resp; - [dictionary setValue:authResp.code forKey:ARGUMENT_KEY_RESULT_CODE]; - [dictionary setValue:authResp.state forKey:ARGUMENT_KEY_RESULT_STATE]; - [dictionary setValue:authResp.lang forKey:ARGUMENT_KEY_RESULT_LANG]; - [dictionary setValue:authResp.country forKey:ARGUMENT_KEY_RESULT_COUNTRY]; + [dictionary setValue:authResp.code forKey:@"code"]; + [dictionary setValue:authResp.state forKey:@"state"]; + [dictionary setValue:authResp.lang forKey:@"lang"]; + [dictionary setValue:authResp.country forKey:@"country"]; } - [_channel invokeMethod:METHOD_ONAUTHRESP arguments:dictionary]; + [_channel invokeMethod:@"onAuthResp" arguments:dictionary]; } else if ([resp isKindOfClass:[OpenWebviewResp class]]) { // 浏览器 - [_channel invokeMethod:METHOD_ONOPENURLRESP arguments:dictionary]; + [_channel invokeMethod:@"onOpenUrlResp" arguments:dictionary]; } else if ([resp isKindOfClass:[SendMessageToWXResp class]]) { // 分享 - [_channel invokeMethod:METHOD_ONSHAREMSGRESP arguments:dictionary]; + [_channel invokeMethod:@"onShareMsgResp" arguments:dictionary]; } else if ([resp isKindOfClass:[WXSubscribeMsgResp class]]) { // 一次性订阅消息 if (resp.errCode == WXSuccess) { WXSubscribeMsgResp *subscribeMsgResp = (WXSubscribeMsgResp *)resp; [dictionary setValue:subscribeMsgResp.templateId - forKey:ARGUMENT_KEY_RESULT_TEMPLATEID]; + forKey:@"templateId"]; [dictionary setValue:[NSNumber numberWithUnsignedInt:subscribeMsgResp.scene] - forKey:ARGUMENT_KEY_RESULT_SCENE]; + forKey:@"scene"]; [dictionary setValue:subscribeMsgResp.action - forKey:ARGUMENT_KEY_RESULT_ACTION]; + forKey:@"action"]; [dictionary setValue:subscribeMsgResp.reserved - forKey:ARGUMENT_KEY_RESULT_RESERVED]; + forKey:@"reserved"]; } - [_channel invokeMethod:METHOD_ONSUBSCRIBEMSGRESP arguments:dictionary]; + [_channel invokeMethod:@"onSubscribeMsgResp" arguments:dictionary]; } else if ([resp isKindOfClass:[WXLaunchMiniProgramResp class]]) { // 打开小程序 if (resp.errCode == WXSuccess) { WXLaunchMiniProgramResp *launchMiniProgramResp = (WXLaunchMiniProgramResp *)resp; [dictionary setValue:launchMiniProgramResp.extMsg - forKey:ARGUMENT_KEY_RESULT_EXTMSG]; + forKey:@"extMsg"]; } - [_channel invokeMethod:METHOD_ONLAUNCHMINIPROGRAMRESP arguments:dictionary]; + [_channel invokeMethod:@"onLaunchMiniProgramResp" arguments:dictionary]; } else if ([resp isKindOfClass:[WXOpenCustomerServiceResp class]]) { - [_channel invokeMethod:METHOD_ONOPENCUSTOMERSERVICECHATRESP arguments:dictionary]; + [_channel invokeMethod:@"onOpenCustomerServiceChatResp" arguments:dictionary]; } else if ([resp isKindOfClass:[WXOpenBusinessViewResp class]]) { if (resp.errCode == WXSuccess) { WXOpenBusinessViewResp *openBusinessViewResp = (WXOpenBusinessViewResp *)resp; - [dictionary setValue:openBusinessViewResp.businessType forKey:ARGUMENT_KEY_RESULT_BUSINESSTYPE]; - [dictionary setValue:openBusinessViewResp.extMsg forKey:ARGUMENT_KEY_RESULT_EXTMSG]; + [dictionary setValue:openBusinessViewResp.businessType forKey:@"businessType"]; + [dictionary setValue:openBusinessViewResp.extMsg forKey:@"extMsg"]; } - [_channel invokeMethod:METHOD_ONOPENBUSINESSVIEWRESP arguments:dictionary]; + [_channel invokeMethod:@"onOpenBusinessViewResp" arguments:dictionary]; } else if ([resp isKindOfClass:[WXOpenBusinessWebViewResp class]]) { if (resp.errCode == WXSuccess) { WXOpenBusinessWebViewResp *openBusinessWebviewResp = (WXOpenBusinessWebViewResp *)resp; - [dictionary setValue:[NSNumber numberWithUnsignedInt:openBusinessWebviewResp.businessType] forKey:ARGUMENT_KEY_RESULT_BUSINESSTYPE]; - [dictionary setValue:openBusinessWebviewResp.result forKey:ARGUMENT_KEY_RESULT_RESULTINFO]; + [dictionary setValue:[NSNumber numberWithUnsignedInt:openBusinessWebviewResp.businessType] forKey:@"businessType"]; + [dictionary setValue:openBusinessWebviewResp.result forKey:@"resultInfo"]; } - [_channel invokeMethod:METHOD_ONOPENBUSINESSWEBVIEWRESP arguments:dictionary]; + [_channel invokeMethod:@"onOpenBusinessWebviewResp" arguments:dictionary]; } #ifndef NO_PAY else if ([resp isKindOfClass:[PayResp class]]) { // 支付 if (resp.errCode == WXSuccess) { PayResp *payResp = (PayResp *)resp; - [dictionary setValue:payResp.returnKey forKey:ARGUMENT_KEY_RESULT_RETURNKEY]; + [dictionary setValue:payResp.returnKey forKey:@"returnKey"]; } - [_channel invokeMethod:METHOD_ONPAYRESP arguments:dictionary]; + [_channel invokeMethod:@"onPayResp" arguments:dictionary]; } #endif } @@ -633,21 +518,21 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode"; imageData = UIImageJPEGRepresentation(image, 1); } NSDictionary *dictionary = @{ - ARGUMENT_KEY_RESULT_IMAGEDATA : imageData, + @"imageData" : imageData, }; - [_channel invokeMethod:METHOD_ONAUTHGOTQRCODE arguments:dictionary]; + [_channel invokeMethod:@"onAuthGotQrcode" arguments:dictionary]; } - (void)onQrcodeScanned { - [_channel invokeMethod:METHOD_ONAUTHQRCODESCANNED arguments:nil]; + [_channel invokeMethod:@"onAuthQrcodeScanned" arguments:nil]; } - (void)onAuthFinish:(int)errCode AuthCode:(NSString *)authCode { NSDictionary *dictionary = @{ - ARGUMENT_KEY_RESULT_ERRORCODE : [NSNumber numberWithInt:errCode], - ARGUMENT_KEY_RESULT_AUTHCODE : authCode, + @"errorCode" : [NSNumber numberWithInt:errCode], + @"authCode" : authCode, }; - [_channel invokeMethod:METHOD_ONAUTHFINISH arguments:dictionary]; + [_channel invokeMethod:@"onAuthFinish" arguments:dictionary]; } @end diff --git a/ios/wechat_kit.podspec b/ios/wechat_kit.podspec index b06d160..4b4486e 100644 --- a/ios/wechat_kit.podspec +++ b/ios/wechat_kit.podspec @@ -1,6 +1,6 @@ # # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. -# Run `pod lib lint wechat_kit.podspec' to validate before publishing. +# Run `pod lib lint wechat_kit.podspec` to validate before publishing. # if defined?($WechatKitSubspec) @@ -11,19 +11,19 @@ end Pod::Spec.new do |s| s.name = 'wechat_kit' - s.version = '3.2.0' + s.version = '4.0.0' s.summary = 'The Flutter plugin for WeChat SDKs.' s.description = <<-DESC A powerful Flutter plugin allowing developers to auth/pay/share with native Android & iOS WeChat SDKs. DESC - s.homepage = 'https://github.com/RxReader/wechat_kit' + s.homepage = 'http://example.com' s.license = { :file => '../LICENSE' } - s.author = { 'RxReader' => 'email@example.com' } + s.author = { 'Your Company' => 'email@example.com' } s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.public_header_files = 'Classes/**/*.h' s.dependency 'Flutter' - s.platform = :ios, '8.0' + s.platform = :ios, '9.0' s.static_framework = true # s.default_subspecs = :none diff --git a/lib/src/wechat.dart b/lib/src/wechat.dart old mode 100755 new mode 100644 index 756ac7c..9784cb3 --- a/lib/src/wechat.dart +++ b/lib/src/wechat.dart @@ -1,335 +1,129 @@ -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; import 'dart:typed_data'; -import 'package:convert/convert.dart'; -import 'package:crypto/crypto.dart'; -import 'package:flutter/services.dart'; import 'package:wechat_kit/src/model/qrauth.dart'; import 'package:wechat_kit/src/model/req.dart'; import 'package:wechat_kit/src/model/resp.dart'; import 'package:wechat_kit/src/wechat_constant.dart'; +import 'package:wechat_kit/src/wechat_kit_platform_interface.dart'; -/// The Wechat instance. class Wechat { - Wechat._(); - - static Wechat get instance => _instance; - static late final Wechat _instance = Wechat._(); - - static const String _METHOD_REGISTERAPP = 'registerApp'; - static const String _METHOD_HANDLEINITIALWXREQ = 'handleInitialWXReq'; - static const String _METHOD_ISINSTALLED = 'isInstalled'; - static const String _METHOD_ISSUPPORTAPI = 'isSupportApi'; - static const String _METHOD_ISSUPPORTSTATEAPI = 'isSupportStateAPI'; - static const String _METHOD_OPENWECHAT = 'openWechat'; - static const String _METHOD_AUTH = 'auth'; - static const String _METHOD_STARTQRAUTH = 'startQrauth'; - static const String _METHOD_STOPQRAUTH = 'stopQrauth'; - static const String _METHOD_OPENURL = 'openUrl'; - static const String _METHOD_OPENRANKLIST = 'openRankList'; - static const String _METHOD_SHARETEXT = 'shareText'; - static const String _METHOD_SHAREIMAGE = 'shareImage'; - static const String _METHOD_SHAREFILE = 'shareFile'; - static const String _METHOD_SHAREEMOJI = 'shareEmoji'; - static const String _METHOD_SHAREMUSIC = 'shareMusic'; - static const String _METHOD_SHAREVIDEO = 'shareVideo'; - static const String _METHOD_SHAREWEBPAGE = 'shareWebpage'; - static const String _METHOD_SHAREMINIPROGRAM = 'shareMiniProgram'; - static const String _METHOD_SUBSCRIBEMSG = 'subscribeMsg'; - static const String _METHOD_LAUNCHMINIPROGRAM = 'launchMiniProgram'; - static const String _METHOD_OPENCUSTOMERSERVICECHAT = - 'openCustomerServiceChat'; - static const String _METHOD_OPENBUSINESSVIEW = 'openBusinessView'; - static const String _METHOD_OPENBUSINESSWEBVIEW = 'openBusinessWebview'; - static const String _METHOD_PAY = 'pay'; - - static const String _METHOD_ONLAUNCHFROMWXREQ = 'onLaunchFromWXReq'; - static const String _METHOD_ONSHOWMESSAGEFROMWXREQ = 'onShowMessageFromWXReq'; - - static const String _METHOD_ONAUTHRESP = 'onAuthResp'; - static const String _METHOD_ONOPENURLRESP = 'onOpenUrlResp'; - static const String _METHOD_ONSHAREMSGRESP = 'onShareMsgResp'; - static const String _METHOD_ONSUBSCRIBEMSGRESP = 'onSubscribeMsgResp'; - static const String _METHOD_ONLAUNCHMINIPROGRAMRESP = - 'onLaunchMiniProgramResp'; - static const String _METHOD_ONOPENCUSTOMERSERVICECHATRESP = - 'onOpenCustomerServiceChatResp'; - static const String _METHOD_ONOPENBUSINESSVIEWRESP = 'onOpenBusinessViewResp'; - static const String _METHOD_ONOPENBUSINESSWEBVIEWRESP = - 'onOpenBusinessWebviewResp'; - static const String _METHOD_ONPAYRESP = 'onPayResp'; - static const String _METHOD_ONAUTHGOTQRCODE = 'onAuthGotQrcode'; - static const String _METHOD_ONAUTHQRCODESCANNED = 'onAuthQrcodeScanned'; - static const String _METHOD_ONAUTHFINISH = 'onAuthFinish'; - - static const String _ARGUMENT_KEY_APPID = 'appId'; - static const String _ARGUMENT_KEY_UNIVERSALLINK = 'universalLink'; - static const String _ARGUMENT_KEY_SCOPE = 'scope'; - static const String _ARGUMENT_KEY_STATE = 'state'; - static const String _ARGUMENT_KEY_NONCESTR = 'noncestr'; - static const String _ARGUMENT_KEY_TIMESTAMP = 'timestamp'; - static const String _ARGUMENT_KEY_SIGNATURE = 'signature'; - static const String _ARGUMENT_KEY_URL = 'url'; - static const String _ARGUMENT_KEY_QUERY = 'query'; - static const String _ARGUMENT_KEY_USERNAME = 'username'; - static const String _ARGUMENT_KEY_SCENE = 'scene'; - static const String _ARGUMENT_KEY_TEXT = 'text'; - static const String _ARGUMENT_KEY_TITLE = 'title'; - static const String _ARGUMENT_KEY_DESCRIPTION = 'description'; - static const String _ARGUMENT_KEY_THUMBDATA = 'thumbData'; - static const String _ARGUMENT_KEY_IMAGEDATA = 'imageData'; - static const String _ARGUMENT_KEY_IMAGEURI = 'imageUri'; - static const String _ARGUMENT_KEY_FILEDATA = 'fileData'; - static const String _ARGUMENT_KEY_FILEURI = 'fileUri'; - static const String _ARGUMENT_KEY_FILEEXTENSION = 'fileExtension'; - static const String _ARGUMENT_KEY_EMOJIDATA = 'emojiData'; - static const String _ARGUMENT_KEY_EMOJIURI = 'emojiUri'; - static const String _ARGUMENT_KEY_MUSICURL = 'musicUrl'; - static const String _ARGUMENT_KEY_MUSICDATAURL = 'musicDataUrl'; - static const String _ARGUMENT_KEY_MUSICLOWBANDURL = 'musicLowBandUrl'; - static const String _ARGUMENT_KEY_MUSICLOWBANDDATAURL = 'musicLowBandDataUrl'; - static const String _ARGUMENT_KEY_VIDEOURL = 'videoUrl'; - static const String _ARGUMENT_KEY_VIDEOLOWBANDURL = 'videoLowBandUrl'; - static const String _ARGUMENT_KEY_WEBPAGEURL = 'webpageUrl'; - static const String _ARGUMENT_KEY_PATH = 'path'; - static const String _ARGUMENT_KEY_HDIMAGEDATA = 'hdImageData'; - static const String _ARGUMENT_KEY_WITHSHARETICKET = 'withShareTicket'; - static const String _ARGUMENT_KEY_TYPE = 'type'; - static const String _ARGUMENT_KEY_DISABLEFORWARD = 'disableForward'; - static const String _ARGUMENT_KEY_TEMPLATEID = 'templateId'; - static const String _ARGUMENT_KEY_RESERVED = 'reserved'; - static const String _ARGUMENT_KEY_CORPID = 'corpId'; - static const String _ARGUMENT_KEY_BUSINESSTYPE = 'businessType'; - static const String _ARGUMENT_KEY_QUERYINFO = 'queryInfo'; - static const String _ARGUMENT_KEY_PARTNERID = 'partnerId'; - static const String _ARGUMENT_KEY_PREPAYID = 'prepayId'; - static const String _ARGUMENT_KEY_PACKAGE = 'package'; - static const String _ARGUMENT_KEY_SIGN = 'sign'; - static const String _ARGUMENT_KEY_EXTINFO = 'extInfo'; - - static const String _SCHEME_FILE = 'file'; - - late final MethodChannel _channel = - const MethodChannel('v7lin.github.io/wechat_kit') - ..setMethodCallHandler(_handleMethod); - - final StreamController _reqStreamController = - StreamController.broadcast(); - - final StreamController _respStreamController = - StreamController.broadcast(); - - final StreamController _qrauthRespStreamController = - StreamController.broadcast(); + const Wechat._(); /// 向微信注册应用 - Future registerApp({ + static Future registerApp({ required String appId, required String? universalLink, }) { - assert(!Platform.isIOS || (universalLink?.isNotEmpty ?? false)); - return _channel.invokeMethod( - _METHOD_REGISTERAPP, - { - _ARGUMENT_KEY_APPID: appId, - _ARGUMENT_KEY_UNIVERSALLINK: universalLink, - }, + return WechatKitPlatform.instance.registerApp( + appId: appId, + universalLink: universalLink, ); } - /// 微信回调 - 冷启 - Future handleInitialWXReq() { - return _channel.invokeMethod(_METHOD_HANDLEINITIALWXREQ); - } - - Future _handleMethod(MethodCall call) async { - // 优先处理不需要参数的请求 - if (call.method == _METHOD_ONAUTHQRCODESCANNED) { - _qrauthRespStreamController.add(const QrcodeScannedResp()); - return; - } - - final Map _data = - (call.arguments as Map).cast(); - - switch (call.method) { - // onReq - case _METHOD_ONLAUNCHFROMWXREQ: - _reqStreamController.add(LaunchFromWXReq.fromJson(_data)); - break; - case _METHOD_ONSHOWMESSAGEFROMWXREQ: - _reqStreamController.add(ShowMessageFromWXReq.fromJson(_data)); - break; - // onResp - case _METHOD_ONAUTHRESP: - _respStreamController.add(AuthResp.fromJson(_data)); - break; - case _METHOD_ONOPENURLRESP: - _respStreamController.add(OpenUrlResp.fromJson(_data)); - break; - case _METHOD_ONSHAREMSGRESP: - _respStreamController.add(ShareMsgResp.fromJson(_data)); - break; - case _METHOD_ONSUBSCRIBEMSGRESP: - _respStreamController.add(SubscribeMsgResp.fromJson(_data)); - break; - case _METHOD_ONLAUNCHMINIPROGRAMRESP: - _respStreamController.add(LaunchMiniProgramResp.fromJson(_data)); - break; - case _METHOD_ONOPENCUSTOMERSERVICECHATRESP: - _respStreamController.add(OpenCustomerServiceChatResp.fromJson(_data)); - break; - case _METHOD_ONOPENBUSINESSVIEWRESP: - _respStreamController.add(OpenBusinessViewResp.fromJson(_data)); - break; - case _METHOD_ONOPENBUSINESSWEBVIEWRESP: - _respStreamController.add(OpenBusinessWebviewResp.fromJson(_data)); - break; - case _METHOD_ONPAYRESP: - _respStreamController.add(PayResp.fromJson(_data)); - break; - // onQrauth - case _METHOD_ONAUTHGOTQRCODE: - _qrauthRespStreamController.add(GotQrcodeResp.fromJson(_data)); - break; - case _METHOD_ONAUTHFINISH: - _qrauthRespStreamController.add(FinishResp.fromJson(_data)); - break; - } + /// + static Stream reqStream() { + return WechatKitPlatform.instance.reqStream(); } /// - Stream reqStream() { - return _reqStreamController.stream; - } - - /// - Stream respStream() { - return _respStreamController.stream; + static Stream respStream() { + return WechatKitPlatform.instance.respStream(); } /// 扫码登录 - Stream qrauthRespStream() { - return _qrauthRespStreamController.stream; + static Stream qrauthRespStream() { + return WechatKitPlatform.instance.qrauthRespStream(); + } + + /// 微信回调 - 冷启 + static Future handleInitialWXReq() { + return WechatKitPlatform.instance.handleInitialWXReq(); } /// 检测微信是否已安装 - Future isInstalled() async { - return await _channel.invokeMethod(_METHOD_ISINSTALLED) ?? false; + static Future isInstalled() { + return WechatKitPlatform.instance.isInstalled(); } /// 判断当前微信的版本是否支持OpenApi - Future isSupportApi() async { - return await _channel.invokeMethod(_METHOD_ISSUPPORTAPI) ?? false; + static Future isSupportApi() { + return WechatKitPlatform.instance.isSupportApi(); } /// 判断当前微信的版本是否支持分享微信状态功能 - Future isSupportStateAPI() async { - return await _channel.invokeMethod(_METHOD_ISSUPPORTSTATEAPI) ?? - false; + static Future isSupportStateApi() { + return WechatKitPlatform.instance.isSupportStateApi(); } /// 打开微信 - Future openWechat() async { - return await _channel.invokeMethod(_METHOD_OPENWECHAT) ?? false; + static Future openWechat() { + return WechatKitPlatform.instance.openWechat(); } // --- 微信APP授权登录 /// 授权登录 - Future auth({ + static Future auth({ required List scope, String? state, + int type = WechatAuthType.NORMAL, }) { - return _channel.invokeMethod(_METHOD_AUTH, { - _ARGUMENT_KEY_SCOPE: scope.join(','), // Scope - if (state != null) _ARGUMENT_KEY_STATE: state, - }); - } - - /// iOS:未安装微信,授权登录 - Future sendAuth({ - required List scope, - String? state, - }) { - assert(Platform.isIOS); - return _channel.invokeMethod('sendAuth', { - _ARGUMENT_KEY_SCOPE: scope.join(','), // Scope - if (state != null) _ARGUMENT_KEY_STATE: state, - }); + return WechatKitPlatform.instance.auth( + scope: scope, + state: state, + type: type, + ); } // --- 微信APP扫码登录 /// 调用微信 API 获得 ticket,开始扫码登录 - Future startQrauth({ + static Future startQrauth({ required String appId, required List scope, required String noncestr, required String ticket, }) { - final String timestamp = '${DateTime.now().millisecondsSinceEpoch}'; - final String content = 'appid=$appId' - '&noncestr=$noncestr' - '&sdk_ticket=$ticket' - '×tamp=$timestamp'; - final String signature = hex.encode( - sha1.convert(utf8.encode(content)).bytes, - ); - return _channel.invokeMethod( - _METHOD_STARTQRAUTH, - { - _ARGUMENT_KEY_APPID: appId, - _ARGUMENT_KEY_SCOPE: scope.join(','), // Scope - _ARGUMENT_KEY_NONCESTR: noncestr, - _ARGUMENT_KEY_TIMESTAMP: timestamp, - _ARGUMENT_KEY_SIGNATURE: signature, - }, + return WechatKitPlatform.instance.startQrauth( + appId: appId, + scope: scope, + noncestr: noncestr, + ticket: ticket, ); } /// 暂停扫码登录请求 - Future stopQrauth() { - return _channel.invokeMethod(_METHOD_STOPQRAUTH); + static Future stopQrauth() { + return WechatKitPlatform.instance.stopQrauth(); } + // + /// 打开指定网页 - Future openUrl({ + static Future openUrl({ required String url, }) { - assert(url.length <= 10 * 1024); - return _channel.invokeMethod( - _METHOD_OPENURL, - { - _ARGUMENT_KEY_URL: url, - }, - ); + return WechatKitPlatform.instance.openUrl(url: url); } /// 打开硬件排行榜 - Future openRankList() { - return _channel.invokeMethod(_METHOD_OPENRANKLIST); + static Future openRankList() { + return WechatKitPlatform.instance.openRankList(); } /// 分享 - 文本 - Future shareText({ + static Future shareText({ required int scene, required String text, }) { - assert(text.length <= 10 * 1024); - return _channel.invokeMethod( - _METHOD_SHARETEXT, - { - _ARGUMENT_KEY_SCENE: scene, // Scene - _ARGUMENT_KEY_TEXT: text, - }, + return WechatKitPlatform.instance.shareText( + scene: scene, + text: text, ); } /// 分享 - 图片 - Future shareImage({ + static Future shareImage({ required int scene, String? title, String? description, @@ -337,31 +131,18 @@ class Wechat { Uint8List? imageData, Uri? imageUri, }) { - assert(title == null || title.length <= 512); - assert(description == null || description.length <= 1024); - assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); - assert( - (imageData != null && imageData.lengthInBytes <= 25 * 1024 * 1024) || - (imageUri != null && - imageUri.isScheme(_SCHEME_FILE) && - imageUri.toFilePath().length <= 10 * 1024 && - File.fromUri(imageUri).lengthSync() <= 25 * 1024 * 1024), - ); - return _channel.invokeMethod( - _METHOD_SHAREIMAGE, - { - _ARGUMENT_KEY_SCENE: scene, // Scene - if (title != null) _ARGUMENT_KEY_TITLE: title, - if (description != null) _ARGUMENT_KEY_DESCRIPTION: description, - if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData, - if (imageData != null) _ARGUMENT_KEY_IMAGEDATA: imageData, - if (imageUri != null) _ARGUMENT_KEY_IMAGEURI: imageUri.toString(), - }, + return WechatKitPlatform.instance.shareImage( + scene: scene, + title: title, + description: description, + thumbData: thumbData, + imageData: imageData, + imageUri: imageUri, ); } /// 分享 - 文件 - Future shareFile({ + static Future shareFile({ required int scene, String? title, String? description, @@ -370,33 +151,19 @@ class Wechat { Uri? fileUri, String? fileExtension, }) { - assert(title == null || title.length <= 512); - assert(description == null || description.length <= 1024); - assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); - assert( - (fileData != null && fileData.lengthInBytes <= 10 * 1024 * 1024) || - (fileUri != null && - fileUri.isScheme(_SCHEME_FILE) && - fileUri.toFilePath().length <= 10 * 1024 && - File.fromUri(fileUri).lengthSync() <= 10 * 1024 * 1024), - ); - assert(Platform.isAndroid || (fileExtension?.isNotEmpty ?? false)); - return _channel.invokeMethod( - _METHOD_SHAREFILE, - { - _ARGUMENT_KEY_SCENE: scene, // Scene - if (title != null) _ARGUMENT_KEY_TITLE: title, - if (description != null) _ARGUMENT_KEY_DESCRIPTION: description, - if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData, - if (fileData != null) _ARGUMENT_KEY_FILEDATA: fileData, - if (fileUri != null) _ARGUMENT_KEY_FILEURI: fileUri.toString(), - if (fileExtension != null) _ARGUMENT_KEY_FILEEXTENSION: fileExtension, - }, + return WechatKitPlatform.instance.shareFile( + scene: scene, + title: title, + description: description, + thumbData: thumbData, + fileData: fileData, + fileUri: fileUri, + fileExtension: fileExtension, ); } /// 分享 - Emoji/GIF - Future shareEmoji({ + static Future shareEmoji({ required int scene, String? title, String? description, @@ -404,31 +171,18 @@ class Wechat { Uint8List? emojiData, Uri? emojiUri, }) { - assert(title == null || title.length <= 512); - assert(description == null || description.length <= 1024); - assert(thumbData.lengthInBytes <= 32 * 1024); - assert( - (emojiData != null && emojiData.lengthInBytes <= 10 * 1024 * 1024) || - (emojiUri != null && - emojiUri.isScheme(_SCHEME_FILE) && - emojiUri.toFilePath().length <= 10 * 1024 && - File.fromUri(emojiUri).lengthSync() <= 10 * 1024 * 1024), - ); - return _channel.invokeMethod( - _METHOD_SHAREEMOJI, - { - _ARGUMENT_KEY_SCENE: scene, // Scene - if (title != null) _ARGUMENT_KEY_TITLE: title, - if (description != null) _ARGUMENT_KEY_DESCRIPTION: description, - _ARGUMENT_KEY_THUMBDATA: thumbData, - if (emojiData != null) _ARGUMENT_KEY_EMOJIDATA: emojiData, - if (emojiUri != null) _ARGUMENT_KEY_EMOJIURI: emojiUri.toString(), - }, + return WechatKitPlatform.instance.shareEmoji( + scene: scene, + title: title, + description: description, + thumbData: thumbData, + emojiData: emojiData, + emojiUri: emojiUri, ); } /// 分享 - 音乐 - Future shareMediaMusic({ + static Future shareMediaMusic({ required int scene, String? title, String? description, @@ -438,32 +192,20 @@ class Wechat { String? musicLowBandUrl, String? musicLowBandDataUrl, }) { - assert(title == null || title.length <= 512); - assert(description == null || description.length <= 1024); - assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); - assert( - (musicUrl != null && musicUrl.length <= 10 * 1024) || - (musicLowBandUrl != null && musicLowBandUrl.length <= 10 * 1024), - ); - return _channel.invokeMethod( - _METHOD_SHAREMUSIC, - { - _ARGUMENT_KEY_SCENE: scene, // Scene - if (title != null) _ARGUMENT_KEY_TITLE: title, - if (description != null) _ARGUMENT_KEY_DESCRIPTION: description, - if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData, - if (musicUrl != null) _ARGUMENT_KEY_MUSICURL: musicUrl, - if (musicDataUrl != null) _ARGUMENT_KEY_MUSICDATAURL: musicDataUrl, - if (musicLowBandUrl != null) - _ARGUMENT_KEY_MUSICLOWBANDURL: musicLowBandUrl, - if (musicLowBandDataUrl != null) - _ARGUMENT_KEY_MUSICLOWBANDDATAURL: musicLowBandDataUrl, - }, + return WechatKitPlatform.instance.shareMediaMusic( + scene: scene, + title: title, + description: description, + thumbData: thumbData, + musicUrl: musicUrl, + musicDataUrl: musicDataUrl, + musicLowBandUrl: musicLowBandUrl, + musicLowBandDataUrl: musicLowBandDataUrl, ); } /// 分享 - 视频 - Future shareVideo({ + static Future shareVideo({ required int scene, String? title, String? description, @@ -471,53 +213,35 @@ class Wechat { String? videoUrl, String? videoLowBandUrl, }) { - assert(title == null || title.length <= 512); - assert(description == null || description.length <= 1024); - assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); - assert( - (videoUrl != null && videoUrl.length <= 10 * 1024) || - (videoLowBandUrl != null && videoLowBandUrl.length <= 10 * 1024), - ); - return _channel.invokeMethod( - _METHOD_SHAREVIDEO, - { - _ARGUMENT_KEY_SCENE: scene, // Scene - if (title != null) _ARGUMENT_KEY_TITLE: title, - if (description != null) _ARGUMENT_KEY_DESCRIPTION: description, - if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData, - if (videoUrl != null) _ARGUMENT_KEY_VIDEOURL: videoUrl, - if (videoLowBandUrl != null) - _ARGUMENT_KEY_VIDEOLOWBANDURL: videoLowBandUrl, - }, + return WechatKitPlatform.instance.shareVideo( + scene: scene, + title: title, + description: description, + thumbData: thumbData, + videoUrl: videoUrl, + videoLowBandUrl: videoLowBandUrl, ); } /// 分享 - 网页 - Future shareWebpage({ + static Future shareWebpage({ required int scene, String? title, String? description, Uint8List? thumbData, required String webpageUrl, }) { - assert(title == null || title.length <= 512); - assert(description == null || description.length <= 1024); - assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); - assert(webpageUrl.length <= 10 * 1024); - return _channel.invokeMethod( - _METHOD_SHAREWEBPAGE, - { - _ARGUMENT_KEY_SCENE: scene, // Scene - if (title != null) _ARGUMENT_KEY_TITLE: title, - if (description != null) _ARGUMENT_KEY_DESCRIPTION: description, - if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData, - _ARGUMENT_KEY_WEBPAGEURL: webpageUrl, - }, + return WechatKitPlatform.instance.shareWebpage( + scene: scene, + title: title, + description: description, + thumbData: thumbData, + webpageUrl: webpageUrl, ); } /// 分享 - 小程序 - 目前只支持分享到会话 - Future shareMiniProgram({ + static Future shareMiniProgram({ required int scene, String? title, String? description, @@ -527,77 +251,58 @@ class Wechat { String? path, Uint8List? hdImageData, bool withShareTicket = false, - int type = WechatMiniProgram.release, + int type = WechatMiniProgram.RELEASE, bool disableForward = false, }) { - assert(scene == WechatScene.SESSION); - assert(title == null || title.length <= 512); - assert(description == null || description.length <= 1024); - assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); - assert(hdImageData == null || hdImageData.lengthInBytes <= 128 * 1024); - return _channel.invokeMethod( - _METHOD_SHAREMINIPROGRAM, - { - _ARGUMENT_KEY_SCENE: scene, // Scene - if (title != null) _ARGUMENT_KEY_TITLE: title, - if (description != null) _ARGUMENT_KEY_DESCRIPTION: description, - if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData, - _ARGUMENT_KEY_WEBPAGEURL: webpageUrl, - _ARGUMENT_KEY_USERNAME: userName, - if (path != null) _ARGUMENT_KEY_PATH: path, - if (hdImageData != null) _ARGUMENT_KEY_HDIMAGEDATA: hdImageData, - _ARGUMENT_KEY_WITHSHARETICKET: withShareTicket, - _ARGUMENT_KEY_TYPE: type, - _ARGUMENT_KEY_DISABLEFORWARD: disableForward, - }, + return WechatKitPlatform.instance.shareMiniProgram( + scene: scene, + title: title, + description: description, + thumbData: thumbData, + webpageUrl: webpageUrl, + userName: userName, + path: path, + hdImageData: hdImageData, + withShareTicket: withShareTicket, + type: type, + disableForward: disableForward, ); } /// 一次性订阅消息 - Future subscribeMsg({ + static Future subscribeMsg({ required int scene, required String templateId, String? reserved, }) { - assert(templateId.length <= 1024); - assert(reserved == null || reserved.length <= 1024); - return _channel.invokeMethod( - _METHOD_SUBSCRIBEMSG, - { - _ARGUMENT_KEY_SCENE: scene, - _ARGUMENT_KEY_TEMPLATEID: templateId, - if (reserved != null) _ARGUMENT_KEY_RESERVED: reserved, - }, + return WechatKitPlatform.instance.subscribeMsg( + scene: scene, + templateId: templateId, + reserved: reserved, ); } /// 打开小程序 - Future launchMiniProgram({ + static Future launchMiniProgram({ required String userName, String? path, - int type = WechatMiniProgram.release, + int type = WechatMiniProgram.RELEASE, }) { - return _channel.invokeMethod( - _METHOD_LAUNCHMINIPROGRAM, - { - _ARGUMENT_KEY_USERNAME: userName, - if (path != null) _ARGUMENT_KEY_PATH: path, - _ARGUMENT_KEY_TYPE: type, - }, + return WechatKitPlatform.instance.launchMiniProgram( + userName: userName, + path: path, + type: type, ); } /// 打开微信客服 - Future openCustomerServiceChat({ + static Future openCustomerServiceChat({ required String corpId, required String url, }) { - return _channel.invokeMethod( - _METHOD_OPENCUSTOMERSERVICECHAT, - { - _ARGUMENT_KEY_CORPID: corpId, - _ARGUMENT_KEY_URL: url, - }, + return WechatKitPlatform.instance.openCustomerServiceChat( + corpId: corpId, + url: url, ); } @@ -605,34 +310,28 @@ class Wechat { /// * 免确认模式:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter6_1_7.shtml /// * 需确认授权:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter6_1_11.shtml /// * 拉起小程序:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter6_1_23.shtml - Future openBusinessView({ + static Future openBusinessView({ required String businessType, String? query, String? extInfo, }) { - return _channel.invokeMethod( - _METHOD_OPENBUSINESSVIEW, - { - _ARGUMENT_KEY_BUSINESSTYPE: businessType, - if (query != null) _ARGUMENT_KEY_QUERY: query, - if (extInfo != null) _ARGUMENT_KEY_EXTINFO: extInfo, - }, + return WechatKitPlatform.instance.openBusinessView( + businessType: businessType, + query: query, + extInfo: extInfo, ); } /// APP纯签约 /// * APP纯签约-预签约接口:https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_5 /// * APP纯签约-预签约接口:https://pay.weixin.qq.com/wiki/doc/api/pap_jt_v2.php?chapter=19_5&index=2_2 - Future openBusinessWebview({ + static Future openBusinessWebview({ required int businessType, Map? resultInfo, }) { - return _channel.invokeMethod( - _METHOD_OPENBUSINESSWEBVIEW, - { - _ARGUMENT_KEY_BUSINESSTYPE: businessType, - if (resultInfo != null) _ARGUMENT_KEY_QUERYINFO: resultInfo, - }, + return WechatKitPlatform.instance.openBusinessWebview( + businessType: businessType, + resultInfo: resultInfo, ); } @@ -643,7 +342,7 @@ class Wechat { /// * 默认包含支付,参考 https://github.com/RxReader/wechat_kit/blob/master/example/ios/Podfile /// 修改 `$WechatKitSubspec = 'no_pay'` 可切换为不包含支付。 /// * 不含「iOS 支付」调用会抛出 [MissingPluginException]。 - Future pay({ + static Future pay({ required String appId, required String partnerId, required String prepayId, @@ -652,17 +351,14 @@ class Wechat { required String timeStamp, required String sign, }) { - return _channel.invokeMethod( - _METHOD_PAY, - { - _ARGUMENT_KEY_APPID: appId, - _ARGUMENT_KEY_PARTNERID: partnerId, - _ARGUMENT_KEY_PREPAYID: prepayId, - _ARGUMENT_KEY_NONCESTR: nonceStr, - _ARGUMENT_KEY_TIMESTAMP: timeStamp, - _ARGUMENT_KEY_PACKAGE: package, - _ARGUMENT_KEY_SIGN: sign, - }, + return WechatKitPlatform.instance.pay( + appId: appId, + partnerId: partnerId, + prepayId: prepayId, + package: package, + nonceStr: nonceStr, + timeStamp: timeStamp, + sign: sign, ); } } diff --git a/lib/src/wechat_constant.dart b/lib/src/wechat_constant.dart index 0aca828..3c4f53b 100755 --- a/lib/src/wechat_constant.dart +++ b/lib/src/wechat_constant.dart @@ -8,6 +8,16 @@ class WechatScope { static const String SNSAPI_USERINFO = 'snsapi_userinfo'; } +class WechatAuthType { + const WechatAuthType._(); + + /// APP授权 + static const int NORMAL = 0; + + /// WEB授权 + static const int WEB = 1; +} + class WechatScene { const WechatScene._(); @@ -42,11 +52,11 @@ class WechatMiniProgram { const WechatMiniProgram._(); /// 正式版 - static const int release = 0; + static const int RELEASE = 0; /// 测试版 - static const int test = 1; + static const int TEST = 1; /// 体验版 - static const int preview = 2; + static const int PREVIEW = 2; } diff --git a/lib/src/wechat_kit_method_channel.dart b/lib/src/wechat_kit_method_channel.dart new file mode 100644 index 0000000..0a37f51 --- /dev/null +++ b/lib/src/wechat_kit_method_channel.dart @@ -0,0 +1,549 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:crypto/crypto.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; +import 'package:wechat_kit/src/model/qrauth.dart'; +import 'package:wechat_kit/src/model/req.dart'; +import 'package:wechat_kit/src/model/resp.dart'; +import 'package:wechat_kit/src/wechat_constant.dart'; +import 'package:wechat_kit/src/wechat_kit_platform_interface.dart'; + +/// An implementation of [WechatKitPlatform] that uses method channels. +class MethodChannelWechatKit extends WechatKitPlatform { + /// The method channel used to interact with the native platform. + @visibleForTesting + late final MethodChannel methodChannel = const MethodChannel('v7lin.github.io/wechat_kit')..setMethodCallHandler(_handleMethod); + + final StreamController _reqStreamController = StreamController.broadcast(); + + final StreamController _respStreamController = StreamController.broadcast(); + + final StreamController _qrauthRespStreamController = StreamController.broadcast(); + + Future _handleMethod(MethodCall call) async { + // 优先处理不需要参数的请求 + if (call.method == 'onAuthQrcodeScanned') { + _qrauthRespStreamController.add(const QrcodeScannedResp()); + return; + } + + final Map data = (call.arguments as Map).cast(); + + switch (call.method) { + // onReq + case 'onLaunchFromWXReq': + _reqStreamController.add(LaunchFromWXReq.fromJson(data)); + break; + case 'onShowMessageFromWXReq': + _reqStreamController.add(ShowMessageFromWXReq.fromJson(data)); + break; + // onResp + case 'onAuthResp': + _respStreamController.add(AuthResp.fromJson(data)); + break; + case 'onOpenUrlResp': + _respStreamController.add(OpenUrlResp.fromJson(data)); + break; + case 'onShareMsgResp': + _respStreamController.add(ShareMsgResp.fromJson(data)); + break; + case 'onSubscribeMsgResp': + _respStreamController.add(SubscribeMsgResp.fromJson(data)); + break; + case 'onLaunchMiniProgramResp': + _respStreamController.add(LaunchMiniProgramResp.fromJson(data)); + break; + case 'onOpenCustomerServiceChatResp': + _respStreamController.add(OpenCustomerServiceChatResp.fromJson(data)); + break; + case 'onOpenBusinessViewResp': + _respStreamController.add(OpenBusinessViewResp.fromJson(data)); + break; + case 'onOpenBusinessWebviewResp': + _respStreamController.add(OpenBusinessWebviewResp.fromJson(data)); + break; + case 'onPayResp': + _respStreamController.add(PayResp.fromJson(data)); + break; + // onQrauth + case 'onAuthGotQrcode': + _qrauthRespStreamController.add(GotQrcodeResp.fromJson(data)); + break; + case 'onAuthFinish': + _qrauthRespStreamController.add(FinishResp.fromJson(data)); + break; + } + } + + @override + Future registerApp({ + required String appId, + required String? universalLink, + }) { + assert(!Platform.isIOS || (universalLink?.isNotEmpty ?? false)); + return methodChannel.invokeMethod( + 'registerApp', + { + 'appId': appId, + 'universalLink': universalLink, + }, + ); + } + + @override + Stream reqStream() { + return _reqStreamController.stream; + } + + @override + Stream respStream() { + return _respStreamController.stream; + } + + @override + Stream qrauthRespStream() { + return _qrauthRespStreamController.stream; + } + + @override + Future handleInitialWXReq() { + return methodChannel.invokeMethod('handleInitialWXReq'); + } + + @override + Future isInstalled() async { + return await methodChannel.invokeMethod('isInstalled') ?? false; + } + + @override + Future isSupportApi() async { + return await methodChannel.invokeMethod('isSupportApi') ?? false; + } + + @override + Future isSupportStateApi() async { + return await methodChannel.invokeMethod('isSupportStateApi') ?? false; + } + + @override + Future openWechat() async { + return await methodChannel.invokeMethod('openWechat') ?? false; + } + + // --- 微信APP授权登录 + + @override + Future auth({ + required List scope, + String? state, + int type = WechatAuthType.NORMAL, + }) { + assert((Platform.isAndroid && type == WechatAuthType.NORMAL) || (Platform.isIOS && [WechatAuthType.NORMAL, WechatAuthType.WEB].contains(type))); + return methodChannel.invokeMethod('auth', { + 'scope': scope.join(','), // Scope + if (state != null) 'state': state, + 'type': type, + }); + } + + // --- 微信APP扫码登录 + + @override + Future startQrauth({ + required String appId, + required List scope, + required String noncestr, + required String ticket, + }) { + final String timestamp = '${DateTime.now().millisecondsSinceEpoch}'; + final String content = 'appid=$appId' + '&noncestr=$noncestr' + '&sdk_ticket=$ticket' + '×tamp=$timestamp'; + final String signature = hex.encode( + sha1.convert(utf8.encode(content)).bytes, + ); + return methodChannel.invokeMethod( + 'startQrauth', + { + 'appId': appId, + 'scope': scope.join(','), // Scope + 'noncestr': noncestr, + 'timestamp': timestamp, + 'signature': signature, + }, + ); + } + + @override + Future stopQrauth() { + return methodChannel.invokeMethod('stopQrauth'); + } + + // + + @override + Future openUrl({ + required String url, + }) { + assert(url.length <= 10 * 1024); + return methodChannel.invokeMethod( + 'openUrl', + { + 'url': url, + }, + ); + } + + @override + Future openRankList() { + return methodChannel.invokeMethod('openRankList'); + } + + @override + Future shareText({ + required int scene, + required String text, + }) { + assert(text.length <= 10 * 1024); + return methodChannel.invokeMethod( + 'shareText', + { + 'scene': scene, // Scene + 'text': text, + }, + ); + } + + @override + Future shareImage({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + Uint8List? imageData, + Uri? imageUri, + }) { + assert(title == null || title.length <= 512); + assert(description == null || description.length <= 1024); + assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); + assert( + (imageData != null && imageData.lengthInBytes <= 25 * 1024 * 1024) || + (imageUri != null && + imageUri.isScheme('file') && + imageUri.toFilePath().length <= 10 * 1024 && + File.fromUri(imageUri).lengthSync() <= 25 * 1024 * 1024), + ); + return methodChannel.invokeMethod( + 'shareImage', + { + 'scene': scene, // Scene + if (title != null) 'title': title, + if (description != null) 'description': description, + if (thumbData != null) 'thumbData': thumbData, + if (imageData != null) 'imageData': imageData, + if (imageUri != null) 'imageUri': imageUri.toString(), + }, + ); + } + + @override + Future shareFile({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + Uint8List? fileData, + Uri? fileUri, + String? fileExtension, + }) { + assert(title == null || title.length <= 512); + assert(description == null || description.length <= 1024); + assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); + assert( + (fileData != null && fileData.lengthInBytes <= 10 * 1024 * 1024) || + (fileUri != null && + fileUri.isScheme('file') && + fileUri.toFilePath().length <= 10 * 1024 && + File.fromUri(fileUri).lengthSync() <= 10 * 1024 * 1024), + ); + assert(Platform.isAndroid || (fileExtension?.isNotEmpty ?? false)); + return methodChannel.invokeMethod( + 'shareFile', + { + 'scene': scene, // Scene + if (title != null) 'title': title, + if (description != null) 'description': description, + if (thumbData != null) 'thumbData': thumbData, + if (fileData != null) 'fileData': fileData, + if (fileUri != null) 'fileUri': fileUri.toString(), + if (fileExtension != null) 'fileExtension': fileExtension, + }, + ); + } + + @override + Future shareEmoji({ + required int scene, + String? title, + String? description, + required Uint8List thumbData, + Uint8List? emojiData, + Uri? emojiUri, + }) { + assert(title == null || title.length <= 512); + assert(description == null || description.length <= 1024); + assert(thumbData.lengthInBytes <= 32 * 1024); + assert( + (emojiData != null && emojiData.lengthInBytes <= 10 * 1024 * 1024) || + (emojiUri != null && + emojiUri.isScheme('file') && + emojiUri.toFilePath().length <= 10 * 1024 && + File.fromUri(emojiUri).lengthSync() <= 10 * 1024 * 1024), + ); + return methodChannel.invokeMethod( + 'shareEmoji', + { + 'scene': scene, // Scene + if (title != null) 'title': title, + if (description != null) 'description': description, + 'thumbData': thumbData, + if (emojiData != null) 'emojiData': emojiData, + if (emojiUri != null) 'emojiUri': emojiUri.toString(), + }, + ); + } + + @override + Future shareMediaMusic({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + String? musicUrl, + String? musicDataUrl, + String? musicLowBandUrl, + String? musicLowBandDataUrl, + }) { + assert(title == null || title.length <= 512); + assert(description == null || description.length <= 1024); + assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); + assert( + (musicUrl != null && musicUrl.length <= 10 * 1024) || + (musicLowBandUrl != null && musicLowBandUrl.length <= 10 * 1024), + ); + return methodChannel.invokeMethod( + 'shareMusic', + { + 'scene': scene, // Scene + if (title != null) 'title': title, + if (description != null) 'description': description, + if (thumbData != null) 'thumbData': thumbData, + if (musicUrl != null) 'musicUrl': musicUrl, + if (musicDataUrl != null) 'musicDataUrl': musicDataUrl, + if (musicLowBandUrl != null) + 'musicLowBandUrl': musicLowBandUrl, + if (musicLowBandDataUrl != null) + 'musicLowBandDataUrl': musicLowBandDataUrl, + }, + ); + } + + @override + Future shareVideo({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + String? videoUrl, + String? videoLowBandUrl, + }) { + assert(title == null || title.length <= 512); + assert(description == null || description.length <= 1024); + assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); + assert( + (videoUrl != null && videoUrl.length <= 10 * 1024) || + (videoLowBandUrl != null && videoLowBandUrl.length <= 10 * 1024), + ); + return methodChannel.invokeMethod( + 'shareVideo', + { + 'scene': scene, // Scene + if (title != null) 'title': title, + if (description != null) 'description': description, + if (thumbData != null) 'thumbData': thumbData, + if (videoUrl != null) 'videoUrl': videoUrl, + if (videoLowBandUrl != null) + 'videoLowBandUrl': videoLowBandUrl, + }, + ); + } + + @override + Future shareWebpage({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + required String webpageUrl, + }) { + assert(title == null || title.length <= 512); + assert(description == null || description.length <= 1024); + assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); + assert(webpageUrl.length <= 10 * 1024); + return methodChannel.invokeMethod( + 'shareWebpage', + { + 'scene': scene, // Scene + if (title != null) 'title': title, + if (description != null) 'description': description, + if (thumbData != null) 'thumbData': thumbData, + 'webpageUrl': webpageUrl, + }, + ); + } + + @override + Future shareMiniProgram({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + required String webpageUrl, + required String userName, + String? path, + Uint8List? hdImageData, + bool withShareTicket = false, + int type = WechatMiniProgram.RELEASE, + bool disableForward = false, + }) { + assert(scene == WechatScene.SESSION); + assert(title == null || title.length <= 512); + assert(description == null || description.length <= 1024); + assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024); + assert(hdImageData == null || hdImageData.lengthInBytes <= 128 * 1024); + return methodChannel.invokeMethod( + 'shareMiniProgram', + { + 'scene': scene, // Scene + if (title != null) 'title': title, + if (description != null) 'description': description, + if (thumbData != null) 'thumbData': thumbData, + 'webpageUrl': webpageUrl, + 'username': userName, + if (path != null) 'path': path, + if (hdImageData != null) 'hdImageData': hdImageData, + 'withShareTicket': withShareTicket, + 'type': type, + 'disableForward': disableForward, + }, + ); + } + + @override + Future subscribeMsg({ + required int scene, + required String templateId, + String? reserved, + }) { + assert(templateId.length <= 1024); + assert(reserved == null || reserved.length <= 1024); + return methodChannel.invokeMethod( + 'subscribeMsg', + { + 'scene': scene, + 'templateId': templateId, + if (reserved != null) 'reserved': reserved, + }, + ); + } + + @override + Future launchMiniProgram({ + required String userName, + String? path, + int type = WechatMiniProgram.RELEASE, + }) { + return methodChannel.invokeMethod( + 'launchMiniProgram', + { + 'username': userName, + if (path != null) 'path': path, + 'type': type, + }, + ); + } + + @override + Future openCustomerServiceChat({ + required String corpId, + required String url, + }) { + return methodChannel.invokeMethod( + 'openCustomerServiceChat', + { + 'corpId': corpId, + 'url': url, + }, + ); + } + + @override + Future openBusinessView({ + required String businessType, + String? query, + String? extInfo, + }) { + return methodChannel.invokeMethod( + 'openBusinessView', + { + 'businessType': businessType, + if (query != null) 'query': query, + if (extInfo != null) 'extInfo': extInfo, + }, + ); + } + + @override + Future openBusinessWebview({ + required int businessType, + Map? resultInfo, + }) { + return methodChannel.invokeMethod( + 'openBusinessWebview', + { + 'businessType': businessType, + if (resultInfo != null) 'queryInfo': resultInfo, + }, + ); + } + + @override + Future pay({ + required String appId, + required String partnerId, + required String prepayId, + required String package, + required String nonceStr, + required String timeStamp, + required String sign, + }) { + return methodChannel.invokeMethod( + 'pay', + { + 'appId': appId, + 'partnerId': partnerId, + 'prepayId': prepayId, + 'noncestr': nonceStr, + 'timestamp': timeStamp, + 'package': package, + 'sign': sign, + }, + ); + } +} diff --git a/lib/src/wechat_kit_platform_interface.dart b/lib/src/wechat_kit_platform_interface.dart new file mode 100644 index 0000000..430d1c3 --- /dev/null +++ b/lib/src/wechat_kit_platform_interface.dart @@ -0,0 +1,247 @@ +import 'dart:typed_data'; + +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:wechat_kit/src/model/qrauth.dart'; +import 'package:wechat_kit/src/model/req.dart'; +import 'package:wechat_kit/src/model/resp.dart'; +import 'package:wechat_kit/src/wechat_constant.dart'; +import 'package:wechat_kit/src/wechat_kit_method_channel.dart'; + +abstract class WechatKitPlatform extends PlatformInterface { + /// Constructs a WechatKitPlatform. + WechatKitPlatform() : super(token: _token); + + static final Object _token = Object(); + + static WechatKitPlatform _instance = MethodChannelWechatKit(); + + /// The default instance of [WechatKitPlatform] to use. + /// + /// Defaults to [MethodChannelWechatKit]. + static WechatKitPlatform get instance => _instance; + + /// Platform-specific implementations should set this with their own + /// platform-specific class that extends [WechatKitPlatform] when + /// they register themselves. + static set instance(WechatKitPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + Future registerApp({ + required String appId, + required String? universalLink, + }) { + throw UnimplementedError('registerApp({required appId, required universalLink}) has not been implemented.'); + } + + Stream reqStream() { + throw UnimplementedError('reqStream() has not been implemented.'); + } + + Stream respStream() { + throw UnimplementedError('respStream() has not been implemented.'); + } + + Stream qrauthRespStream() { + throw UnimplementedError('qrauthRespStream() has not been implemented.'); + } + + Future handleInitialWXReq() { + throw UnimplementedError('handleInitialWXReq() has not been implemented.'); + } + + Future isInstalled() { + throw UnimplementedError('isInstalled() has not been implemented.'); + } + + Future isSupportApi() { + throw UnimplementedError('isSupportApi() has not been implemented.'); + } + + Future isSupportStateApi() { + throw UnimplementedError('isSupportStateApi() has not been implemented.'); + } + + Future openWechat() { + throw UnimplementedError('openWechat() has not been implemented.'); + } + + // --- 微信APP授权登录 + + Future auth({ + required List scope, + String? state, + int type = WechatAuthType.NORMAL, + }) { + throw UnimplementedError('auth({required scope, state, type}) has not been implemented.'); + } + + // --- 微信APP扫码登录 + + Future startQrauth({ + required String appId, + required List scope, + required String noncestr, + required String ticket, + }) { + throw UnimplementedError('startQrauth({required appId, required scope, required noncestr, required ticket}) has not been implemented.'); + } + + Future stopQrauth() { + throw UnimplementedError('stopQrauth() has not been implemented.'); + } + + // + + Future openUrl({ + required String url, + }) { + throw UnimplementedError('openUrl({required url}) has not been implemented.'); + } + + Future openRankList() { + throw UnimplementedError('openRankList() has not been implemented.'); + } + + Future shareText({ + required int scene, + required String text, + }) { + throw UnimplementedError('shareText({required scene, required text}) has not been implemented.'); + } + + Future shareImage({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + Uint8List? imageData, + Uri? imageUri, + }) { + throw UnimplementedError('shareImage({required scene, title, description, thumbData, imageData, imageUri}) has not been implemented.'); + } + + Future shareFile({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + Uint8List? fileData, + Uri? fileUri, + String? fileExtension, + }) { + throw UnimplementedError('shareFile({required scene, title, description, thumbData, fileData, fileUri, fileExtension}) has not been implemented.'); + } + + Future shareEmoji({ + required int scene, + String? title, + String? description, + required Uint8List thumbData, + Uint8List? emojiData, + Uri? emojiUri, + }) { + throw UnimplementedError('shareEmoji({required scene, title, description, required thumbData, emojiData, emojiUri}) has not been implemented.'); + } + + Future shareMediaMusic({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + String? musicUrl, + String? musicDataUrl, + String? musicLowBandUrl, + String? musicLowBandDataUrl, + }) { + throw UnimplementedError('shareMediaMusic({required scene, title, description, thumbData, musicUrl, musicDataUrl, musicLowBandUrl, musicLowBandDataUrl}) has not been implemented.'); + } + + Future shareVideo({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + String? videoUrl, + String? videoLowBandUrl, + }) { + throw UnimplementedError('shareVideo({required scene, title, description, thumbData, videoUrl, videoLowBandUrl}) has not been implemented.'); + } + + Future shareWebpage({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + required String webpageUrl, + }) { + throw UnimplementedError('shareWebpage({required scene, title, description, thumbData, required webpageUrl}) has not been implemented.'); + } + + Future shareMiniProgram({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + required String webpageUrl, + required String userName, + String? path, + Uint8List? hdImageData, + bool withShareTicket = false, + int type = WechatMiniProgram.RELEASE, + bool disableForward = false, + }) { + throw UnimplementedError('shareMiniProgram({required scene, title, description, thumbData, required webpageUrl, required userName, path, hdImageData, withShareTicket, type, disableForward}) has not been implemented.'); + } + + Future subscribeMsg({ + required int scene, + required String templateId, + String? reserved, + }) { + throw UnimplementedError('subscribeMsg({required scene, required templateId, reserved}) has not been implemented.'); + } + + Future launchMiniProgram({ + required String userName, + String? path, + int type = WechatMiniProgram.RELEASE, + }) { + throw UnimplementedError('launchMiniProgram({required userName, path, type}) has not been implemented.'); + } + + Future openCustomerServiceChat({ + required String corpId, + required String url, + }) { + throw UnimplementedError('openCustomerServiceChat({required corpId, required url}) has not been implemented.'); + } + + Future openBusinessView({ + required String businessType, + String? query, + String? extInfo, + }) { + throw UnimplementedError('openBusinessView({required businessType, query, extInfo}) has not been implemented.'); + } + + Future openBusinessWebview({ + required int businessType, + Map? resultInfo, + }) { + throw UnimplementedError('openBusinessWebview({required businessType, resultInfo}) has not been implemented.'); + } + + Future pay({ + required String appId, + required String partnerId, + required String prepayId, + required String package, + required String nonceStr, + required String timeStamp, + required String sign, + }) { + throw UnimplementedError('pay({required appId, required partnerId, required prepayId, required package, required nonceStr, required timeStamp, required sign}) has not been implemented.'); + } +} diff --git a/lib/wechat_kit.dart b/lib/wechat_kit.dart old mode 100755 new mode 100644 diff --git a/pubspec.yaml b/pubspec.yaml index 6a4ec44..00abb12 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,27 +1,27 @@ name: wechat_kit description: A powerful Flutter plugin allowing developers to auth/share/pay with natvie Android & iOS Wechat SDKs. -version: 3.2.0 +version: 4.0.0 # author: v7lin homepage: https://github.com/rxreader/wechat_kit environment: - sdk: ">=2.12.0 <3.0.0" - flutter: ">=2.0.0" + sdk: ">=2.17.0 <3.0.0" + flutter: ">=2.5.0" dependencies: flutter: sdk: flutter + plugin_platform_interface: ^2.0.2 - convert: ^3.0.0 - crypto: ^3.0.0 + convert: ^3.0.1 + crypto: ^3.0.2 - json_annotation: ^4.0.0 + json_annotation: ^4.5.0 dev_dependencies: flutter_test: sdk: flutter - - pedantic: + flutter_lints: ^2.0.0 build_runner: json_serializable: @@ -29,11 +29,17 @@ dev_dependencies: # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec -# The following section is specific to Flutter. +# The following section is specific to Flutter packages. flutter: # This section identifies this Flutter project as a plugin project. - # The 'pluginClass' and Android 'package' identifiers should not ordinarily - # be modified. They are used by the tooling to maintain consistency when + # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) + # 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. plugin: platforms: @@ -52,7 +58,7 @@ flutter: # https://flutter.dev/assets-and-images/#from-packages # # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. + # https://flutter.dev/assets-and-images/#resolution-aware # To add custom fonts to your plugin package, add a fonts section here, # in this "flutter" section. Each entry in this list should have a diff --git a/test/wechat_kit_method_channel_test.dart b/test/wechat_kit_method_channel_test.dart new file mode 100644 index 0000000..97cabe0 --- /dev/null +++ b/test/wechat_kit_method_channel_test.dart @@ -0,0 +1,27 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:wechat_kit/src/wechat_kit_method_channel.dart'; + +void main() { + final MethodChannelWechatKit platform = MethodChannelWechatKit(); + const MethodChannel channel = MethodChannel('v7lin.github.io/wechat_kit'); + + TestWidgetsFlutterBinding.ensureInitialized(); + + setUp(() { + channel.setMockMethodCallHandler((MethodCall methodCall) async { + switch (methodCall.method) { + case 'isInstalled': + return true; + } + }); + }); + + tearDown(() { + channel.setMockMethodCallHandler(null); + }); + + test('isInstalled', () async { + expect(await platform.isInstalled(), true); + }); +} diff --git a/test/wechat_kit_test.dart b/test/wechat_kit_test.dart deleted file mode 100644 index ea5506c..0000000 --- a/test/wechat_kit_test.dart +++ /dev/null @@ -1,138 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; - -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:pedantic/pedantic.dart'; -import 'package:wechat_kit/wechat_kit.dart'; - -void main() { - TestWidgetsFlutterBinding.ensureInitialized(); - - const MethodChannel channel = MethodChannel('v7lin.github.io/wechat_kit'); - - setUp(() { - channel.setMockMethodCallHandler((MethodCall call) async { - switch (call.method) { - case 'registerApp': - return null; - case 'isInstalled': - return true; - case 'isSupportApi': - return true; - case 'openWechat': - return true; - case 'auth': - unawaited(channel.binaryMessenger.handlePlatformMessage( - channel.name, - channel.codec.encodeMethodCall(MethodCall( - 'onAuthResp', - json.decode( - '{"country":"CN","code":null,"errorCode":-2,"state":null,"lang":"zh_CN","errorMsg":null}'))), - (ByteData? data) { - print('mock ${channel.name} ${call.method}'); - }, - )); - return null; - case 'startQrauth': - case 'stopQrauth': - throw PlatformException(code: '0', message: '懒得去mock'); - case 'openUrl': - case 'openRankList': - throw PlatformException(code: '0', message: '懒得去mock'); - case 'shareText': - case 'shareImage': - case 'shareEmoji': - case 'shareMusic': - case 'shareVideo': - case 'shareWebpage': - case 'shareMiniProgram': - unawaited(channel.binaryMessenger.handlePlatformMessage( - channel.name, - channel.codec.encodeMethodCall(MethodCall('onShareMsgResp', - json.decode('{"errorCode":0,"errorMsg":null}'))), - (ByteData? data) { - print('mock ${channel.name} ${call.method}'); - }, - )); - return null; - case 'subscribeMsg': - case 'launchMiniProgram': - throw PlatformException(code: '0', message: '懒得去mock'); - case 'pay': - unawaited(channel.binaryMessenger.handlePlatformMessage( - channel.name, - channel.codec.encodeMethodCall(MethodCall( - 'onPayResp', - json.decode( - '{"errorCode":-2,"returnKey":"","errorMsg":null}'))), - (ByteData? data) { - print('mock ${channel.name} ${call.method}'); - }, - )); - return null; - } - throw PlatformException(code: '0', message: '想啥呢,升级插件不想升级Mock?'); - }); - }); - - tearDown(() { - channel.setMockMethodCallHandler(null); - }); - - test('isInstalled', () async { - expect(await Wechat.instance.isInstalled(), true); - }); - - test('isSupportApi', () async { - expect(await Wechat.instance.isSupportApi(), true); - }); - - test('auth', () async { - final StreamSubscription subs = - Wechat.instance.respStream().listen((BaseResp resp) { - expect(resp.runtimeType, AuthResp); - expect(resp.errorCode, BaseResp.ERRORCODE_USERCANCEL); - }); - await Wechat.instance.auth( - scope: [ - WechatScope.SNSAPI_USERINFO, - ], - ); - await Future.delayed(const Duration(seconds: 1)); - await subs.cancel(); - }); - - test('share', () async { - final StreamSubscription subs = - Wechat.instance.respStream().listen((BaseResp resp) { - expect(resp.runtimeType, ShareMsgResp); - expect(resp.errorCode, BaseResp.ERRORCODE_SUCCESS); - }); - await Wechat.instance.shareText( - scene: WechatScene.SESSION, - text: 'share text', - ); - await Future.delayed(const Duration(seconds: 1)); - await subs.cancel(); - }); - - test('pay', () async { - final StreamSubscription subs = - Wechat.instance.respStream().listen((BaseResp resp) { - expect(resp.runtimeType, PayResp); - expect(resp.errorCode, BaseResp.ERRORCODE_USERCANCEL); - }); - await Wechat.instance.pay( - appId: 'mock', - partnerId: 'mock', - prepayId: 'mock', - package: 'mock', - nonceStr: 'mock', - timeStamp: 'mock', - sign: 'mock', - ); - await Future.delayed(const Duration(seconds: 1)); - await subs.cancel(); - }); -} diff --git a/test/wechat_test.dart b/test/wechat_test.dart new file mode 100644 index 0000000..140070e --- /dev/null +++ b/test/wechat_test.dart @@ -0,0 +1,273 @@ +import 'dart:typed_data'; + +import 'package:flutter_test/flutter_test.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'package:wechat_kit/src/model/qrauth.dart'; +import 'package:wechat_kit/src/model/req.dart'; +import 'package:wechat_kit/src/model/resp.dart'; +import 'package:wechat_kit/src/wechat.dart'; +import 'package:wechat_kit/src/wechat_constant.dart'; +import 'package:wechat_kit/src/wechat_kit_method_channel.dart'; +import 'package:wechat_kit/src/wechat_kit_platform_interface.dart'; + +class MockWechatKitPlatform with MockPlatformInterfaceMixin implements WechatKitPlatform { + @override + Future registerApp({ + required String appId, + required String? universalLink, + }) { + throw UnimplementedError(); + } + + @override + Stream reqStream() { + throw UnimplementedError(); + } + + @override + Stream respStream() { + throw UnimplementedError(); + } + + @override + Stream qrauthRespStream() { + throw UnimplementedError(); + } + + @override + Future handleInitialWXReq() { + throw UnimplementedError(); + } + + @override + Future isInstalled() { + return Future.value(true); + } + + @override + Future isSupportApi() { + throw UnimplementedError(); + } + + @override + Future isSupportStateApi() { + throw UnimplementedError(); + } + + @override + Future openWechat() { + throw UnimplementedError(); + } + + // --- 微信APP授权登录 + + @override + Future auth({ + required List scope, + String? state, + int type = WechatAuthType.NORMAL, + }) { + throw UnimplementedError(); + } + + // --- 微信APP扫码登录 + + @override + Future startQrauth({ + required String appId, + required List scope, + required String noncestr, + required String ticket, + }) { + throw UnimplementedError(); + } + + @override + Future stopQrauth() { + throw UnimplementedError(); + } + + // + + @override + Future openUrl({ + required String url, + }) { + throw UnimplementedError(); + } + + @override + Future openRankList() { + throw UnimplementedError(); + } + + @override + Future shareText({ + required int scene, + required String text, + }) { + throw UnimplementedError(); + } + + @override + Future shareImage({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + Uint8List? imageData, + Uri? imageUri, + }) { + throw UnimplementedError(); + } + + @override + Future shareFile({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + Uint8List? fileData, + Uri? fileUri, + String? fileExtension, + }) { + throw UnimplementedError(); + } + + @override + Future shareEmoji({ + required int scene, + String? title, + String? description, + required Uint8List thumbData, + Uint8List? emojiData, + Uri? emojiUri, + }) { + throw UnimplementedError(); + } + + @override + Future shareMediaMusic({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + String? musicUrl, + String? musicDataUrl, + String? musicLowBandUrl, + String? musicLowBandDataUrl, + }) { + throw UnimplementedError(); + } + + @override + Future shareVideo({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + String? videoUrl, + String? videoLowBandUrl, + }) { + throw UnimplementedError(); + } + + @override + Future shareWebpage({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + required String webpageUrl, + }) { + throw UnimplementedError(); + } + + @override + Future shareMiniProgram({ + required int scene, + String? title, + String? description, + Uint8List? thumbData, + required String webpageUrl, + required String userName, + String? path, + Uint8List? hdImageData, + bool withShareTicket = false, + int type = WechatMiniProgram.RELEASE, + bool disableForward = false, + }) { + throw UnimplementedError(); + } + + @override + Future subscribeMsg({ + required int scene, + required String templateId, + String? reserved, + }) { + throw UnimplementedError(); + } + + @override + Future launchMiniProgram({ + required String userName, + String? path, + int type = WechatMiniProgram.RELEASE, + }) { + throw UnimplementedError(); + } + + @override + Future openCustomerServiceChat({ + required String corpId, + required String url, + }) { + throw UnimplementedError(); + } + + @override + Future openBusinessView({ + required String businessType, + String? query, + String? extInfo, + }) { + throw UnimplementedError(); + } + + @override + Future openBusinessWebview({ + required int businessType, + Map? resultInfo, + }) { + throw UnimplementedError(); + } + + @override + Future pay({ + required String appId, + required String partnerId, + required String prepayId, + required String package, + required String nonceStr, + required String timeStamp, + required String sign, + }) { + throw UnimplementedError(); + } +} + +void main() { + final WechatKitPlatform initialPlatform = WechatKitPlatform.instance; + + test('$MethodChannelWechatKit is the default instance', () { + expect(initialPlatform, isInstanceOf()); + }); + + test('getPlatformVersion', () async { + final MockWechatKitPlatform fakePlatform = MockWechatKitPlatform(); + WechatKitPlatform.instance = fakePlatform; + + expect(await Wechat.isInstalled(), true); + }); +}