Files
cordova-shuto-api/README.md

14 KiB
Raw Permalink Blame History

ShutoApi Cordova Plugin

这是一个Cordova插件用于在前端和原生代码之间进行通信特别是提供了后台触发前端导航的功能。

安装

cordova plugin add /path/to/cordova-shuto-api

API参考

方法

close()

关闭当前功能或视图。

cordova.plugins.ShutoApi.close(
    function() {
        console.log('Close success');
    },
    function(error) {
        console.error('Close error:', error);
    }
);

getUserInfo()

获取用户信息。

cordova.plugins.ShutoApi.getUserInfo(
    function(userInfo) {
        console.log('User info:', userInfo);
    },
    function(error) {
        console.error('Get user info error:', error);
    }
);

ionicReady()

标识前端应用已就绪。调用此方法后,原生代码中的事件管理器会触发 ionicReady 事件。

cordova.plugins.ShutoApi.ionicReady();

建议在应用初始化完成后调用:

document.addEventListener('deviceready', function() {
    // 应用初始化逻辑...
    
    // 通知原生代码前端已就绪
    cordova.plugins.ShutoApi.ionicReady();
}, false);

事件

navigate

当后台需要前端导航到指定路由时触发。

事件数据:

  • route: 需要导航到的路由路径
  • params: 导航参数(可选,对象类型)

uploadLog

当后台需要前端上传日志时触发。前端从本地存储获取日志数据并上传,完成后需要通过 callback 返回上传结果。

事件数据:

  • 无参数(前端从本地获取日志数据)

syncTodo

当后台需要前端同步待办事项时触发。前端接收用户信息参数,同步待办事项数据后通过 callback 返回结果。

事件数据:

  • userInfo: 用户信息对象,包含用户标识等信息

事件监听示例

基本用法(无回调事件)

// 监听导航事件
cordova.plugins.ShutoApi.addEventListener('navigate', function(data) {
    console.log('需要导航到:', data.route);
    console.log('导航参数:', data.params);
    
    // 在这里实现前端导航逻辑
    // 例如如果使用Vue Router:
    // router.push({ path: data.route, query: data.params || {} });
    
    // 例如如果使用React Router:
    // history.push(data.route, data.params || {});
    
    // 例如如果使用React Router v6:
    // navigate(data.route, { state: data.params || {} });
});

// 监听日志上传事件(需要回调)
cordova.plugins.ShutoApi.addEventListener('uploadLog', function(_, callback) {
    console.log('触发日志上传');

    // 从本地存储获取日志数据
    var logData = {
        logs: JSON.parse(localStorage.getItem('appLogs') || '[]'),
        timestamp: Date.now(),
        appVersion: '1.0.0'
    };

    // 模拟异步上传(使用 setTimeout 模拟网络延迟)
    setTimeout(function() {
        try {
            // 模拟上传到服务器
            var uploadResult = {
                success: true,
                uploadedAt: new Date().toISOString(),
                recordId: 'log_' + Date.now(),
                count: logData.logs.length
            };

            console.log('日志上传成功:', uploadResult);

            // 上传成功后清空本地日志
            localStorage.removeItem('appLogs');

            // 返回成功结果
            callback(uploadResult);
        } catch (error) {
            console.error('日志上传失败:', error.message);
            // 返回错误信息
            callback(null, error.message);
        }
    }, 1500); // 模拟 1.5 秒的网络延迟
});

// 监听待办事项同步事件(需要回调)
cordova.plugins.ShutoApi.addEventListener('syncTodo', function(userInfo) {
    console.log('触发待办事项同步:', userInfo);
});

带回调的事件

如果事件需要前端处理后返回结果,可以使用带回调的事件:

// 监听需要回调的事件
cordova.plugins.ShutoApi.addEventListener('confirm', function(data, callback) {
    console.log('确认消息:', data.message);
    
    // 显示确认对话框
    if (confirm(data.message)) {
        // 用户确认,返回成功
        callback({ confirmed: true });
    } else {
        // 用户取消,返回错误
        callback(null, 'User cancelled');
    }
});

// 监听需要异步处理的事件
cordova.plugins.ShutoApi.addEventListener('fetchData', function(params, callback) {
    console.log('需要获取数据:', params.url);
    
    // 异步获取数据
    fetch(params.url)
        .then(response => response.json())
        .then(data => {
            // 成功回调
            callback(data);
        })
        .catch(error => {
            // 错误回调
            callback(null, error.message);
        });
});

