diff --git a/.drone.yml b/.drone.yml index 2c586a3..47aaf68 100755 --- a/.drone.yml +++ b/.drone.yml @@ -16,19 +16,9 @@ steps: # - name: pub-cache # path: /opt/flutter/.pub-cache # commands: +# - flutter pub run build_runner clean # - flutter pub run build_runner build --delete-conflicting-outputs -#- name: android-check -# image: v7lin/flutter:1.17.3-stable -# volumes: -# - name: pub-cache -# path: /opt/flutter/.pub-cache -# - name: gradle -# path: /root/.gradle -# commands: -# - cd example/android/ -# - ./gradlew :wechat_kit:check - # docker run --rm -it -v ${PWD}:/src v7lin/clang:5.0.2-r0 sh -c "clang-format -style=file -i src/Classes/*.h src/Classes/*.m" #- name: ios-format # image: v7lin/clang diff --git a/.gitignore b/.gitignore index 5f2e1f4..95abf25 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,6 @@ build/ -# custom -.idea/ +# *.iml +.idea/ diff --git a/CHANGELOG.md b/CHANGELOG.md index d8b548b..b26e6bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.0.0 + +* nullsafety +* 不再支持 Android embedding v1 +* Weibo 单例 + ## 1.1.0 * 优化 diff --git a/README.md b/README.md index 0564f69..d35f979 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ # weibo_kit -[![Build Status](https://cloud.drone.io/api/badges/v7lin/weibo_kit/status.svg)](https://cloud.drone.io/v7lin/weibo_kit) -[![Codecov](https://codecov.io/gh/v7lin/weibo_kit/branch/master/graph/badge.svg)](https://codecov.io/gh/v7lin/weibo_kit) -[![GitHub Tag](https://img.shields.io/github/tag/v7lin/weibo_kit.svg)](https://github.com/v7lin/weibo_kit/releases) +[![Build Status](https://cloud.drone.io/api/badges/rxreader/weibo_kit/status.svg)](https://cloud.drone.io/rxreader/weibo_kit) +[![Codecov](https://codecov.io/gh/rxreader/weibo_kit/branch/master/graph/badge.svg)](https://codecov.io/gh/rxreader/weibo_kit) +[![GitHub Tag](https://img.shields.io/github/tag/rxreader/weibo_kit.svg)](https://github.com/rxreader/weibo_kit/releases) [![Pub Package](https://img.shields.io/pub/v/weibo_kit.svg)](https://pub.dartlang.org/packages/weibo_kit) -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/v7lin/weibo_kit/blob/master/LICENSE) +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/rxreader/weibo_kit/blob/master/LICENSE) flutter版新浪微博SDK ## fake 系列 libraries -* [flutter版微信SDK](https://github.com/v7lin/wechat_kit) -* [flutter版腾讯(QQ)SDK](https://github.com/v7lin/tencent_kit) -* [flutter版新浪微博SDK](https://github.com/v7lin/weibo_kit) -* [flutter版支付宝SDK](https://github.com/v7lin/alipay_kit) -* [flutter版walle渠道打包工具](https://github.com/v7lin/walle_kit) +* [flutter版微信SDK](https://github.com/rxreader/wechat_kit) +* [flutter版腾讯(QQ)SDK](https://github.com/rxreader/tencent_kit) +* [flutter版新浪微博SDK](https://github.com/rxreader/weibo_kit) +* [flutter版支付宝SDK](https://github.com/rxreader/alipay_kit) +* [flutter版walle渠道打包工具](https://github.com/rxreader/walle_kit) ## dart/flutter 私服 -* [simple_pub_server](https://github.com/v7lin/simple_pub_server) +* [simple_pub_server](https://github.com/rxreader/simple_pub_server) ## docs @@ -29,6 +29,15 @@ flutter版新浪微博SDK ## android +```groovy +buildscript { + dependencies { + // 3.5.4/3.6.4/4.x.x + classpath 'com.android.tools.build:gradle:3.5.4' + } +} +``` + ``` # 不需要做任何额外接入工作 # 混淆已打入 Library,随 Library 引用,自动添加到 apk 打包混淆 @@ -153,13 +162,16 @@ iOS 9系统策略更新,限制了http协议的访问,此外应用需要在 ``` ## flutter +* break change + * 2.0.0: nullsafety & 不再支持 Android embedding v1 & Weibo 单例 + * snapshot ``` dependencies: weibo_kit: git: - url: https://github.com/v7lin/weibo_kit.git + url: https://github.com/rxreader/weibo_kit.git ``` * release diff --git a/analysis_options.yaml b/analysis_options.yaml old mode 100755 new mode 100644 index fd29b1d..41cde2e --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -29,12 +29,15 @@ analyzer: missing_return: warning # allow having TODOs 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 exclude: - - "**/*.g.dart" + - "lib/*.g.dart" linter: rules: @@ -46,6 +49,7 @@ 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 - annotate_overrides # - avoid_annotating_with_dynamic # conflicts with always_specify_types # - avoid_as # required for implicit-casts: true @@ -55,7 +59,8 @@ linter: - avoid_classes_with_only_static_members # - avoid_double_and_int_checks # only useful when targeting JS runtime - avoid_empty_else - # - avoid_equals_and_hash_code_on_mutable_classes # not yet tested + - avoid_equals_and_hash_code_on_mutable_classes + # - avoid_escaping_inner_quotes # not yet tested - avoid_field_initializers_in_const_classes - avoid_function_literals_in_foreach_calls # - avoid_implementing_value_types # not yet tested @@ -74,9 +79,10 @@ linter: - 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_shadowing_type_parameters # not yet tested + - avoid_shadowing_type_parameters - avoid_single_cascade_in_expression_statements - avoid_slow_async_io + # - avoid_type_to_string # we do this commonly - avoid_types_as_parameter_names # - avoid_types_on_closure_parameters # conflicts with always_specify_types # - avoid_unnecessary_containers # not yet tested @@ -88,60 +94,66 @@ linter: - camel_case_types - cancel_subscriptions # - cascade_invocations # not yet tested + - cast_nullable_to_non_nullable # - close_sinks # not reliable enough # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 # - 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 yet tested + # - curly_braces_in_flow_control_structures # not required by flutter style # - diagnostic_describe_all_properties # not yet tested - directives_ordering + # - do_not_use_environment # we do this commonly - empty_catches - empty_constructor_bodies - empty_statements - # - file_names # not yet tested + - exhaustive_cases + - file_names # not yet tested - flutter_style_todos - hash_and_equals - implementation_imports # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 - iterable_contains_unrelated_type - # - join_return_with_assignment # not yet tested + # - join_return_with_assignment # not required by flutter style + - leading_newlines_in_multiline_strings - library_names - library_prefixes - # - lines_longer_than_80_chars # not yet tested + # - 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 - no_adjacent_strings_in_list + # - no_default_cases # too many false positives - no_duplicate_case_values - # - no_logic_in_create_state # not yet tested - # - no_runtimeType_toString # not yet tested + - no_logic_in_create_state + # - no_runtimeType_toString # ok in tests; we enable this only in packages/ - non_constant_identifier_names - # - null_closures # not yet tested + - null_check_on_nullable_type_parameter + # - null_closures # not required by flutter style # - 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 - overridden_fields - package_api_docs - - package_names + # - package_names # non conforming packages in sdk - package_prefixed_library_names # - parameter_assignments # we do this commonly - prefer_adjacent_string_concatenation - prefer_asserts_in_initializer_lists - # - prefer_asserts_with_message # not yet tested + # - prefer_asserts_with_message # not required by flutter style - prefer_collection_literals - prefer_conditional_assignment - prefer_const_constructors - prefer_const_constructors_in_immutables - prefer_const_declarations - prefer_const_literals_to_create_immutables - # - prefer_constructors_over_static_methods # not yet tested + # - prefer_constructors_over_static_methods # far too many false positives - prefer_contains # - prefer_double_quotes # opposite of prefer_single_quotes - prefer_equal_for_default_values # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods - # - prefer_final_fields - # - prefer_final_in_for_each - # - prefer_final_locals + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals - prefer_for_elements_to_map_fromIterable - prefer_foreach # - prefer_function_declarations_over_variables # not yet tested @@ -166,16 +178,18 @@ linter: # - provide_deprecation_message # not yet tested # - 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 - slash_for_doc_comments # - sort_child_properties_last # not yet tested - sort_constructors_first - - sort_pub_dependencies + # - sort_pub_dependencies # prevents separating pinned transitive dependencies - sort_unnamed_constructors_first - test_types_in_equals - throw_in_finally + - tighten_type_of_initializing_formals # - type_annotate_public_apis # subset of always_specify_types - type_init_formals - # - unawaited_futures # too many false positives + - unawaited_futures # too many false positives # - unnecessary_await_in_return # not yet tested - unnecessary_brace_in_string_interps - unnecessary_const @@ -184,20 +198,27 @@ linter: # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 - unnecessary_new - unnecessary_null_aware_assignments + # - unnecessary_null_checks # not yet tested - unnecessary_null_in_if_null_operators + - unnecessary_nullable_for_final_variable_declarations - unnecessary_overrides - unnecessary_parenthesis + # - unnecessary_raw_strings # not yet tested - unnecessary_statements + - unnecessary_string_escapes - unnecessary_string_interpolations - unnecessary_this - unrelated_type_equality_checks # - unsafe_html # not yet tested - use_full_hex_values_for_flutter_colors # - use_function_type_syntax_for_parameters # not yet tested + - use_is_even_rather_than_modulo # - use_key_in_widget_constructors # not yet tested + - use_late_for_private_fields_and_variables + - use_raw_strings - use_rethrow_when_possible # - use_setters_to_change_properties # not yet tested # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review - valid_regexps - - void_checks \ No newline at end of file + - void_checks diff --git a/android/build.gradle b/android/build.gradle index b0de8f6..aed5c63 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ group 'io.github.v7lin.weibo_kit' -version '1.1.0' +version '2.0.0' buildscript { repositories { @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:4.1.0' } } @@ -25,7 +25,6 @@ rootProject.allprojects { } apply plugin: 'com.android.library' -apply from: './quality.gradle' android { compileSdkVersion 28 @@ -54,8 +53,6 @@ android { } dependencies { - implementation 'androidx.annotation:annotation:1.0.0' - // v9.12.0 vendorImplementation 'androidx.appcompat:appcompat:1.0.0' vendorImplementation 'com.sina.weibo.sdk:core:9.12.0:openDefaultRelease@aar' diff --git a/android/checkstyle.xml b/android/checkstyle.xml deleted file mode 100644 index 90627f2..0000000 --- a/android/checkstyle.xml +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 01a286e..3c9d085 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/android/quality.gradle b/android/quality.gradle deleted file mode 100644 index 9b0abf2..0000000 --- a/android/quality.gradle +++ /dev/null @@ -1,17 +0,0 @@ -apply plugin: 'checkstyle' - -check.dependsOn 'checkstyle' - -checkstyle { -// toolVersion = "6.15" -} - -task checkstyle(type: Checkstyle) { - configFile project.file('checkstyle.xml') - source 'src/main/java' - ignoreFailures false - showViolations true - include '**/*.java' - - classpath = files() -} diff --git a/android/src/main/java/io/github/v7lin/weibo_kit/WeiboKit.java b/android/src/main/java/io/github/v7lin/weibo_kit/WeiboKit.java deleted file mode 100644 index cf0bda1..0000000 --- a/android/src/main/java/io/github/v7lin/weibo_kit/WeiboKit.java +++ /dev/null @@ -1,274 +0,0 @@ -package io.github.v7lin.weibo_kit; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.sina.weibo.sdk.api.ImageObject; -import com.sina.weibo.sdk.api.TextObject; -import com.sina.weibo.sdk.api.WebpageObject; -import com.sina.weibo.sdk.api.WeiboMultiMessage; -import com.sina.weibo.sdk.auth.AuthInfo; -import com.sina.weibo.sdk.auth.Oauth2AccessToken; -import com.sina.weibo.sdk.auth.WbAuthListener; -import com.sina.weibo.sdk.common.UiError; -import com.sina.weibo.sdk.openapi.IWBAPI; -import com.sina.weibo.sdk.openapi.WBAPIFactory; -import com.sina.weibo.sdk.share.WbShareCallback; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugin.common.PluginRegistry; - -public class WeiboKit implements MethodChannel.MethodCallHandler, PluginRegistry.ActivityResultListener { - - private static class WeiboErrorCode { - public static final int SUCCESS = 0;//成功 - public static final int USERCANCEL = -1;//用户取消发送 - public static final int SENT_FAIL = -2;//发送失败 - public static final int AUTH_DENY = -3;//授权失败 - public static final int USERCANCEL_INSTALL = -4;//用户取消安装微博客户端 - public static final int PAY_FAIL = -5;//支付失败 - public static final int SHARE_IN_SDK_FAILED = -8;//分享失败 详情见response UserInfo - public static final int UNSUPPORT = -99;//不支持的请求 - public static final int UNKNOWN = -100; - } - - private static final String METHOD_REGISTERAPP = "registerApp"; - private static final String METHOD_ISINSTALLED = "isInstalled"; - private static final String METHOD_AUTH = "auth"; - private static final String METHOD_SHARETEXT = "shareText"; - private static final String METHOD_SHAREIMAGE = "shareImage"; - private static final String METHOD_SHAREWEBPAGE = "shareWebpage"; - - private static final String METHOD_ONAUTHRESP = "onAuthResp"; - private static final String METHOD_ONSHAREMSGRESP = "onShareMsgResp"; - - private static final String ARGUMENT_KEY_APPKEY = "appKey"; - private static final String ARGUMENT_KEY_SCOPE = "scope"; - private static final String ARGUMENT_KEY_REDIRECTURL = "redirectUrl"; - 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_WEBPAGEURL = "webpageUrl"; - - private static final String ARGUMENT_KEY_RESULT_ERRORCODE = "errorCode"; - private static final String ARGUMENT_KEY_RESULT_ERRORMESSAGE = "errorMessage"; - private static final String ARGUMENT_KEY_RESULT_USERID = "userId"; - private static final String ARGUMENT_KEY_RESULT_ACCESSTOKEN = "accessToken"; - private static final String ARGUMENT_KEY_RESULT_REFRESHTOKEN = "refreshToken"; - private static final String ARGUMENT_KEY_RESULT_EXPIRESIN = "expiresIn"; - - // - - private Context applicationContext; - private Activity activity; - - private MethodChannel channel; - - private IWBAPI iwbapi; - - public WeiboKit() { - super(); - } - - public WeiboKit(Context applicationContext, Activity activity) { - this.applicationContext = applicationContext; - this.activity = activity; - } - - // - - public void setApplicationContext(@Nullable Context applicationContext) { - this.applicationContext = applicationContext; - } - - public void setActivity(@Nullable Activity activity) { - this.activity = activity; - } - - public void startListening(@NonNull BinaryMessenger messenger) { - channel = new MethodChannel(messenger, "v7lin.github.io/weibo_kit"); - channel.setMethodCallHandler(this); - } - - public void stopListening() { - channel.setMethodCallHandler(null); - channel = null; - } - - // --- MethodCallHandler - - @Override - public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - if (METHOD_REGISTERAPP.equals(call.method)) { - String appKey = call.argument(ARGUMENT_KEY_APPKEY); - String scope = call.argument(ARGUMENT_KEY_SCOPE); - String redirectUrl = call.argument(ARGUMENT_KEY_REDIRECTURL); - - iwbapi = WBAPIFactory.createWBAPI(activity); - iwbapi.registerApp(applicationContext, new AuthInfo(applicationContext, appKey, redirectUrl, scope)); - result.success(null); - } else if (METHOD_ISINSTALLED.equals(call.method)) { - result.success(iwbapi.isWBAppInstalled()); - } else if (METHOD_AUTH.equals(call.method)) { - handleAuthCall(call, result); - } else if (METHOD_SHARETEXT.equals(call.method)) { - handleShareTextCall(call, result); - } else if (METHOD_SHAREIMAGE.equals(call.method) || - METHOD_SHAREWEBPAGE.equals(call.method)) { - handleShareMediaCall(call, result); - } else { - result.notImplemented(); - } - } - - private void handleAuthCall(MethodCall call, MethodChannel.Result result) { - if (iwbapi != null) { - iwbapi.authorize(new WbAuthListener() { - @Override - public void onComplete(Oauth2AccessToken token) { - Map map = new HashMap<>(); - if (token.isSessionValid()) { - map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SUCCESS); - map.put(ARGUMENT_KEY_RESULT_USERID, token.getUid()); - map.put(ARGUMENT_KEY_RESULT_ACCESSTOKEN, token.getAccessToken()); - map.put(ARGUMENT_KEY_RESULT_REFRESHTOKEN, token.getRefreshToken()); - long expiresIn = (long) Math.ceil((token.getExpiresTime() - System.currentTimeMillis()) / 1000.0); - map.put(ARGUMENT_KEY_RESULT_EXPIRESIN, expiresIn);// 向上取整 - } else { - map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.UNKNOWN); - } - if (channel != null) { - channel.invokeMethod(METHOD_ONAUTHRESP, map); - } - } - - @Override - public void onError(UiError uiError) { - Map map = new HashMap<>(); - map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.UNKNOWN); - channel.invokeMethod(METHOD_ONAUTHRESP, map); - } - - @Override - public void onCancel() { - Map map = new HashMap<>(); - map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.USERCANCEL); - if (channel != null) { - channel.invokeMethod(METHOD_ONAUTHRESP, map); - } - } - }); - } - result.success(null); - } - - private void handleShareTextCall(MethodCall call, MethodChannel.Result result) { - WeiboMultiMessage message = new WeiboMultiMessage(); - - TextObject object = new TextObject(); - object.text = call.argument(ARGUMENT_KEY_TEXT);// 1024 - - message.textObject = object; - - if (iwbapi != null) { - iwbapi.shareMessage(message, false); - } - result.success(null); - } - - private void handleShareMediaCall(MethodCall call, MethodChannel.Result result) { - WeiboMultiMessage message = new WeiboMultiMessage(); - - if (METHOD_SHAREIMAGE.equals(call.method)) { - if (call.hasArgument(ARGUMENT_KEY_TEXT)) { - TextObject object = new TextObject(); - object.text = call.argument(ARGUMENT_KEY_TEXT);// 1024 - - message.textObject = object; - } - - ImageObject object = new ImageObject(); - if (call.hasArgument(ARGUMENT_KEY_IMAGEDATA)) { - object.imageData = call.argument(ARGUMENT_KEY_IMAGEDATA);// 2 * 1024 * 1024 - } else if (call.hasArgument(ARGUMENT_KEY_IMAGEURI)) { - String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI); - object.imagePath = Uri.parse(imageUri).getPath();// 512 - 10 * 1024 * 1024 - } - - message.mediaObject = object; - } else if (METHOD_SHAREWEBPAGE.equals(call.method)) { - WebpageObject object = new WebpageObject(); - object.identify = UUID.randomUUID().toString(); - object.title = call.argument(ARGUMENT_KEY_TITLE);// 512 - object.description = call.argument(ARGUMENT_KEY_DESCRIPTION);// 1024 - object.thumbData = call.argument(ARGUMENT_KEY_THUMBDATA);// 32 * 1024 - object.defaultText = call.argument(ARGUMENT_KEY_DESCRIPTION); - object.actionUrl = call.argument(ARGUMENT_KEY_WEBPAGEURL);// 512 - - message.mediaObject = object; - } - - if (iwbapi != null) { - iwbapi.shareMessage(message, false); - } - result.success(null); - } - - @Override - public boolean onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case 32973: - if (iwbapi != null) { - iwbapi.authorizeCallback(requestCode, resultCode, data); - } - return true; - case 10001: - if (iwbapi != null) { - iwbapi.doResultIntent(data, new WbShareCallback() { - @Override - public void onComplete() { - Map map = new HashMap<>(); - map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SUCCESS); - if (channel != null) { - channel.invokeMethod(METHOD_ONSHAREMSGRESP, map); - } - } - - @Override - public void onError(UiError uiError) { - Map map = new HashMap<>(); - map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SHARE_IN_SDK_FAILED); - if (channel != null) { - channel.invokeMethod(METHOD_ONSHAREMSGRESP, map); - } - } - - @Override - public void onCancel() { - Map map = new HashMap<>(); - map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.USERCANCEL); - if (channel != null) { - channel.invokeMethod(METHOD_ONSHAREMSGRESP, map); - } - } - }); - } - return true; - } - return false; - } -} diff --git a/android/src/main/java/io/github/v7lin/weibo_kit/WeiboKitPlugin.java b/android/src/main/java/io/github/v7lin/weibo_kit/WeiboKitPlugin.java index f59863d..d8c042b 100644 --- a/android/src/main/java/io/github/v7lin/weibo_kit/WeiboKitPlugin.java +++ b/android/src/main/java/io/github/v7lin/weibo_kit/WeiboKitPlugin.java @@ -1,76 +1,294 @@ package io.github.v7lin.weibo_kit; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; + import androidx.annotation.NonNull; +import com.sina.weibo.sdk.api.ImageObject; +import com.sina.weibo.sdk.api.TextObject; +import com.sina.weibo.sdk.api.WebpageObject; +import com.sina.weibo.sdk.api.WeiboMultiMessage; +import com.sina.weibo.sdk.auth.AuthInfo; +import com.sina.weibo.sdk.auth.Oauth2AccessToken; +import com.sina.weibo.sdk.auth.WbAuthListener; +import com.sina.weibo.sdk.common.UiError; +import com.sina.weibo.sdk.openapi.IWBAPI; +import com.sina.weibo.sdk.openapi.WBAPIFactory; +import com.sina.weibo.sdk.share.WbShareCallback; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; -import io.flutter.plugin.common.PluginRegistry.Registrar; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.PluginRegistry; -/** WeiboKitPlugin */ -public class WeiboKitPlugin implements FlutterPlugin, ActivityAware { - // This static function is optional and equivalent to onAttachedToEngine. It supports the old - // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting - // plugin registration via this function while apps migrate to use the new Android APIs - // post-flutter-1.12 via https://flutter.dev/go/android-project-migration. - // - // It is encouraged to share logic between onAttachedToEngine and registerWith to keep - // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called - // depending on the user's project. onAttachedToEngine or registerWith must both be defined - // in the same class. - public static void registerWith(Registrar registrar) { - WeiboKit weiboKit = new WeiboKit(registrar.context(), registrar.activity()); - registrar.addActivityResultListener(weiboKit); - weiboKit.startListening(registrar.messenger()); - } +/** + * WeiboKitPlugin + */ +public class WeiboKitPlugin implements FlutterPlugin, ActivityAware, PluginRegistry.ActivityResultListener, MethodCallHandler { - // --- FlutterPlugin + private static class WeiboErrorCode { + public static final int SUCCESS = 0;//成功 + public static final int USERCANCEL = -1;//用户取消发送 + public static final int SENT_FAIL = -2;//发送失败 + public static final int AUTH_DENY = -3;//授权失败 + public static final int USERCANCEL_INSTALL = -4;//用户取消安装微博客户端 + public static final int PAY_FAIL = -5;//支付失败 + public static final int SHARE_IN_SDK_FAILED = -8;//分享失败 详情见response UserInfo + public static final int UNSUPPORT = -99;//不支持的请求 + public static final int UNKNOWN = -100; + } - private final WeiboKit weiboKit; + private static final String METHOD_REGISTERAPP = "registerApp"; + private static final String METHOD_ISINSTALLED = "isInstalled"; + private static final String METHOD_AUTH = "auth"; + private static final String METHOD_SHARETEXT = "shareText"; + private static final String METHOD_SHAREIMAGE = "shareImage"; + private static final String METHOD_SHAREWEBPAGE = "shareWebpage"; - private ActivityPluginBinding pluginBinding; + private static final String METHOD_ONAUTHRESP = "onAuthResp"; + private static final String METHOD_ONSHAREMSGRESP = "onShareMsgResp"; - public WeiboKitPlugin() { - weiboKit = new WeiboKit(); - } + private static final String ARGUMENT_KEY_APPKEY = "appKey"; + private static final String ARGUMENT_KEY_SCOPE = "scope"; + private static final String ARGUMENT_KEY_REDIRECTURL = "redirectUrl"; + 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_WEBPAGEURL = "webpageUrl"; - @Override - public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { - weiboKit.setApplicationContext(binding.getApplicationContext()); - weiboKit.setActivity(null); - weiboKit.startListening(binding.getBinaryMessenger()); - } + private static final String ARGUMENT_KEY_RESULT_ERRORCODE = "errorCode"; + private static final String ARGUMENT_KEY_RESULT_ERRORMESSAGE = "errorMessage"; + private static final String ARGUMENT_KEY_RESULT_USERID = "userId"; + private static final String ARGUMENT_KEY_RESULT_ACCESSTOKEN = "accessToken"; + private static final String ARGUMENT_KEY_RESULT_REFRESHTOKEN = "refreshToken"; + private static final String ARGUMENT_KEY_RESULT_EXPIRESIN = "expiresIn"; - @Override - public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { - weiboKit.stopListening(); - weiboKit.setActivity(null); - weiboKit.setApplicationContext(null); - } + /// 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 + /// when the Flutter Engine is detached from the Activity + private MethodChannel channel; + private Context applicationContext; + private ActivityPluginBinding activityPluginBinding; - // --- ActivityAware + private IWBAPI iwbapi; - @Override - public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { - weiboKit.setActivity(binding.getActivity()); - pluginBinding = binding; - pluginBinding.addActivityResultListener(weiboKit); - } + // --- FlutterPlugin - @Override - public void onDetachedFromActivityForConfigChanges() { - onDetachedFromActivity(); - } + @Override + public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { + channel = new MethodChannel(binding.getBinaryMessenger(), "v7lin.github.io/weibo_kit"); + channel.setMethodCallHandler(this); + applicationContext = binding.getApplicationContext(); + } - @Override - public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { - onAttachedToActivity(binding); - } + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + channel.setMethodCallHandler(null); + channel = null; + applicationContext = null; + } - @Override - public void onDetachedFromActivity() { - weiboKit.setActivity(null); - pluginBinding.removeActivityResultListener(weiboKit); - pluginBinding = null; - } + // --- ActivityAware + + @Override + public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { + activityPluginBinding = binding; + activityPluginBinding.addActivityResultListener(this); + } + + @Override + public void onDetachedFromActivityForConfigChanges() { + onDetachedFromActivity(); + } + + @Override + public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { + onAttachedToActivity(binding); + } + + @Override + public void onDetachedFromActivity() { + activityPluginBinding.removeActivityResultListener(this); + activityPluginBinding = null; + } + + // --- ActivityResultListener + + @Override + public boolean onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case 32973: + if (iwbapi != null) { + iwbapi.authorizeCallback(requestCode, resultCode, data); + } + return true; + case 10001: + if (iwbapi != null) { + iwbapi.doResultIntent(data, new WbShareCallback() { + @Override + public void onComplete() { + Map map = new HashMap<>(); + map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SUCCESS); + if (channel != null) { + channel.invokeMethod(METHOD_ONSHAREMSGRESP, map); + } + } + + @Override + public void onError(UiError uiError) { + Map map = new HashMap<>(); + map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SHARE_IN_SDK_FAILED); + if (channel != null) { + channel.invokeMethod(METHOD_ONSHAREMSGRESP, map); + } + } + + @Override + public void onCancel() { + Map map = new HashMap<>(); + map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.USERCANCEL); + if (channel != null) { + channel.invokeMethod(METHOD_ONSHAREMSGRESP, map); + } + } + }); + } + return true; + } + return false; + } + + // --- MethodCallHandler + + @Override + public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { + if (METHOD_REGISTERAPP.equals(call.method)) { + String appKey = call.argument(ARGUMENT_KEY_APPKEY); + String scope = call.argument(ARGUMENT_KEY_SCOPE); + String redirectUrl = call.argument(ARGUMENT_KEY_REDIRECTURL); + iwbapi = WBAPIFactory.createWBAPI(activityPluginBinding.getActivity()); + iwbapi.registerApp(applicationContext, new AuthInfo(applicationContext, appKey, redirectUrl, scope)); + result.success(null); + } else if (METHOD_ISINSTALLED.equals(call.method)) { + result.success(iwbapi.isWBAppInstalled()); + } else if (METHOD_AUTH.equals(call.method)) { + handleAuthCall(call, result); + } else if (METHOD_SHARETEXT.equals(call.method)) { + handleShareTextCall(call, result); + } else if (METHOD_SHAREIMAGE.equals(call.method) || + METHOD_SHAREWEBPAGE.equals(call.method)) { + handleShareMediaCall(call, result); + } else { + result.notImplemented(); + } + } + + private void handleAuthCall(@NonNull MethodCall call, @NonNull Result result) { + if (iwbapi != null) { + iwbapi.authorize(new WbAuthListener() { + @Override + public void onComplete(Oauth2AccessToken token) { + Map map = new HashMap<>(); + if (token.isSessionValid()) { + map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SUCCESS); + map.put(ARGUMENT_KEY_RESULT_USERID, token.getUid()); + map.put(ARGUMENT_KEY_RESULT_ACCESSTOKEN, token.getAccessToken()); + map.put(ARGUMENT_KEY_RESULT_REFRESHTOKEN, token.getRefreshToken()); + long expiresIn = (long) Math.ceil((token.getExpiresTime() - System.currentTimeMillis()) / 1000.0); + map.put(ARGUMENT_KEY_RESULT_EXPIRESIN, expiresIn);// 向上取整 + } else { + map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.UNKNOWN); + } + if (channel != null) { + channel.invokeMethod(METHOD_ONAUTHRESP, map); + } + } + + @Override + public void onError(UiError uiError) { + Map map = new HashMap<>(); + map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.UNKNOWN); + if (channel != null) { + channel.invokeMethod(METHOD_ONAUTHRESP, map); + } + } + + @Override + public void onCancel() { + Map map = new HashMap<>(); + map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.USERCANCEL); + if (channel != null) { + channel.invokeMethod(METHOD_ONAUTHRESP, map); + } + } + }); + } + result.success(null); + } + + private void handleShareTextCall(@NonNull MethodCall call, @NonNull Result result) { + WeiboMultiMessage message = new WeiboMultiMessage(); + + TextObject object = new TextObject(); + object.text = call.argument(ARGUMENT_KEY_TEXT);// 1024 + + message.textObject = object; + + if (iwbapi != null) { + iwbapi.shareMessage(message, false); + } + result.success(null); + } + + private void handleShareMediaCall(@NonNull MethodCall call, @NonNull Result result) { + WeiboMultiMessage message = new WeiboMultiMessage(); + + if (METHOD_SHAREIMAGE.equals(call.method)) { + if (call.hasArgument(ARGUMENT_KEY_TEXT)) { + TextObject object = new TextObject(); + object.text = call.argument(ARGUMENT_KEY_TEXT);// 1024 + + message.textObject = object; + } + + ImageObject object = new ImageObject(); + if (call.hasArgument(ARGUMENT_KEY_IMAGEDATA)) { + object.imageData = call.argument(ARGUMENT_KEY_IMAGEDATA);// 2 * 1024 * 1024 + } else if (call.hasArgument(ARGUMENT_KEY_IMAGEURI)) { + String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI); + object.imagePath = Uri.parse(imageUri).getPath();// 512 - 10 * 1024 * 1024 + } + + message.mediaObject = object; + } else if (METHOD_SHAREWEBPAGE.equals(call.method)) { + WebpageObject object = new WebpageObject(); + object.identify = UUID.randomUUID().toString(); + object.title = call.argument(ARGUMENT_KEY_TITLE);// 512 + object.description = call.argument(ARGUMENT_KEY_DESCRIPTION);// 1024 + object.thumbData = call.argument(ARGUMENT_KEY_THUMBDATA);// 32 * 1024 + object.defaultText = call.argument(ARGUMENT_KEY_DESCRIPTION); + object.actionUrl = call.argument(ARGUMENT_KEY_WEBPAGEURL);// 512 + + message.mediaObject = object; + } + + if (iwbapi != null) { + iwbapi.shareMessage(message, false); + } + result.success(null); + } } diff --git a/android/src/vendor/AndroidManifest.xml b/android/src/vendor/AndroidManifest.xml index f18bed2..c04f26a 100644 --- a/android/src/vendor/AndroidManifest.xml +++ b/android/src/vendor/AndroidManifest.xml @@ -3,4 +3,9 @@ + + + + + diff --git a/example/.gitignore b/example/.gitignore index 1ba9c33..0fa6b67 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -22,6 +22,7 @@ # Flutter/Dart/Pub related **/doc/api/ +**/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies @@ -39,5 +40,7 @@ app.*.symbols # Obfuscation related app.*.map.json -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/example/android/.gitignore b/example/android/.gitignore index bc2100d..0a741cb 100644 --- a/example/android/.gitignore +++ b/example/android/.gitignore @@ -5,3 +5,7 @@ gradle-wrapper.jar /gradlew.bat /local.properties GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/example/android/build.gradle b/example/android/build.gradle index e0d7ae2..c9e3db0 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:4.1.0' } } diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 296b146..bc6a58a 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/example/ios/Podfile b/example/ios/Podfile index 5a69b89..f7d6a5e 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -10,75 +10,29 @@ project 'Runner', { 'Release' => :release, } -def parse_KV_file(file, separator='=') - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return []; +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" end - generated_key_values = {} - skip_line_start_symbols = ["#", "/"] - File.foreach(file_abs_path) do |line| - next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } - plugin = line.split(pattern=separator) - if plugin.length == 2 - podname = plugin[0].strip() - path = plugin[1].strip() - podpath = File.expand_path("#{path}", file_abs_path) - generated_key_values[podname] = podpath - else - puts "Invalid plugin specification: #{line}" - end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches end - generated_key_values + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" end +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + target 'Runner' do - # Flutter Pod - - copied_flutter_dir = File.join(__dir__, 'Flutter') - copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') - copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') - unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) - # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. - # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. - # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. - - generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') - unless File.exist?(generated_xcode_build_settings_path) - raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) - cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; - - unless File.exist?(copied_framework_path) - FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) - end - unless File.exist?(copied_podspec_path) - FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) - end - end - - # Keep pod path relative so it can be checked into Podfile.lock. - pod 'Flutter', :path => 'Flutter' - - # Plugin Pods - - # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock - # referring to absolute paths on developers' machines. - system('rm -rf .symlinks') - system('mkdir -p .symlinks/plugins') - plugin_pods = parse_KV_file('../.flutter-plugins') - plugin_pods.each do |name, path| - symlink = File.join('.symlinks', 'plugins', name) - File.symlink(path, symlink) - pod name, :path => File.join(symlink, 'ios') - end + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end post_install do |installer| installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['ENABLE_BITCODE'] = 'NO' - end + flutter_additional_ios_build_settings(target) end end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index ebbb024..3af323d 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,15 +1,17 @@ PODS: - Flutter (1.0.0) + - FMDB (2.7.5): + - FMDB/standard (= 2.7.5) + - FMDB/standard (2.7.5) - path_provider (0.0.1): - Flutter - - path_provider_linux (0.0.1): + - sqflite (0.0.2): - Flutter - - path_provider_macos (0.0.1): + - FMDB (>= 2.7.5) + - weibo_kit (2.0.0): - Flutter - - weibo_kit (1.1.0): - - Flutter - - weibo_kit/vendor (= 1.1.0) - - weibo_kit/vendor (1.1.0): + - weibo_kit/vendor (= 2.0.0) + - weibo_kit/vendor (2.0.0): - Flutter - Weibo_SDK (~> 3.2.7) - Weibo_SDK (3.2.7) @@ -17,12 +19,12 @@ PODS: DEPENDENCIES: - Flutter (from `Flutter`) - path_provider (from `.symlinks/plugins/path_provider/ios`) - - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`) - - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`) + - sqflite (from `.symlinks/plugins/sqflite/ios`) - weibo_kit (from `.symlinks/plugins/weibo_kit/ios`) SPEC REPOS: trunk: + - FMDB - Weibo_SDK EXTERNAL SOURCES: @@ -30,21 +32,19 @@ EXTERNAL SOURCES: :path: Flutter path_provider: :path: ".symlinks/plugins/path_provider/ios" - path_provider_linux: - :path: ".symlinks/plugins/path_provider_linux/ios" - path_provider_macos: - :path: ".symlinks/plugins/path_provider_macos/ios" + sqflite: + :path: ".symlinks/plugins/sqflite/ios" weibo_kit: :path: ".symlinks/plugins/weibo_kit/ios" SPEC CHECKSUMS: - Flutter: 0e3d915762c693b495b44d77113d4970485de6ec + Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c + FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c - path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 - path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 - weibo_kit: 82a3b5501bbe2ae59528e683a80277079ecc95cb + sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 + weibo_kit: 9327afb47ffde6c4fd4b091973f91eae4440a0c4 Weibo_SDK: 5a4d08f7e1fedbb635435e4585c8c0439c7da089 -PODFILE CHECKSUM: f32fb4e7c14f8b3ca19a369d7be425dd9241af27 +PODFILE CHECKSUM: 8e679eca47255a8ca8067c4c67aab20e64cb974d -COCOAPODS: 1.8.4 +COCOAPODS: 1.10.0 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 17a88d4..a76981f 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -149,7 +149,6 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 1F77EE1FF4C528197971DB94 /* [CP] Embed Pods Frameworks */, BEFF80007E7E4E2B2694658C /* [CP] Copy Pods Resources */, ); buildRules = ( @@ -208,23 +207,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1F77EE1FF4C528197971DB94 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Embed Pods Frameworks"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; diff --git a/example/lib/main.dart b/example/lib/main.dart index 98fc2c4..3cea8e3 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -3,26 +3,22 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:image/image.dart' as image; -import 'package:okhttp_kit/okhttp_kit.dart'; -import 'package:path/path.dart' as path; -import 'package:path_provider/path_provider.dart' as path_provider; import 'package:weibo_kit/weibo_kit.dart'; -void main() { - runZoned(() { - runApp(MyApp()); - }, onError: (dynamic error, dynamic stack) { - print(error); - print(stack); - }); +const String _WEIBO_APP_KEY = 'your weibo app key'; +const List _WEIBO_SCOPE = [ + WeiboScope.ALL, +]; - if (Platform.isAndroid) { - SystemUiOverlayStyle systemUiOverlayStyle = - const SystemUiOverlayStyle(statusBarColor: Colors.transparent); - SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle); - } +void main() { + WidgetsFlutterBinding.ensureInitialized(); + Weibo.instance.registerApp( + appKey: _WEIBO_APP_KEY, + scope: _WEIBO_SCOPE, + ); + runApp(MyApp()); } class MyApp extends StatelessWidget { @@ -42,48 +38,33 @@ class Home extends StatefulWidget { } class _HomeState extends State { - static const String _WEIBO_APP_KEY = 'your weibo app key'; - static const List _WEIBO_SCOPE = [ - WeiboScope.ALL, - ]; + late final StreamSubscription _auth = + Weibo.instance.authResp().listen(_listenAuth); + late final StreamSubscription _share = + Weibo.instance.shareMsgResp().listen(_listenShareMsg); - Weibo _weibo = Weibo() - ..registerApp( - appKey: _WEIBO_APP_KEY, - scope: _WEIBO_SCOPE, - ); - - StreamSubscription _auth; - StreamSubscription _share; - - WeiboAuthResp _authResp; + WeiboAuthResp? _authResp; @override void initState() { super.initState(); - _auth = _weibo.authResp().listen(_listenAuth); - _share = _weibo.shareMsgResp().listen(_listenShareMsg); } void _listenAuth(WeiboAuthResp resp) { _authResp = resp; - String content = 'auth: ${resp.errorCode}'; + final String content = 'auth: ${resp.errorCode}'; _showTips('登录', content); } void _listenShareMsg(WeiboSdkResp resp) { - String content = 'share: ${resp.errorCode}'; + final String content = 'share: ${resp.errorCode}'; _showTips('分享', content); } @override void dispose() { - if (_auth != null) { - _auth.cancel(); - } - if (_share != null) { - _share.cancel(); - } + _auth.cancel(); + _share.cancel(); super.dispose(); } @@ -98,14 +79,15 @@ class _HomeState extends State { ListTile( title: const Text('环境检查'), onTap: () async { - String content = 'weibo: ${await _weibo.isInstalled()}'; + final String content = + 'weibo: ${await Weibo.instance.isInstalled()}'; _showTips('环境检查', content); }, ), ListTile( title: const Text('登录'), onTap: () { - _weibo.auth( + Weibo.instance.auth( appKey: _WEIBO_APP_KEY, scope: _WEIBO_SCOPE, ); @@ -114,15 +96,14 @@ class _HomeState extends State { ListTile( title: const Text('用户信息'), onTap: () async { - if (_authResp != null && - _authResp.errorCode == WeiboSdkResp.SUCCESS) { - WeiboUserInfoResp userInfoResp = await _weibo.getUserInfo( + if (_authResp?.isSuccessful ?? false) { + final WeiboUserInfoResp userInfoResp = + await Weibo.instance.getUserInfo( appkey: _WEIBO_APP_KEY, - userId: _authResp.userId, - accessToken: _authResp.accessToken, + userId: _authResp!.userId!, + accessToken: _authResp!.accessToken!, ); - if (userInfoResp != null && - userInfoResp.errorCode == WeiboApiResp.ERROR_CODE_SUCCESS) { + if (userInfoResp.isSuccessful) { _showTips('用户信息', '${userInfoResp.screenName}\n${userInfoResp.description}\n${userInfoResp.location}\n${userInfoResp.profileImageUrl}'); } else { @@ -135,7 +116,7 @@ class _HomeState extends State { ListTile( title: const Text('文字分享'), onTap: () { - _weibo.shareText( + Weibo.instance.shareText( text: 'Share Text', ); }, @@ -143,70 +124,32 @@ class _HomeState extends State { ListTile( title: const Text('图片分享'), onTap: () async { - OkHttpClient client = OkHttpClientBuilder().build(); - Response resp = await client - .newCall(RequestBuilder() - .get() - .url(HttpUrl.parse( - 'https://www.baidu.com/img/bd_logo1.png?where=super')) - .build()) - .enqueue(); - if (resp.isSuccessful()) { - Directory saveDir = Platform.isAndroid - ? await path_provider.getExternalStorageDirectory() - : await path_provider.getApplicationDocumentsDirectory(); - File saveFile = File(path.join(saveDir.path, 'timg.png')); - if (!saveFile.existsSync()) { - saveFile.createSync(recursive: true); - saveFile.writeAsBytesSync( - await resp.body().bytes(), - flush: true, - ); - } - await _weibo.shareImage( - text: 'Share Text', - imageUri: Uri.file(saveFile.path), - ); - } + final File file = await DefaultCacheManager().getSingleFile( + 'https://www.baidu.com/img/bd_logo1.png?where=super'); + await Weibo.instance.shareImage( + text: 'Share Text', + imageUri: Uri.file(file.path), + ); }, ), ListTile( title: const Text('网页分享'), onTap: () async { - OkHttpClient client = OkHttpClientBuilder().build(); - Response resp = await client - .newCall(RequestBuilder() - .get() - .url(HttpUrl.parse( - 'https://www.baidu.com/img/bd_logo1.png?where=super')) - .build()) - .enqueue(); - if (resp.isSuccessful()) { - Directory saveDir = Platform.isAndroid - ? await path_provider.getExternalStorageDirectory() - : await path_provider.getApplicationDocumentsDirectory(); - File saveFile = File(path.join(saveDir.path, 'timg.png')); - if (!saveFile.existsSync()) { - saveFile.createSync(recursive: true); - saveFile.writeAsBytesSync( - await resp.body().bytes(), - flush: true, - ); - } - image.Image thumbnail = - image.decodePng(saveFile.readAsBytesSync()); - Uint8List thumbData = thumbnail.getBytes(); - if (thumbData.length > 32 * 1024) { - thumbData = Uint8List.fromList(image.encodeJpg(thumbnail, - quality: 100 * 32 * 1024 ~/ thumbData.length)); - } - await _weibo.shareWebpage( - title: 'title', - description: 'share webpage', - thumbData: thumbData.buffer.asUint8List(), - webpageUrl: 'https://www.baidu.com', - ); + final File file = await DefaultCacheManager().getSingleFile( + 'https://www.baidu.com/img/bd_logo1.png?where=super'); + 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)); } + await Weibo.instance.shareWebpage( + title: 'title', + description: 'share webpage', + thumbData: thumbData.buffer.asUint8List(), + webpageUrl: 'https://www.baidu.com', + ); }, ), ], diff --git a/example/pubspec.lock b/example/pubspec.lock index 55722ff..bd477c5 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -7,206 +7,227 @@ packages: name: archive url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.13" - args: - dependency: transitive - description: - name: args - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.6.0" + version: "3.1.2" async: dependency: transitive description: name: async url: "https://pub.flutter-io.cn" source: hosted - version: "2.4.1" + version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.0" + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.3" + version: "1.2.0" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.flutter-io.cn" source: hosted - version: "1.14.12" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.1.1" + version: "1.15.0" crypto: dependency: transitive description: name: crypto url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.4" + version: "3.0.0" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.3" + version: "1.0.2" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.2.0" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.0.0" file: dependency: transitive description: name: file url: "https://pub.flutter-io.cn" source: hosted - version: "5.2.0" - fixnum: - dependency: transitive - description: - name: fixnum - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.10.11" + version: "6.1.0" 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.flutter-io.cn" + source: hosted + version: "3.0.0-nullsafety.1" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" - image: + http: dependency: transitive + description: + name: http + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.13.0" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.0.0" + image: + dependency: "direct main" description: name: image url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.12" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.16.1" + version: "3.0.1" json_annotation: dependency: transitive description: name: json_annotation url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.1" + version: "4.0.0" matcher: dependency: transitive description: name: matcher url: "https://pub.flutter-io.cn" source: hosted - version: "0.12.6" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.8" - okhttp_kit: - dependency: "direct main" - description: - name: okhttp_kit - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.0.2" + version: "1.3.0" path: - dependency: "direct main" + dependency: transitive description: name: path url: "https://pub.flutter-io.cn" source: hosted - version: "1.6.4" + version: "1.8.0" path_provider: - dependency: "direct main" + dependency: transitive description: name: path_provider url: "https://pub.flutter-io.cn" source: hosted - version: "1.6.11" + version: "2.0.1" path_provider_linux: dependency: transitive description: name: path_provider_linux url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.1+1" + version: "2.0.0" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.4+3" + version: "2.0.0" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.2" + version: "2.0.1" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.0" pedantic: dependency: "direct dev" description: name: pedantic url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.0" + version: "1.11.0" petitparser: dependency: transitive description: name: petitparser url: "https://pub.flutter-io.cn" source: hosted - version: "2.4.0" + version: "4.0.2" platform: dependency: transitive description: name: platform url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.1" + version: "3.0.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.2" + version: "2.0.0" process: dependency: transitive description: name: process url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.13" - quiver: + version: "4.1.0" + rxdart: dependency: transitive description: - name: quiver + name: rxdart url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.3" + version: "0.26.0" sky_engine: dependency: transitive description: flutter @@ -218,77 +239,112 @@ packages: name: source_span url: "https://pub.flutter-io.cn" source: hosted - version: "1.7.0" + version: "1.8.0" + sqflite: + dependency: transitive + description: + name: sqflite + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.0+3" + sqflite_common: + dependency: transitive + description: + name: sqflite_common + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.0+2" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.3" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.5" + version: "1.1.0" + synchronized: + dependency: transitive + description: + name: synchronized + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.flutter-io.cn" source: hosted - version: "0.2.15" + version: "0.2.19" typed_data: dependency: transitive description: name: typed_data url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.6" + version: "1.3.0" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.0.1" vector_math: dependency: transitive description: name: vector_math url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.8" + version: "2.1.0" weibo_kit: dependency: "direct main" description: path: ".." relative: true source: path - version: "1.1.0" + version: "2.0.0" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.0.4" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.0" + version: "0.2.0" xml: dependency: transitive description: name: xml url: "https://pub.flutter-io.cn" source: hosted - version: "3.6.1" + version: "5.0.2" sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + dart: ">=2.12.0 <3.0.0" + flutter: ">=1.24.0-10" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 6b85f5d..91a5564 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,12 +1,14 @@ name: weibo_kit_example description: Demonstrates how to use the weibo_kit plugin. -version: 1.0.0+1000 + # The following line prevents the package from being accidentally published to # pub.dev using `pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" + +version: 1.0.0+100 dependencies: flutter: @@ -22,12 +24,10 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 + cupertino_icons: ^1.0.2 - path: ^1.6.4 - path_provider: ^1.4.0 - - okhttp_kit: ^1.0.0 + image: ^3.0.1 + flutter_cache_manager: ^3.0.0-nullsafety.1 dev_dependencies: flutter_test: diff --git a/ios/.clang-format b/ios/.clang-format new file mode 100755 index 0000000..1c7a1f7 --- /dev/null +++ b/ios/.clang-format @@ -0,0 +1,44 @@ +# 基础样式 +BasedOnStyle: LLVM + +# 缩进宽度 +IndentWidth: 4 + +# 圆括号的换行方式 +BreakBeforeBraces: Attach + +# 是否允许循环单行 +AllowShortLoopsOnASingleLine: false + +# 支持一行的if +AllowShortIfStatementsOnASingleLine: false + +# switch的case缩进 +IndentCaseLabels: true + +# 针对OC的block的缩进宽度 +ObjCBlockIndentWidth: 4 + +# 针对OC,属性名后加空格 +ObjCSpaceAfterProperty: true + +# 每行字符的长度 +ColumnLimit: 0 + +# 注释对齐 +AlignTrailingComments: true + +# 括号后加空格 +SpaceAfterCStyleCast: false + +# 不在小括号里加空格 +SpacesInParentheses: false + +# 不在中括号里加空格 +SpacesInSquareBrackets: false + +AllowShortBlocksOnASingleLine: false + +AllowShortCaseLabelsOnASingleLine: false + +AllowShortFunctionsOnASingleLine: false diff --git a/ios/weibo_kit.podspec b/ios/weibo_kit.podspec index cffbde0..4f3dd38 100644 --- a/ios/weibo_kit.podspec +++ b/ios/weibo_kit.podspec @@ -4,7 +4,7 @@ # Pod::Spec.new do |s| s.name = 'weibo_kit' - s.version = '1.1.0' + s.version = '2.0.0' s.summary = 'A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Weibo SDKs.' s.description = <<-DESC A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Weibo SDKs. diff --git a/lib/src/model/api/weibo_api_resp.dart b/lib/src/model/api/weibo_api_resp.dart index 349bd10..f62b131 100644 --- a/lib/src/model/api/weibo_api_resp.dart +++ b/lib/src/model/api/weibo_api_resp.dart @@ -1,14 +1,21 @@ +import 'package:json_annotation/json_annotation.dart'; + abstract class WeiboApiResp { - WeiboApiResp({ - int errorCode, + const WeiboApiResp({ + required this.errorCode, this.error, this.request, - }) : errorCode = errorCode ?? ERROR_CODE_SUCCESS; + }); static const int ERROR_CODE_SUCCESS = 0; /// https://open.weibo.com/wiki/Help/error + @JsonKey( + defaultValue: ERROR_CODE_SUCCESS, + ) final int errorCode; - final String error; - final String request; + final String? error; + final String? request; + + bool get isSuccessful => errorCode == ERROR_CODE_SUCCESS; } diff --git a/lib/src/model/api/weibo_user_info_resp.dart b/lib/src/model/api/weibo_user_info_resp.dart index 7379538..5c7881d 100644 --- a/lib/src/model/api/weibo_user_info_resp.dart +++ b/lib/src/model/api/weibo_user_info_resp.dart @@ -4,15 +4,14 @@ import 'package:weibo_kit/src/model/api/weibo_api_resp.dart'; part 'weibo_user_info_resp.g.dart'; @JsonSerializable( - anyMap: true, explicitToJson: true, fieldRename: FieldRename.snake, ) class WeiboUserInfoResp extends WeiboApiResp { - WeiboUserInfoResp({ - int errorCode, - String error, - String request, + const WeiboUserInfoResp({ + required int errorCode, + String? error, + String? request, this.id, this.idstr, this.screenName, @@ -25,46 +24,42 @@ class WeiboUserInfoResp extends WeiboApiResp { this.avatarHd, }) : super(errorCode: errorCode, error: error, request: request); - factory WeiboUserInfoResp.fromJson(Map json) => + factory WeiboUserInfoResp.fromJson(Map json) => _$WeiboUserInfoRespFromJson(json); /// 用户UID(int64) - final int id; + final int? id; /// 字符串型的用户 UID - final String idstr; + final String? idstr; /// 用户昵称 - final String screenName; + final String? screenName; /// 友好显示名称 - final String name; + final String? name; /// 用户所在地 - final String location; + final String? location; /// 用户个人描述 - final String description; + final String? description; /// 用户头像地址,50×50像素 - final String profileImageUrl; + final String? profileImageUrl; /// 性别,m:男、f:女、n:未知 - final String gender; + final String? gender; /// 用户大头像地址 - final String avatarLarge; + final String? avatarLarge; /// 用户高清大头像地址 - final String avatarHd; + final String? avatarHd; - bool isMale() { - return gender == 'm'; - } + bool get isMale => gender == 'm'; - bool isFemale() { - return gender == 'f'; - } + bool get isFemale => gender == 'f'; - Map toJson() => _$WeiboUserInfoRespToJson(this); + Map toJson() => _$WeiboUserInfoRespToJson(this); } diff --git a/lib/src/model/api/weibo_user_info_resp.g.dart b/lib/src/model/api/weibo_user_info_resp.g.dart index 34995c2..c0ed1bf 100644 --- a/lib/src/model/api/weibo_user_info_resp.g.dart +++ b/lib/src/model/api/weibo_user_info_resp.g.dart @@ -6,21 +6,21 @@ part of 'weibo_user_info_resp.dart'; // JsonSerializableGenerator // ************************************************************************** -WeiboUserInfoResp _$WeiboUserInfoRespFromJson(Map json) { +WeiboUserInfoResp _$WeiboUserInfoRespFromJson(Map json) { return WeiboUserInfoResp( - errorCode: json['error_code'] as int, - error: json['error'] as String, - request: json['request'] as String, - id: json['id'] as int, - idstr: json['idstr'] as String, - screenName: json['screen_name'] as String, - name: json['name'] as String, - location: json['location'] as String, - description: json['description'] as String, - profileImageUrl: json['profile_image_url'] as String, - gender: json['gender'] as String, - avatarLarge: json['avatar_large'] as String, - avatarHd: json['avatar_hd'] as String, + errorCode: json['error_code'] as int? ?? 0, + error: json['error'] as String?, + request: json['request'] as String?, + id: json['id'] as int?, + idstr: json['idstr'] as String?, + screenName: json['screen_name'] as String?, + name: json['name'] as String?, + location: json['location'] as String?, + description: json['description'] as String?, + profileImageUrl: json['profile_image_url'] as String?, + gender: json['gender'] as String?, + avatarLarge: json['avatar_large'] as String?, + avatarHd: json['avatar_hd'] as String?, ); } diff --git a/lib/src/model/sdk/weibo_auth_resp.dart b/lib/src/model/sdk/weibo_auth_resp.dart index e4cfb87..b1e1176 100644 --- a/lib/src/model/sdk/weibo_auth_resp.dart +++ b/lib/src/model/sdk/weibo_auth_resp.dart @@ -4,27 +4,26 @@ import 'package:weibo_kit/src/model/sdk/weibo_sdk_resp.dart'; part 'weibo_auth_resp.g.dart'; @JsonSerializable( - anyMap: true, explicitToJson: true, ) class WeiboAuthResp extends WeiboSdkResp { WeiboAuthResp({ - int errorCode, - String errorMessage, + required int errorCode, + String? errorMessage, this.userId, this.accessToken, this.refreshToken, this.expiresIn, }) : super(errorCode: errorCode, errorMessage: errorMessage); - factory WeiboAuthResp.fromJson(Map json) => + factory WeiboAuthResp.fromJson(Map json) => _$WeiboAuthRespFromJson(json); - final String userId; - final String accessToken; - final String refreshToken; - final int expiresIn; + final String? userId; + final String? accessToken; + final String? refreshToken; + final int? expiresIn; @override - Map toJson() => _$WeiboAuthRespToJson(this); + Map toJson() => _$WeiboAuthRespToJson(this); } diff --git a/lib/src/model/sdk/weibo_auth_resp.g.dart b/lib/src/model/sdk/weibo_auth_resp.g.dart index d224e25..c20b88a 100644 --- a/lib/src/model/sdk/weibo_auth_resp.g.dart +++ b/lib/src/model/sdk/weibo_auth_resp.g.dart @@ -6,14 +6,14 @@ part of 'weibo_auth_resp.dart'; // JsonSerializableGenerator // ************************************************************************** -WeiboAuthResp _$WeiboAuthRespFromJson(Map json) { +WeiboAuthResp _$WeiboAuthRespFromJson(Map json) { return WeiboAuthResp( - errorCode: json['errorCode'] as int, - errorMessage: json['errorMessage'] as String, - userId: json['userId'] as String, - accessToken: json['accessToken'] as String, - refreshToken: json['refreshToken'] as String, - expiresIn: json['expiresIn'] as int, + errorCode: json['errorCode'] as int? ?? 0, + errorMessage: json['errorMessage'] as String?, + userId: json['userId'] as String?, + accessToken: json['accessToken'] as String?, + refreshToken: json['refreshToken'] as String?, + expiresIn: json['expiresIn'] as int?, ); } diff --git a/lib/src/model/sdk/weibo_sdk_resp.dart b/lib/src/model/sdk/weibo_sdk_resp.dart index 30c6c27..c8b5b6f 100644 --- a/lib/src/model/sdk/weibo_sdk_resp.dart +++ b/lib/src/model/sdk/weibo_sdk_resp.dart @@ -3,16 +3,15 @@ import 'package:json_annotation/json_annotation.dart'; part 'weibo_sdk_resp.g.dart'; @JsonSerializable( - anyMap: true, explicitToJson: true, ) class WeiboSdkResp { - WeiboSdkResp({ - int errorCode, + const WeiboSdkResp({ + required this.errorCode, this.errorMessage, - }) : errorCode = errorCode ?? SUCCESS; + }); - factory WeiboSdkResp.fromJson(Map json) => + factory WeiboSdkResp.fromJson(Map json) => _$WeiboSdkRespFromJson(json); /// 成功 @@ -42,8 +41,15 @@ class WeiboSdkResp { /// 未知 static const int UNKNOWN = -100; + @JsonKey( + defaultValue: SUCCESS, + ) final int errorCode; - final String errorMessage; + final String? errorMessage; - Map toJson() => _$WeiboSdkRespToJson(this); + bool get isSuccessful => errorCode == SUCCESS; + + bool get isCancelled => errorCode == USERCANCEL; + + Map toJson() => _$WeiboSdkRespToJson(this); } diff --git a/lib/src/model/sdk/weibo_sdk_resp.g.dart b/lib/src/model/sdk/weibo_sdk_resp.g.dart index 2745ee0..bfe939c 100644 --- a/lib/src/model/sdk/weibo_sdk_resp.g.dart +++ b/lib/src/model/sdk/weibo_sdk_resp.g.dart @@ -6,10 +6,10 @@ part of 'weibo_sdk_resp.dart'; // JsonSerializableGenerator // ************************************************************************** -WeiboSdkResp _$WeiboSdkRespFromJson(Map json) { +WeiboSdkResp _$WeiboSdkRespFromJson(Map json) { return WeiboSdkResp( - errorCode: json['errorCode'] as int, - errorMessage: json['errorMessage'] as String, + errorCode: json['errorCode'] as int? ?? 0, + errorMessage: json['errorMessage'] as String?, ); } diff --git a/lib/src/weibo.dart b/lib/src/weibo.dart index 9c0f684..94863b6 100644 --- a/lib/src/weibo.dart +++ b/lib/src/weibo.dart @@ -3,16 +3,18 @@ import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; -import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:weibo_kit/src/model/api/weibo_user_info_resp.dart'; import 'package:weibo_kit/src/model/sdk/weibo_auth_resp.dart'; import 'package:weibo_kit/src/model/sdk/weibo_sdk_resp.dart'; class Weibo { - Weibo() { - _channel.setMethodCallHandler(_handleMethod); - } + /// + Weibo._(); + + static Weibo get instance => _instance; + + static final Weibo _instance = Weibo._(); static const String _METHOD_REGISTERAPP = 'registerApp'; static const String _METHOD_ISINSTALLED = 'isInstalled'; @@ -40,8 +42,9 @@ class Weibo { static const String _DEFAULT_REDIRECTURL = 'https://api.weibo.com/oauth2/default.html'; - final MethodChannel _channel = - const MethodChannel('v7lin.github.io/weibo_kit'); + late final MethodChannel _channel = + const MethodChannel('v7lin.github.io/weibo_kit') + ..setMethodCallHandler(_handleMethod); final StreamController _authRespStreamController = StreamController.broadcast(); @@ -50,13 +53,11 @@ class Weibo { StreamController.broadcast(); Future registerApp({ - @required String appKey, - @required List scope, + required String appKey, + required List scope, String redirectUrl = _DEFAULT_REDIRECTURL, // 新浪微博开放平台 -> 我的应用 -> 应用信息 -> 高级信息 -> OAuth2.0授权设置 }) { - assert(appKey != null && appKey.isNotEmpty); - assert(scope != null && scope.isNotEmpty); return _channel.invokeMethod( _METHOD_REGISTERAPP, { @@ -71,11 +72,11 @@ class Weibo { switch (call.method) { case _METHOD_ONAUTHRESP: _authRespStreamController.add( - WeiboAuthResp.fromJson(call.arguments as Map)); + WeiboAuthResp.fromJson(call.arguments as Map)); break; case _METHOD_ONSHAREMSGRESP: - _shareMsgRespStreamController.add( - WeiboSdkResp.fromJson(call.arguments as Map)); + _shareMsgRespStreamController + .add(WeiboSdkResp.fromJson(call.arguments as Map)); break; } } @@ -90,18 +91,16 @@ class Weibo { return _shareMsgRespStreamController.stream; } - Future isInstalled() { - return _channel.invokeMethod(_METHOD_ISINSTALLED); + Future isInstalled() async { + return await _channel.invokeMethod(_METHOD_ISINSTALLED) ?? false; } /// 登录 Future auth({ - @required String appKey, - @required List scope, + required String appKey, + required List scope, String redirectUrl = _DEFAULT_REDIRECTURL, }) { - assert(appKey != null && appKey.isNotEmpty); - assert(scope != null && scope.isNotEmpty); return _channel.invokeMethod( _METHOD_AUTH, { @@ -114,13 +113,11 @@ class Weibo { /// 用户信息 Future getUserInfo({ - @required String appkey, - @required String userId, - @required String accessToken, + required String appkey, + required String userId, + required String accessToken, }) { - assert(userId != null && userId.isNotEmpty); - assert(accessToken != null && accessToken.isNotEmpty); - Map params = { + final Map params = { 'uid': userId, }; return HttpClient() @@ -130,9 +127,9 @@ class Weibo { return request.close(); }).then((HttpClientResponse response) async { if (response.statusCode == HttpStatus.ok) { - String content = await utf8.decodeStream(response); + final String content = await utf8.decodeStream(response); return WeiboUserInfoResp.fromJson( - json.decode(content) as Map); + json.decode(content) as Map); } throw HttpException( 'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.'); @@ -147,10 +144,10 @@ class Weibo { ) { params['source'] = appkey; params['access_token'] = accessToken; - Uri baseUri = Uri.parse(baseUrl); - Map> queryParametersAll = + final Uri baseUri = Uri.parse(baseUrl); + final Map> queryParametersAll = Map>.of(baseUri.queryParametersAll); - for (MapEntry entry in params.entries) { + for (final MapEntry entry in params.entries) { queryParametersAll.remove(entry.key); queryParametersAll.putIfAbsent(entry.key, () => [entry.value]); } @@ -159,9 +156,8 @@ class Weibo { /// 分享 - 文本 Future shareText({ - @required String text, + required String text, }) { - assert(text != null && text.length <= 1024); return _channel.invokeMethod( _METHOD_SHARETEXT, { @@ -172,9 +168,9 @@ class Weibo { /// 分享 - 图片 Future shareImage({ - String text, - Uint8List imageData, - Uri imageUri, + String? text, + Uint8List? imageData, + Uri? imageUri, }) { assert(text == null || text.length <= 1024); assert((imageData != null && imageData.lengthInBytes <= 2 * 1024 * 1024) || @@ -194,19 +190,15 @@ class Weibo { /// 分享 - 网页 Future shareWebpage({ - @required String title, - @required String description, - @required Uint8List thumbData, - @required String webpageUrl, + required String title, + required String description, + required Uint8List thumbData, + required String webpageUrl, }) { - assert(title != null && title.isNotEmpty && title.length <= 512); - assert(description != null && - description.isNotEmpty && - description.length <= 1024); - assert(thumbData != null && thumbData.lengthInBytes <= 32 * 1024); - assert(webpageUrl != null && - webpageUrl.isNotEmpty && - webpageUrl.length <= 255); + assert(title.length <= 512); + assert(description.isNotEmpty && description.length <= 1024); + assert(thumbData.lengthInBytes <= 32 * 1024); + assert(webpageUrl.length <= 255); return _channel.invokeMethod( _METHOD_SHAREWEBPAGE, { diff --git a/lib/src/weibo_constant.dart b/lib/src/weibo_constant.dart index b655c04..ef81fe8 100644 --- a/lib/src/weibo_constant.dart +++ b/lib/src/weibo_constant.dart @@ -1,5 +1,5 @@ class WeiboScope { - WeiboScope._(); + const WeiboScope._(); static const String EMAIL = 'email'; static const String DIRECT_MESSAGES_READ = 'direct_messages_read'; diff --git a/pubspec.lock b/pubspec.lock index 5db9c3d..efd7c08 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,168 +7,182 @@ packages: name: _fe_analyzer_shared url: "https://pub.flutter-io.cn" source: hosted - version: "4.0.0" + version: "18.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.flutter-io.cn" source: hosted - version: "0.39.10" - archive: - dependency: transitive - description: - name: archive - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.0.13" + version: "1.2.0" args: dependency: transitive description: name: args url: "https://pub.flutter-io.cn" source: hosted - version: "1.6.0" + version: "2.0.0" async: dependency: transitive description: name: async url: "https://pub.flutter-io.cn" source: hosted - version: "2.4.1" + version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.0" + version: "2.1.0" build: dependency: transitive description: name: build url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.0" + version: "2.0.0" build_config: dependency: transitive description: name: build_config url: "https://pub.flutter-io.cn" source: hosted - version: "0.4.2" + version: "0.4.7" build_daemon: dependency: transitive description: name: build_daemon url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.4" + version: "2.1.10" build_resolvers: dependency: transitive description: name: build_resolvers url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.9" + version: "2.0.0" build_runner: dependency: "direct dev" description: name: build_runner url: "https://pub.flutter-io.cn" source: hosted - version: "1.10.0" + version: "1.12.2" build_runner_core: dependency: transitive description: name: build_runner_core url: "https://pub.flutter-io.cn" source: hosted - version: "5.2.0" + version: "6.1.12" built_collection: dependency: transitive description: name: built_collection url: "https://pub.flutter-io.cn" source: hosted - version: "4.3.2" + version: "5.0.0" built_value: dependency: transitive description: name: built_value url: "https://pub.flutter-io.cn" source: hosted - version: "7.1.0" + version: "8.0.3" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.3" + version: "1.2.0" checked_yaml: dependency: transitive description: name: checked_yaml url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.2" + version: "2.0.1" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.3.0" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.1.0" code_builder: dependency: transitive description: name: code_builder url: "https://pub.flutter-io.cn" source: hosted - version: "3.3.0" + version: "3.7.0" collection: dependency: transitive description: name: collection url: "https://pub.flutter-io.cn" source: hosted - version: "1.14.12" + version: "1.15.0" convert: dependency: transitive description: name: convert url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.1" + version: "3.0.0" crypto: dependency: transitive description: name: crypto url: "https://pub.flutter-io.cn" source: hosted - version: "2.1.4" - csslib: - dependency: transitive - description: - name: csslib - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.16.1" + version: "3.0.0" dart_style: dependency: transitive description: name: dart_style url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.6" + version: "1.3.14" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.2.0" file: dependency: transitive description: name: file url: "https://pub.flutter-io.cn" source: hosted - version: "5.2.0" + version: "6.1.0" fixnum: dependency: transitive description: name: fixnum url: "https://pub.flutter-io.cn" source: hosted - version: "0.10.11" + version: "1.0.0" flutter: dependency: "direct main" description: flutter @@ -185,245 +199,140 @@ packages: name: glob url: "https://pub.flutter-io.cn" source: hosted - version: "1.2.0" + version: "2.0.0" graphs: dependency: transitive description: name: graphs url: "https://pub.flutter-io.cn" source: hosted - version: "0.2.0" - html: - dependency: transitive - description: - name: html - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.14.0+3" + version: "1.0.0" http_multi_server: dependency: transitive description: name: http_multi_server url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.0" + version: "3.0.0" http_parser: dependency: transitive description: name: http_parser url: "https://pub.flutter-io.cn" source: hosted - version: "3.1.4" - image: - dependency: transitive - description: - name: image - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.1.12" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.16.1" + version: "4.0.0" io: dependency: transitive description: name: io url: "https://pub.flutter-io.cn" source: hosted - version: "0.3.4" + version: "1.0.0" js: dependency: transitive description: name: js url: "https://pub.flutter-io.cn" source: hosted - version: "0.6.2" + version: "0.6.3" json_annotation: dependency: "direct main" description: name: json_annotation url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.1" + version: "4.0.0" json_serializable: dependency: "direct dev" description: name: json_serializable url: "https://pub.flutter-io.cn" source: hosted - version: "3.3.0" + version: "4.0.3" logging: dependency: transitive description: name: logging url: "https://pub.flutter-io.cn" source: hosted - version: "0.11.4" + version: "1.0.0" matcher: dependency: transitive description: name: matcher url: "https://pub.flutter-io.cn" source: hosted - version: "0.12.6" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.8" + version: "1.3.0" mime: dependency: transitive description: name: mime url: "https://pub.flutter-io.cn" source: hosted - version: "0.9.6+3" - node_interop: - dependency: transitive - description: - name: node_interop - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.1.1" - node_io: - dependency: transitive - description: - name: node_io - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.1.1" - okhttp_kit: - dependency: "direct dev" - description: - name: okhttp_kit - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.0.2" + version: "1.0.0" package_config: dependency: transitive description: name: package_config url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.3" + version: "2.0.0" path: - dependency: "direct dev" + dependency: transitive description: name: path url: "https://pub.flutter-io.cn" source: hosted - version: "1.6.4" - path_provider: - dependency: "direct dev" - description: - name: path_provider - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.6.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.0.1+1" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.0.4+3" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.0.2" + version: "1.8.0" pedantic: dependency: "direct dev" description: name: pedantic url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.0" - petitparser: - dependency: transitive - description: - name: petitparser - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.4.0" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.2.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.0.2" + version: "1.11.0" pool: dependency: transitive description: name: pool url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.0" - process: - dependency: transitive - description: - name: process - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.0.13" + version: "1.5.0" pub_semver: dependency: transitive description: name: pub_semver url: "https://pub.flutter-io.cn" source: hosted - version: "1.4.4" + version: "2.0.0" pubspec_parse: dependency: transitive description: name: pubspec_parse url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.5" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.flutter-io.cn" - source: hosted - version: "2.1.3" + version: "1.0.0" shelf: dependency: transitive description: name: shelf url: "https://pub.flutter-io.cn" source: hosted - version: "0.7.5" + version: "1.1.0" shelf_web_socket: dependency: transitive description: name: shelf_web_socket url: "https://pub.flutter-io.cn" source: hosted - version: "0.2.3" + version: "1.0.1" sky_engine: dependency: transitive description: flutter @@ -435,112 +344,98 @@ packages: name: source_gen url: "https://pub.flutter-io.cn" source: hosted - version: "0.9.5" + version: "0.9.10+4" source_span: dependency: transitive description: name: source_span url: "https://pub.flutter-io.cn" source: hosted - version: "1.7.0" + version: "1.8.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.flutter-io.cn" source: hosted - version: "1.9.3" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.0" + version: "2.1.0" stream_transform: dependency: transitive description: name: stream_transform url: "https://pub.flutter-io.cn" source: hosted - version: "1.2.0" + version: "2.0.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.5" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.flutter-io.cn" source: hosted - version: "0.2.15" + version: "0.2.19" timing: dependency: transitive description: name: timing url: "https://pub.flutter-io.cn" source: hosted - version: "0.1.1+2" + version: "1.0.0" typed_data: dependency: transitive description: name: typed_data url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.6" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.flutter-io.cn" source: hosted - version: "2.0.8" + version: "2.1.0" watcher: dependency: transitive description: name: watcher url: "https://pub.flutter-io.cn" source: hosted - version: "0.9.7+15" + version: "1.0.0" web_socket_channel: dependency: transitive description: name: web_socket_channel url: "https://pub.flutter-io.cn" source: hosted - version: "1.1.0" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.flutter-io.cn" - source: hosted - version: "0.1.0" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.flutter-io.cn" - source: hosted - version: "3.6.1" + version: "2.0.0" yaml: dependency: transitive description: name: yaml url: "https://pub.flutter-io.cn" source: hosted - version: "2.2.1" + version: "3.1.0" sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" + dart: ">=2.12.0 <3.0.0" + flutter: ">=1.20.0" diff --git a/pubspec.yaml b/pubspec.yaml index 9638420..d0a446c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,28 +1,23 @@ name: weibo_kit description: A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Weibo SDKs. -version: 1.1.0 +version: 2.0.0 # author: v7lin -homepage: https://github.com/v7lin/fake_weibo +homepage: https://github.com/rxreader/weibo_kit.git environment: - sdk: ">=2.7.0 <3.0.0" - flutter: ">=1.10.0" + sdk: ">=2.12.0 <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - json_annotation: '>=2.0.0 <4.0.0' + json_annotation: ^4.0.0 dev_dependencies: flutter_test: sdk: flutter - path: ^1.6.4 - path_provider: ^1.4.0 - - okhttp_kit: ^1.0.0 - pedantic: build_runner: diff --git a/test/weibo_kit_test.dart b/test/weibo_kit_test.dart index b992a95..6682d95 100644 --- a/test/weibo_kit_test.dart +++ b/test/weibo_kit_test.dart @@ -10,7 +10,6 @@ void main() { TestWidgetsFlutterBinding.ensureInitialized(); const MethodChannel channel = MethodChannel('v7lin.github.io/weibo_kit'); - final Weibo weibo = Weibo(); setUp(() { channel.setMockMethodCallHandler((MethodCall call) async { @@ -24,7 +23,7 @@ void main() { channel.name, channel.codec.encodeMethodCall( MethodCall('onAuthResp', json.decode('{"errorCode":-1}'))), - (ByteData data) { + (ByteData? data) { // mock success }, )); @@ -36,7 +35,7 @@ void main() { channel.name, channel.codec.encodeMethodCall( MethodCall('onShareMsgResp', json.decode('{"errorCode":-1}'))), - (ByteData data) { + (ByteData? data) { // mock success }, )); @@ -51,15 +50,15 @@ void main() { }); test('isInstalled', () async { - expect(await weibo.isInstalled(), true); + expect(await Weibo.instance.isInstalled(), true); }); test('auth', () async { - StreamSubscription sub = - weibo.authResp().listen((WeiboAuthResp resp) { + final StreamSubscription sub = + Weibo.instance.authResp().listen((WeiboAuthResp resp) { expect(resp.errorCode, WeiboSdkResp.USERCANCEL); }); - await weibo.auth( + await Weibo.instance.auth( appKey: 'your weibo app key', scope: [WeiboScope.ALL], ); @@ -67,11 +66,11 @@ void main() { }); test('share', () async { - StreamSubscription sub = - weibo.shareMsgResp().listen((WeiboSdkResp resp) { + final StreamSubscription sub = + Weibo.instance.shareMsgResp().listen((WeiboSdkResp resp) { expect(resp.errorCode, WeiboSdkResp.USERCANCEL); }); - await weibo.shareText( + await Weibo.instance.shareText( text: 'share text', ); await sub.cancel();