├── ios ├── Assets │ └── .gitkeep ├── Classes │ ├── WeiboKitPlugin.h │ └── WeiboKitPlugin.m ├── .gitignore ├── .clang-format └── weibo_kit.podspec ├── android ├── consumer-rules.pro ├── settings.gradle ├── consumer-vendor-rules.pro ├── .gitignore ├── src │ ├── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ │ └── io │ │ │ └── github │ │ │ └── v7lin │ │ │ └── weibo_kit │ │ │ └── WeiboKitPlugin.java │ └── vendor │ │ ├── res │ │ └── xml │ │ │ └── weibo_kit_filepaths.xml │ │ └── AndroidManifest.xml └── build.gradle ├── .gitattributes ├── .github └── workflows │ ├── publish_manually.yml │ ├── publish.yml │ └── build.yml ├── example ├── android │ ├── gradle.properties │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── java │ │ │ │ │ └── io │ │ │ │ │ │ └── github │ │ │ │ │ │ └── v7lin │ │ │ │ │ │ └── weibo_kit_example │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── settings.gradle │ └── build.gradle ├── ios │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner │ │ ├── AppDelegate.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── main.m │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ └── project.pbxproj │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── .gitignore │ ├── Podfile │ └── Podfile.lock ├── analysis_options.yaml ├── test │ └── widget_test.dart ├── README.md ├── .gitignore ├── lib │ ├── api │ │ ├── model │ │ │ ├── weibo_api_resp.g.dart │ │ │ └── weibo_api_resp.dart │ │ └── weibo_api.dart │ └── main.dart ├── pubspec.yaml └── pubspec.lock ├── lib ├── weibo_kit.dart ├── src │ ├── weibo.dart │ ├── weibo_constant.dart │ ├── model │ │ ├── resp.g.dart │ │ └── resp.dart │ ├── weibo_kit_platform_interface.dart │ └── weibo_kit_method_channel.dart └── weibo_kit_platform_interface.dart ├── .gitignore ├── test ├── weibo_kit_method_channel_test.dart └── weibo_kit_test.dart ├── CHANGELOG.md ├── .metadata ├── pubspec.yaml ├── .drone.yml ├── README.md ├── LICENSE └── analysis_options.yaml /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /android/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * linguist-language=Dart -------------------------------------------------------------------------------- /.github/workflows/publish_manually.yml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'weibo_kit' 2 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /ios/Classes/WeiboKitPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface WeiboKitPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /android/consumer-vendor-rules.pro: -------------------------------------------------------------------------------- 1 | # 微博 2 | 3 | -keep public class com.sina.weibo.sdk.**{*;} 4 | -keep public class com.weibo.ssosdk.**{*;} 5 | -------------------------------------------------------------------------------- /lib/weibo_kit.dart: -------------------------------------------------------------------------------- 1 | library weibo_kit; 2 | 3 | export 'src/model/resp.dart'; 4 | export 'src/weibo.dart'; 5 | export 'src/weibo_constant.dart'; 6 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .cxx 10 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RxReader/weibo_kit/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /lib/src/weibo.dart: -------------------------------------------------------------------------------- 1 | import 'package:weibo_kit/src/weibo_kit_platform_interface.dart'; 2 | 3 | class Weibo { 4 | const Weibo._(); 5 | 6 | static WeiboKitPlatform get instance => WeiboKitPlatform.instance; 7 | } 8 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Take our settings from the repo's main analysis_options.yaml file, but include 2 | # an additional rule to validate that public members are documented. 3 | 4 | include: ../analysis_options.yaml 5 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/weibo_kit_platform_interface.dart: -------------------------------------------------------------------------------- 1 | library weibo_kit_platform_interface; 2 | 3 | export 'src/model/resp.dart'; 4 | export 'src/weibo_constant.dart'; 5 | export 'src/weibo_kit_method_channel.dart'; 6 | export 'src/weibo_kit_platform_interface.dart'; 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/io/github/v7lin/weibo_kit_example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package io.github.v7lin.weibo_kit_example; 2 | 3 | import io.flutter.embedding.android.FlutterActivity; 4 | 5 | public class MainActivity extends FlutterActivity { 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip 7 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility in the flutter_test package. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter_test/flutter_test.dart'; 9 | 10 | void main() { 11 | testWidgets('smoke test', (WidgetTester tester) async {}); 12 | } 13 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/ephemeral/ 38 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # weibo_kit_example 2 | 3 | Demonstrates how to use the weibo_kit plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | .packages 30 | build/ 31 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /ios/.clang-format: -------------------------------------------------------------------------------- 1 | # 基础样式 2 | BasedOnStyle: LLVM 3 | 4 | # 缩进宽度 5 | IndentWidth: 4 6 | 7 | # 圆括号的换行方式 8 | BreakBeforeBraces: Attach 9 | 10 | # 是否允许循环单行 11 | AllowShortLoopsOnASingleLine: false 12 | 13 | # 支持一行的if 14 | AllowShortIfStatementsOnASingleLine: false 15 | 16 | # switch的case缩进 17 | IndentCaseLabels: true 18 | 19 | # 针对OC的block的缩进宽度 20 | ObjCBlockIndentWidth: 4 21 | 22 | # 针对OC,属性名后加空格 23 | ObjCSpaceAfterProperty: true 24 | 25 | # 每行字符的长度 26 | ColumnLimit: 0 27 | 28 | # 注释对齐 29 | AlignTrailingComments: true 30 | 31 | # 括号后加空格 32 | SpaceAfterCStyleCast: false 33 | 34 | # 不在小括号里加空格 35 | SpacesInParentheses: false 36 | 37 | # 不在中括号里加空格 38 | SpacesInSquareBrackets: false 39 | 40 | AllowShortBlocksOnASingleLine: false 41 | 42 | AllowShortCaseLabelsOnASingleLine: false 43 | 44 | AllowShortFunctionsOnASingleLine: false 45 | -------------------------------------------------------------------------------- /test/weibo_kit_method_channel_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/services.dart'; 2 | import 'package:flutter_test/flutter_test.dart'; 3 | import 'package:weibo_kit/src/weibo_kit_method_channel.dart'; 4 | 5 | void main() { 6 | final MethodChannelWeiboKit platform = MethodChannelWeiboKit(); 7 | const MethodChannel channel = MethodChannel('v7lin.github.io/weibo_kit'); 8 | 9 | TestWidgetsFlutterBinding.ensureInitialized(); 10 | 11 | setUp(() { 12 | channel.setMockMethodCallHandler((MethodCall methodCall) async { 13 | switch (methodCall.method) { 14 | case 'isInstalled': 15 | return true; 16 | } 17 | }); 18 | }); 19 | 20 | tearDown(() { 21 | channel.setMockMethodCallHandler(null); 22 | }); 23 | 24 | test('isInstalled', () async { 25 | expect(await platform.isInstalled(), true); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 4.0.1 2 | 3 | * fix 4 | * shareMultiImage/shareVideo 5 | * breake change: expiresIn -> expiresTime 6 | 7 | ## 4.0.0 8 | 9 | * 升级 Flutter 3.0 10 | * break change: 官方标准化插件 11 | 12 | ## 3.1.0 13 | 14 | * 升级 Android SDK 15 | 16 | ## 3.0.0 17 | 18 | * 重构 19 | 20 | ## 2.0.1 21 | 22 | * bugfix 23 | 24 | ## 2.0.0 25 | 26 | * nullsafety 27 | * 不再支持 Android embedding v1 28 | * Weibo 单例 29 | 30 | ## 1.1.0 31 | 32 | * 优化 33 | 34 | ## 1.0.1 35 | 36 | * 优化 37 | 38 | ## 1.0.0 39 | 40 | * 升级 Android/iOS SDK 41 | 42 | ## 0.2.4 43 | 44 | * 降级Android SDK 45 | * 升级iOS SDK 46 | 47 | ## 0.2.3 48 | 49 | * 升级Android SDK 50 | 51 | ## 0.2.2 52 | 53 | * 简化 54 | 55 | ## 0.2.1 56 | 57 | * 添加大图分享 58 | * 添加图文分享 59 | 60 | ## 0.2.0 61 | 62 | * 优化 63 | * 自动化发布 64 | 65 | ## 0.1.0 66 | 67 | * 规范 library 代码 68 | 69 | ## 0.0.1 70 | 71 | * android/ios weibo 72 | -------------------------------------------------------------------------------- /android/src/vendor/res/xml/weibo_kit_filepaths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 11 | 12 | 13 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: publish 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [published] 7 | 8 | jobs: 9 | publish: 10 | name: Publish 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: subosito/flutter-action@v2 15 | with: 16 | channel: 'stable' 17 | - name: Run pub.dev/inject-credentials@shell 18 | env: 19 | CREDENTIALS: ${{ secrets.CREDENTIALS_JSON }} 20 | run: | 21 | if [ -z $PUB_CACHE ];then 22 | PUB_CACHE=~/.pub-cache 23 | fi 24 | mkdir -p $PUB_CACHE 25 | echo $CREDENTIALS > $PUB_CACHE/credentials.json 26 | - run: flutter --version 27 | - run: flutter pub get 28 | - run: dart format --set-exit-if-changed . 29 | - run: echo "y" | flutter pub publish 30 | -------------------------------------------------------------------------------- /lib/src/weibo_constant.dart: -------------------------------------------------------------------------------- 1 | class WeiboRegister { 2 | const WeiboRegister._(); 3 | 4 | static const String DEFAULT_REDIRECTURL = 5 | 'https://api.weibo.com/oauth2/default.html'; 6 | } 7 | 8 | class WeiboScope { 9 | const WeiboScope._(); 10 | 11 | static const String EMAIL = 'email'; 12 | static const String DIRECT_MESSAGES_READ = 'direct_messages_read'; 13 | static const String DIRECT_MESSAGES_WRITE = 'direct_messages_write'; 14 | static const String FRIENDSHIPS_GROUPS_READ = 'friendships_groups_read'; 15 | static const String FRIENDSHIPS_GROUPS_WRITE = 'friendships_groups_write'; 16 | static const String STATUSES_TO_ME_READ = 'statuses_to_me_read'; 17 | static const String FOLLOW_APP_OFFICIAL_MICROBLOG = 18 | 'follow_app_official_microblog'; 19 | static const String INVITATION_WRITE = 'invitation_write'; 20 | static const String ALL = 'all'; 21 | } 22 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Symbolication related 39 | app.*.symbols 40 | 41 | # Obfuscation related 42 | app.*.map.json 43 | 44 | # Android Studio will place build artifacts here 45 | /android/app/debug 46 | /android/app/profile 47 | /android/app/release 48 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/src/vendor/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 8 | channel: stable 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 17 | base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 18 | - platform: android 19 | create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 20 | base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 21 | - platform: ios 22 | create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 23 | base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 24 | 25 | # User provided section 26 | 27 | # List of Local paths (relative to this file) that should be 28 | # ignored by the migrate tool. 29 | # 30 | # Files that are not part of the templates will be ignored by default. 31 | unmanaged_files: 32 | - 'lib/main.dart' 33 | - 'ios/Runner.xcodeproj/project.pbxproj' 34 | -------------------------------------------------------------------------------- /ios/weibo_kit.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint weibo_kit.podspec` to validate before publishing. 4 | # 5 | 6 | pubspec = YAML.load_file(File.join('..', 'pubspec.yaml')) 7 | library_version = pubspec['version'].gsub('+', '-') 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'weibo_kit' 11 | s.version = library_version 12 | s.summary = 'A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Weibo SDKs.' 13 | s.description = <<-DESC 14 | A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Weibo SDKs. 15 | DESC 16 | s.homepage = 'http://example.com' 17 | s.license = { :file => '../LICENSE' } 18 | s.author = { 'Your Company' => 'email@example.com' } 19 | s.source = { :path => '.' } 20 | s.source_files = 'Classes/**/*' 21 | s.public_header_files = 'Classes/**/*.h' 22 | s.dependency 'Flutter' 23 | s.platform = :ios, '9.0' 24 | 25 | # v3.3.0 26 | s.static_framework = true 27 | s.subspec 'vendor' do |sp| 28 | sp.dependency 'Weibo_SDK', '~> 3.3.0' 29 | end 30 | 31 | # Flutter.framework does not contain a i386 slice. 32 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 33 | end 34 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 32 | end 33 | 34 | post_install do |installer| 35 | installer.pods_project.targets.each do |target| 36 | flutter_additional_ios_build_settings(target) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /lib/src/model/resp.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'resp.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | AuthResp _$AuthRespFromJson(Map json) => AuthResp( 10 | errorCode: json['errorCode'] as int? ?? 0, 11 | errorMessage: json['errorMessage'] as String?, 12 | userId: json['userId'] as String?, 13 | accessToken: json['accessToken'] as String?, 14 | refreshToken: json['refreshToken'] as String?, 15 | expiresTime: json['expiresTime'] as int?, 16 | ); 17 | 18 | Map _$AuthRespToJson(AuthResp instance) => { 19 | 'errorCode': instance.errorCode, 20 | 'errorMessage': instance.errorMessage, 21 | 'userId': instance.userId, 22 | 'accessToken': instance.accessToken, 23 | 'refreshToken': instance.refreshToken, 24 | 'expiresTime': instance.expiresTime, 25 | }; 26 | 27 | ShareMsgResp _$ShareMsgRespFromJson(Map json) => ShareMsgResp( 28 | errorCode: json['errorCode'] as int? ?? 0, 29 | errorMessage: json['errorMessage'] as String?, 30 | ); 31 | 32 | Map _$ShareMsgRespToJson(ShareMsgResp instance) => 33 | { 34 | 'errorCode': instance.errorCode, 35 | 'errorMessage': instance.errorMessage, 36 | }; 37 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - FMDB (2.7.5): 4 | - FMDB/standard (= 2.7.5) 5 | - FMDB/standard (2.7.5) 6 | - path_provider_ios (0.0.1): 7 | - Flutter 8 | - sqflite (0.0.2): 9 | - Flutter 10 | - FMDB (>= 2.7.5) 11 | - weibo_kit (4.0.0): 12 | - Flutter 13 | - weibo_kit/vendor (= 4.0.0) 14 | - weibo_kit/vendor (4.0.0): 15 | - Flutter 16 | - Weibo_SDK (~> 3.3.0) 17 | - Weibo_SDK (3.3.0) 18 | 19 | DEPENDENCIES: 20 | - Flutter (from `Flutter`) 21 | - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) 22 | - sqflite (from `.symlinks/plugins/sqflite/ios`) 23 | - weibo_kit (from `.symlinks/plugins/weibo_kit/ios`) 24 | 25 | SPEC REPOS: 26 | trunk: 27 | - FMDB 28 | - Weibo_SDK 29 | 30 | EXTERNAL SOURCES: 31 | Flutter: 32 | :path: Flutter 33 | path_provider_ios: 34 | :path: ".symlinks/plugins/path_provider_ios/ios" 35 | sqflite: 36 | :path: ".symlinks/plugins/sqflite/ios" 37 | weibo_kit: 38 | :path: ".symlinks/plugins/weibo_kit/ios" 39 | 40 | SPEC CHECKSUMS: 41 | Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a 42 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 43 | path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 44 | sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 45 | weibo_kit: 8064857ffe649258a0e813d94e4690cf4ef4d948 46 | Weibo_SDK: 7478846cccb43c4785ba76b214115fb7ec9dc0d4 47 | 48 | PODFILE CHECKSUM: 8e679eca47255a8ca8067c4c67aab20e64cb974d 49 | 50 | COCOAPODS: 1.11.3 51 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build_ios: 7 | name: Build iOS on ${{ matrix.os }} 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: [macos-latest] 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: subosito/flutter-action@v2 15 | with: 16 | channel: 'stable' 17 | - name: Run llvm/clang-format@shell 18 | run: | 19 | brew install clang-format 20 | - run: clang-format -style=file -i ios/Classes/*.h ios/Classes/*.m --dry-run --Werror 21 | - run: flutter --version 22 | - run: flutter pub get 23 | - run: dart format --set-exit-if-changed . 24 | - run: flutter pub publish --dry-run 25 | - run: flutter analyze lib example/lib 26 | - run: cd example; flutter build ios --no-codesign 27 | 28 | build_android: 29 | name: Build Android on ${{ matrix.os }} 30 | runs-on: ${{ matrix.os }} 31 | strategy: 32 | fail-fast: false 33 | matrix: 34 | os: [windows-latest, ubuntu-latest, macos-latest] 35 | steps: 36 | - uses: actions/checkout@v3 37 | - uses: actions/setup-java@v2 38 | with: 39 | distribution: 'zulu' 40 | java-version: '11' 41 | - uses: subosito/flutter-action@v2 42 | with: 43 | channel: 'stable' 44 | - run: flutter --version 45 | - run: flutter pub get 46 | - run: dart format --set-exit-if-changed . 47 | - run: flutter pub publish --dry-run 48 | - run: flutter analyze lib example/lib 49 | - run: cd example; flutter build apk --debug 50 | -------------------------------------------------------------------------------- /example/lib/api/model/weibo_api_resp.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'weibo_api_resp.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | WeiboUserInfoResp _$WeiboUserInfoRespFromJson(Map json) { 10 | return WeiboUserInfoResp( 11 | errorCode: json['error_code'] as int? ?? 0, 12 | error: json['error'] as String?, 13 | request: json['request'] as String?, 14 | id: json['id'] as int?, 15 | idstr: json['idstr'] as String?, 16 | screenName: json['screen_name'] as String?, 17 | name: json['name'] as String?, 18 | location: json['location'] as String?, 19 | description: json['description'] as String?, 20 | profileImageUrl: json['profile_image_url'] as String?, 21 | gender: json['gender'] as String?, 22 | avatarLarge: json['avatar_large'] as String?, 23 | avatarHd: json['avatar_hd'] as String?, 24 | ); 25 | } 26 | 27 | Map _$WeiboUserInfoRespToJson(WeiboUserInfoResp instance) => 28 | { 29 | 'error_code': instance.errorCode, 30 | 'error': instance.error, 31 | 'request': instance.request, 32 | 'id': instance.id, 33 | 'idstr': instance.idstr, 34 | 'screen_name': instance.screenName, 35 | 'name': instance.name, 36 | 'location': instance.location, 37 | 'description': instance.description, 38 | 'profile_image_url': instance.profileImageUrl, 39 | 'gender': instance.gender, 40 | 'avatar_large': instance.avatarLarge, 41 | 'avatar_hd': instance.avatarHd, 42 | }; 43 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | File pubspec = new File(project.projectDir.parentFile, 'pubspec.yaml') 2 | String yaml = pubspec.text 3 | // Using \s*['|"]?([^\n|'|"]*)['|"]? to extract version number. 4 | java.util.regex.Matcher versionMatcher = java.util.regex.Pattern.compile("^version:\\s*['|\"]?([^\\n|'|\"]*)['|\"]?\$", java.util.regex.Pattern.MULTILINE).matcher(yaml) 5 | versionMatcher.find() 6 | String library_version = versionMatcher.group(1).replaceAll("\\+", "-") 7 | 8 | group 'io.github.v7lin.weibo_kit' 9 | version library_version 10 | 11 | buildscript { 12 | repositories { 13 | google() 14 | mavenCentral() 15 | } 16 | 17 | dependencies { 18 | classpath 'com.android.tools.build:gradle:7.1.2' 19 | } 20 | } 21 | 22 | rootProject.allprojects { 23 | repositories { 24 | google() 25 | mavenCentral() 26 | } 27 | } 28 | 29 | apply plugin: 'com.android.library' 30 | 31 | android { 32 | compileSdkVersion 31 33 | 34 | compileOptions { 35 | sourceCompatibility JavaVersion.VERSION_1_8 36 | targetCompatibility JavaVersion.VERSION_1_8 37 | } 38 | 39 | resourcePrefix 'weibo_kit' 40 | 41 | defaultConfig { 42 | minSdkVersion 16 43 | 44 | // library 混淆 -> 随 library 引用,自动添加到 apk 打包混淆 45 | consumerProguardFiles 'consumer-rules.pro' 46 | } 47 | 48 | flavorDimensions 'vendor' 49 | 50 | productFlavors { 51 | vendor { 52 | dimension 'vendor' 53 | 54 | // library 混淆 -> 随 library 引用,自动添加到 apk 打包混淆 55 | consumerProguardFiles 'consumer-vendor-rules.pro' 56 | } 57 | } 58 | } 59 | 60 | dependencies { 61 | vendorImplementation 'androidx.appcompat:appcompat:1.0.0' 62 | vendorImplementation 'io.github.sinaweibosdk:core:12.5.0@aar' 63 | } 64 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /example/lib/api/weibo_api.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | import 'dart:io'; 4 | 5 | import 'package:weibo_kit_example/api/model/weibo_api_resp.dart'; 6 | 7 | class WeiboApi { 8 | const WeiboApi._(); 9 | 10 | /// 用户信息 11 | static Future getUserInfo({ 12 | required String appkey, 13 | required String userId, 14 | required String accessToken, 15 | }) { 16 | final Map params = { 17 | 'uid': userId, 18 | }; 19 | return HttpClient() 20 | .getUrl(_encodeUrl('https://api.weibo.com/2/users/show.json', appkey, 21 | accessToken, params)) 22 | .then((HttpClientRequest request) { 23 | return request.close(); 24 | }).then((HttpClientResponse response) async { 25 | if (response.statusCode == HttpStatus.ok) { 26 | final String content = await utf8.decodeStream(response); 27 | return WeiboUserInfoResp.fromJson( 28 | json.decode(content) as Map); 29 | } 30 | throw HttpException( 31 | 'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.'); 32 | }); 33 | } 34 | 35 | static Uri _encodeUrl( 36 | String baseUrl, 37 | String appkey, 38 | String accessToken, 39 | Map params, 40 | ) { 41 | params['source'] = appkey; 42 | params['access_token'] = accessToken; 43 | final Uri baseUri = Uri.parse(baseUrl); 44 | final Map> queryParametersAll = 45 | Map>.of(baseUri.queryParametersAll); 46 | for (final MapEntry entry in params.entries) { 47 | queryParametersAll.remove(entry.key); 48 | queryParametersAll.putIfAbsent(entry.key, () => [entry.value]); 49 | } 50 | return baseUri.replace(queryParameters: queryParametersAll); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /example/lib/api/model/weibo_api_resp.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'weibo_api_resp.g.dart'; 4 | 5 | abstract class WeiboApiResp { 6 | const WeiboApiResp({ 7 | required this.errorCode, 8 | this.error, 9 | this.request, 10 | }); 11 | 12 | static const int ERROR_CODE_SUCCESS = 0; 13 | 14 | /// https://open.weibo.com/wiki/Help/error 15 | @JsonKey( 16 | defaultValue: ERROR_CODE_SUCCESS, 17 | ) 18 | final int errorCode; 19 | final String? error; 20 | final String? request; 21 | 22 | bool get isSuccessful => errorCode == ERROR_CODE_SUCCESS; 23 | } 24 | 25 | @JsonSerializable( 26 | explicitToJson: true, 27 | fieldRename: FieldRename.snake, 28 | ) 29 | class WeiboUserInfoResp extends WeiboApiResp { 30 | const WeiboUserInfoResp({ 31 | required super.errorCode, 32 | super.error, 33 | super.request, 34 | this.id, 35 | this.idstr, 36 | this.screenName, 37 | this.name, 38 | this.location, 39 | this.description, 40 | this.profileImageUrl, 41 | this.gender, 42 | this.avatarLarge, 43 | this.avatarHd, 44 | }); 45 | 46 | factory WeiboUserInfoResp.fromJson(Map json) => 47 | _$WeiboUserInfoRespFromJson(json); 48 | 49 | /// 用户UID(int64) 50 | final int? id; 51 | 52 | /// 字符串型的用户 UID 53 | final String? idstr; 54 | 55 | /// 用户昵称 56 | final String? screenName; 57 | 58 | /// 友好显示名称 59 | final String? name; 60 | 61 | /// 用户所在地 62 | final String? location; 63 | 64 | /// 用户个人描述 65 | final String? description; 66 | 67 | /// 用户头像地址,50×50像素 68 | final String? profileImageUrl; 69 | 70 | /// 性别,m:男、f:女、n:未知 71 | final String? gender; 72 | 73 | /// 用户大头像地址 74 | final String? avatarLarge; 75 | 76 | /// 用户高清大头像地址 77 | final String? avatarHd; 78 | 79 | bool get isMale => gender == 'm'; 80 | 81 | bool get isFemale => gender == 'f'; 82 | 83 | Map toJson() => _$WeiboUserInfoRespToJson(this); 84 | } 85 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion flutter.compileSdkVersion 30 | ndkVersion flutter.ndkVersion 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | defaultConfig { 38 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 39 | applicationId "io.github.v7lin.weibo_kit_example" 40 | // You can update the following values to match your application needs. 41 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. 42 | minSdkVersion flutter.minSdkVersion 43 | targetSdkVersion flutter.targetSdkVersion 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | -------------------------------------------------------------------------------- /lib/src/model/resp.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | 3 | import 'package:json_annotation/json_annotation.dart'; 4 | 5 | part 'resp.g.dart'; 6 | 7 | abstract class BaseResp { 8 | const BaseResp({ 9 | required this.errorCode, 10 | this.errorMessage, 11 | }); 12 | 13 | /// 成功 14 | static const int SUCCESS = 0; 15 | 16 | /// 用户取消发送 17 | static const int USERCANCEL = -1; 18 | 19 | /// 发送失败 20 | static const int SENT_FAIL = -2; 21 | 22 | /// 授权失败 23 | static const int AUTH_DENY = -3; 24 | 25 | /// 用户取消安装微博客户端 26 | static const int USERCANCEL_INSTALL = -4; 27 | 28 | /// 支付失败 29 | static const int PAY_FAIL = -5; 30 | 31 | /// 分享失败 详情见response UserInfo 32 | static const int SHARE_IN_SDK_FAILED = -8; 33 | 34 | /// 不支持的请求 35 | static const int UNSUPPORT = -99; 36 | 37 | /// 未知 38 | static const int UNKNOWN = -100; 39 | 40 | @JsonKey( 41 | defaultValue: SUCCESS, 42 | ) 43 | final int errorCode; 44 | final String? errorMessage; 45 | 46 | bool get isSuccessful => errorCode == SUCCESS; 47 | 48 | bool get isCancelled => errorCode == USERCANCEL; 49 | 50 | Map toJson(); 51 | 52 | @override 53 | String toString() => const JsonEncoder.withIndent(' ').convert(toJson()); 54 | } 55 | 56 | @JsonSerializable( 57 | explicitToJson: true, 58 | ) 59 | class AuthResp extends BaseResp { 60 | const AuthResp({ 61 | required super.errorCode, 62 | super.errorMessage, 63 | this.userId, 64 | this.accessToken, 65 | this.refreshToken, 66 | this.expiresTime, 67 | }); 68 | 69 | factory AuthResp.fromJson(Map json) => 70 | _$AuthRespFromJson(json); 71 | 72 | final String? userId; 73 | final String? accessToken; 74 | final String? refreshToken; 75 | final int? expiresTime; 76 | 77 | @override 78 | Map toJson() => _$AuthRespToJson(this); 79 | } 80 | 81 | @JsonSerializable( 82 | explicitToJson: true, 83 | ) 84 | class ShareMsgResp extends BaseResp { 85 | const ShareMsgResp({ 86 | required super.errorCode, 87 | super.errorMessage, 88 | }); 89 | 90 | factory ShareMsgResp.fromJson(Map json) => 91 | _$ShareMsgRespFromJson(json); 92 | 93 | @override 94 | Map toJson() => _$ShareMsgRespToJson(this); 95 | } 96 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: weibo_kit 2 | description: A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Weibo SDKs. 3 | version: 4.0.1 4 | # author: v7lin 5 | homepage: https://github.com/RxReader/weibo_kit.git 6 | 7 | environment: 8 | sdk: ">=2.17.0 <3.0.0" 9 | flutter: ">=2.5.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | plugin_platform_interface: ^2.0.2 15 | 16 | json_annotation: ^4.5.0 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | flutter_lints: ^2.0.0 22 | 23 | build_runner: 24 | json_serializable: 25 | 26 | # For information on the generic Dart part of this file, see the 27 | # following page: https://dart.dev/tools/pub/pubspec 28 | 29 | # The following section is specific to Flutter packages. 30 | flutter: 31 | # This section identifies this Flutter project as a plugin project. 32 | # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) 33 | # which should be registered in the plugin registry. This is required for 34 | # using method channels. 35 | # The Android 'package' specifies package in which the registered class is. 36 | # This is required for using method channels on Android. 37 | # The 'ffiPlugin' specifies that native code should be built and bundled. 38 | # This is required for using `dart:ffi`. 39 | # All these are used by the tooling to maintain consistency when 40 | # adding or updating assets for this project. 41 | plugin: 42 | platforms: 43 | android: 44 | package: io.github.v7lin.weibo_kit 45 | pluginClass: WeiboKitPlugin 46 | ios: 47 | pluginClass: WeiboKitPlugin 48 | 49 | # To add assets to your plugin package, add an assets section, like this: 50 | # assets: 51 | # - images/a_dot_burr.jpeg 52 | # - images/a_dot_ham.jpeg 53 | # 54 | # For details regarding assets in packages, see 55 | # https://flutter.dev/assets-and-images/#from-packages 56 | # 57 | # An image asset can refer to one or more resolution-specific "variants", see 58 | # https://flutter.dev/assets-and-images/#resolution-aware 59 | 60 | # To add custom fonts to your plugin package, add a fonts section here, 61 | # in this "flutter" section. Each entry in this list should have a 62 | # "family" key with the font family name, and a "fonts" key with a 63 | # list giving the asset and other descriptors for the font. For 64 | # example: 65 | # fonts: 66 | # - family: Schyler 67 | # fonts: 68 | # - asset: fonts/Schyler-Regular.ttf 69 | # - asset: fonts/Schyler-Italic.ttf 70 | # style: italic 71 | # - family: Trajan Pro 72 | # fonts: 73 | # - asset: fonts/TrajanPro.ttf 74 | # - asset: fonts/TrajanPro_Bold.ttf 75 | # weight: 700 76 | # 77 | # For details regarding fonts in packages, see 78 | # https://flutter.dev/custom-fonts/#from-packages 79 | -------------------------------------------------------------------------------- /test/weibo_kit_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; 5 | import 'package:weibo_kit/src/model/resp.dart'; 6 | import 'package:weibo_kit/src/weibo.dart'; 7 | import 'package:weibo_kit/src/weibo_constant.dart'; 8 | import 'package:weibo_kit/src/weibo_kit_method_channel.dart'; 9 | import 'package:weibo_kit/src/weibo_kit_platform_interface.dart'; 10 | 11 | class MockWeiboKitPlatform 12 | with MockPlatformInterfaceMixin 13 | implements WeiboKitPlatform { 14 | @override 15 | Future registerApp({ 16 | required String appKey, 17 | required String? universalLink, 18 | required List scope, 19 | String redirectUrl = WeiboRegister.DEFAULT_REDIRECTURL, 20 | }) { 21 | throw UnimplementedError(); 22 | } 23 | 24 | @override 25 | Stream respStream() { 26 | throw UnimplementedError(); 27 | } 28 | 29 | @override 30 | Future isInstalled() { 31 | throw UnimplementedError(); 32 | } 33 | 34 | @override 35 | Future isSupportMultipleImage() { 36 | throw UnimplementedError(); 37 | } 38 | 39 | @override 40 | Future auth({ 41 | required String appKey, 42 | required List scope, 43 | String redirectUrl = WeiboRegister.DEFAULT_REDIRECTURL, 44 | }) { 45 | throw UnimplementedError(); 46 | } 47 | 48 | @override 49 | Future shareText({ 50 | required String text, 51 | bool clientOnly = false, 52 | }) { 53 | throw UnimplementedError(); 54 | } 55 | 56 | @override 57 | Future shareImage({ 58 | String? text, 59 | Uint8List? imageData, 60 | Uri? imageUri, 61 | bool clientOnly = false, 62 | }) { 63 | throw UnimplementedError(); 64 | } 65 | 66 | @override 67 | Future shareMultiImage({ 68 | String? text, 69 | required List imageUris, 70 | bool clientOnly = false, 71 | }) { 72 | throw UnimplementedError(); 73 | } 74 | 75 | @override 76 | Future shareVideo({ 77 | String? text, 78 | required Uri videoUri, 79 | bool clientOnly = false, 80 | }) { 81 | throw UnimplementedError(); 82 | } 83 | 84 | @override 85 | Future shareWebpage({ 86 | required String title, 87 | required String description, 88 | required Uint8List thumbData, 89 | required String webpageUrl, 90 | bool clientOnly = false, 91 | }) { 92 | throw UnimplementedError(); 93 | } 94 | } 95 | 96 | void main() { 97 | final WeiboKitPlatform initialPlatform = WeiboKitPlatform.instance; 98 | 99 | test('$MethodChannelWeiboKit is the default instance', () { 100 | expect(initialPlatform, isInstanceOf()); 101 | }); 102 | 103 | test('isInstalled', () async { 104 | final MockWeiboKitPlatform fakePlatform = MockWeiboKitPlatform(); 105 | WeiboKitPlatform.instance = fakePlatform; 106 | 107 | expect(await Weibo.instance.isInstalled(), true); 108 | }); 109 | } 110 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: weibo_kit_example 2 | description: Demonstrates how to use the weibo_kit plugin. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | version: 1.0.0+100 9 | 10 | environment: 11 | sdk: ">=2.17.0 <3.0.0" 12 | 13 | # Dependencies specify other packages that your package needs in order to work. 14 | # To automatically upgrade your package dependencies to the latest versions 15 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 16 | # dependencies can be manually updated by changing the version numbers below to 17 | # the latest version available on pub.dev. To see which dependencies have newer 18 | # versions available, run `flutter pub outdated`. 19 | dependencies: 20 | flutter: 21 | sdk: flutter 22 | 23 | weibo_kit: 24 | # When depending on this package from a real application you should use: 25 | # weibo_kit: ^x.y.z 26 | # See https://dart.dev/tools/pub/dependencies#version-constraints 27 | # The example app is bundled with the plugin so we use a path dependency on 28 | # the parent directory to use the current plugin's version. 29 | path: ../ 30 | 31 | # The following adds the Cupertino Icons font to your application. 32 | # Use with the CupertinoIcons class for iOS style icons. 33 | cupertino_icons: ^1.0.2 34 | 35 | path: ^1.8.1 36 | path_provider: ^2.0.10 37 | image: ^3.0.1 38 | flutter_cache_manager: ^3.0.0 39 | 40 | json_annotation: ^4.5.0 41 | 42 | dev_dependencies: 43 | flutter_test: 44 | sdk: flutter 45 | 46 | # The "flutter_lints" package below contains a set of recommended lints to 47 | # encourage good coding practices. The lint set provided by the package is 48 | # activated in the `analysis_options.yaml` file located at the root of your 49 | # package. See that file for information about deactivating specific lint 50 | # rules and activating additional ones. 51 | flutter_lints: ^2.0.0 52 | 53 | build_runner: 54 | json_serializable: 55 | 56 | # For information on the generic Dart part of this file, see the 57 | # following page: https://dart.dev/tools/pub/pubspec 58 | 59 | # The following section is specific to Flutter packages. 60 | flutter: 61 | 62 | # The following line ensures that the Material Icons font is 63 | # included with your application, so that you can use the icons in 64 | # the material Icons class. 65 | uses-material-design: true 66 | 67 | # To add assets to your application, add an assets section, like this: 68 | # assets: 69 | # - images/a_dot_burr.jpeg 70 | # - images/a_dot_ham.jpeg 71 | 72 | # An image asset can refer to one or more resolution-specific "variants", see 73 | # https://flutter.dev/assets-and-images/#resolution-aware 74 | 75 | # For details regarding adding assets from package dependencies, see 76 | # https://flutter.dev/assets-and-images/#from-packages 77 | 78 | # To add custom fonts to your application, add a fonts section here, 79 | # in this "flutter" section. Each entry in this list should have a 80 | # "family" key with the font family name, and a "fonts" key with a 81 | # list giving the asset and other descriptors for the font. For 82 | # example: 83 | # fonts: 84 | # - family: Schyler 85 | # fonts: 86 | # - asset: fonts/Schyler-Regular.ttf 87 | # - asset: fonts/Schyler-Italic.ttf 88 | # style: italic 89 | # - family: Trajan Pro 90 | # fonts: 91 | # - asset: fonts/TrajanPro.ttf 92 | # - asset: fonts/TrajanPro_Bold.ttf 93 | # weight: 700 94 | # 95 | # For details regarding fonts from package dependencies, 96 | # see https://flutter.dev/custom-fonts/#from-packages 97 | -------------------------------------------------------------------------------- /lib/src/weibo_kit_platform_interface.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | 3 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; 4 | import 'package:weibo_kit/src/model/resp.dart'; 5 | import 'package:weibo_kit/src/weibo_constant.dart'; 6 | import 'package:weibo_kit/src/weibo_kit_method_channel.dart'; 7 | 8 | abstract class WeiboKitPlatform extends PlatformInterface { 9 | /// Constructs a WeiboKitPlatform. 10 | WeiboKitPlatform() : super(token: _token); 11 | 12 | static final Object _token = Object(); 13 | 14 | static WeiboKitPlatform _instance = MethodChannelWeiboKit(); 15 | 16 | /// The default instance of [WeiboKitPlatform] to use. 17 | /// 18 | /// Defaults to [MethodChannelWeiboKit]. 19 | static WeiboKitPlatform get instance => _instance; 20 | 21 | /// Platform-specific implementations should set this with their own 22 | /// platform-specific class that extends [WeiboKitPlatform] when 23 | /// they register themselves. 24 | static set instance(WeiboKitPlatform instance) { 25 | PlatformInterface.verifyToken(instance, _token); 26 | _instance = instance; 27 | } 28 | 29 | /// 30 | Future registerApp({ 31 | required String appKey, 32 | required String? universalLink, 33 | required List scope, 34 | String redirectUrl = WeiboRegister 35 | .DEFAULT_REDIRECTURL, // 新浪微博开放平台 -> 我的应用 -> 应用信息 -> 高级信息 -> OAuth2.0授权设置 36 | }) { 37 | throw UnimplementedError( 38 | 'registerApp({required appKey, required universalLink, required scope, redirectUrl}) has not been implemented.'); 39 | } 40 | 41 | /// 42 | Stream respStream() { 43 | throw UnimplementedError('respStream() has not been implemented.'); 44 | } 45 | 46 | /// 47 | Future isInstalled() { 48 | throw UnimplementedError('isInstalled() has not been implemented.'); 49 | } 50 | 51 | /// 52 | Future isSupportMultipleImage() { 53 | throw UnimplementedError( 54 | 'isSupportMultipleImage() has not been implemented.'); 55 | } 56 | 57 | /// 登录 58 | Future auth({ 59 | required String appKey, 60 | required List scope, 61 | String redirectUrl = WeiboRegister.DEFAULT_REDIRECTURL, 62 | }) { 63 | throw UnimplementedError( 64 | 'auth({required appKey, required scope, redirectUrl}) has not been implemented.'); 65 | } 66 | 67 | /// 分享 - 文本 68 | Future shareText({ 69 | required String text, 70 | bool clientOnly = false /* Android Only */, 71 | }) { 72 | throw UnimplementedError( 73 | 'shareText({required text, clientOnly}) has not been implemented.'); 74 | } 75 | 76 | /// 分享 - 图片 77 | /// Android 图片文件分享用 shareMultiImage 78 | Future shareImage({ 79 | String? text, 80 | Uint8List? imageData, 81 | Uri? imageUri, 82 | bool clientOnly = false /* Android Only */, 83 | }) { 84 | throw UnimplementedError( 85 | 'shareImage({text, imageData, imageUri, clientOnly}) has not been implemented.'); 86 | } 87 | 88 | /// 分享 - 多图 89 | Future shareMultiImage({ 90 | String? text, 91 | required List imageUris, 92 | bool clientOnly = false /* Android Only */, 93 | }) { 94 | throw UnimplementedError( 95 | 'shareMultiImage({text, required imageUris, clientOnly}) has not been implemented.'); 96 | } 97 | 98 | /// 分享 - 视频 99 | Future shareVideo({ 100 | String? text, 101 | required Uri videoUri, 102 | bool clientOnly = false /* Android Only */, 103 | }) { 104 | throw UnimplementedError( 105 | 'shareVideo({text, required videoUri, clientOnly}) has not been implemented.'); 106 | } 107 | 108 | /// 分享 - 网页 109 | Future shareWebpage({ 110 | required String title, 111 | required String description, 112 | required Uint8List thumbData, 113 | required String webpageUrl, 114 | bool clientOnly = false /* Android Only */, 115 | }) { 116 | throw UnimplementedError( 117 | 'shareWebpage({required title, required description, required thumbData, required webpageUrl, clientOnly}) has not been implemented.'); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Weibo Kit 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | weibo_kit_example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleURLTypes 24 | 25 | 26 | CFBundleTypeRole 27 | Editor 28 | CFBundleURLName 29 | weibo 30 | CFBundleURLSchemes 31 | 32 | your 33 | weibo 34 | app 35 | key 36 | 37 | 38 | 39 | CFBundleVersion 40 | $(FLUTTER_BUILD_NUMBER) 41 | LSApplicationQueriesSchemes 42 | 43 | sinaweibo 44 | sinaweibohd 45 | weibosdk 46 | weibosdk2.5 47 | 48 | LSRequiresIPhoneOS 49 | 50 | NSAppTransportSecurity 51 | 52 | NSAllowsArbitraryLoads 53 | 54 | NSExceptionDomains 55 | 56 | sina.cn 57 | 58 | NSExceptionMinimumTLSVersion 59 | TLSv1.0 60 | NSIncludesSubdomains 61 | 62 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 63 | 64 | NSThirdPartyExceptionRequiresForwardSecrecy 65 | 66 | 67 | sina.com.cn 68 | 69 | NSExceptionMinimumTLSVersion 70 | TLSv1.0 71 | NSIncludesSubdomains 72 | 73 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 74 | 75 | NSThirdPartyExceptionRequiresForwardSecrecy 76 | 77 | 78 | sinaimg.cn 79 | 80 | NSExceptionMinimumTLSVersion 81 | TLSv1.0 82 | NSIncludesSubdomains 83 | 84 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 85 | 86 | NSThirdPartyExceptionRequiresForwardSecrecy 87 | 88 | 89 | sinajs.cn 90 | 91 | NSExceptionMinimumTLSVersion 92 | TLSv1.0 93 | NSIncludesSubdomains 94 | 95 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 96 | 97 | NSThirdPartyExceptionRequiresForwardSecrecy 98 | 99 | 100 | weibo.cn 101 | 102 | NSExceptionMinimumTLSVersion 103 | TLSv1.0 104 | NSIncludesSubdomains 105 | 106 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 107 | 108 | NSThirdPartyExceptionRequiresForwardSecrecy 109 | 110 | 111 | weibo.com 112 | 113 | NSExceptionMinimumTLSVersion 114 | TLSv1.0 115 | NSIncludesSubdomains 116 | 117 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 118 | 119 | NSThirdPartyExceptionRequiresForwardSecrecy 120 | 121 | 122 | 123 | 124 | UILaunchStoryboardName 125 | LaunchScreen 126 | UIMainStoryboardFile 127 | Main 128 | UISupportedInterfaceOrientations 129 | 130 | UIInterfaceOrientationPortrait 131 | UIInterfaceOrientationLandscapeLeft 132 | UIInterfaceOrientationLandscapeRight 133 | 134 | UISupportedInterfaceOrientations~ipad 135 | 136 | UIInterfaceOrientationPortrait 137 | UIInterfaceOrientationPortraitUpsideDown 138 | UIInterfaceOrientationLandscapeLeft 139 | UIInterfaceOrientationLandscapeRight 140 | 141 | UIViewControllerBasedStatusBarAppearance 142 | 143 | CADisableMinimumFrameDurationOnPhone 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /.drone.yml: -------------------------------------------------------------------------------- 1 | kind: pipeline 2 | name: default 3 | 4 | steps: 5 | - name: prepare 6 | image: v7lin/flutter:1.17.3-stable 7 | volumes: 8 | - name: pub-cache 9 | path: /opt/flutter/.pub-cache 10 | commands: 11 | - flutter packages get 12 | 13 | #- name: build_runner 14 | # image: v7lin/flutter:1.17.3-stable 15 | # volumes: 16 | # - name: pub-cache 17 | # path: /opt/flutter/.pub-cache 18 | # commands: 19 | # - flutter pub run build_runner clean 20 | # - flutter pub run build_runner build --delete-conflicting-outputs 21 | 22 | # 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" 23 | #- name: ios-format 24 | # image: v7lin/clang 25 | # commands: 26 | # - cd ios/ 27 | # - clang-format -style=file -i src/Classes/*.h src/Classes/*.m 28 | 29 | - name: format 30 | image: v7lin/flutter:1.17.3-stable 31 | volumes: 32 | - name: pub-cache 33 | path: /opt/flutter/.pub-cache 34 | commands: 35 | - flutter format --dry-run --set-exit-if-changed . 36 | 37 | - name: analyze 38 | image: v7lin/flutter:1.17.3-stable 39 | volumes: 40 | - name: pub-cache 41 | path: /opt/flutter/.pub-cache 42 | commands: 43 | - flutter analyze 44 | 45 | - name: test 46 | image: v7lin/flutter:1.17.3-stable 47 | volumes: 48 | - name: pub-cache 49 | path: /opt/flutter/.pub-cache 50 | commands: 51 | - flutter test --coverage 52 | # - cd example/ 53 | # - flutter test 54 | 55 | - name: proguard 56 | image: v7lin/flutter:1.17.3-stable 57 | volumes: 58 | - name: pub-cache 59 | path: /opt/flutter/.pub-cache 60 | - name: gradle 61 | path: /root/.gradle 62 | commands: 63 | - cd example/ 64 | - flutter build apk 65 | 66 | - name: coverage 67 | image: plugins/codecov:2.0.3 68 | settings: 69 | token: 70 | from_secret: CODECOV_TOKEN 71 | files: 72 | - ./coverage/lcov.info 73 | when: 74 | event: 75 | exclude: 76 | - pull_request 77 | 78 | - name: publish-check 79 | image: v7lin/flutter:1.17.3-stable 80 | volumes: 81 | - name: pub-cache 82 | path: /opt/flutter/.pub-cache 83 | commands: 84 | - flutter packages pub publish --dry-run 85 | 86 | volumes: 87 | - name: pub-cache 88 | temp: {} 89 | - name: gradle 90 | temp: {} 91 | 92 | --- 93 | kind: pipeline 94 | name: publish 95 | 96 | steps: 97 | - name: restore-cache 98 | image: alpine:3.9.3 99 | volumes: 100 | - name: pub-cache 101 | path: /opt/flutter/.pub-cache 102 | commands: 103 | - FLUTTER_HOME=/opt/flutter/.pub-cache 104 | - wget -P $FLUTTER_HOME https://raw.githubusercontent.com/v7lin/pub_credentials/master/credentials.json.enc 105 | 106 | - name: restore-cache-openssl 107 | image: v7lin/openssl:1.1.1b 108 | volumes: 109 | - name: pub-cache 110 | path: /opt/flutter/.pub-cache 111 | environment: 112 | ENC_METHOD: 113 | from_secret: ENC_METHOD 114 | ENC_PASSWORD: 115 | from_secret: ENC_PASSWORD 116 | commands: 117 | - FLUTTER_HOME=/opt/flutter/.pub-cache 118 | - openssl enc -d -$ENC_METHOD -k $ENC_PASSWORD -in $FLUTTER_HOME/credentials.json.enc -out $FLUTTER_HOME/credentials.json 119 | - rm $FLUTTER_HOME/credentials.json.enc 120 | 121 | - name: publish 122 | image: v7lin/flutter:1.17.3-stable 123 | volumes: 124 | - name: pub-cache 125 | path: /opt/flutter/.pub-cache 126 | commands: 127 | - echo "y" | flutter packages pub publish 128 | 129 | - name: save-cache-openssl 130 | image: v7lin/openssl:1.1.1b 131 | volumes: 132 | - name: pub-cache 133 | path: /opt/flutter/.pub-cache 134 | environment: 135 | ENC_METHOD: 136 | from_secret: ENC_METHOD 137 | ENC_PASSWORD: 138 | from_secret: ENC_PASSWORD 139 | commands: 140 | - FLUTTER_HOME=/opt/flutter/.pub-cache 141 | - openssl enc -e -$ENC_METHOD -k $ENC_PASSWORD -in $FLUTTER_HOME/credentials.json -out $FLUTTER_HOME/credentials.json.enc 142 | - rm /opt/flutter/.pub-cache/credentials.json 143 | 144 | - name: save-cache 145 | image: docker:git 146 | volumes: 147 | - name: pub-cache 148 | path: /opt/flutter/.pub-cache 149 | environment: 150 | GIT_USER_EMAIL: 151 | from_secret: GIT_USER_EMAIL 152 | GIT_USER_NAME: 153 | from_secret: GIT_USER_NAME 154 | GIT_USER_PASSWORD: 155 | from_secret: GIT_USER_PASSWORD # 密码含'@',用'%40'替换 -> URLEncoder.encode("@","utf-8"); 156 | commands: 157 | - FLUTTER_HOME=/opt/flutter/.pub-cache 158 | - git config --global user.email $GIT_USER_EMAIL 159 | - git config --global user.name $GIT_USER_NAME 160 | - git config --global credential.helper store 161 | - git clone -b master https://$GIT_USER_NAME:$GIT_USER_PASSWORD@github.com/v7lin/pub_credentials.git $FLUTTER_HOME/pub_credentials 162 | - rm $FLUTTER_HOME/pub_credentials/credentials.json.enc 163 | - mv $FLUTTER_HOME/credentials.json.enc $FLUTTER_HOME/pub_credentials/credentials.json.enc 164 | - cd $FLUTTER_HOME/pub_credentials 165 | - git commit -am "update credentials by ci/cd tools" 166 | - git push 167 | 168 | volumes: 169 | - name: pub-cache 170 | temp: {} 171 | 172 | trigger: 173 | status: 174 | - success 175 | event: 176 | - tag 177 | 178 | depends_on: 179 | - default 180 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # weibo_kit 2 | 3 | [![Pub Package](https://img.shields.io/pub/v/weibo_kit.svg)](https://pub.dev/packages/weibo_kit) 4 | [![License](https://img.shields.io/github/license/RxReader/weibo_kit)](https://github.com/RxReader/weibo_kit/blob/master/LICENSE) 5 | 6 | flutter版新浪微博SDK 7 | 8 | ## 相关工具 9 | 10 | * [Flutter版微信SDK](https://github.com/RxReader/wechat_kit) 11 | * [Flutter版腾讯(QQ)SDK](https://github.com/RxReader/tencent_kit) 12 | * [Flutter版新浪微博SDK](https://github.com/RxReader/weibo_kit) 13 | * [Flutter版支付宝SDK](https://github.com/RxReader/alipay_kit) 14 | * [Flutter版深度链接](https://github.com/RxReader/link_kit) 15 | * [Flutter版walle渠道打包工具](https://github.com/RxReader/walle_kit) 16 | 17 | ## dart/flutter 私服 18 | 19 | * [simple_pub_server](https://github.com/rxreader/simple_pub_server) 20 | 21 | ## docs 22 | 23 | * [Android 应用接入](https://open.weibo.com/wiki/Sdk/android) 24 | * [iOS 应用接入](https://open.weibo.com/wiki/Sdk/ios) 25 | * [Android Github](https://github.com/sinaweibosdk/weibo_android_sdk) 26 | * [iOS Github](https://github.com/sinaweibosdk/weibo_ios_sdk) 27 | * [Universal Links](https://developer.apple.com/documentation/uikit/inter-process_communication/allowing_apps_and_websites_to_link_to_your_content) 28 | 29 | ## android 30 | 31 | ``` 32 | # 不需要做任何额外接入工作 33 | # 混淆已打入 Library,随 Library 引用,自动添加到 apk 打包混淆 34 | ``` 35 | 36 | * [获取 Android 签名信息](https://github.com/RxReader/wechat_kit#android) 37 | 38 | ## ios 39 | 40 | ``` 41 | iOS 9.0 42 | ``` 43 | 44 | ``` 45 | 在Xcode中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“URL type“添加“URL scheme”为你所注册的应用程序id 46 | 47 | URL Types 48 | weibosdk: identifier=weibo schemes=wb${appKey} 49 | ``` 50 | 51 | ``` 52 | iOS 9系统策略更新,限制了http协议的访问,此外应用需要在“Info.plist”中将要使用的URL Schemes列为白名单,才可正常检查其他应用是否安装。 53 | LSApplicationQueriesSchemes 54 | 55 | sinaweibo 56 | sinaweibohd 57 | weibosdk 58 | weibosdk2.5 59 | weibosdk3.3 60 | 61 | ``` 62 | 63 | ``` 64 | 由于iOS9/10的发布,原有ATS设置在iOS10上会出现https网络访问限制的问题,为了确保好的应用体验,我们需要采取如下措施: 65 | NSAppTransportSecurity 66 | 67 | NSAllowsArbitraryLoads 68 | 69 | NSExceptionDomains 70 | 71 | sina.cn 72 | 73 | NSExceptionMinimumTLSVersion 74 | TLSv1.0 75 | NSIncludesSubdomains 76 | 77 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 78 | 79 | NSThirdPartyExceptionRequiresForwardSecrecy 80 | 81 | 82 | sina.com.cn 83 | 84 | NSExceptionMinimumTLSVersion 85 | TLSv1.0 86 | NSIncludesSubdomains 87 | 88 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 89 | 90 | NSThirdPartyExceptionRequiresForwardSecrecy 91 | 92 | 93 | sinaimg.cn 94 | 95 | NSExceptionMinimumTLSVersion 96 | TLSv1.0 97 | NSIncludesSubdomains 98 | 99 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 100 | 101 | NSThirdPartyExceptionRequiresForwardSecrecy 102 | 103 | 104 | sinajs.cn 105 | 106 | NSExceptionMinimumTLSVersion 107 | TLSv1.0 108 | NSIncludesSubdomains 109 | 110 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 111 | 112 | NSThirdPartyExceptionRequiresForwardSecrecy 113 | 114 | 115 | weibo.cn 116 | 117 | NSExceptionMinimumTLSVersion 118 | TLSv1.0 119 | NSIncludesSubdomains 120 | 121 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 122 | 123 | NSThirdPartyExceptionRequiresForwardSecrecy 124 | 125 | 126 | weibo.com 127 | 128 | NSExceptionMinimumTLSVersion 129 | TLSv1.0 130 | NSIncludesSubdomains 131 | 132 | NSThirdPartyExceptionAllowsInsecureHTTPLoads 133 | 134 | NSThirdPartyExceptionRequiresForwardSecrecy 135 | 136 | 137 | 138 | 139 | ``` 140 | 141 | ## flutter 142 | 143 | * break change 144 | * 4.0.1: expiresIn -> expiresTime 145 | * 4.0.0: 按标准插件书写重构 146 | * 3.0.0: 重构 147 | * 2.0.2: iOS Universal Links 148 | * 2.0.0: nullsafety & 不再支持 Android embedding v1 & Weibo 单例 149 | 150 | * snapshot 151 | 152 | ``` 153 | dependencies: 154 | weibo_kit: 155 | git: 156 | url: https://github.com/rxreader/weibo_kit.git 157 | ``` 158 | 159 | * release 160 | 161 | ``` 162 | dependencies: 163 | weibo_kit: ^${latestTag} 164 | ``` 165 | 166 | * example 167 | 168 | [示例](./example/lib/main.dart) 169 | 170 | ## Star History 171 | 172 | ![stars](https://starchart.cc/rxreader/weibo_kit.svg) 173 | -------------------------------------------------------------------------------- /lib/src/weibo_kit_method_channel.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:io'; 3 | import 'dart:typed_data'; 4 | 5 | import 'package:flutter/foundation.dart'; 6 | import 'package:flutter/services.dart'; 7 | import 'package:weibo_kit/src/model/resp.dart'; 8 | import 'package:weibo_kit/src/weibo_constant.dart'; 9 | import 'package:weibo_kit/src/weibo_kit_platform_interface.dart'; 10 | 11 | /// An implementation of [WeiboKitPlatform] that uses method channels. 12 | class MethodChannelWeiboKit extends WeiboKitPlatform { 13 | /// The method channel used to interact with the native platform. 14 | @visibleForTesting 15 | late final MethodChannel methodChannel = 16 | const MethodChannel('v7lin.github.io/weibo_kit') 17 | ..setMethodCallHandler(_handleMethod); 18 | final StreamController _respStreamController = 19 | StreamController.broadcast(); 20 | 21 | Future _handleMethod(MethodCall call) async { 22 | switch (call.method) { 23 | case 'onAuthResp': 24 | _respStreamController.add(AuthResp.fromJson( 25 | (call.arguments as Map).cast())); 26 | break; 27 | case 'onShareMsgResp': 28 | _respStreamController.add(ShareMsgResp.fromJson( 29 | (call.arguments as Map).cast())); 30 | break; 31 | } 32 | } 33 | 34 | @override 35 | Future registerApp({ 36 | required String appKey, 37 | required String? universalLink, 38 | required List scope, 39 | String redirectUrl = WeiboRegister.DEFAULT_REDIRECTURL, 40 | }) { 41 | assert(!Platform.isIOS || (universalLink?.isNotEmpty ?? false)); 42 | return methodChannel.invokeMethod( 43 | 'registerApp', 44 | { 45 | 'appKey': appKey, 46 | 'universalLink': universalLink, 47 | 'scope': scope.join(','), 48 | 'redirectUrl': redirectUrl, 49 | }, 50 | ); 51 | } 52 | 53 | @override 54 | Stream respStream() { 55 | return _respStreamController.stream; 56 | } 57 | 58 | @override 59 | Future isInstalled() async { 60 | return await methodChannel.invokeMethod('isInstalled') ?? false; 61 | } 62 | 63 | @override 64 | Future isSupportMultipleImage() async { 65 | return await methodChannel.invokeMethod('isSupportMultipleImage') ?? 66 | false; 67 | } 68 | 69 | @override 70 | Future auth({ 71 | required String appKey, 72 | required List scope, 73 | String redirectUrl = WeiboRegister.DEFAULT_REDIRECTURL, 74 | }) { 75 | return methodChannel.invokeMethod( 76 | 'auth', 77 | { 78 | 'appKey': appKey, 79 | 'scope': scope.join(','), 80 | 'redirectUrl': redirectUrl, 81 | }, 82 | ); 83 | } 84 | 85 | @override 86 | Future shareText({ 87 | required String text, 88 | bool clientOnly = false, 89 | }) { 90 | return methodChannel.invokeMethod( 91 | 'shareText', 92 | { 93 | 'text': text, 94 | 'clientOnly': clientOnly, 95 | }, 96 | ); 97 | } 98 | 99 | @override 100 | Future shareImage({ 101 | String? text, 102 | Uint8List? imageData, 103 | Uri? imageUri, 104 | bool clientOnly = false, 105 | }) { 106 | assert(text == null || text.length <= 1024); 107 | assert((imageData != null && imageData.lengthInBytes <= 2 * 1024 * 1024) || 108 | (imageUri != null && 109 | imageUri.isScheme('file') && 110 | imageUri.toFilePath().length <= 512 && 111 | File.fromUri(imageUri).lengthSync() <= 10 * 1024 * 1024)); 112 | return methodChannel.invokeMethod( 113 | 'shareImage', 114 | { 115 | if (text != null && text.isNotEmpty) 'text': text, 116 | if (imageData != null) 'imageData': imageData, 117 | if (imageUri != null) 'imageUri': imageUri.toString(), 118 | 'clientOnly': clientOnly, 119 | }, 120 | ); 121 | } 122 | 123 | @override 124 | Future shareMultiImage({ 125 | String? text, 126 | required List imageUris, 127 | bool clientOnly = false, 128 | }) { 129 | assert(text == null || text.length <= 1024); 130 | assert(imageUris.isNotEmpty && 131 | imageUris.every((Uri element) => element.isScheme('file')) && 132 | imageUris 133 | .map((Uri element) => File.fromUri(element).lengthSync()) 134 | .reduce((int value, int element) => value + element) <= 135 | 30 * 1024 * 1024); 136 | return methodChannel.invokeMethod( 137 | 'shareMultiImage', 138 | { 139 | if (text != null && text.isNotEmpty) 'text': text, 140 | 'imageUris': 141 | imageUris.map((Uri element) => element.toString()).toList(), 142 | 'clientOnly': clientOnly, 143 | }, 144 | ); 145 | } 146 | 147 | @override 148 | Future shareVideo({ 149 | String? text, 150 | required Uri videoUri, 151 | bool clientOnly = false, 152 | }) { 153 | assert(text == null || text.length <= 1024); 154 | assert(videoUri.isScheme('file') && 155 | File.fromUri(videoUri).lengthSync() <= 50 * 1024 * 1024); 156 | return methodChannel.invokeMethod( 157 | 'shareVideo', 158 | { 159 | if (text != null && text.isNotEmpty) 'text': text, 160 | 'videoUri': videoUri.toString(), 161 | 'clientOnly': clientOnly, 162 | }, 163 | ); 164 | } 165 | 166 | @override 167 | Future shareWebpage({ 168 | required String title, 169 | required String description, 170 | required Uint8List thumbData, 171 | required String webpageUrl, 172 | bool clientOnly = false, 173 | }) { 174 | assert(title.length <= 512); 175 | assert(description.isNotEmpty && description.length <= 1024); 176 | assert(thumbData.lengthInBytes <= 32 * 1024); 177 | assert(webpageUrl.length <= 255); 178 | return methodChannel.invokeMethod( 179 | 'shareWebpage', 180 | { 181 | 'title': title, 182 | 'description': description, 183 | 'thumbData': thumbData, 184 | 'webpageUrl': webpageUrl, 185 | 'clientOnly': clientOnly, 186 | }, 187 | ); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:io'; 3 | import 'dart:typed_data'; 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_cache_manager/flutter_cache_manager.dart'; 7 | import 'package:image/image.dart' as imglib; 8 | // import 'package:path/path.dart' as path; 9 | // import 'package:path_provider/path_provider.dart' as path_provider; 10 | import 'package:weibo_kit/weibo_kit.dart'; 11 | import 'package:weibo_kit_example/api/model/weibo_api_resp.dart'; 12 | import 'package:weibo_kit_example/api/weibo_api.dart'; 13 | 14 | const String _WEIBO_APP_KEY = 'your weibo app key'; 15 | const String _WEIBO_UNIVERSAL_LINK = 'your weibo universal link'; 16 | const List _WEIBO_SCOPE = [ 17 | WeiboScope.ALL, 18 | ]; 19 | 20 | void main() { 21 | runApp(MyApp()); 22 | } 23 | 24 | class MyApp extends StatelessWidget { 25 | const MyApp({ 26 | super.key, 27 | }); 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | return MaterialApp( 32 | home: Home(), 33 | ); 34 | } 35 | } 36 | 37 | class Home extends StatefulWidget { 38 | const Home({ 39 | super.key, 40 | }); 41 | 42 | @override 43 | State createState() { 44 | return _HomeState(); 45 | } 46 | } 47 | 48 | class _HomeState extends State { 49 | late final StreamSubscription _respSubs; 50 | 51 | AuthResp? _authResp; 52 | 53 | @override 54 | void initState() { 55 | super.initState(); 56 | _respSubs = Weibo.instance.respStream().listen(_listenResp); 57 | } 58 | 59 | void _listenResp(BaseResp resp) { 60 | if (resp is AuthResp) { 61 | _authResp = resp; 62 | final String content = 'auth: ${resp.errorCode}'; 63 | _showTips('登录', content); 64 | } else if (resp is ShareMsgResp) { 65 | final String content = 'share: ${resp.errorCode}'; 66 | _showTips('分享', content); 67 | } 68 | } 69 | 70 | @override 71 | void dispose() { 72 | _respSubs.cancel(); 73 | super.dispose(); 74 | } 75 | 76 | @override 77 | Widget build(BuildContext context) { 78 | return Scaffold( 79 | appBar: AppBar( 80 | title: Text('Weibo Kit Demo'), 81 | ), 82 | body: ListView( 83 | children: [ 84 | ListTile( 85 | title: Text('注册APP'), 86 | onTap: () async { 87 | await Weibo.instance.registerApp( 88 | appKey: _WEIBO_APP_KEY, 89 | universalLink: _WEIBO_UNIVERSAL_LINK, 90 | scope: _WEIBO_SCOPE, 91 | ); 92 | _showTips('注册APP', '注册成功'); 93 | }, 94 | ), 95 | ListTile( 96 | title: Text('环境检查'), 97 | onTap: () async { 98 | final String content = 99 | 'weibo: ${await Weibo.instance.isInstalled()}'; 100 | _showTips('环境检查', content); 101 | }, 102 | ), 103 | ListTile( 104 | title: Text('登录'), 105 | onTap: () { 106 | Weibo.instance.auth( 107 | appKey: _WEIBO_APP_KEY, 108 | scope: _WEIBO_SCOPE, 109 | ); 110 | }, 111 | ), 112 | ListTile( 113 | title: Text('用户信息'), 114 | onTap: () async { 115 | if (_authResp?.isSuccessful ?? false) { 116 | final WeiboUserInfoResp userInfoResp = 117 | await WeiboApi.getUserInfo( 118 | appkey: _WEIBO_APP_KEY, 119 | userId: _authResp!.userId!, 120 | accessToken: _authResp!.accessToken!, 121 | ); 122 | if (userInfoResp.isSuccessful) { 123 | _showTips('用户信息', 124 | '${userInfoResp.screenName}\n${userInfoResp.description}\n${userInfoResp.location}\n${userInfoResp.profileImageUrl}'); 125 | } else { 126 | _showTips('用户信息', 127 | '获取用户信息失败\n${userInfoResp.errorCode}:${userInfoResp.error}'); 128 | } 129 | } 130 | }, 131 | ), 132 | ListTile( 133 | title: Text('文字分享'), 134 | onTap: () { 135 | Weibo.instance.shareText( 136 | text: 'Share Text', 137 | ); 138 | }, 139 | ), 140 | ListTile( 141 | title: Text('图片分享'), 142 | onTap: () async { 143 | final File file = await DefaultCacheManager().getSingleFile( 144 | 'https://www.baidu.com/img/bd_logo1.png?where=super'); 145 | // if (Platform.isAndroid) { 146 | // // 仅支持 Context.getExternalFilesDir(null)/Context.getExternalCacheDirs(null) 路径分享 147 | // // path_provider.getExternalCacheDirectories(); 148 | // // path_provider.getExternalStorageDirectory(); 149 | // final Directory temporaryDir = 150 | // await path_provider.getTemporaryDirectory(); 151 | // if (path.isWithin(temporaryDir.parent.path, file.path)) { 152 | // // 复制 153 | // final File copyFile = File(path.join( 154 | // (await path_provider.getExternalStorageDirectory())!.path, 155 | // path.basename(file.path))); 156 | // if (copyFile.existsSync()) { 157 | // await copyFile.delete(); 158 | // } 159 | // await copyFile.writeAsBytes(await file.readAsBytes()); 160 | // file = copyFile; 161 | // } 162 | // } 163 | await Weibo.instance.shareMultiImage( 164 | text: 'Share Text', 165 | imageUris: [Uri.file(file.path)], 166 | ); 167 | }, 168 | ), 169 | ListTile( 170 | title: Text('网页分享'), 171 | onTap: () async { 172 | final File file = await DefaultCacheManager().getSingleFile( 173 | 'https://www.baidu.com/img/bd_logo1.png?where=super'); 174 | final imglib.Image thumbnail = 175 | imglib.decodeImage(file.readAsBytesSync())!; 176 | Uint8List thumbData = thumbnail.getBytes(); 177 | if (thumbData.length > 32 * 1024) { 178 | thumbData = Uint8List.fromList(imglib.encodeJpg(thumbnail, 179 | quality: 100 * 32 * 1024 ~/ thumbData.length)); 180 | } 181 | await Weibo.instance.shareWebpage( 182 | title: 'title', 183 | description: 'share webpage', 184 | thumbData: thumbData.buffer.asUint8List(), 185 | webpageUrl: 'https://www.baidu.com', 186 | ); 187 | }, 188 | ), 189 | ], 190 | ), 191 | ); 192 | } 193 | 194 | void _showTips(String title, String content) { 195 | showDialog( 196 | context: context, 197 | builder: (BuildContext context) { 198 | return AlertDialog( 199 | title: Text(title), 200 | content: Text(content), 201 | ); 202 | }, 203 | ); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /ios/Classes/WeiboKitPlugin.m: -------------------------------------------------------------------------------- 1 | #import "WeiboKitPlugin.h" 2 | #import 3 | 4 | @interface WeiboKitPlugin () 5 | 6 | @end 7 | 8 | @implementation WeiboKitPlugin { 9 | FlutterMethodChannel *_channel; 10 | } 11 | 12 | + (void)registerWithRegistrar:(NSObject *)registrar { 13 | FlutterMethodChannel *channel = [FlutterMethodChannel 14 | methodChannelWithName:@"v7lin.github.io/weibo_kit" 15 | binaryMessenger:[registrar messenger]]; 16 | WeiboKitPlugin *instance = [[WeiboKitPlugin alloc] initWithChannel:channel]; 17 | [registrar addApplicationDelegate:instance]; 18 | [registrar addMethodCallDelegate:instance channel:channel]; 19 | } 20 | 21 | - (instancetype)initWithChannel:(FlutterMethodChannel *)channel { 22 | self = [super init]; 23 | if (self) { 24 | _channel = channel; 25 | } 26 | return self; 27 | } 28 | 29 | - (void)handleMethodCall:(FlutterMethodCall *)call 30 | result:(FlutterResult)result { 31 | if ([@"registerApp" isEqualToString:call.method]) { 32 | NSString *appKey = call.arguments[@"appKey"]; 33 | NSString *universalLink = call.arguments[@"universalLink"]; 34 | [WeiboSDK registerApp:appKey universalLink:universalLink]; 35 | result(nil); 36 | } else if ([@"isInstalled" isEqualToString:call.method]) { 37 | result([NSNumber numberWithBool:[WeiboSDK isWeiboAppInstalled]]); 38 | } else if ([@"isSupportMultipleImage" isEqualToString:call.method]) { 39 | result([NSNumber numberWithBool:YES]); 40 | } else if ([@"auth" isEqualToString:call.method]) { 41 | [self handleAuthCall:call result:result]; 42 | } else if ([@"shareText" isEqualToString:call.method] || 43 | [@"shareImage" isEqualToString:call.method] || 44 | [@"shareMultiImage" isEqualToString:call.method] || 45 | [@"shareVideo" isEqualToString:call.method] || 46 | [@"shareWebpage" isEqualToString:call.method]) { 47 | [self handleShareCall:call result:result]; 48 | } else { 49 | result(FlutterMethodNotImplemented); 50 | } 51 | } 52 | 53 | - (void)handleAuthCall:(FlutterMethodCall *)call result:(FlutterResult)result { 54 | WBAuthorizeRequest *request = [WBAuthorizeRequest request]; 55 | request.scope = call.arguments[@"scope"]; 56 | request.redirectURI = call.arguments[@"redirectUrl"]; 57 | request.shouldShowWebViewForAuthIfCannotSSO = YES; 58 | request.shouldOpenWeiboAppInstallPageIfNotInstalled = NO; 59 | [WeiboSDK sendRequest:request 60 | completion:^(BOOL success){ 61 | // do nothing 62 | }]; 63 | result(nil); 64 | } 65 | 66 | - (void)handleShareCall:(FlutterMethodCall *)call result:(FlutterResult)result { 67 | WBMessageObject *message = [WBMessageObject message]; 68 | if ([@"shareText" isEqualToString:call.method]) { 69 | message.text = call.arguments[@"text"]; 70 | } else if ([@"shareImage" isEqualToString:call.method]) { 71 | message.text = call.arguments[@"text"]; 72 | WBImageObject *object = [WBImageObject object]; 73 | FlutterStandardTypedData *imageData = call.arguments[@"imageData"]; 74 | if (imageData != nil) { 75 | object.imageData = imageData.data; 76 | } else { 77 | NSString *imageUri = call.arguments[@"imageUri"]; 78 | NSURL *imageUrl = [NSURL URLWithString:imageUri]; 79 | object.imageData = [NSData dataWithContentsOfFile:imageUrl.path]; 80 | } 81 | message.imageObject = object; 82 | } else if ([@"shareMultiImage" isEqualToString:call.method]) { 83 | message.text = call.arguments[@"text"]; 84 | WBImageObject *object = [WBImageObject object]; 85 | NSArray *imageUris = call.arguments[@"imageUris"]; 86 | NSMutableArray *images = [[NSMutableArray alloc] init]; 87 | for (NSString *imageUri in imageUris) { 88 | NSURL *imageUrl = [NSURL URLWithString:imageUri]; 89 | [images addObject:[UIImage imageWithContentsOfFile:imageUrl.path]]; 90 | } 91 | [object addImages:images]; 92 | message.imageObject = object; 93 | } else if ([@"shareVideo" isEqualToString:call.method]) { 94 | message.text = call.arguments[@"text"]; 95 | WBNewVideoObject *object = [WBNewVideoObject object]; 96 | NSString *videoUri = call.arguments[@"videoUri"]; 97 | [object addVideo:[NSURL URLWithString:videoUri]]; 98 | message.videoObject = object; 99 | } else if ([@"shareWebpage" isEqualToString:call.method]) { 100 | WBWebpageObject *object = [WBWebpageObject object]; 101 | object.objectID = [[NSUUID UUID].UUIDString stringByReplacingOccurrencesOfString:@"-" withString:@""]; 102 | object.title = call.arguments[@"title"]; 103 | object.description = call.arguments[@"description"]; 104 | FlutterStandardTypedData *thumbData = call.arguments[@"thumbData"]; 105 | if (thumbData != nil) { 106 | object.thumbnailData = thumbData.data; 107 | } 108 | object.webpageUrl = call.arguments[@"webpageUrl"]; 109 | message.mediaObject = object; 110 | } 111 | WBSendMessageToWeiboRequest *request = [WBSendMessageToWeiboRequest request]; 112 | request.message = message; 113 | [WeiboSDK sendRequest:request 114 | completion:^(BOOL success){ 115 | // do nothing 116 | }]; 117 | result(nil); 118 | } 119 | 120 | #pragma mark - AppDelegate 121 | 122 | - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { 123 | return [WeiboSDK handleOpenURL:url delegate:self]; 124 | } 125 | 126 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { 127 | return [WeiboSDK handleOpenURL:url delegate:self]; 128 | } 129 | 130 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { 131 | return [WeiboSDK handleOpenURL:url delegate:self]; 132 | } 133 | 134 | - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *_Nonnull))restorationHandler { 135 | return [WeiboSDK handleOpenUniversalLink:userActivity delegate:self]; 136 | } 137 | 138 | #pragma mark - WeiboSDKDelegate 139 | 140 | - (void)didReceiveWeiboRequest:(WBBaseRequest *)request { 141 | } 142 | 143 | - (void)didReceiveWeiboResponse:(WBBaseResponse *)response { 144 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 145 | [dictionary setValue:[NSNumber numberWithInteger:response.statusCode] forKey:@"errorCode"]; 146 | if ([response isKindOfClass:[WBAuthorizeResponse class]]) { 147 | if (response.statusCode == WeiboSDKResponseStatusCodeSuccess) { 148 | WBAuthorizeResponse *authorizeResponse = (WBAuthorizeResponse *)response; 149 | NSString *userId = authorizeResponse.userID; 150 | NSString *accessToken = authorizeResponse.accessToken; 151 | NSString *refreshToken = authorizeResponse.refreshToken; 152 | long long expiresTime = authorizeResponse.expirationDate.timeIntervalSince1970 * 1000; 153 | [dictionary setValue:userId forKey:@"userId"]; 154 | [dictionary setValue:accessToken forKey:@"accessToken"]; 155 | [dictionary setValue:refreshToken forKey:@"refreshToken"]; 156 | [dictionary setValue:[NSNumber numberWithLongLong:expiresTime] forKey:@"expiresTime"]; 157 | } 158 | [_channel invokeMethod:@"onAuthResp" arguments:dictionary]; 159 | } else if ([response isKindOfClass:[WBSendMessageToWeiboResponse class]]) { 160 | if (response.statusCode == WeiboSDKResponseStatusCodeSuccess) { 161 | WBSendMessageToWeiboResponse *sendMessageToWeiboResponse = (WBSendMessageToWeiboResponse *)response; 162 | } 163 | [_channel invokeMethod:@"onShareMsgResp" arguments:dictionary]; 164 | } 165 | } 166 | 167 | @end 168 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # Specify analysis options. 2 | # 3 | # Until there are meta linter rules, each desired lint must be explicitly enabled. 4 | # See: https://github.com/dart-lang/linter/issues/288 5 | # 6 | # For a list of lints, see: http://dart-lang.github.io/linter/lints/ 7 | # See the configuration guide for more 8 | # https://github.com/dart-lang/sdk/tree/main/pkg/analyzer#configuring-the-analyzer 9 | # 10 | # There are other similar analysis options files in the flutter repos, 11 | # which should be kept in sync with this file: 12 | # 13 | # - analysis_options.yaml (this file) 14 | # - https://github.com/flutter/plugins/blob/master/analysis_options.yaml 15 | # - https://github.com/flutter/engine/blob/master/analysis_options.yaml 16 | # - https://github.com/flutter/packages/blob/master/analysis_options.yaml 17 | # 18 | # This file contains the analysis options used by Flutter tools, such as IntelliJ, 19 | # Android Studio, and the `flutter analyze` command. 20 | 21 | analyzer: 22 | language: 23 | strict-raw-types: true 24 | errors: 25 | # treat missing required parameters as a warning (not a hint) 26 | missing_required_param: warning 27 | # treat missing returns as a warning (not a hint) 28 | missing_return: warning 29 | # allow having TODO comments in the code 30 | todo: ignore 31 | # allow self-reference to deprecated members (we do this because otherwise we have 32 | # to annotate every member in every test, assert, etc, when we deprecate something) 33 | deprecated_member_use_from_same_package: ignore 34 | # TODO(ianh): https://github.com/flutter/flutter/issues/74381 35 | # Clean up existing unnecessary imports, and remove line to ignore. 36 | unnecessary_import: ignore 37 | # Turned off until null-safe rollout is complete. 38 | unnecessary_null_comparison: ignore 39 | exclude: 40 | - "bin/cache/**" 41 | # Ignore protoc generated files 42 | - "dev/conductor/lib/proto/*" 43 | # 44 | - "lib/*.g.dart" 45 | - "lib/**/*.g.dart" 46 | 47 | linter: 48 | rules: 49 | # these rules are documented on and in the same order as 50 | # the Dart Lint rules page to make maintenance easier 51 | # https://github.com/dart-lang/linter/blob/master/example/all.yaml 52 | - always_declare_return_types 53 | - always_put_control_body_on_new_line 54 | # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 55 | - always_require_non_null_named_parameters 56 | - always_specify_types 57 | - always_use_package_imports # we do this commonly 58 | - annotate_overrides 59 | # - avoid_annotating_with_dynamic # conflicts with always_specify_types 60 | - avoid_bool_literals_in_conditional_expressions 61 | # - avoid_catches_without_on_clauses # blocked on https://github.com/dart-lang/linter/issues/3023 62 | # - avoid_catching_errors # blocked on https://github.com/dart-lang/linter/issues/3023 63 | - avoid_classes_with_only_static_members 64 | - avoid_double_and_int_checks 65 | - avoid_dynamic_calls 66 | - avoid_empty_else 67 | - avoid_equals_and_hash_code_on_mutable_classes 68 | - avoid_escaping_inner_quotes 69 | - avoid_field_initializers_in_const_classes 70 | # - avoid_final_parameters # incompatible with prefer_final_parameters 71 | - avoid_function_literals_in_foreach_calls 72 | - avoid_implementing_value_types 73 | - avoid_init_to_null 74 | - avoid_js_rounded_ints 75 | # - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to 76 | - avoid_null_checks_in_equality_operators 77 | # - avoid_positional_boolean_parameters # would have been nice to enable this but by now there's too many places that break it 78 | - avoid_print 79 | # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) 80 | # - avoid_redundant_argument_values 81 | - avoid_relative_lib_imports 82 | - avoid_renaming_method_parameters 83 | - avoid_return_types_on_setters 84 | # - avoid_returning_null # still violated by some pre-nnbd code that we haven't yet migrated 85 | - avoid_returning_null_for_future 86 | - avoid_returning_null_for_void 87 | # - avoid_returning_this # there are enough valid reasons to return `this` that this lint ends up with too many false positives 88 | - avoid_setters_without_getters 89 | - avoid_shadowing_type_parameters 90 | - avoid_single_cascade_in_expression_statements 91 | - avoid_slow_async_io 92 | - avoid_type_to_string 93 | - avoid_types_as_parameter_names 94 | # - avoid_types_on_closure_parameters # conflicts with always_specify_types 95 | - avoid_unnecessary_containers 96 | - avoid_unused_constructor_parameters 97 | - avoid_void_async 98 | # - avoid_web_libraries_in_flutter # we use web libraries in web-specific code, and our tests prevent us from using them elsewhere 99 | - await_only_futures 100 | - camel_case_extensions 101 | - camel_case_types 102 | - cancel_subscriptions 103 | # - cascade_invocations # doesn't match the typical style of this repo 104 | - cast_nullable_to_non_nullable 105 | # - close_sinks # not reliable enough 106 | # - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142 107 | # - conditional_uri_does_not_exist # not yet tested 108 | # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 109 | - control_flow_in_finally 110 | # - curly_braces_in_flow_control_structures # not required by flutter style 111 | - depend_on_referenced_packages 112 | - deprecated_consistency 113 | # - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib) 114 | - directives_ordering 115 | # - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic 116 | - empty_catches 117 | - empty_constructor_bodies 118 | - empty_statements 119 | - eol_at_end_of_file 120 | - exhaustive_cases 121 | - file_names 122 | - flutter_style_todos 123 | - hash_and_equals 124 | - implementation_imports 125 | # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 126 | - iterable_contains_unrelated_type 127 | # - join_return_with_assignment # not required by flutter style 128 | - leading_newlines_in_multiline_strings 129 | - library_names 130 | - library_prefixes 131 | - library_private_types_in_public_api 132 | # - lines_longer_than_80_chars # not required by flutter style 133 | - list_remove_unrelated_type 134 | # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/linter/issues/453 135 | - missing_whitespace_between_adjacent_strings 136 | - no_adjacent_strings_in_list 137 | - no_default_cases 138 | - no_duplicate_case_values 139 | - no_leading_underscores_for_library_prefixes 140 | - no_leading_underscores_for_local_identifiers 141 | - no_logic_in_create_state 142 | # - no_runtimeType_toString # ok in tests; we enable this only in packages/ 143 | - non_constant_identifier_names 144 | - noop_primitive_operations 145 | - null_check_on_nullable_type_parameter 146 | - null_closures 147 | # - omit_local_variable_types # opposite of always_specify_types 148 | # - one_member_abstracts # too many false positives 149 | - only_throw_errors # this does get disabled in a few places where we have legacy code that uses strings et al 150 | - overridden_fields 151 | - package_api_docs 152 | - package_names 153 | - package_prefixed_library_names 154 | # - parameter_assignments # we do this commonly 155 | - prefer_adjacent_string_concatenation 156 | - prefer_asserts_in_initializer_lists 157 | # - prefer_asserts_with_message # not required by flutter style 158 | - prefer_collection_literals 159 | - prefer_conditional_assignment 160 | # - prefer_const_constructors 161 | - prefer_const_constructors_in_immutables 162 | - prefer_const_declarations 163 | # - prefer_const_literals_to_create_immutables 164 | # - prefer_constructors_over_static_methods # far too many false positives 165 | - prefer_contains 166 | # - prefer_double_quotes # opposite of prefer_single_quotes 167 | - prefer_equal_for_default_values 168 | # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods 169 | - prefer_final_fields 170 | - prefer_final_in_for_each 171 | - prefer_final_locals 172 | # - 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 173 | - prefer_for_elements_to_map_fromIterable 174 | - prefer_foreach 175 | - prefer_function_declarations_over_variables 176 | - prefer_generic_function_type_aliases 177 | - prefer_if_elements_to_conditional_expressions 178 | - prefer_if_null_operators 179 | - prefer_initializing_formals 180 | - prefer_inlined_adds 181 | # - prefer_int_literals # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#use-double-literals-for-double-constants 182 | - prefer_interpolation_to_compose_strings 183 | - prefer_is_empty 184 | - prefer_is_not_empty 185 | - prefer_is_not_operator 186 | - prefer_iterable_whereType 187 | # - prefer_mixin # Has false positives, see https://github.com/dart-lang/linter/issues/3018 188 | # - prefer_null_aware_method_calls # "call()" is confusing to people new to the language since it's not documented anywhere 189 | - prefer_null_aware_operators 190 | # - prefer_relative_imports 191 | - prefer_single_quotes 192 | - prefer_spread_collections 193 | - prefer_typing_uninitialized_variables 194 | - prefer_void_to_null 195 | - provide_deprecation_message 196 | # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml 197 | - recursive_getters 198 | # - require_trailing_commas # blocked on https://github.com/dart-lang/sdk/issues/47441 199 | - secure_pubspec_urls 200 | - sized_box_for_whitespace 201 | # - sized_box_shrink_expand # not yet tested 202 | - slash_for_doc_comments 203 | - sort_child_properties_last 204 | - sort_constructors_first 205 | # - sort_pub_dependencies # prevents separating pinned transitive dependencies 206 | - sort_unnamed_constructors_first 207 | - test_types_in_equals 208 | - throw_in_finally 209 | - tighten_type_of_initializing_formals 210 | # - type_annotate_public_apis # subset of always_specify_types 211 | - type_init_formals 212 | # - unawaited_futures # too many false positives, especially with the way AnimationController works 213 | - unnecessary_await_in_return 214 | - unnecessary_brace_in_string_interps 215 | - unnecessary_const 216 | - unnecessary_constructor_name 217 | # - unnecessary_final # conflicts with prefer_final_locals 218 | - unnecessary_getters_setters 219 | # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 220 | - unnecessary_late 221 | - unnecessary_new 222 | - unnecessary_null_aware_assignments 223 | - unnecessary_null_checks 224 | - unnecessary_null_in_if_null_operators 225 | - unnecessary_nullable_for_final_variable_declarations 226 | - unnecessary_overrides 227 | - unnecessary_parenthesis 228 | # - unnecessary_raw_strings # what's "necessary" is a matter of opinion; consistency across strings can help readability more than this lint 229 | - unnecessary_statements 230 | - unnecessary_string_escapes 231 | - unnecessary_string_interpolations 232 | - unnecessary_this 233 | - unrelated_type_equality_checks 234 | - unsafe_html 235 | - use_build_context_synchronously 236 | # - use_decorated_box # not yet tested 237 | - use_full_hex_values_for_flutter_colors 238 | - use_function_type_syntax_for_parameters 239 | - use_if_null_to_convert_nulls_to_bools 240 | - use_is_even_rather_than_modulo 241 | - use_key_in_widget_constructors 242 | - use_late_for_private_fields_and_variables 243 | - use_named_constants 244 | - use_raw_strings 245 | - use_rethrow_when_possible 246 | - use_setters_to_change_properties 247 | # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 248 | - use_test_throws_matchers 249 | # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review 250 | - valid_regexps 251 | - void_checks 252 | -------------------------------------------------------------------------------- /android/src/main/java/io/github/v7lin/weibo_kit/WeiboKitPlugin.java: -------------------------------------------------------------------------------- 1 | package io.github.v7lin.weibo_kit; 2 | 3 | import android.content.ComponentName; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.pm.PackageManager; 7 | import android.content.pm.ProviderInfo; 8 | import android.net.Uri; 9 | import android.os.Build; 10 | 11 | import androidx.annotation.NonNull; 12 | import androidx.annotation.Nullable; 13 | 14 | import com.sina.weibo.sdk.api.ImageObject; 15 | import com.sina.weibo.sdk.api.MultiImageObject; 16 | import com.sina.weibo.sdk.api.TextObject; 17 | import com.sina.weibo.sdk.api.VideoSourceObject; 18 | import com.sina.weibo.sdk.api.WebpageObject; 19 | import com.sina.weibo.sdk.api.WeiboMultiMessage; 20 | import com.sina.weibo.sdk.auth.AuthInfo; 21 | import com.sina.weibo.sdk.auth.Oauth2AccessToken; 22 | import com.sina.weibo.sdk.auth.WbAuthListener; 23 | import com.sina.weibo.sdk.common.UiError; 24 | import com.sina.weibo.sdk.content.FileProvider; 25 | import com.sina.weibo.sdk.openapi.IWBAPI; 26 | import com.sina.weibo.sdk.openapi.WBAPIFactory; 27 | import com.sina.weibo.sdk.share.WbShareCallback; 28 | 29 | import java.io.File; 30 | import java.util.ArrayList; 31 | import java.util.Arrays; 32 | import java.util.HashMap; 33 | import java.util.List; 34 | import java.util.Map; 35 | import java.util.UUID; 36 | 37 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 38 | import io.flutter.embedding.engine.plugins.activity.ActivityAware; 39 | import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; 40 | import io.flutter.plugin.common.MethodCall; 41 | import io.flutter.plugin.common.MethodChannel; 42 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 43 | import io.flutter.plugin.common.MethodChannel.Result; 44 | import io.flutter.plugin.common.PluginRegistry; 45 | 46 | /** 47 | * WeiboKitPlugin 48 | */ 49 | public class WeiboKitPlugin implements FlutterPlugin, ActivityAware, PluginRegistry.ActivityResultListener, MethodCallHandler { 50 | private static class WeiboErrorCode { 51 | public static final int SUCCESS = 0;//成功 52 | public static final int USERCANCEL = -1;//用户取消发送 53 | public static final int SENT_FAIL = -2;//发送失败 54 | public static final int AUTH_DENY = -3;//授权失败 55 | public static final int USERCANCEL_INSTALL = -4;//用户取消安装微博客户端 56 | public static final int PAY_FAIL = -5;//支付失败 57 | public static final int SHARE_IN_SDK_FAILED = -8;//分享失败 详情见response UserInfo 58 | public static final int UNSUPPORT = -99;//不支持的请求 59 | public static final int UNKNOWN = -100; 60 | } 61 | 62 | /// The MethodChannel that will the communication between Flutter and native Android 63 | /// 64 | /// This local reference serves to register the plugin with the Flutter Engine and unregister it 65 | /// when the Flutter Engine is detached from the Activity 66 | private MethodChannel channel; 67 | private Context applicationContext; 68 | private ActivityPluginBinding activityPluginBinding; 69 | 70 | private IWBAPI iwbapi; 71 | 72 | // --- FlutterPlugin 73 | 74 | @Override 75 | public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { 76 | channel = new MethodChannel(binding.getBinaryMessenger(), "v7lin.github.io/weibo_kit"); 77 | channel.setMethodCallHandler(this); 78 | applicationContext = binding.getApplicationContext(); 79 | } 80 | 81 | @Override 82 | public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { 83 | channel.setMethodCallHandler(null); 84 | channel = null; 85 | applicationContext = null; 86 | } 87 | 88 | // --- ActivityAware 89 | 90 | @Override 91 | public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { 92 | activityPluginBinding = binding; 93 | activityPluginBinding.addActivityResultListener(this); 94 | } 95 | 96 | @Override 97 | public void onDetachedFromActivityForConfigChanges() { 98 | onDetachedFromActivity(); 99 | } 100 | 101 | @Override 102 | public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { 103 | onAttachedToActivity(binding); 104 | } 105 | 106 | @Override 107 | public void onDetachedFromActivity() { 108 | activityPluginBinding.removeActivityResultListener(this); 109 | activityPluginBinding = null; 110 | } 111 | 112 | // --- ActivityResultListener 113 | 114 | @Override 115 | public boolean onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { 116 | switch (requestCode) { 117 | case 32973: 118 | if (iwbapi != null) { 119 | iwbapi.authorizeCallback(activityPluginBinding.getActivity(), requestCode, resultCode, data); 120 | } 121 | return true; 122 | case 10001: 123 | if (iwbapi != null) { 124 | iwbapi.doResultIntent(data, new WbShareCallback() { 125 | @Override 126 | public void onComplete() { 127 | final Map map = new HashMap<>(); 128 | map.put("errorCode", WeiboErrorCode.SUCCESS); 129 | if (channel != null) { 130 | channel.invokeMethod("onShareMsgResp", map); 131 | } 132 | } 133 | 134 | @Override 135 | public void onError(UiError uiError) { 136 | final Map map = new HashMap<>(); 137 | map.put("errorCode", WeiboErrorCode.SHARE_IN_SDK_FAILED); 138 | if (channel != null) { 139 | channel.invokeMethod("onShareMsgResp", map); 140 | } 141 | } 142 | 143 | @Override 144 | public void onCancel() { 145 | final Map map = new HashMap<>(); 146 | map.put("errorCode", WeiboErrorCode.USERCANCEL); 147 | if (channel != null) { 148 | channel.invokeMethod("onShareMsgResp", map); 149 | } 150 | } 151 | }); 152 | } 153 | return true; 154 | } 155 | return false; 156 | } 157 | 158 | // --- MethodCallHandler 159 | 160 | @Override 161 | public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { 162 | if ("registerApp".equals(call.method)) { 163 | final String appKey = call.argument("appKey"); 164 | final String scope = call.argument("scope"); 165 | final String redirectUrl = call.argument("redirectUrl"); 166 | iwbapi = WBAPIFactory.createWBAPI(activityPluginBinding.getActivity()); 167 | iwbapi.registerApp(applicationContext, new AuthInfo(applicationContext, appKey, redirectUrl, scope)); 168 | result.success(null); 169 | } else if ("isInstalled".equals(call.method)) { 170 | if (iwbapi != null) { 171 | result.success(iwbapi.isWBAppInstalled()); 172 | } else { 173 | result.error("FAILED", "请先调用registerApp", null); 174 | } 175 | } else if ("isSupportMultipleImage".equals(call.method)) { 176 | if (iwbapi != null) { 177 | result.success(iwbapi.isWBAppSupportMultipleImage()); 178 | } else { 179 | result.error("FAILED", "请先调用registerApp", null); 180 | } 181 | } else if ("auth".equals(call.method)) { 182 | if (iwbapi != null) { 183 | handleAuthCall(call, result); 184 | } else { 185 | result.error("FAILED", "请先调用registerApp", null); 186 | } 187 | } else if (Arrays.asList("shareText", "shareImage", "shareMultiImage", "shareVideo", "shareWebpage").contains(call.method)) { 188 | if (iwbapi != null) { 189 | handleShareCall(call, result); 190 | } else { 191 | result.error("FAILED", "请先调用registerApp", null); 192 | } 193 | } else { 194 | result.notImplemented(); 195 | } 196 | } 197 | 198 | private void handleAuthCall(@NonNull MethodCall call, @NonNull Result result) { 199 | iwbapi.authorize(activityPluginBinding.getActivity(), new WbAuthListener() { 200 | @Override 201 | public void onComplete(Oauth2AccessToken token) { 202 | final Map map = new HashMap<>(); 203 | if (token.isSessionValid()) { 204 | map.put("errorCode", WeiboErrorCode.SUCCESS); 205 | map.put("userId", token.getUid()); 206 | map.put("accessToken", token.getAccessToken()); 207 | map.put("refreshToken", token.getRefreshToken()); 208 | map.put("expiresTime", token.getExpiresTime()); 209 | } else { 210 | map.put("errorCode", WeiboErrorCode.UNKNOWN); 211 | } 212 | if (channel != null) { 213 | channel.invokeMethod("onAuthResp", map); 214 | } 215 | } 216 | 217 | @Override 218 | public void onError(UiError uiError) { 219 | final Map map = new HashMap<>(); 220 | map.put("errorCode", WeiboErrorCode.UNKNOWN); 221 | if (channel != null) { 222 | channel.invokeMethod("onAuthResp", map); 223 | } 224 | } 225 | 226 | @Override 227 | public void onCancel() { 228 | final Map map = new HashMap<>(); 229 | map.put("errorCode", WeiboErrorCode.USERCANCEL); 230 | if (channel != null) { 231 | channel.invokeMethod("onAuthResp", map); 232 | } 233 | } 234 | }); 235 | result.success(null); 236 | } 237 | 238 | private void handleShareCall(@NonNull MethodCall call, @NonNull Result result) { 239 | final WeiboMultiMessage message = new WeiboMultiMessage(); 240 | if ("shareText".equals(call.method)) { 241 | final TextObject object = new TextObject(); 242 | object.text = call.argument("text");// 1024 243 | message.textObject = object; 244 | } else if ("shareImage".equals(call.method)) { 245 | if (call.hasArgument("text")) { 246 | final TextObject object = new TextObject(); 247 | object.text = call.argument("text");// 1024 248 | message.textObject = object; 249 | } 250 | final ImageObject object = new ImageObject(); 251 | if (call.hasArgument("imageData")) { 252 | object.imageData = call.argument("imageData");// 2 * 1024 * 1024 253 | } else if (call.hasArgument("imageUri")) { 254 | final String imageUri = call.argument("imageUri"); 255 | object.imagePath = Uri.parse(imageUri).getPath();// 512 - 10 * 1024 * 1024 256 | } 257 | message.imageObject = object; 258 | } else if ("shareMultiImage".equals(call.method)) { 259 | if (call.hasArgument("text")) { 260 | final TextObject object = new TextObject(); 261 | object.text = call.argument("text");// 1024 262 | message.textObject = object; 263 | } 264 | final MultiImageObject object = new MultiImageObject(); 265 | final List imageUris = call.argument("imageUris"); 266 | final ArrayList images = new ArrayList<>(); 267 | for (String imageUri : imageUris) { 268 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 269 | try { 270 | final ProviderInfo providerInfo = applicationContext.getPackageManager().getProviderInfo(new ComponentName(applicationContext, FileProvider.class), PackageManager.MATCH_DEFAULT_ONLY); 271 | final Uri shareFileUri = FileProvider.getUriForFile(applicationContext, providerInfo.authority, new File(Uri.parse(imageUri).getPath())); 272 | applicationContext.grantUriPermission("com.sina.weibo", shareFileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); 273 | images.add(shareFileUri); 274 | } catch (PackageManager.NameNotFoundException e) { 275 | images.add(Uri.parse(imageUri)); 276 | } 277 | } else { 278 | images.add(Uri.parse(imageUri)); 279 | } 280 | } 281 | object.imageList = images; 282 | message.multiImageObject = object; 283 | } else if ("shareVideo".equals(call.method)) { 284 | if (call.hasArgument("text")) { 285 | final TextObject object = new TextObject(); 286 | object.text = call.argument("text");// 1024 287 | message.textObject = object; 288 | } 289 | final VideoSourceObject object = new VideoSourceObject(); 290 | final String videoUri = call.argument("videoUri"); 291 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 292 | try { 293 | final ProviderInfo providerInfo = applicationContext.getPackageManager().getProviderInfo(new ComponentName(applicationContext, FileProvider.class), PackageManager.MATCH_DEFAULT_ONLY); 294 | final Uri shareFileUri = FileProvider.getUriForFile(applicationContext, providerInfo.authority, new File(Uri.parse(videoUri).getPath())); 295 | applicationContext.grantUriPermission("com.sina.weibo", shareFileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); 296 | object.videoPath = shareFileUri; 297 | } catch (PackageManager.NameNotFoundException e) { 298 | object.videoPath = Uri.parse(videoUri); 299 | } 300 | } else { 301 | object.videoPath = Uri.parse(videoUri); 302 | } 303 | message.videoSourceObject = object; 304 | } else if ("shareWebpage".equals(call.method)) { 305 | final WebpageObject object = new WebpageObject(); 306 | object.identify = UUID.randomUUID().toString(); 307 | object.title = call.argument("title");// 512 308 | object.description = call.argument("description");// 1024 309 | object.thumbData = call.argument("thumbData");// 32 * 1024 310 | object.defaultText = call.argument("description"); 311 | object.actionUrl = call.argument("webpageUrl");// 512 312 | 313 | message.mediaObject = object; 314 | } 315 | 316 | final boolean clientOnly = call.argument("clientOnly"); 317 | 318 | iwbapi.shareMessage(activityPluginBinding.getActivity(), message, clientOnly); 319 | result.success(null); 320 | } 321 | } 322 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _fe_analyzer_shared: 5 | dependency: transitive 6 | description: 7 | name: _fe_analyzer_shared 8 | url: "https://pub.flutter-io.cn" 9 | source: hosted 10 | version: "40.0.0" 11 | analyzer: 12 | dependency: transitive 13 | description: 14 | name: analyzer 15 | url: "https://pub.flutter-io.cn" 16 | source: hosted 17 | version: "4.1.0" 18 | archive: 19 | dependency: transitive 20 | description: 21 | name: archive 22 | url: "https://pub.flutter-io.cn" 23 | source: hosted 24 | version: "3.3.0" 25 | args: 26 | dependency: transitive 27 | description: 28 | name: args 29 | url: "https://pub.flutter-io.cn" 30 | source: hosted 31 | version: "2.3.1" 32 | async: 33 | dependency: transitive 34 | description: 35 | name: async 36 | url: "https://pub.flutter-io.cn" 37 | source: hosted 38 | version: "2.8.2" 39 | boolean_selector: 40 | dependency: transitive 41 | description: 42 | name: boolean_selector 43 | url: "https://pub.flutter-io.cn" 44 | source: hosted 45 | version: "2.1.0" 46 | build: 47 | dependency: transitive 48 | description: 49 | name: build 50 | url: "https://pub.flutter-io.cn" 51 | source: hosted 52 | version: "2.3.0" 53 | build_config: 54 | dependency: transitive 55 | description: 56 | name: build_config 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "1.0.0" 60 | build_daemon: 61 | dependency: transitive 62 | description: 63 | name: build_daemon 64 | url: "https://pub.flutter-io.cn" 65 | source: hosted 66 | version: "3.1.0" 67 | build_resolvers: 68 | dependency: transitive 69 | description: 70 | name: build_resolvers 71 | url: "https://pub.flutter-io.cn" 72 | source: hosted 73 | version: "2.0.8" 74 | build_runner: 75 | dependency: "direct dev" 76 | description: 77 | name: build_runner 78 | url: "https://pub.flutter-io.cn" 79 | source: hosted 80 | version: "2.1.11" 81 | build_runner_core: 82 | dependency: transitive 83 | description: 84 | name: build_runner_core 85 | url: "https://pub.flutter-io.cn" 86 | source: hosted 87 | version: "7.2.3" 88 | built_collection: 89 | dependency: transitive 90 | description: 91 | name: built_collection 92 | url: "https://pub.flutter-io.cn" 93 | source: hosted 94 | version: "5.1.1" 95 | built_value: 96 | dependency: transitive 97 | description: 98 | name: built_value 99 | url: "https://pub.flutter-io.cn" 100 | source: hosted 101 | version: "8.3.0" 102 | characters: 103 | dependency: transitive 104 | description: 105 | name: characters 106 | url: "https://pub.flutter-io.cn" 107 | source: hosted 108 | version: "1.2.0" 109 | charcode: 110 | dependency: transitive 111 | description: 112 | name: charcode 113 | url: "https://pub.flutter-io.cn" 114 | source: hosted 115 | version: "1.3.1" 116 | checked_yaml: 117 | dependency: transitive 118 | description: 119 | name: checked_yaml 120 | url: "https://pub.flutter-io.cn" 121 | source: hosted 122 | version: "2.0.1" 123 | clock: 124 | dependency: transitive 125 | description: 126 | name: clock 127 | url: "https://pub.flutter-io.cn" 128 | source: hosted 129 | version: "1.1.0" 130 | code_builder: 131 | dependency: transitive 132 | description: 133 | name: code_builder 134 | url: "https://pub.flutter-io.cn" 135 | source: hosted 136 | version: "4.1.0" 137 | collection: 138 | dependency: transitive 139 | description: 140 | name: collection 141 | url: "https://pub.flutter-io.cn" 142 | source: hosted 143 | version: "1.16.0" 144 | convert: 145 | dependency: transitive 146 | description: 147 | name: convert 148 | url: "https://pub.flutter-io.cn" 149 | source: hosted 150 | version: "3.0.1" 151 | crypto: 152 | dependency: transitive 153 | description: 154 | name: crypto 155 | url: "https://pub.flutter-io.cn" 156 | source: hosted 157 | version: "3.0.2" 158 | cupertino_icons: 159 | dependency: "direct main" 160 | description: 161 | name: cupertino_icons 162 | url: "https://pub.flutter-io.cn" 163 | source: hosted 164 | version: "1.0.4" 165 | dart_style: 166 | dependency: transitive 167 | description: 168 | name: dart_style 169 | url: "https://pub.flutter-io.cn" 170 | source: hosted 171 | version: "2.2.3" 172 | fake_async: 173 | dependency: transitive 174 | description: 175 | name: fake_async 176 | url: "https://pub.flutter-io.cn" 177 | source: hosted 178 | version: "1.3.0" 179 | ffi: 180 | dependency: transitive 181 | description: 182 | name: ffi 183 | url: "https://pub.flutter-io.cn" 184 | source: hosted 185 | version: "1.2.1" 186 | file: 187 | dependency: transitive 188 | description: 189 | name: file 190 | url: "https://pub.flutter-io.cn" 191 | source: hosted 192 | version: "6.1.2" 193 | fixnum: 194 | dependency: transitive 195 | description: 196 | name: fixnum 197 | url: "https://pub.flutter-io.cn" 198 | source: hosted 199 | version: "1.0.1" 200 | flutter: 201 | dependency: "direct main" 202 | description: flutter 203 | source: sdk 204 | version: "0.0.0" 205 | flutter_cache_manager: 206 | dependency: "direct main" 207 | description: 208 | name: flutter_cache_manager 209 | url: "https://pub.flutter-io.cn" 210 | source: hosted 211 | version: "3.3.0" 212 | flutter_lints: 213 | dependency: "direct dev" 214 | description: 215 | name: flutter_lints 216 | url: "https://pub.flutter-io.cn" 217 | source: hosted 218 | version: "2.0.1" 219 | flutter_test: 220 | dependency: "direct dev" 221 | description: flutter 222 | source: sdk 223 | version: "0.0.0" 224 | frontend_server_client: 225 | dependency: transitive 226 | description: 227 | name: frontend_server_client 228 | url: "https://pub.flutter-io.cn" 229 | source: hosted 230 | version: "2.1.3" 231 | glob: 232 | dependency: transitive 233 | description: 234 | name: glob 235 | url: "https://pub.flutter-io.cn" 236 | source: hosted 237 | version: "2.0.2" 238 | graphs: 239 | dependency: transitive 240 | description: 241 | name: graphs 242 | url: "https://pub.flutter-io.cn" 243 | source: hosted 244 | version: "2.1.0" 245 | http: 246 | dependency: transitive 247 | description: 248 | name: http 249 | url: "https://pub.flutter-io.cn" 250 | source: hosted 251 | version: "0.13.4" 252 | http_multi_server: 253 | dependency: transitive 254 | description: 255 | name: http_multi_server 256 | url: "https://pub.flutter-io.cn" 257 | source: hosted 258 | version: "3.2.0" 259 | http_parser: 260 | dependency: transitive 261 | description: 262 | name: http_parser 263 | url: "https://pub.flutter-io.cn" 264 | source: hosted 265 | version: "4.0.1" 266 | image: 267 | dependency: "direct main" 268 | description: 269 | name: image 270 | url: "https://pub.flutter-io.cn" 271 | source: hosted 272 | version: "3.2.0" 273 | io: 274 | dependency: transitive 275 | description: 276 | name: io 277 | url: "https://pub.flutter-io.cn" 278 | source: hosted 279 | version: "1.0.3" 280 | js: 281 | dependency: transitive 282 | description: 283 | name: js 284 | url: "https://pub.flutter-io.cn" 285 | source: hosted 286 | version: "0.6.4" 287 | json_annotation: 288 | dependency: "direct main" 289 | description: 290 | name: json_annotation 291 | url: "https://pub.flutter-io.cn" 292 | source: hosted 293 | version: "4.5.0" 294 | json_serializable: 295 | dependency: "direct dev" 296 | description: 297 | name: json_serializable 298 | url: "https://pub.flutter-io.cn" 299 | source: hosted 300 | version: "6.2.0" 301 | lints: 302 | dependency: transitive 303 | description: 304 | name: lints 305 | url: "https://pub.flutter-io.cn" 306 | source: hosted 307 | version: "2.0.0" 308 | logging: 309 | dependency: transitive 310 | description: 311 | name: logging 312 | url: "https://pub.flutter-io.cn" 313 | source: hosted 314 | version: "1.0.2" 315 | matcher: 316 | dependency: transitive 317 | description: 318 | name: matcher 319 | url: "https://pub.flutter-io.cn" 320 | source: hosted 321 | version: "0.12.11" 322 | material_color_utilities: 323 | dependency: transitive 324 | description: 325 | name: material_color_utilities 326 | url: "https://pub.flutter-io.cn" 327 | source: hosted 328 | version: "0.1.4" 329 | meta: 330 | dependency: transitive 331 | description: 332 | name: meta 333 | url: "https://pub.flutter-io.cn" 334 | source: hosted 335 | version: "1.7.0" 336 | mime: 337 | dependency: transitive 338 | description: 339 | name: mime 340 | url: "https://pub.flutter-io.cn" 341 | source: hosted 342 | version: "1.0.2" 343 | package_config: 344 | dependency: transitive 345 | description: 346 | name: package_config 347 | url: "https://pub.flutter-io.cn" 348 | source: hosted 349 | version: "2.0.2" 350 | path: 351 | dependency: "direct main" 352 | description: 353 | name: path 354 | url: "https://pub.flutter-io.cn" 355 | source: hosted 356 | version: "1.8.1" 357 | path_provider: 358 | dependency: "direct main" 359 | description: 360 | name: path_provider 361 | url: "https://pub.flutter-io.cn" 362 | source: hosted 363 | version: "2.0.10" 364 | path_provider_android: 365 | dependency: transitive 366 | description: 367 | name: path_provider_android 368 | url: "https://pub.flutter-io.cn" 369 | source: hosted 370 | version: "2.0.14" 371 | path_provider_ios: 372 | dependency: transitive 373 | description: 374 | name: path_provider_ios 375 | url: "https://pub.flutter-io.cn" 376 | source: hosted 377 | version: "2.0.9" 378 | path_provider_linux: 379 | dependency: transitive 380 | description: 381 | name: path_provider_linux 382 | url: "https://pub.flutter-io.cn" 383 | source: hosted 384 | version: "2.1.6" 385 | path_provider_macos: 386 | dependency: transitive 387 | description: 388 | name: path_provider_macos 389 | url: "https://pub.flutter-io.cn" 390 | source: hosted 391 | version: "2.0.6" 392 | path_provider_platform_interface: 393 | dependency: transitive 394 | description: 395 | name: path_provider_platform_interface 396 | url: "https://pub.flutter-io.cn" 397 | source: hosted 398 | version: "2.0.4" 399 | path_provider_windows: 400 | dependency: transitive 401 | description: 402 | name: path_provider_windows 403 | url: "https://pub.flutter-io.cn" 404 | source: hosted 405 | version: "2.0.6" 406 | pedantic: 407 | dependency: transitive 408 | description: 409 | name: pedantic 410 | url: "https://pub.flutter-io.cn" 411 | source: hosted 412 | version: "1.11.1" 413 | petitparser: 414 | dependency: transitive 415 | description: 416 | name: petitparser 417 | url: "https://pub.flutter-io.cn" 418 | source: hosted 419 | version: "5.0.0" 420 | platform: 421 | dependency: transitive 422 | description: 423 | name: platform 424 | url: "https://pub.flutter-io.cn" 425 | source: hosted 426 | version: "3.1.0" 427 | plugin_platform_interface: 428 | dependency: transitive 429 | description: 430 | name: plugin_platform_interface 431 | url: "https://pub.flutter-io.cn" 432 | source: hosted 433 | version: "2.1.2" 434 | pool: 435 | dependency: transitive 436 | description: 437 | name: pool 438 | url: "https://pub.flutter-io.cn" 439 | source: hosted 440 | version: "1.5.0" 441 | process: 442 | dependency: transitive 443 | description: 444 | name: process 445 | url: "https://pub.flutter-io.cn" 446 | source: hosted 447 | version: "4.2.4" 448 | pub_semver: 449 | dependency: transitive 450 | description: 451 | name: pub_semver 452 | url: "https://pub.flutter-io.cn" 453 | source: hosted 454 | version: "2.1.1" 455 | pubspec_parse: 456 | dependency: transitive 457 | description: 458 | name: pubspec_parse 459 | url: "https://pub.flutter-io.cn" 460 | source: hosted 461 | version: "1.2.0" 462 | rxdart: 463 | dependency: transitive 464 | description: 465 | name: rxdart 466 | url: "https://pub.flutter-io.cn" 467 | source: hosted 468 | version: "0.27.3" 469 | shelf: 470 | dependency: transitive 471 | description: 472 | name: shelf 473 | url: "https://pub.flutter-io.cn" 474 | source: hosted 475 | version: "1.3.0" 476 | shelf_web_socket: 477 | dependency: transitive 478 | description: 479 | name: shelf_web_socket 480 | url: "https://pub.flutter-io.cn" 481 | source: hosted 482 | version: "1.0.1" 483 | sky_engine: 484 | dependency: transitive 485 | description: flutter 486 | source: sdk 487 | version: "0.0.99" 488 | source_gen: 489 | dependency: transitive 490 | description: 491 | name: source_gen 492 | url: "https://pub.flutter-io.cn" 493 | source: hosted 494 | version: "1.2.2" 495 | source_helper: 496 | dependency: transitive 497 | description: 498 | name: source_helper 499 | url: "https://pub.flutter-io.cn" 500 | source: hosted 501 | version: "1.3.2" 502 | source_span: 503 | dependency: transitive 504 | description: 505 | name: source_span 506 | url: "https://pub.flutter-io.cn" 507 | source: hosted 508 | version: "1.8.2" 509 | sqflite: 510 | dependency: transitive 511 | description: 512 | name: sqflite 513 | url: "https://pub.flutter-io.cn" 514 | source: hosted 515 | version: "2.0.2+1" 516 | sqflite_common: 517 | dependency: transitive 518 | description: 519 | name: sqflite_common 520 | url: "https://pub.flutter-io.cn" 521 | source: hosted 522 | version: "2.2.1+1" 523 | stack_trace: 524 | dependency: transitive 525 | description: 526 | name: stack_trace 527 | url: "https://pub.flutter-io.cn" 528 | source: hosted 529 | version: "1.10.0" 530 | stream_channel: 531 | dependency: transitive 532 | description: 533 | name: stream_channel 534 | url: "https://pub.flutter-io.cn" 535 | source: hosted 536 | version: "2.1.0" 537 | stream_transform: 538 | dependency: transitive 539 | description: 540 | name: stream_transform 541 | url: "https://pub.flutter-io.cn" 542 | source: hosted 543 | version: "2.0.0" 544 | string_scanner: 545 | dependency: transitive 546 | description: 547 | name: string_scanner 548 | url: "https://pub.flutter-io.cn" 549 | source: hosted 550 | version: "1.1.0" 551 | synchronized: 552 | dependency: transitive 553 | description: 554 | name: synchronized 555 | url: "https://pub.flutter-io.cn" 556 | source: hosted 557 | version: "3.0.0+2" 558 | term_glyph: 559 | dependency: transitive 560 | description: 561 | name: term_glyph 562 | url: "https://pub.flutter-io.cn" 563 | source: hosted 564 | version: "1.2.0" 565 | test_api: 566 | dependency: transitive 567 | description: 568 | name: test_api 569 | url: "https://pub.flutter-io.cn" 570 | source: hosted 571 | version: "0.4.9" 572 | timing: 573 | dependency: transitive 574 | description: 575 | name: timing 576 | url: "https://pub.flutter-io.cn" 577 | source: hosted 578 | version: "1.0.0" 579 | typed_data: 580 | dependency: transitive 581 | description: 582 | name: typed_data 583 | url: "https://pub.flutter-io.cn" 584 | source: hosted 585 | version: "1.3.1" 586 | uuid: 587 | dependency: transitive 588 | description: 589 | name: uuid 590 | url: "https://pub.flutter-io.cn" 591 | source: hosted 592 | version: "3.0.6" 593 | vector_math: 594 | dependency: transitive 595 | description: 596 | name: vector_math 597 | url: "https://pub.flutter-io.cn" 598 | source: hosted 599 | version: "2.1.2" 600 | watcher: 601 | dependency: transitive 602 | description: 603 | name: watcher 604 | url: "https://pub.flutter-io.cn" 605 | source: hosted 606 | version: "1.0.1" 607 | web_socket_channel: 608 | dependency: transitive 609 | description: 610 | name: web_socket_channel 611 | url: "https://pub.flutter-io.cn" 612 | source: hosted 613 | version: "2.2.0" 614 | weibo_kit: 615 | dependency: "direct main" 616 | description: 617 | path: ".." 618 | relative: true 619 | source: path 620 | version: "4.0.0" 621 | win32: 622 | dependency: transitive 623 | description: 624 | name: win32 625 | url: "https://pub.flutter-io.cn" 626 | source: hosted 627 | version: "2.6.1" 628 | xdg_directories: 629 | dependency: transitive 630 | description: 631 | name: xdg_directories 632 | url: "https://pub.flutter-io.cn" 633 | source: hosted 634 | version: "0.2.0+1" 635 | xml: 636 | dependency: transitive 637 | description: 638 | name: xml 639 | url: "https://pub.flutter-io.cn" 640 | source: hosted 641 | version: "6.0.1" 642 | yaml: 643 | dependency: transitive 644 | description: 645 | name: yaml 646 | url: "https://pub.flutter-io.cn" 647 | source: hosted 648 | version: "3.1.1" 649 | sdks: 650 | dart: ">=2.17.0 <3.0.0" 651 | flutter: ">=2.8.1" 652 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 13 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | 9D6A641CC2AA3D1DAB1CA737 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D17CA4B716FF2615EC5592DD /* libPods-Runner.a */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXCopyFilesBuildPhase section */ 21 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 22 | isa = PBXCopyFilesBuildPhase; 23 | buildActionMask = 2147483647; 24 | dstPath = ""; 25 | dstSubfolderSpec = 10; 26 | files = ( 27 | ); 28 | name = "Embed Frameworks"; 29 | runOnlyForDeploymentPostprocessing = 0; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 08F4E8DC6CED25389BD315E9 /* 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 = ""; }; 35 | 148E72EBAA782EE70454F3DD /* 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 = ""; }; 36 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 37 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 38 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 39 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 40 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 41 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 42 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 43 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 44 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 47 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 48 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 49 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | AD1CFD40D1E8023F905A8C4C /* 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 = ""; }; 51 | D17CA4B716FF2615EC5592DD /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 9D6A641CC2AA3D1DAB1CA737 /* libPods-Runner.a in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | 02EA110EDFCF98FC06871CF0 /* Frameworks */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | D17CA4B716FF2615EC5592DD /* libPods-Runner.a */, 70 | ); 71 | name = Frameworks; 72 | sourceTree = ""; 73 | }; 74 | 9740EEB11CF90186004384FC /* Flutter */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 78 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 79 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 80 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 81 | ); 82 | name = Flutter; 83 | sourceTree = ""; 84 | }; 85 | 97C146E51CF9000F007C117D = { 86 | isa = PBXGroup; 87 | children = ( 88 | 9740EEB11CF90186004384FC /* Flutter */, 89 | 97C146F01CF9000F007C117D /* Runner */, 90 | 97C146EF1CF9000F007C117D /* Products */, 91 | D4D0DC52653A5DE40E2C9908 /* Pods */, 92 | 02EA110EDFCF98FC06871CF0 /* Frameworks */, 93 | ); 94 | sourceTree = ""; 95 | }; 96 | 97C146EF1CF9000F007C117D /* Products */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 97C146EE1CF9000F007C117D /* Runner.app */, 100 | ); 101 | name = Products; 102 | sourceTree = ""; 103 | }; 104 | 97C146F01CF9000F007C117D /* Runner */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 108 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 109 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 110 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 111 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 112 | 97C147021CF9000F007C117D /* Info.plist */, 113 | 97C146F11CF9000F007C117D /* Supporting Files */, 114 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 115 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 116 | ); 117 | path = Runner; 118 | sourceTree = ""; 119 | }; 120 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 97C146F21CF9000F007C117D /* main.m */, 124 | ); 125 | name = "Supporting Files"; 126 | sourceTree = ""; 127 | }; 128 | D4D0DC52653A5DE40E2C9908 /* Pods */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | AD1CFD40D1E8023F905A8C4C /* Pods-Runner.debug.xcconfig */, 132 | 08F4E8DC6CED25389BD315E9 /* Pods-Runner.release.xcconfig */, 133 | 148E72EBAA782EE70454F3DD /* Pods-Runner.profile.xcconfig */, 134 | ); 135 | name = Pods; 136 | path = Pods; 137 | sourceTree = ""; 138 | }; 139 | /* End PBXGroup section */ 140 | 141 | /* Begin PBXNativeTarget section */ 142 | 97C146ED1CF9000F007C117D /* Runner */ = { 143 | isa = PBXNativeTarget; 144 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 145 | buildPhases = ( 146 | AD4B13FBAB7E2A550C0DD869 /* [CP] Check Pods Manifest.lock */, 147 | 9740EEB61CF901F6004384FC /* Run Script */, 148 | 97C146EA1CF9000F007C117D /* Sources */, 149 | 97C146EB1CF9000F007C117D /* Frameworks */, 150 | 97C146EC1CF9000F007C117D /* Resources */, 151 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 152 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 153 | 64BE94D785EB23A0C92F017D /* [CP] Copy Pods Resources */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | ); 159 | name = Runner; 160 | productName = Runner; 161 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 162 | productType = "com.apple.product-type.application"; 163 | }; 164 | /* End PBXNativeTarget section */ 165 | 166 | /* Begin PBXProject section */ 167 | 97C146E61CF9000F007C117D /* Project object */ = { 168 | isa = PBXProject; 169 | attributes = { 170 | LastUpgradeCheck = 1300; 171 | ORGANIZATIONNAME = ""; 172 | TargetAttributes = { 173 | 97C146ED1CF9000F007C117D = { 174 | CreatedOnToolsVersion = 7.3.1; 175 | }; 176 | }; 177 | }; 178 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 179 | compatibilityVersion = "Xcode 9.3"; 180 | developmentRegion = en; 181 | hasScannedForEncodings = 0; 182 | knownRegions = ( 183 | en, 184 | Base, 185 | ); 186 | mainGroup = 97C146E51CF9000F007C117D; 187 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 188 | projectDirPath = ""; 189 | projectRoot = ""; 190 | targets = ( 191 | 97C146ED1CF9000F007C117D /* Runner */, 192 | ); 193 | }; 194 | /* End PBXProject section */ 195 | 196 | /* Begin PBXResourcesBuildPhase section */ 197 | 97C146EC1CF9000F007C117D /* Resources */ = { 198 | isa = PBXResourcesBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 202 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 203 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 204 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 205 | ); 206 | runOnlyForDeploymentPostprocessing = 0; 207 | }; 208 | /* End PBXResourcesBuildPhase section */ 209 | 210 | /* Begin PBXShellScriptBuildPhase section */ 211 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 212 | isa = PBXShellScriptBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | ); 216 | inputPaths = ( 217 | ); 218 | name = "Thin Binary"; 219 | outputPaths = ( 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | shellPath = /bin/sh; 223 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 224 | }; 225 | 64BE94D785EB23A0C92F017D /* [CP] Copy Pods Resources */ = { 226 | isa = PBXShellScriptBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | ); 230 | inputFileListPaths = ( 231 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", 232 | ); 233 | name = "[CP] Copy Pods Resources"; 234 | outputFileListPaths = ( 235 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | shellPath = /bin/sh; 239 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; 240 | showEnvVarsInLog = 0; 241 | }; 242 | 9740EEB61CF901F6004384FC /* Run Script */ = { 243 | isa = PBXShellScriptBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | ); 247 | inputPaths = ( 248 | ); 249 | name = "Run Script"; 250 | outputPaths = ( 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | shellPath = /bin/sh; 254 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 255 | }; 256 | AD4B13FBAB7E2A550C0DD869 /* [CP] Check Pods Manifest.lock */ = { 257 | isa = PBXShellScriptBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | ); 261 | inputFileListPaths = ( 262 | ); 263 | inputPaths = ( 264 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 265 | "${PODS_ROOT}/Manifest.lock", 266 | ); 267 | name = "[CP] Check Pods Manifest.lock"; 268 | outputFileListPaths = ( 269 | ); 270 | outputPaths = ( 271 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | shellPath = /bin/sh; 275 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 276 | showEnvVarsInLog = 0; 277 | }; 278 | /* End PBXShellScriptBuildPhase section */ 279 | 280 | /* Begin PBXSourcesBuildPhase section */ 281 | 97C146EA1CF9000F007C117D /* Sources */ = { 282 | isa = PBXSourcesBuildPhase; 283 | buildActionMask = 2147483647; 284 | files = ( 285 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 286 | 97C146F31CF9000F007C117D /* main.m in Sources */, 287 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 288 | ); 289 | runOnlyForDeploymentPostprocessing = 0; 290 | }; 291 | /* End PBXSourcesBuildPhase section */ 292 | 293 | /* Begin PBXVariantGroup section */ 294 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 295 | isa = PBXVariantGroup; 296 | children = ( 297 | 97C146FB1CF9000F007C117D /* Base */, 298 | ); 299 | name = Main.storyboard; 300 | sourceTree = ""; 301 | }; 302 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 303 | isa = PBXVariantGroup; 304 | children = ( 305 | 97C147001CF9000F007C117D /* Base */, 306 | ); 307 | name = LaunchScreen.storyboard; 308 | sourceTree = ""; 309 | }; 310 | /* End PBXVariantGroup section */ 311 | 312 | /* Begin XCBuildConfiguration section */ 313 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 314 | isa = XCBuildConfiguration; 315 | buildSettings = { 316 | ALWAYS_SEARCH_USER_PATHS = NO; 317 | CLANG_ANALYZER_NONNULL = YES; 318 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 319 | CLANG_CXX_LIBRARY = "libc++"; 320 | CLANG_ENABLE_MODULES = YES; 321 | CLANG_ENABLE_OBJC_ARC = YES; 322 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 323 | CLANG_WARN_BOOL_CONVERSION = YES; 324 | CLANG_WARN_COMMA = YES; 325 | CLANG_WARN_CONSTANT_CONVERSION = YES; 326 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 327 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 328 | CLANG_WARN_EMPTY_BODY = YES; 329 | CLANG_WARN_ENUM_CONVERSION = YES; 330 | CLANG_WARN_INFINITE_RECURSION = YES; 331 | CLANG_WARN_INT_CONVERSION = YES; 332 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 333 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 334 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 335 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 336 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 337 | CLANG_WARN_STRICT_PROTOTYPES = YES; 338 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 339 | CLANG_WARN_UNREACHABLE_CODE = YES; 340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 341 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 342 | COPY_PHASE_STRIP = NO; 343 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 344 | ENABLE_NS_ASSERTIONS = NO; 345 | ENABLE_STRICT_OBJC_MSGSEND = YES; 346 | GCC_C_LANGUAGE_STANDARD = gnu99; 347 | GCC_NO_COMMON_BLOCKS = YES; 348 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 349 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 350 | GCC_WARN_UNDECLARED_SELECTOR = YES; 351 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 352 | GCC_WARN_UNUSED_FUNCTION = YES; 353 | GCC_WARN_UNUSED_VARIABLE = YES; 354 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 355 | MTL_ENABLE_DEBUG_INFO = NO; 356 | SDKROOT = iphoneos; 357 | SUPPORTED_PLATFORMS = iphoneos; 358 | TARGETED_DEVICE_FAMILY = "1,2"; 359 | VALIDATE_PRODUCT = YES; 360 | }; 361 | name = Profile; 362 | }; 363 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 364 | isa = XCBuildConfiguration; 365 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 366 | buildSettings = { 367 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 368 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 369 | DEVELOPMENT_TEAM = 78W43A3TE2; 370 | ENABLE_BITCODE = NO; 371 | INFOPLIST_FILE = Runner/Info.plist; 372 | LD_RUNPATH_SEARCH_PATHS = ( 373 | "$(inherited)", 374 | "@executable_path/Frameworks", 375 | ); 376 | PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.weiboKitExample; 377 | PRODUCT_NAME = "$(TARGET_NAME)"; 378 | VERSIONING_SYSTEM = "apple-generic"; 379 | }; 380 | name = Profile; 381 | }; 382 | 97C147031CF9000F007C117D /* Debug */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | ALWAYS_SEARCH_USER_PATHS = NO; 386 | CLANG_ANALYZER_NONNULL = YES; 387 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 388 | CLANG_CXX_LIBRARY = "libc++"; 389 | CLANG_ENABLE_MODULES = YES; 390 | CLANG_ENABLE_OBJC_ARC = YES; 391 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 392 | CLANG_WARN_BOOL_CONVERSION = YES; 393 | CLANG_WARN_COMMA = YES; 394 | CLANG_WARN_CONSTANT_CONVERSION = YES; 395 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 396 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 397 | CLANG_WARN_EMPTY_BODY = YES; 398 | CLANG_WARN_ENUM_CONVERSION = YES; 399 | CLANG_WARN_INFINITE_RECURSION = YES; 400 | CLANG_WARN_INT_CONVERSION = YES; 401 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 402 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 403 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 404 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 405 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 406 | CLANG_WARN_STRICT_PROTOTYPES = YES; 407 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 408 | CLANG_WARN_UNREACHABLE_CODE = YES; 409 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 410 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 411 | COPY_PHASE_STRIP = NO; 412 | DEBUG_INFORMATION_FORMAT = dwarf; 413 | ENABLE_STRICT_OBJC_MSGSEND = YES; 414 | ENABLE_TESTABILITY = YES; 415 | GCC_C_LANGUAGE_STANDARD = gnu99; 416 | GCC_DYNAMIC_NO_PIC = NO; 417 | GCC_NO_COMMON_BLOCKS = YES; 418 | GCC_OPTIMIZATION_LEVEL = 0; 419 | GCC_PREPROCESSOR_DEFINITIONS = ( 420 | "DEBUG=1", 421 | "$(inherited)", 422 | ); 423 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 424 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 425 | GCC_WARN_UNDECLARED_SELECTOR = YES; 426 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 427 | GCC_WARN_UNUSED_FUNCTION = YES; 428 | GCC_WARN_UNUSED_VARIABLE = YES; 429 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 430 | MTL_ENABLE_DEBUG_INFO = YES; 431 | ONLY_ACTIVE_ARCH = YES; 432 | SDKROOT = iphoneos; 433 | TARGETED_DEVICE_FAMILY = "1,2"; 434 | }; 435 | name = Debug; 436 | }; 437 | 97C147041CF9000F007C117D /* Release */ = { 438 | isa = XCBuildConfiguration; 439 | buildSettings = { 440 | ALWAYS_SEARCH_USER_PATHS = NO; 441 | CLANG_ANALYZER_NONNULL = YES; 442 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 443 | CLANG_CXX_LIBRARY = "libc++"; 444 | CLANG_ENABLE_MODULES = YES; 445 | CLANG_ENABLE_OBJC_ARC = YES; 446 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 447 | CLANG_WARN_BOOL_CONVERSION = YES; 448 | CLANG_WARN_COMMA = YES; 449 | CLANG_WARN_CONSTANT_CONVERSION = YES; 450 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 451 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 452 | CLANG_WARN_EMPTY_BODY = YES; 453 | CLANG_WARN_ENUM_CONVERSION = YES; 454 | CLANG_WARN_INFINITE_RECURSION = YES; 455 | CLANG_WARN_INT_CONVERSION = YES; 456 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 457 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 458 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 459 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 460 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 461 | CLANG_WARN_STRICT_PROTOTYPES = YES; 462 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 463 | CLANG_WARN_UNREACHABLE_CODE = YES; 464 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 465 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 466 | COPY_PHASE_STRIP = NO; 467 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 468 | ENABLE_NS_ASSERTIONS = NO; 469 | ENABLE_STRICT_OBJC_MSGSEND = YES; 470 | GCC_C_LANGUAGE_STANDARD = gnu99; 471 | GCC_NO_COMMON_BLOCKS = YES; 472 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 473 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 474 | GCC_WARN_UNDECLARED_SELECTOR = YES; 475 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 476 | GCC_WARN_UNUSED_FUNCTION = YES; 477 | GCC_WARN_UNUSED_VARIABLE = YES; 478 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 479 | MTL_ENABLE_DEBUG_INFO = NO; 480 | SDKROOT = iphoneos; 481 | SUPPORTED_PLATFORMS = iphoneos; 482 | TARGETED_DEVICE_FAMILY = "1,2"; 483 | VALIDATE_PRODUCT = YES; 484 | }; 485 | name = Release; 486 | }; 487 | 97C147061CF9000F007C117D /* Debug */ = { 488 | isa = XCBuildConfiguration; 489 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 490 | buildSettings = { 491 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 492 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 493 | DEVELOPMENT_TEAM = 78W43A3TE2; 494 | ENABLE_BITCODE = NO; 495 | INFOPLIST_FILE = Runner/Info.plist; 496 | LD_RUNPATH_SEARCH_PATHS = ( 497 | "$(inherited)", 498 | "@executable_path/Frameworks", 499 | ); 500 | PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.weiboKitExample; 501 | PRODUCT_NAME = "$(TARGET_NAME)"; 502 | VERSIONING_SYSTEM = "apple-generic"; 503 | }; 504 | name = Debug; 505 | }; 506 | 97C147071CF9000F007C117D /* Release */ = { 507 | isa = XCBuildConfiguration; 508 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 509 | buildSettings = { 510 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 511 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 512 | DEVELOPMENT_TEAM = 78W43A3TE2; 513 | ENABLE_BITCODE = NO; 514 | INFOPLIST_FILE = Runner/Info.plist; 515 | LD_RUNPATH_SEARCH_PATHS = ( 516 | "$(inherited)", 517 | "@executable_path/Frameworks", 518 | ); 519 | PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.weiboKitExample; 520 | PRODUCT_NAME = "$(TARGET_NAME)"; 521 | VERSIONING_SYSTEM = "apple-generic"; 522 | }; 523 | name = Release; 524 | }; 525 | /* End XCBuildConfiguration section */ 526 | 527 | /* Begin XCConfigurationList section */ 528 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 529 | isa = XCConfigurationList; 530 | buildConfigurations = ( 531 | 97C147031CF9000F007C117D /* Debug */, 532 | 97C147041CF9000F007C117D /* Release */, 533 | 249021D3217E4FDB00AE95B9 /* Profile */, 534 | ); 535 | defaultConfigurationIsVisible = 0; 536 | defaultConfigurationName = Release; 537 | }; 538 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 539 | isa = XCConfigurationList; 540 | buildConfigurations = ( 541 | 97C147061CF9000F007C117D /* Debug */, 542 | 97C147071CF9000F007C117D /* Release */, 543 | 249021D4217E4FDB00AE95B9 /* Profile */, 544 | ); 545 | defaultConfigurationIsVisible = 0; 546 | defaultConfigurationName = Release; 547 | }; 548 | /* End XCConfigurationList section */ 549 | }; 550 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 551 | } 552 | --------------------------------------------------------------------------------