Commit ce8183bdcdde38301f7250a0e30f0592f5a99c4f

Authored by wdn127929
1 parent cedb188a

企业微信分享未完成

Showing 112 changed files with 3389 additions and 19 deletions
... ... @@ -140,4 +140,9 @@
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
</application>
<queries>
<package android:name="com.tencent.wework" />
<!-- // 指定企业微信包名 -->
</queries>
</manifest>
... ...
... ... @@ -77,6 +77,8 @@ PODS:
- Flutter
- flutter_statusbarcolor_ns (0.0.1):
- Flutter
- flutter_wxwork (0.0.1):
- Flutter
- fluttertoast (0.0.2):
- Flutter
- Toast
... ... @@ -187,6 +189,7 @@ DEPENDENCIES:
- flutter_native_image (from `.symlinks/plugins/flutter_native_image/ios`)
- flutter_sms (from `.symlinks/plugins/flutter_sms/ios`)
- flutter_statusbarcolor_ns (from `.symlinks/plugins/flutter_statusbarcolor_ns/ios`)
- flutter_wxwork (from `.symlinks/plugins/flutter_wxwork/ios`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- fluwx (from `.symlinks/plugins/fluwx/ios`)
- foundation_fluttify (from `.symlinks/plugins/foundation_fluttify/ios`)
... ... @@ -281,6 +284,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_sms/ios"
flutter_statusbarcolor_ns:
:path: ".symlinks/plugins/flutter_statusbarcolor_ns/ios"
flutter_wxwork:
:path: ".symlinks/plugins/flutter_wxwork/ios"
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
fluwx:
... ... @@ -357,6 +362,7 @@ SPEC CHECKSUMS:
flutter_native_image: 9c0b7451838484458e5b0fae007b86a4c2d4bdfe
flutter_sms: 91ce41530f55c85d6524d82307a5d555844c086a
flutter_statusbarcolor_ns: 68a360889d88d7915ae524e422aeab62e4063804
flutter_wxwork: 98328a9eadf535ecc0f7cbdfc1ed3d438d4d7335
fluttertoast: 16fbe6039d06a763f3533670197d01fc73459037
fluwx: e9e728cfdb80e82dac5f4ff974b1901a7939dcd0
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
... ...
... ... @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
... ... @@ -353,6 +353,7 @@
"${BUILT_PRODUCTS_DIR}/flutter_native_image/flutter_native_image.framework",
"${BUILT_PRODUCTS_DIR}/flutter_sms/flutter_sms.framework",
"${BUILT_PRODUCTS_DIR}/flutter_statusbarcolor_ns/flutter_statusbarcolor_ns.framework",
"${BUILT_PRODUCTS_DIR}/flutter_wxwork/flutter_wxwork.framework",
"${BUILT_PRODUCTS_DIR}/fluttertoast/fluttertoast.framework",
"${BUILT_PRODUCTS_DIR}/image_cropper/image_cropper.framework",
"${BUILT_PRODUCTS_DIR}/image_gallery_saver/image_gallery_saver.framework",
... ... @@ -401,6 +402,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_native_image.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_sms.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_statusbarcolor_ns.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_wxwork.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/fluttertoast.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_cropper.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/image_gallery_saver.framework",
... ... @@ -556,7 +558,10 @@
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
... ... @@ -697,14 +702,17 @@
CURRENT_PROJECT_VERSION = 521;
DEVELOPMENT_TEAM = 8J59HM8B82;
ENABLE_BITCODE = NO;
FLUTTER_BUILD_MODE = release;
FLUTTER_BUILD_MODE = debug;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
... ... @@ -740,7 +748,10 @@
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
... ...
... ... @@ -31,6 +31,30 @@
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>wwbdca186ec4257973</string>
</array>
<key>CFBundleURLName</key>
<string>corp</string>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>wwauthbdca186ec4257973000006</string>
</array>
<key>CFBundleURLName</key>
<string>scheme</string>
</dict>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>wwauthbdca186ec4257973000006</string>
</array>
<key>CFBundleURLName</key>
<string>1000006</string>
</dict>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
... ... @@ -59,7 +83,6 @@
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSAppleMusicUsageDescription</key>
<string>需要您的同意,APP才能访问媒体资料库</string>
... ...
... ... @@ -15,7 +15,7 @@ class App {
static double bottomBarHeight;
// static GetIt getIt = GetIt.instance;
static bool isInstallWx = false;
static bool isInstallWWork = false;
static final GlobalKey<NavigatorState> navigatorKey =
new GlobalKey<NavigatorState>();
... ...
... ... @@ -51,6 +51,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_wxwork/flutter_wxwork.dart';
// Future<bool> _requestPermissions() async {
// Map<Permission, PermissionStatus> permissions = await [
... ... @@ -192,6 +193,22 @@ class MyAppState extends State<MyApp> {
LogUtil.v("is installed $result");
}
//初始化企业微信SDK
_initWWork() async {
FlutterWxwork flutterWxwork = FlutterWxwork();
bool sss = await flutterWxwork.registerApp(
'wwauthbdca186ec4257973000006', 'wwbdca186ec4257973', '1000006');
print(sss);
var result = await flutterWxwork.isAppInstalled();
print(result);
// if (result != null && result) {
// App.isInstallWWork = true;
// } else {
// App.isInstallWWork = false;
// }
LogUtil.v("is installed $result");
}
//初始化dio
initDio() {
DioUtil.openDebug();
... ... @@ -227,6 +244,7 @@ class MyAppState extends State<MyApp> {
_ontherInit() async {
initDio();
await _initFluwx();
await _initWWork();
LogUtil.init(isDebug: true, tag: 'ONE_KEY');
Provider.debugCheckInvalidValueType = null;
await initializeDateFormatting();
... ...
... ... @@ -9,6 +9,7 @@ import 'package:flutter_easyrefresh/ball_pulse_footer.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import 'package:flutter_easyrefresh/material_header.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_wxwork/flutter_wxwork.dart';
import 'package:fluwx/fluwx.dart';
import 'package:one_key/app.dart';
import 'package:one_key/res/colors.dart';
... ... @@ -43,6 +44,7 @@ class _FirstPageState extends State<FirstPage> {
_ontherInit() async {
initDio();
await _initFluwx();
await _initWWork();
LogUtil.init(isDebug: true, tag: 'ONE_KEY');
Provider.debugCheckInvalidValueType = null;
await initializeDateFormatting();
... ... @@ -73,6 +75,20 @@ class _FirstPageState extends State<FirstPage> {
LogUtil.v("is installed $result");
}
//初始化企业微信SDK
_initWWork() async {
FlutterWxwork flutterWxwork = FlutterWxwork();
bool sss = await flutterWxwork.registerApp(
'wwauthbdca186ec4257973000006', 'wwbdca186ec4257973', '1000006');
var result = await flutterWxwork.isAppInstalled();
// if (result != null && result) {
// App.isInstallWWork = true;
// } else {
// App.isInstallWWork = false;
// }
LogUtil.v("is installed $result");
}
//初始化dio
initDio() {
DioUtil.openDebug();
... ...
... ... @@ -14,6 +14,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
// import 'package:flutter_statusbarcolor/flutter_statusbarcolor.dart';
import 'package:flutter_statusbarcolor_ns/flutter_statusbarcolor_ns.dart';
import 'package:flutter_wxwork/flutter_wxwork.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter/services.dart';
import 'package:fluwx/fluwx.dart';
... ... @@ -1377,6 +1378,7 @@ class Utils {
String _description = "OneKey";
// Uint8List source = await testComporessList(context, _thumbnail);
print(_path);
var model = new WeChatShareMiniProgramModel(
miniProgramType: Constant.wxMiniProgramType,
webPageUrl: _webPageUrl,
... ... @@ -2066,6 +2068,19 @@ class Utils {
// }
String _description = "进入查看包间详情,转发同行好友,还可一键导航到饭店";
// Uint8List source = await testComporessList(context, _thumbnail);
FlutterWxwork flutterWxwork = FlutterWxwork();
bool sss = await flutterWxwork.registerApp('wwauthbdca186ec4257973000006',
'wwbdca186ec4257973', '1000006');
print(sss);
bool isSuccess = await flutterWxwork.shareMiniProgram(
userName: 'gh_487873d353b3@app',
path: _path,
hdImageData: _thumbnail,
title: _title);
return isSuccess;
/*** 注释一下下===========
//跳转小程序
var model = new WeChatShareMiniProgramModel(
... ... @@ -2081,18 +2096,10 @@ class Utils {
thumbnail: WeChatImage.network(_thumbnail)
// thumbnail: WeChatImage.binary(image)
);
//分享链接
// var model = WeChatShareWebPageModel(
// // 'https://xt04.colorcun.com/h5/index.html#/?id=$rid&hasInvitation=1',
// 'https://xt04.colorcun.com/h5/index.html?id=$rid&hasInvitation=1&hasSellerShare=1',
// title: _title,
// description: _description,
// thumbnail: WeChatImage.network(_thumbnail),
// scene: WeChatScene.SESSION,
// );
bool isSuccess = await shareToWeChat(model);
return isSuccess;
*/
}
//检查网络连接
... ...
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.packages
build/
... ...
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.
version:
revision: eb6d86ee27deecba4a83536aa20f366a6044895c
channel: stable
project_type: plugin
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: eb6d86ee27deecba4a83536aa20f366a6044895c
base_revision: eb6d86ee27deecba4a83536aa20f366a6044895c
- platform: android
create_revision: eb6d86ee27deecba4a83536aa20f366a6044895c
base_revision: eb6d86ee27deecba4a83536aa20f366a6044895c
- platform: ios
create_revision: eb6d86ee27deecba4a83536aa20f366a6044895c
base_revision: eb6d86ee27deecba4a83536aa20f366a6044895c
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
... ...
## 0.0.1
* TODO: Describe initial release.
... ...
TODO: Add your license here.
... ...
# flutter_wxwork
A new Flutter plugin project.
## Getting Started
This project is a starting point for a Flutter
[plug-in package](https://flutter.dev/developing-packages/),
a specialized package that includes platform-specific implementation code for
Android and/or iOS.
For help getting started with Flutter development, view the
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
... ...
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
... ...
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.cxx
... ...
85811fdeeab3e6378f1ae757e3e45719
\ No newline at end of file
... ...
e2d7230103f0366b3ab9986f409c06c6c37b398d
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tecent</groupId>
<artifactId>sdk</artifactId>
<version>2.0.12</version>
<packaging>aar</packaging>
</project>
... ...
4d692fdbce7e06bf09e5154e8c7339be
\ No newline at end of file
... ...
b104313c20c0682d7d488805d61db889a9cc7ea9
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<groupId>com.tecent</groupId>
<artifactId>sdk</artifactId>
<versioning>
<release>2.0.12</release>
<versions>
<version>2.0.12</version>
</versions>
<lastUpdated>20230706035721</lastUpdated>
</versioning>
</metadata>
... ...
0845877a0e8540a7882cdc2fc4dbbc07
\ No newline at end of file
... ...
9d8eb88e3c52335f161001635c9a87d88388e444
\ No newline at end of file
... ...
group 'com.wxwork.flutter_wxwork'
version '1.0'
buildscript {
repositories {
google()
mavenCentral()
// maven {
// url uri('libs')
// }
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
}
}
// 定义一个方法, 用于获取当前moudle的dir
def getCurrentProjectDir() {
String result = ""
rootProject.allprojects { project ->
if (project.properties.get("identityPath").toString() == ":flutter_wxwork") {
result = project.properties.get("projectDir").toString()
}
}
return result
}
rootProject.allprojects {
def dir = getCurrentProjectDir()
repositories {
google()
mavenCentral()
maven { // 添加这个指向本地的仓库目录
url "$dir/aar"
}
}
}
apply plugin: 'com.android.library'
android {
compileSdkVersion 31
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion 16
}
dependencies {
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:5.0.0'
implementation "com.tecent:sdk:2.0.12"
}
testOptions {
unitTests.all {
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen { false }
showStandardStreams = true
}
}
}
}
// dependencies {
// implementation fileTree(include: ['*.aar'], dir: 'libs')
// }
\ No newline at end of file
... ...
rootProject.name = 'flutter_wxwork'
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wxwork.flutter_wxwork">
</manifest>
... ...
package com.wxwork.flutter_wxwork;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import com.tencent.wework.api.model.WWMediaText;
package com.example.flutter_wxwork;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import com.tencent.wework.api.IWWAPI;
import com.tencent.wework.api.IWWAPIEventHandler;
import com.tencent.wework.api.WWAPIFactory;
import com.tencent.wework.api.model.BaseMessage;
import com.tencent.wework.api.model.WWAuthMessage;
import java.util.HashMap;
import java.util.Map;
/**
* FlutterWxworkPlugin
*/
public class FlutterWxworkPlugin implements FlutterPlugin, MethodCallHandler {
/// The MethodChannel that will the communication between Flutter and native Android
///
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
/// when the Flutter Engine is detached from the Activity
private MethodChannel channel;
private String APPID;
private String AGENTID;
private String SCHEMA;
private IWWAPI iwwapi;
private Context context;
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_wxwork");
channel.setMethodCallHandler(this);
context = flutterPluginBinding.getApplicationContext();
iwwapi = WWAPIFactory.createWWAPI(context);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
@SuppressWarnings("unchecked")
Map<String, String> arguments = (Map<String, String>) call.arguments;
if (call.method.equals("isAppInstalled")) {
boolean installed = iwwapi.isWWAppInstalled();
if (installed) {
result.success("1");
} else {
result.success("0");
}
} else if (call.method.equals("register")) {
APPID = arguments.get("corpId");
SCHEMA = arguments.get("scheme");
AGENTID = arguments.get("agentId");
boolean hasRegister = iwwapi.registerApp(SCHEMA);
if (hasRegister) {
result.success("1");
} else {
result.success("0");
}
} else if (call.method.equals("auth")) {
String state = arguments.get("state");
final WWAuthMessage.Req req = new WWAuthMessage.Req();
req.sch = SCHEMA;
req.appId = APPID;
req.agentId = AGENTID;
req.state = state;
// Toast.makeText(context, "sch:" + req.sch,
// Toast.LENGTH_SHORT).show();
iwwapi.sendMessage(req, new IWWAPIEventHandler() {
@Override
public void handleResp(BaseMessage resp) {
if (resp instanceof WWAuthMessage.Resp) {
WWAuthMessage.Resp rsp = (WWAuthMessage.Resp) resp;
Map<String, String> map = new HashMap<>();
map.put("code", rsp.code);
map.put("errCode", String.valueOf(rsp.errCode));
map.put("state", String.valueOf(rsp.state));
result.success(map);
}
}
});
}
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
}
}
\ No newline at end of file
... ...
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Symbolication related
app.*.symbols
# Obfuscation related
app.*.map.json
# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
... ...
# flutter_wxwork_example
Demonstrates how to use the flutter_wxwork plugin.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
... ...
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
... ...
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks
... ...
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.wxwork.flutter_wxwork_example"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wxwork.flutter_wxwork_example">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wxwork.flutter_wxwork_example">
<application
android:label="flutter_wxwork_example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
... ...
package com.wxwork.flutter_wxwork_example;
import io.flutter.embedding.android.FlutterActivity;
public class MainActivity extends FlutterActivity {
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
... ...
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
... ...
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
... ...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wxwork.flutter_wxwork_example">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
... ...
buildscript {
ext.kotlin_version = '1.6.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
... ...
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
... ...
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
... ...
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
... ...
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>
... ...
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
... ...
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
... ...
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
... ...
PODS:
- Flutter (1.0.0)
- flutter_wxwork (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_wxwork (from `.symlinks/plugins/flutter_wxwork/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_wxwork:
:path: ".symlinks/plugins/flutter_wxwork/ios"
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_wxwork: 98328a9eadf535ecc0f7cbdfc1ed3d438d4d7335
PODFILE CHECKSUM: 663715e941f9adb426e33bf9376914006f9ea95b
COCOAPODS: 1.11.3
... ...
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
B28247ACABAF3D574B617C4D /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7276F50182CE37B742DDC5F5 /* libPods-Runner.a */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
0BBE969F27E27004C9AAFFF8 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
0D39D935427B8F068AD66D96 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
7276F50182CE37B742DDC5F5 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
AC602436DE30AD15B532CC56 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
B28247ACABAF3D574B617C4D /* libPods-Runner.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
F805F7336BA4B1118285AFF5 /* Pods */,
AE6633C814A73026273D945C /* Frameworks */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
97C146F11CF9000F007C117D /* Supporting Files */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
);
path = Runner;
sourceTree = "<group>";
};
97C146F11CF9000F007C117D /* Supporting Files */ = {
isa = PBXGroup;
children = (
97C146F21CF9000F007C117D /* main.m */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
AE6633C814A73026273D945C /* Frameworks */ = {
isa = PBXGroup;
children = (
7276F50182CE37B742DDC5F5 /* libPods-Runner.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
F805F7336BA4B1118285AFF5 /* Pods */ = {
isa = PBXGroup;
children = (
0D39D935427B8F068AD66D96 /* Pods-Runner.debug.xcconfig */,
0BBE969F27E27004C9AAFFF8 /* Pods-Runner.release.xcconfig */,
AC602436DE30AD15B532CC56 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
7DFD75DC2CE513B833AE4E1E /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
7DFD75DC2CE513B833AE4E1E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */,
97C146F31CF9000F007C117D /* main.m in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 8J59HM8B82;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.wxwork.flutterWxworkExample;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 8J59HM8B82;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.wxwork.flutterWxworkExample;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 8J59HM8B82;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.wxwork.flutterWxworkExample;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}
... ...
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
... ...
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end
... ...
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
... ...
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
... ...
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
... ...
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
... ...
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Flutter Wxwork</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>flutter_wxwork_example</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>
... ...
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char* argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
... ...
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:flutter/services.dart';
import 'package:flutter_wxwork/flutter_wxwork.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
final _flutterWxworkPlugin = FlutterWxwork();
@override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
// We also handle the message potentially returning null.
try {
platformVersion =
await _flutterWxworkPlugin.getPlatformVersion() ?? 'Unknown platform version';
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: Text('Running on: $_platformVersion\n'),
),
),
);
}
}
... ...
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.9.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.16.0"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.5"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.1"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.2"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_wxwork:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "0.0.1"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.1"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.12.12"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.1.5"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.2"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.5"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.9.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.4.12"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.1.2"
sdks:
dart: ">=2.18.2 <3.0.0"
flutter: ">=2.5.0"
... ...
name: flutter_wxwork_example
description: Demonstrates how to use the flutter_wxwork plugin.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
environment:
sdk: '>=2.18.2 <3.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
flutter_wxwork:
# When depending on this package from a real application you should use:
# flutter_wxwork: ^x.y.z
# See https://dart.dev/tools/pub/dependencies#version-constraints
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
... ...
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_wxwork_example/main.dart';
void main() {
testWidgets('Verify Platform version', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(const MyApp());
// Verify that platform version is retrieved.
expect(
find.byWidgetPredicate(
(Widget widget) => widget is Text &&
widget.data!.startsWith('Running on:'),
),
findsOneWidget,
);
});
}
... ...
.idea/
.vagrant/
.sconsign.dblite
.svn/
.DS_Store
*.swp
profile
DerivedData/
build/
GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
/Flutter/Generated.xcconfig
/Flutter/ephemeral/
/Flutter/flutter_export_environment.sh
\ No newline at end of file
... ...
#import <Flutter/Flutter.h>
#import "WWKApi.h"
@interface FlutterWxworkPlugin : NSObject<FlutterPlugin,WWKApiDelegate>
@end
... ...
#import "FlutterWxworkPlugin.h"
#import "WWKApiObject.h"
@implementation FlutterWxworkPlugin
FlutterResult authResult;
FlutterMethodChannel *channel;
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
channel = [FlutterMethodChannel
methodChannelWithName:@"flutter_wxwork"
binaryMessenger:[registrar messenger]];
FlutterWxworkPlugin* instance = [[FlutterWxworkPlugin alloc] init];
[registrar addMethodCallDelegate:instance channel:channel];
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
if([@"isAppInstalled" isEqualToString:call.method]){
NSString *str = [NSString stringWithFormat:@"%hhd",[WWKApi isAppInstalled]];
result(str);
}else if ([@"register" isEqualToString:call.method]) {
NSDictionary *dic = call.arguments;
NSString *scheme = dic[@"scheme"];
NSString *corpId = dic[@"corpId"];
NSString *agentId = dic[@"agentId"];
result([NSString stringWithFormat:@"%hhd",[WWKApi registerApp:scheme corpId:corpId agentId:agentId]]);
} else if ([@"auth" isEqualToString:call.method]){
WWKSSOReq *req = [[WWKSSOReq alloc] init];
// state参数为这次请求的唯一标示,客户端需要维护其唯一性。SSO回调时会原样返回
req.state = call.arguments[@"state"];
[WWKApi sendReq:req];
authResult = result;
}
else if ([@"shareImage" isEqualToString:call.method]) {
[self shareImage:call result:result];
}
else if ([@"shareMiniProgram" isEqualToString:call.method]) {
[self shareMiniProgram:call result:result];
} else {
result(FlutterMethodNotImplemented);
}
}
- (void)shareImage:(FlutterMethodCall *)call result:(FlutterResult)result {
WWKSendMessageReq *req = [[WWKSendMessageReq alloc] init];
WWKMessageImageAttachment *attachment = [[WWKMessageImageAttachment alloc] init];
attachment.filename = @"test.gif";
attachment.path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"gif"];
req.attachment = attachment;
[WWKApi sendReq:req];
}
- (void)shareMiniProgram:(FlutterMethodCall *)call result:(FlutterResult)result {
WWKSendMessageReq *req = [[WWKSendMessageReq alloc] init];
WWKMessageTextAttachment *attachment = [[WWKMessageTextAttachment alloc] init];
attachment.text = @"企业微信提供了通讯录管理、应用管理、消息推送、身份验证、移动端SDK、素材、OA数据接口、企业支付、电子发票等API,管理员可以使用这些API,为企业接入更多个性化的办公应用。";
req.attachment = attachment;
[WWKApi sendReq:req];
// WWKSendMessageReq *req = [[WWKSendMessageReq alloc] init];
// WWKMessageMiniAppAttachment *attachment = [[WWKMessageMiniAppAttachment alloc] init];
// // 示例用小程序,请填写应用关联的小程序username、路径和图片以及标题
// NSString *userName = call.arguments[@"userName"]; //必须是应用关联的小程序,注意要有@app后缀
// NSString *path = call.arguments[@"path"];
// NSString *hdImageData = call.arguments[@"hdImageData"];
// NSString *title = call.arguments[@"title"];
// attachment.userName = userName; //必须是应用关联的小程序,注意要有@app后缀
// attachment.path = path;
// NSURL *imageURL = [NSURL URLWithString:hdImageData];
// //下载图片
// NSData *data= [NSData dataWithContentsOfURL:imageURL];
// attachment.hdImageData = data;
// // attachment.hdImageData = UIImageJPEGRepresentation([UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"test" ofType:@"jpg"]], 1.0f);
// attachment.title = @"分享标题";
// req.attachment = attachment;
// [WWKApi sendReq:req];
}
// - (void)handleShare:(FlutterMethodCall *)call result:(FlutterResult)result {
// if ([@"shareText" isEqualToString:call.method]) {
// [self shareText:call result:result];
// } else if ([@"shareImage" isEqualToString:call.method]) {
// [self shareImage:call result:result];
// } else if ([@"shareWebPage" isEqualToString:call.method]) {
// [self shareWebPage:call result:result];
// } else if ([@"shareMusic" isEqualToString:call.method]) {
// [self shareMusic:call result:result];
// } else if ([@"shareVideo" isEqualToString:call.method]) {
// [self shareVideo:call result:result];
// } else if ([@"shareMiniProgram" isEqualToString:call.method]) {
// [self shareMiniProgram:call result:result];
// } else if ([@"shareFile" isEqualToString:call.method]) {
// [self shareFile:call result:result];
// }
// }
- (void)checkWWorkInstallation:(FlutterMethodCall *)call result:(FlutterResult)result {
NSString *str = [NSString stringWithFormat:@"%hhd",[WWKApi isAppInstalled]];
result(str);
// result(@([WWKApi isAppInstalled]));
}
- (void)registerApp:(FlutterMethodCall *)call result:(FlutterResult)result {
// NSNumber* doOnIOS =call.arguments[@"iOS"];
// if (![doOnIOS boolValue]) {
// result(@NO);
// return;
// }
// NSString *appId = call.arguments[@"appId"];
// if ([FluwxStringUtil isBlank:appId]) {
// result([FlutterError errorWithCode:@"invalid app id" message:@"are you sure your app id is correct ? " details:appId]);
// return;
// }
// NSString *universalLink = call.arguments[@"universalLink"];
// if ([FluwxStringUtil isBlank:universalLink]) {
// result([FlutterError errorWithCode:@"invalid universal link" message:@"are you sure your universal link is correct ? " details:universalLink]);
// return;
// }
NSString *scheme = call.arguments[@"scheme"]; // 第三方App的Schema
NSString *corpId = call.arguments[@"corpId"]; // 第三方App所属企业的ID
NSString *agentId = call.arguments[@"agentId"]; // 第三方App在企业内部的ID
// BOOL isWeChatRegistered = [WXApi registerApp:appId universalLink:universalLink];
BOOL isWWKRegistered = [WWKApi registerApp:@"wwauthbdca186ec4257973000006" corpId:@"wwbdca186ec4257973" agentId:@"1000006"];
result(@(isWWKRegistered));
// result(@(isWeChatRegistered));
}
#pragma mark - AppDelegate
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options{
return [WWKApi handleOpenURL:url delegate:self];
}
- (BOOL)isBlankString:(NSString *)string{
if (string == nil) {
return YES;
}
if (string == NULL) {
return YES;
}
if ([string isKindOfClass:[NSNull class]]) {
return YES;
}
if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]==0) {
return YES;
}
return NO;
}
- (void)onResp:(WWKBaseResp *)resp {
/*! @brief 所有通过sendReq发送的SDK请求的结果都在这个函数内部进行异步回调
* @param resp SDK处理请求后的返回结果 需要判断具体是哪项业务的回调
*/
/* SSO的回调 */
if ([resp isKindOfClass:[WWKSSOResp class]]) {
WWKSSOResp *r = (WWKSSOResp *)resp;
NSMutableDictionary *mDic = [[NSMutableDictionary alloc]init];
if([self isBlankString:r.code]){
[mDic setObject:@"1" forKey:@"errCode"];
[mDic setObject:@"" forKey:@"code"];
}else{
[mDic setObject:@"0" forKey:@"errCode"];
[mDic setObject:r.code forKey:@"code"];
}
[mDic setObject:r.state forKey:@"state"];
authResult(mDic);
// [channel invokeMethod:@"auth" arguments:mDic];
}
}
@end
... ...
//
// WWKApi.h
// wxwork
//
// Created by WXWork on 16/5/25.
// Copyright © 2019年 Tencent. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "WWKApiObject.h"
#pragma mark - WWKApiDelegate
/*! @brief 接收并处理来自企业微信终端程序的事件消息
*
* 接收并处理来自企业微信终端程序的事件消息,期间企业微信界面会切换到第三方应用程序。
* WWKApiDelegate 会在handleOpenURL:delegate:中使用并触发。
*/
@protocol WWKApiDelegate <NSObject>
@optional
// 企业微信展示对外名称.
typedef NS_ENUM(NSInteger, WWKDiplayNameType) {
WWKDefaultName = 0, // 企业微信
WWKLocalName = 1 // 政务微信
};
/*! @brief 收到一个来自企业微信的请求,第三方应用程序处理完后调用sendResp向企业微信发送结果
*
* 收到一个来自企业微信的请求,异步处理完成后必须调用sendResp发送处理结果给企业微信。
* 目前并未使用。
* @param req 具体请求内容,是自动释放的
*/
- (void)onReq:(WWKBaseReq *)req;
/*! @brief 发送一个sendReq后,收到企业微信的回应
*
* 收到一个来自企业微信的处理结果。调用一次sendReq后会收到onResp。
* 可能收到的处理结果有WWKSendMessageResp等。
* @param resp 具体的回应内容,是自动释放的
*/
- (void)onResp:(WWKBaseResp *)resp;
/*! @brief SessionKey更新回调
*
* 需要设置updateSessionKeyIfNeeded:YES,并且满足企业微信sessionKey更新策略才会调用
* @param
*/
- (void)onSessionKeyUpdate:(NSString *)newSessionKey;
@end
#pragma mark - WWKApi
/*! @brief 企业微信Api接口函数类
*
* 该类封装了企业微信终端SDK的所有接口
*/
@interface WWKApi : NSObject
/*! @brief WWKApi的成员函数,向企业微信终端程序注册第三方应用。
*
* 需要在每次启动第三方应用程序时调用。第一次调用后,会在企业微信的可用应用列表中出现。
* iOS7及以上系统需要调起一次企业微信才会出现在企业微信的可用应用列表中。
* @attention 请保证在主线程中调用此函数
* @param appid 企业微信开发者ID
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)registerApp:(NSString *)appid;
/*! @brief WWKApi的成员函数,向企业微信终端程序注册第三方应用。
*
* 需要在每次启动第三方应用程序时调用。第一次调用后,会在企业微信的可用应用列表中出现。
* iOS7及以上系统需要调起一次企业微信才会出现在企业微信的可用应用列表中。
* @attention 请保证在主线程中调用此函数
* @param appid 第三方应用的appid
* @param scheme 当前app的scheme
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)registerAppID:(NSString *)appid schema:(NSString *)schema;
/*! @brief WWKApi的成员函数,向企业微信终端程序注册企业应用。
*
* 需要在每次启动第三方应用程序时调用。第一次调用后,会在企业微信的可用应用列表中出现。
* @see registerApp
* @param appid 企业微信开发者ID
* @param corpid 企业微信企业ID
* @param agentid 企业微信企业应用ID
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)registerApp:(NSString *)appid corpId:(NSString *)corpid agentId:(NSString *)agentid;
/*! @brief 是否必要时更新sessionKey,默认为NO
*
* @param url 企业微信根据安全策略自动更新sessionKey,如果有更新,会触发onSessionKeyUpdate:回调
*/
+ (void)updateSessionKeyIfNeeded:(BOOL)enable;
/*! @brief 处理企业微信通过URL启动App时传递的数据
*
* 需要在 application:openURL:sourceApplication:annotation:或者application:handleOpenURL中调用。
* @param url 企业微信启动第三方应用时传递过来的URL
* @param delegate WWKApiDelegate对象,用来接收企业微信触发的消息。
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)handleOpenURL:(NSURL *)url delegate:(id<WWKApiDelegate>) delegate;
/*! @brief 检查企业微信是否已被用户安装
*
* @return 企业微信已安装返回YES,未安装返回NO。
* @note 由于iOS系统的限制,在iOS9及以上系统检测企业微信是否安装,需要将企业微信的scheme"wxwork"(云端版本)及"wxworklocal"(本地部署版本)添加到工程的Info.plist中的LSApplicationQueriesSchemes白名单里,否则此方法总是会返回NO。
* 详情参考 https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl
*/
+ (BOOL)isAppInstalled;
/*! @brief 获取企业微信的itunes安装地址
*
* @return 企业微信的安装地址字符串。
*/
+ (NSString *)getAppInstallUrl;
/*! @brief 获取当前企业微信SDK的版本号
*
* @return 返回当前企业微信SDK的版本号
*/
+ (NSString *)getApiVersion;
/*! @brief 打开企业微信
*
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)openApp;
/*!
* @brief 启动登录流程。
* @param navigationController 当前页面的导航栏控制器
* @param state 第三方应用传入的值,登录成功后会透传给第三方应用
* @see WWKSSOReq
*/
+ (void)startSSOLogin:(NSString *)state fromNavigationController:(UINavigationController *)navigationController;
/*! @brief 发送请求到企业微信,等待企业微信返回onResp
*
* 函数调用后,会切换到企业微信的界面。第三方应用程序等待企业微信返回onResp。企业微信在异步处理完成后一定会调用onResp。支持以下类型
* WWKSendMessageReq等。
* @param req 具体的发送请求,在调用函数后,请自己释放。
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)sendReq:(WWKBaseReq *)req;
/*! @brief 收到企业微信onReq的请求,发送对应的应答给企业微信,并切换到企业微信界面
*
* 函数调用后,会切换到企业微信的界面。第三方应用程序收到企业微信onReq的请求,异步处理该请求,完成后必须调用该函数。
* 目前暂未使用
* @param resp 具体的应答内容,调用函数后,请自己释放
* @return 成功返回YES,失败返回NO。
*/
+ (BOOL)sendResp:(WWKBaseResp *)resp;
/*! @brief 获取当前企业微信展示名称
*
* @return 返回当前企业微信展示名称
*/
+ (WWKDiplayNameType)displayNameType;
/*! @brief 设置登录态返回的sessionKey
*
*/
+ (void)setSessionKey:(NSString *)sessionKey;
/*! @brief 初始化OpenData
*
* @以block的形式返回成功或者失败
*/
+(void)initOpenData:(void (^)(BOOL isSucc))completion;
/*! @brief 获取成员或者部门的详细信息
*
* @param 传入WWKOpenDataItem输入,SDK会获取部门或用户名并以block的形式返回
* 需要initOpenData返回成功后才能调用
* @see WWKOpenDataItem
*/
+(void)getOpenData:(NSArray<WWKOpenDataItem *> *)dataList completion:(void (^)(NSError *error,NSArray<WWKOpenDataItem *> *dataArray))completion;
@end
... ...
//
// WWKApiObject.h
// wxwork
//
// Created by WXWork on 16/5/25.
// Copyright © 2019年 Tencent. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@class WWKBaseResp;
@protocol WWKApiSerializable <NSObject>
- (BOOL)deserializeWithDictionary:(NSDictionary *)dict;
@end
@interface WWKBaseObject : NSObject
@property (nonatomic, copy) NSString *bundleID;
@property (nonatomic, copy) NSString *bundleName;
@property (nonatomic, assign) NSUInteger sequence;
@property (nonatomic, readonly, nullable) NSData *serializedData;
@property (nonatomic, readonly, nullable) NSMutableDictionary *serializedDict;
+ (instancetype)deserializeWithData:(NSData *)data appid:(NSString *)appid;
@end
#pragma mark - WWKBaseReq
/*! @brief 该类为企业微信终端SDK所有请求类的基类
*
*/
@interface WWKBaseReq : WWKBaseObject
- (WWKBaseResp *)respObj; // 对应返回的结构
@end
#pragma mark - WWKBaseResp
extern const int WWKBaseRespErrCodeOK; // 操作成功
extern const int WWKBaseRespErrCodeCancelled; // 操作被取消
extern const int WWKBaseRespErrCodeFailed; // 操作失败
extern const int WWKBaseRespErrCodeNotSupported; // 操作不支持(不能识别请求)
extern const int WWKBaseRespErrCodeLowAppVer; // 操作不支持(用户安装的App版本过低)
extern const int WWKBaseRespErrCodeNoPrivileges; // 没有此API的调用权限
extern const int WWKBaseRespErrCodeInvalidCall; // 调用出错(例如传入参数不正确)
extern const int WWKBaseRespErrCodeNetWork; // 网络出错(例如请求超时)
extern const int WWKBaseRespErrCodeSessonKeyTimeOut; // sessionkey超时
/*! @brief 该类为企业微信终端SDK所有响应类的基类
*
*/
@interface WWKBaseResp : WWKBaseObject
/** 错误码 */
@property (nonatomic, assign) int errCode;
/** 错误提示字符串 */
@property (nonatomic, retain, nullable) NSString *errStr;
@end
#pragma mark - WWKSendMessageReq
/*!
* @brief 带在 @c WWKSendMessageReq 中的消息对象基类。实际必须使用其子类
*/
@interface WWKMessageAttachment : NSObject
@end
/*!
* @brief 文本消息
*/
@interface WWKMessageTextAttachment : WWKMessageAttachment
@property (nonatomic, copy) NSString *text;
@end
/*!
* @brief 文件消息
*/
@interface WWKMessageFileAttachment : WWKMessageAttachment
@property (nonatomic, copy) NSString *filename;
@property (nonatomic, copy, nullable) NSString *path;
@property (nonatomic, retain, nullable) NSData *data;
@end
/*!
* @brief 图片消息
*/
@interface WWKMessageImageAttachment : WWKMessageFileAttachment
@end
/*!
* @brief 视频消息
*/
@interface WWKMessageVideoAttachment : WWKMessageFileAttachment
@end
/*!
* @brief 链接消息
*/
@interface WWKMessageLinkAttachment : WWKMessageAttachment
@property (nonatomic, copy, nullable) NSString *title; // 不能超过512bytes
@property (nonatomic, copy, nullable) NSString *summary; // 不能超过1k
@property (nonatomic, copy, nullable) NSString *url;
@property (nonatomic, copy, nullable) NSString *iconurl;
@property (nonatomic, retain, nullable) NSData *icon; // 不能超过32K
// 是否使用带 shareTicket 的转发,只有注册了企业应用的agentid才有效;只能为单条转发,放在WWKMessageGroupAttachment中会被过滤
@property (nonatomic, assign) BOOL withShareTicket;
@property (nonatomic, copy, nullable) NSString *shareTicketState;
@end
/*!
* @brief 小程序消息
*/
@interface WWKMessageMiniAppAttachment : WWKMessageAttachment
@property (nonatomic, copy) NSString *userName; // 小程序username
@property (nonatomic, copy, nullable) NSString *path; // 小程序页面的路径
@property (nonatomic, strong, nullable) NSData *hdImageData; // 小程序预览图 不能超过128k
@property (nonatomic, copy, nullable) NSString *title; // 小程序 当前页title 不能超过512bytes
@end
/*!
* @brief 位置消息
*/
@interface WWKMessageLocationAttachment : WWKMessageAttachment
@property (nonatomic, copy, nullable) NSString *title;
@property (nonatomic, copy, nullable) NSString *address;
@property (nonatomic, assign) double lat;
@property (nonatomic, assign) double lng;
@property (nonatomic, assign) double zoom;
@end
/*!
* @brief 单条聊天记录消息
*/
@interface WWKMessageAttachmentWrapper : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSDate *date;
@property (nonatomic, copy, nullable) NSString *avatarUrl;
@property (nonatomic, copy, nullable) NSData *avatarData;
@property (nonatomic, retain) WWKMessageAttachment *attachment;
@end
/*!
* @brief 聊天记录消息组
*/
@interface WWKMessageGroupAttachment : WWKMessageAttachment
@property (nonatomic, copy) NSArray<WWKMessageAttachmentWrapper *> *contents;
@property (nonatomic, copy) NSString *title;
@end
typedef NS_ENUM(NSUInteger, WWKOpenIdType) {
WWKOpenIdTypeUnKnown = 0,
WWKOpenIdTypeUser, // 成员
WWKOpenIdTypeDepartment //部门
};
@interface WWKOpenIdInfo : NSObject
@property (nonatomic, copy, nullable) NSString *openid;
@property (nonatomic, assign) WWKOpenIdType idType;
@end
/*! @brief 第三方程序发送消息至企业微信终端程序的消息结构体
*
* 第三方程序向企业微信发送信息需要传入WWKSendMessageReq结构体,信息类型包括文本消息和多媒体消息,
* 分别对应于text和message成员。调用该方法后,企业微信处理完信息会向第三方程序发送一个处理结果。
* @see WWKSendMessageResp
*/
@interface WWKSendMessageReq : WWKBaseReq <WWKApiSerializable>
/** 发送消息的多媒体内容
* @see WWKMessageAttachment
*/
@property (nonatomic, retain, nullable) WWKMessageAttachment *attachment;
@end
#pragma mark - WWKSendMessageResp
/*! @brief 企业微信终端向第三方程序返回的WWKSendMessageReq处理结果。
*
* 第三方程序向企业微信终端发送WWKSendMessageReq后,企业微信发送回来的处理结果,该结果用WWKSendMessageResp表示。
*/
@interface WWKSendMessageResp : WWKBaseResp <WWKApiSerializable>
@end
#pragma mark - WWKPickContactReq
/*! @brief 第三方程序从企业微信终端程序选人的消息结构体
*
* 本接口无需登录态,只能选择邮箱联系人。如果需要选择所有联系人,请使用WWKSelectContactReq接口
*
*
*/
@interface WWKPickContactReq : WWKBaseReq <WWKApiSerializable>
@property (nonatomic, copy) NSString *type;
@end
#pragma mark - WWKPickContactResp
@interface WWKContactInfo : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy, nullable) NSString *email;
@end
@interface WWKPickContactResp : WWKBaseResp <WWKApiSerializable>
@property (nonatomic, retain, nullable) NSArray<WWKContactInfo *> *contacts;
@end
#pragma mark - WWKOpenConversationReq
@interface WWKOpenConversationReq : WWKBaseReq <WWKApiSerializable>
@property (nonatomic, assign) uint64_t conversationType;
@property (nonatomic, assign) uint64_t conversationId;
@end
#pragma mark - WWKOpenConversationResp
@interface WWKOpenConversationResp : WWKBaseResp <WWKApiSerializable>
@end
#pragma mark - WWKSSOReq
@interface WWKSSOReq : WWKBaseReq <WWKApiSerializable>
@property (nonatomic, copy) NSString *state;
@end
@interface WWKSSOResp : WWKBaseResp <WWKApiSerializable>
@property (nonatomic, retain, nullable) NSString *state;
@property (nonatomic, retain, nullable) NSString *code;
@end
/*! @brief 第三方程序创建群聊并发送消息至企业微信终端程序的消息结构体(需登录态)
*
* 第三方程序向企业微信发送信息需要传入WWKSendMessageReq结构体,创建群聊成员的openid列表
* (只支持成员,不支持部门),当前登录态返回的openUserid,信息类型包括文本消息和多媒体消息,
* 分别对应于text和message成员。调用该方法后,企业微信处理完信息会向第三方程序发送一个处理结果。
* @see WWKOpenChatWithMessageResp
*/
@interface WWKOpenChatWithMessageReq : WWKBaseReq <WWKApiSerializable>
/** 发送消息的多媒体内容
* @see WWKMessageAttachment
*/
@property (nonatomic, retain, nullable) WWKMessageAttachment *attachment;
/** 发送消息的到新创建的群聊
* 暂不支持传入部门信息
*/
@property (nonatomic, retain, nullable) NSArray<NSString *> *userOpenidList;
/**
* 从后台登录获取的openUserid
*/
@property (nonatomic, retain, nullable) NSString *openUserid;
@end
#pragma mark - WWKOpenChatWithMessageResp
/*! @brief 企业微信终端向第三方程序返回的WWKOpenChatWithMessageReq处理结果。
*
* 第三方程序向企业微信终端发送WWKOpenChatWithMessageReq后,企业微信发送回来的处理结果,该结果用WWKOpenChatWithMessageResp表示。
*/
@interface WWKOpenChatWithMessageResp : WWKBaseResp <WWKApiSerializable>
@end
#pragma mark - WWKSelectContactReq
/*! @brief 第三方程序从企业微信终端程序选人的消息结构体(需登录态)
*
* 第三方程序向企业微信发送信息需要传入当前登录态返回的openUserid。调用该方法后,企业微信调起选人流程,结束后会向第三方程序发送一个处理结果。
* @see WWKSelectContactResp
*/
@interface WWKSelectContactReq : WWKBaseReq <WWKApiSerializable>
/**
* 从后台登录获取的openUserid,必须填写这个字段
*/
@property (nonatomic, retain) NSString *openUserid;
@end
#pragma mark - WWKSelectContactResp
/*! @brief 选人回包
*
* 从这个接口返回的数据不会带人名或部门名,需要调用getOpenData接口获取名字等详细信息
* 目前仅支持选择成员,暂不支持选择部门
*/
@interface WWKSelectContactResp : WWKBaseResp <WWKApiSerializable>
@property (nonatomic, retain, nullable) NSArray<WWKOpenIdInfo *> *openids;
@end
/*! @brief getOpenData接口使用的结构
* @param openid 部门或成员openid信息
* @param type 需要查询的类型,目前仅支持userName(用户名称)、userDepartment(用户主部门名称)以及userGender(用户性别)、departmentName(部门名称),其中userName、userDepartment、userGender在openid为用成员时有效,departmentName在openid为部门时有效
* @param data 传入时不需要填写,getOpenData返回会填充该字段
*/
@interface WWKOpenDataItem : NSObject
@property (nonatomic, copy) NSString *openid;
@property (nonatomic, copy) NSString *type;
@property (nonatomic, copy, nullable) NSString *data;
@end
#pragma mark - WWKSelectPrivilegedContactReq
/*! @brief 第三方程序从企业微信终端程序选人的消息结构体(需登录态)
*
* 选择范围限定为企业通讯录
* 只支持成员,若勾选部门,则对应展开勾选部门下的成员。
* 与WWKSelectContactReq接口的区分是,返回的选择范围,需要经过第三方权限过滤。只返回在可见范围的列表,而完整的列表存在ticket给第三方,用于jsapi/api接口调用。
* @see WWKSelectPrivilegedContactResp
*/
@interface WWKSelectPrivilegedContactReq : WWKBaseReq <WWKApiSerializable>
/**
* 从后台登录获取的loginOpenUserid,必须填写这个字段
* selectedOpenUserIds 预选用户openUserId列表
* selectedTickets 预选ticket列表
*/
@property (nonatomic, copy) NSString *loginOpenUserid;
@property (nonatomic, copy) NSArray<NSString *> *selectedOpenUserIds;
@property (nonatomic, copy) NSArray<NSString *> *selectedTickets;
@end
#pragma mark - WWKSelectPrivilegedContactResp
/*! @brief 选人回包
*
* openUserIdList 返回openid的列表
* selectedTicket 选择的集合Ticket,用于对该选择集合操作的调用凭证。
* expiresIn selectedTicket的有效期,单位为秒
* selectedUserCount 选择的集合Ticket包含的用户数
*/
@interface WWKSelectPrivilegedContactResp : WWKBaseResp <WWKApiSerializable>
@property (nonatomic, copy) NSArray<NSString *> *openUserIdList;
@property (nonatomic, copy) NSString *selectedTicket;
@property (nonatomic, assign) uint32_t expiresIn;
@property (nonatomic, assign) uint32_t selectedUserCount;
@end
#pragma mark - WWKCreateChatWithMsgReq
/*! @brief 新建群聊发消息(需登录态)
*
* 选人范围包括企业通讯录和外部联系人。
* 支持用户传入openUserId,和selectedTicket
* @see WWKCreateChatWithMsgResp
*/
@interface WWKCreateChatWithMsgReq : WWKBaseReq <WWKApiSerializable>
/**
* loginOpenUserid 从后台登录获取的loginOpenUserid,必须填写这个字段
* selectedOpenUserIdList 创建会话的企业通讯录成员信息,格式为字符串,内容为成员的openid列表(可以从WWKSelectPrivilegedContactResp获取),限定必须为应用的可见范围内。列表最多2000项。
* selectedTicketList 已选择的成员集合凭证列表,(可以从WWKSelectPrivilegedContactResp获取)。列表最多10个。
* attachment 消息内容结构体,支持文本、文件、图片、视频、链接、聊天内容,参考WWKMessageAttachment
* chatName 群聊名称
* state 透传参数,最长256,用于回调第三方应用创建群聊事件
*
*/
@property (nonatomic, copy) NSString *loginOpenUserid;
@property (nonatomic, copy) NSArray<NSString *> *selectedOpenUserIdList;
@property (nonatomic, copy) NSArray<NSString *> *selectedTicketList;
@property (nonatomic, retain) WWKMessageAttachment *attachment;
@property (nonatomic, copy, nullable) NSString *chatName;
@property (nonatomic, copy, nullable) NSString *state;
@end
#pragma mark - WWKCreateChatWithMsgResp
/*! @brief 新建群聊发消息回包
*
* errorCode 错误码
* errorMsg 错误码描述
* chatId 若创建群成功,返回群ID
*/
@interface WWKCreateChatWithMsgResp : WWKBaseResp <WWKApiSerializable>
@property (nonatomic, copy, nullable) NSString *chatId;
@end
#pragma mark - WWKOpenExistedChatWithMsgReq
/*! @brief 打开群聊发消息(需登录态)
*/
@interface WWKOpenExistedChatWithMsgReq : WWKBaseReq <WWKApiSerializable>
/**
* loginOpenUserid 从后台登录获取的loginOpenUserid,必须填写这个字段
* attachment 消息内容结构体,支持文本、文件、图片、视频、链接、聊天内容,参考WWKMessageAttachment attachment为可选。若不传参数,则无消息发送确认行为。
* chatId 打开群聊ID,chatId必须是当前用户所在的群聊
*
*/
@property (nonatomic, copy) NSString *loginOpenUserid;
@property (nonatomic, retain, nullable) WWKMessageAttachment *attachment;
@property (nonatomic, copy) NSString *chatId;
@end
#pragma mark - WWKOpenExistedChatWithMsgResp
/*! @brief 打开群聊发消息回包
*
* errorCode 错误码
* errorMsg 错误码描述
*/
@interface WWKOpenExistedChatWithMsgResp : WWKBaseResp <WWKApiSerializable>
@end
NS_ASSUME_NONNULL_END
... ...
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint flutter_wxwork.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'flutter_wxwork'
s.version = '0.0.1'
s.summary = 'A new Flutter plugin project.'
s.description = <<-DESC
A new Flutter plugin project.
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.platform = :ios, '9.0'
# s.dependency 'Classes/libWXWorkApi.a'
s.vendored_libraries = 'Classes/libWXWorkApi.a'
# 依赖的第三方库用到了静态库,还需要添加:
# s.static_framework = true
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
end
... ...
import 'package:flutter_wxwork/flutter_wxwork_method_channel.dart';
import 'flutter_wxwork_platform_interface.dart';
class FlutterWxwork {
Future<String?> getPlatformVersion() {
return FlutterWxworkPlatform.instance.getPlatformVersion();
}
Future<bool?> registerApp(scheme, corpId, agentId) {
return FlutterWxworkPlatform.instance.registerApp(scheme, corpId, agentId);
}
Future<AuthModel?> auth({String state = 'state'}) async {
return FlutterWxworkPlatform.instance.auth();
}
Future<String?> isAppInstalled() {
return FlutterWxworkPlatform.instance.isAppInstalled();
}
Future<bool?> shareImage() {
return FlutterWxworkPlatform.instance.shareImage();
}
Future<bool?> shareMiniProgram(
{String? userName, //必须是应用关联的小程序,注意要有@app后缀
String? path,
String? hdImageData,
String title = "分享标题"}) {
return FlutterWxworkPlatform.instance.shareMiniProgram();
}
}
... ...
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'flutter_wxwork_platform_interface.dart';
/// An implementation of [FlutterWxworkPlatform] that uses method channels.
class MethodChannelFlutterWxwork extends FlutterWxworkPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
final methodChannel = const MethodChannel('flutter_wxwork');
@override
Future<String?> getPlatformVersion() async {
final version =
await methodChannel.invokeMethod<String>('getPlatformVersion');
return version;
}
@override
Future<bool?> registerApp(scheme, corpId, agentId) async {
String? result =
await methodChannel.invokeMethod<String>('register', <String, String>{
'scheme': scheme,
'corpId': corpId,
'agentId': agentId,
});
return _stringToBool(result);
}
@override
Future<String?> isAppInstalled() async {
final isAppInstalled =
await methodChannel.invokeMethod<String>('isAppInstalled');
return isAppInstalled;
}
@override
Future<bool?> shareImage() async {
final shareImage = await methodChannel.invokeMethod<bool>('shareImage');
return shareImage;
}
@override
Future<bool?> shareMiniProgram(
{String? userName, //必须是应用关联的小程序,注意要有@app后缀
String? path,
String? hdImageData,
String title = "分享标题"}) async {
final shareMiniProgram =
await methodChannel.invokeMethod<bool>('shareMiniProgram');
return shareMiniProgram;
}
@override
Future<AuthModel?> auth({String state = 'state'}) async {
var content = await methodChannel.invokeMethod('auth', {"state": state});
return AuthModel.fromJson(Map<String, dynamic>.from(content));
}
bool _stringToBool(String? string) {
if (string == '1') {
return true;
} else {
return false;
}
}
}
class AuthModel {
/// 1.取消 0.成功 2.失败
String? errCode;
String? code;
String? state;
bool get isSuccess => errCode == '1';
AuthModel();
factory AuthModel.fromJson(Map<String, dynamic> json) {
AuthModel model = AuthModel();
model.errCode = json['errCode'];
model.code = json['code'];
model.state = json['state'];
return model;
}
Map<String, dynamic> toJson() {
return {'errorCode': errCode, 'code': code, 'state': state};
}
@override
String toString() {
return jsonEncode(this);
}
}
... ...
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'flutter_wxwork_method_channel.dart';
abstract class FlutterWxworkPlatform extends PlatformInterface {
/// Constructs a FlutterWxworkPlatform.
FlutterWxworkPlatform() : super(token: _token);
static final Object _token = Object();
static FlutterWxworkPlatform _instance = MethodChannelFlutterWxwork();
/// The default instance of [FlutterWxworkPlatform] to use.
///
/// Defaults to [MethodChannelFlutterWxwork].
static FlutterWxworkPlatform get instance => _instance;
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [FlutterWxworkPlatform] when
/// they register themselves.
static set instance(FlutterWxworkPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
Future<String?> getPlatformVersion() {
throw UnimplementedError('platformVersion() has not been implemented.');
}
Future<bool?> registerApp(scheme, corpId, agentId) {
throw UnimplementedError('registerApp() has not been implemented.');
}
Future<String?> isAppInstalled() {
throw UnimplementedError('isAppInstalled() has not been implemented.');
}
Future<bool?> shareImage() {
throw UnimplementedError('shareImage() has not been implemented.');
}
Future<AuthModel?> auth() {
throw UnimplementedError('auth() has not been implemented.');
}
Future<bool?> shareMiniProgram() {
throw UnimplementedError('shareMiniProgram() has not been implemented.');
}
}
... ...
name: flutter_wxwork
description: A new Flutter plugin project.
version: 0.0.1
homepage:
environment:
sdk: '>=2.18.2 <3.0.0'
flutter: ">=2.5.0"
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.2
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# This section identifies this Flutter project as a plugin project.
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
# which should be registered in the plugin registry. This is required for
# using method channels.
# The Android 'package' specifies package in which the registered class is.
# This is required for using method channels on Android.
# The 'ffiPlugin' specifies that native code should be built and bundled.
# This is required for using `dart:ffi`.
# All these are used by the tooling to maintain consistency when
# adding or updating assets for this project.
plugin:
platforms:
android:
package: com.wxwork.flutter_wxwork
pluginClass: FlutterWxworkPlugin
ios:
pluginClass: FlutterWxworkPlugin
# To add assets to your plugin package, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
#
# For details regarding assets in packages, see
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# To add custom fonts to your plugin package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts in packages, see
# https://flutter.dev/custom-fonts/#from-packages
... ...
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_wxwork/flutter_wxwork_method_channel.dart';
void main() {
MethodChannelFlutterWxwork platform = MethodChannelFlutterWxwork();
const MethodChannel channel = MethodChannel('flutter_wxwork');
TestWidgetsFlutterBinding.ensureInitialized();
setUp(() {
channel.setMockMethodCallHandler((MethodCall methodCall) async {
return '42';
});
});
tearDown(() {
channel.setMockMethodCallHandler(null);
});
test('getPlatformVersion', () async {
expect(await platform.getPlatformVersion(), '42');
});
}
... ...
// import 'package:flutter_test/flutter_test.dart';
// import 'package:flutter_wxwork/flutter_wxwork.dart';
// import 'package:flutter_wxwork/flutter_wxwork_platform_interface.dart';
// import 'package:flutter_wxwork/flutter_wxwork_method_channel.dart';
// import 'package:plugin_platform_interface/plugin_platform_interface.dart';
// class MockFlutterWxworkPlatform
// with MockPlatformInterfaceMixin
// implements FlutterWxworkPlatform {
// @override
// Future<String?> getPlatformVersion() => Future.value('42');
// }
// void main() {
// final FlutterWxworkPlatform initialPlatform = FlutterWxworkPlatform.instance;
// test('$MethodChannelFlutterWxwork is the default instance', () {
// expect(initialPlatform, isInstanceOf<MethodChannelFlutterWxwork>());
// });
// test('getPlatformVersion', () async {
// FlutterWxwork flutterWxworkPlugin = FlutterWxwork();
// MockFlutterWxworkPlatform fakePlatform = MockFlutterWxworkPlatform();
// FlutterWxworkPlatform.instance = fakePlatform;
// expect(await flutterWxworkPlugin.getPlatformVersion(), '42');
// });
// }
... ...
... ... @@ -77,7 +77,7 @@ packages:
name: audioplayers
url: "https://pub.flutter-io.cn"
source: hosted
version: "4.1.0"
version: "4.0.1"
audioplayers_android:
dependency: transitive
description:
... ... @@ -679,6 +679,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_wxwork:
dependency: "direct main"
description:
path: "library/flutter_wxwork"
relative: true
source: path
version: "0.0.1"
fluttertoast:
dependency: "direct main"
description:
... ... @@ -1383,7 +1390,7 @@ packages:
name: synchronized
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.0+2"
version: "3.1.0"
table_calendar:
dependency: "direct main"
description:
... ... @@ -1611,5 +1618,5 @@ packages:
source: hosted
version: "3.1.1"
sdks:
dart: ">=2.18.0 <3.0.0"
dart: ">=2.18.2 <3.0.0"
flutter: ">=3.3.0"
... ...
... ... @@ -208,6 +208,8 @@ dependencies:
path: library/sendsms-1.0.3
device_utils_my:
path: library/device_utils_my
flutter_wxwork:
path: library/flutter_wxwork
#联系人索引
azlistview: ^2.0.0
# wechat_assets_picker: ^6.0.6
... ... @@ -244,6 +246,7 @@ dependencies:
# 生成excel
excel: ^3.0.0
# workmanager: ^0.5.1
# flutter_wxwork: ^0.0.3
... ...