移除事件监听

// 定义事件处理函数
function handleNavigate(data) {
    console.log('需要导航到:', data.route);
    // 处理导航逻辑
}

// 添加事件监听
cordova.plugins.ShutoApi.addEventListener('navigate', handleNavigate);

// 移除事件监听
cordova.plugins.ShutoApi.removeEventListener('navigate', handleNavigate);

原生代码使用

独立事件管理器ShutoEventManager

插件提供了独立的事件管理器 ShutoEventManager用于在原生代码中进行事件的监听和触发。这与Cordova插件分离可以在任何原生代码中使用。

事件列表

  • ionicReady: 当前端调用 ionicReady() 方法时触发

iOS

1. 导入头文件

#import "ShutoEventManager.h"

2. 注册事件监听

// 让类遵循 ShutoEventListener 协议
@interface YourViewController () <ShutoEventListener>
@end

@implementation YourViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 注册 ionicReady 事件监听
    [[ShutoEventManager sharedInstance] addListenerForEvent:@"ionicReady" listener:self];
}

// 实现协议方法
- (void)onEvent:(NSString *)eventName data:(NSDictionary *)data {
    if ([eventName isEqualToString:@"ionicReady"]) {
        NSLog(@"前端已就绪,可以执行后续操作");
        // 在这里处理前端就绪后的逻辑
    }
}

- (void)dealloc {
    // 移除所有事件监听
    [[ShutoEventManager sharedInstance] removeListener:self];
}

@end

3. 移除事件监听

// 移除特定事件的监听
[[ShutoEventManager sharedInstance] removeListenerForEvent:@"ionicReady" listener:self];

// 移除所有事件的监听
[[ShutoEventManager sharedInstance] removeListener:self];

4. 触发自定义事件

// 触发事件(可带数据)
NSDictionary *eventData = @{
    @"key": @"value",
    @"timestamp": @([NSDate timeIntervalSinceReferenceDate])
};
[[ShutoEventManager sharedInstance] fireEvent:@"customEvent" data:eventData];

// 触发事件(不带数据)
[[ShutoEventManager sharedInstance] fireEvent:@"customEvent" data:nil];

5. 通过插件实例触发事件Cordova相关

在iOS原生代码中可以通过以下方式触发事件

// 假设你有一个ShutoApi实例
ShutoApi* pluginInstance = [[ShutoApi alloc] init];

// 触发导航事件 - 无参数调用
[pluginInstance navigateToRoute:@"/home/dashboard" parameters:nil];

// 触发导航事件 - 带参数调用
NSDictionary* params = @{
    @"userId": @"12345",
    @"showDetails": @YES
};
[pluginInstance navigateToRoute:@"/user/profile" parameters:params];

// 触发带回调的事件 - 日志上传
[pluginInstance fireEventWithCallback:@"uploadLog" parameters:nil callback:^(NSDictionary* result, NSError* error) {
    if (error) {
        NSLog(@"日志上传失败: %@", error.localizedDescription);
    } else {
        NSLog(@"日志上传成功: %@", result);
        BOOL success = [result[@"success"] boolValue];
        NSString* recordId = result[@"recordId"];
        NSInteger count = [result[@"count"] integerValue];
        NSLog(@"成功上传 %ld 条日志", (long)count);
        // 处理上传结果
    }
}];

// 触发带回调的事件 - 确认对话框
NSDictionary* confirmData = @{
    @"message": @"确定要删除吗?"
};
[pluginInstance fireEventWithCallback:@"confirm" parameters:confirmData callback:^(NSDictionary* result, NSError* error) {
    if (error) {
        NSLog(@"确认失败: %@", error.localizedDescription);
    } else {
        BOOL confirmed = [result[@"confirmed"] boolValue];
        if (confirmed) {
            NSLog(@"用户已确认");
        } else {
            NSLog(@"用户取消");
        }
    }
}];

// 触发带回调的事件 - 获取数据
NSDictionary* fetchData = @{
    @"url": @"https://api.example.com/data"
};
[pluginInstance fireEventWithCallback:@"fetchData" parameters:fetchData callback:^(NSDictionary* result, NSError* error) {
    if (error) {
        NSLog(@"获取数据失败: %@", error.localizedDescription);
    } else {
        NSLog(@"获取数据成功: %@", result);
    }
}];

Android

1. 导入类

import cn.shuto.feishuapi.ShutoEventManager;
import cn.shuto.feishuapi.ShutoEventListener;

2. 注册事件监听

public class YourActivity extends AppCompatActivity implements ShutoEventListener {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 注册 ionicReady 事件监听
        ShutoEventManager.getInstance().addListener("ionicReady", this);
    }
    
    // 实现接口方法
    @Override
    public void onEvent(String eventName, Map<String, Object> data) {
        if ("ionicReady".equals(eventName)) {
            Log.d("YourActivity", "前端已就绪,可以执行后续操作");
            // 在这里处理前端就绪后的逻辑
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 移除所有事件监听
        ShutoEventManager.getInstance().removeListener(this);
    }
}

3. 移除事件监听

// 移除特定事件的监听
ShutoEventManager.getInstance().removeListener("ionicReady", this);

// 移除所有事件的监听
ShutoEventManager.getInstance().removeListener(this);

4. 触发自定义事件

// 触发事件(可带数据)
Map<String, Object> eventData = new HashMap<>();
eventData.put("key", "value");
eventData.put("timestamp", System.currentTimeMillis());
ShutoEventManager.getInstance().fireEvent("customEvent", eventData);

// 触发事件(不带数据)
ShutoEventManager.getInstance().fireEvent("customEvent");

5. 通过插件实例触发事件Cordova相关

在Android原生代码中可以通过以下方式触发事件

// 假设你有一个ShutoApi实例
ShutoApi pluginInstance = new ShutoApi();

try {
    // 触发导航事件 - 无参数调用
    pluginInstance.navigateToRoute("/home/dashboard", null);

    // 触发导航事件 - 带参数调用
    JSONObject params = new JSONObject();
    params.put("userId", "12345");
    params.put("showDetails", true);
    pluginInstance.navigateToRoute("/user/profile", params);

    // 触发带回调的事件 - 日志上传
    pluginInstance.fireEventWithCallback("uploadLog", null, new ShutoApi.EventCallback() {
        @Override
        public void onResult(JSONObject result) {
            try {
                boolean success = result.getBoolean("success");
                String recordId = result.getString("recordId");
                int count = result.getInt("count");
                Log.d("ShutoApi", "日志上传成功: " + result.toString());
                Log.d("ShutoApi", "成功上传 " + count + " 条日志");
                // 处理上传结果
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onError(String errorMessage) {
            Log.e("ShutoApi", "日志上传失败: " + errorMessage);
        }
    });

    // 触发带回调的事件 - 确认对话框
    JSONObject confirmData = new JSONObject();
    confirmData.put("message", "确定要删除吗?");
    pluginInstance.fireEventWithCallback("confirm", confirmData, new ShutoApi.EventCallback() {
        @Override
        public void onResult(JSONObject result) {
            try {
                boolean confirmed = result.getBoolean("confirmed");
                if (confirmed) {
                    Log.d("ShutoApi", "用户已确认");
                } else {
                    Log.d("ShutoApi", "用户取消");
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onError(String errorMessage) {
            Log.e("ShutoApi", "确认失败: " + errorMessage);
        }
    });

    // 触发带回调的事件 - 获取数据
    JSONObject fetchData = new JSONObject();
    fetchData.put("url", "https://api.example.com/data");
    pluginInstance.fireEventWithCallback("fetchData", fetchData, new ShutoApi.EventCallback() {
        @Override
        public void onResult(JSONObject result) {
            Log.d("ShutoApi", "获取数据成功: " + result.toString());
        }

        @Override
        public void onError(String errorMessage) {
            Log.e("ShutoApi", "获取数据失败: " + errorMessage);
        }
    });
} catch (JSONException e) {
    e.printStackTrace();
}

注意事项

  1. 确保在使用事件监听之前Cordova设备已经准备就绪。可以在deviceready事件后进行初始化:
document.addEventListener('deviceready', function() {
    // 在这里设置事件监听
    cordova.plugins.ShutoApi.addEventListener('navigate', function(data) {
        // 处理导航事件
    });
}, false);
  1. 当不再需要事件监听时,记得移除它,以避免内存泄漏。

  2. 事件监听是持久化的,只要插件处于活动状态,就会保持监听。