# ShutoApi Cordova Plugin 这是一个Cordova插件,用于在前端和原生代码之间进行通信,特别是提供了后台触发前端导航的功能。 ## 安装 ```bash cordova plugin add /path/to/cordova-shuto-api ``` ## API参考 ### 方法 #### close() 关闭当前功能或视图。 ```javascript cordova.plugins.ShutoApi.close( function() { console.log('Close success'); }, function(error) { console.error('Close error:', error); } ); ``` #### getUserInfo() 获取用户信息。 ```javascript cordova.plugins.ShutoApi.getUserInfo( function(userInfo) { console.log('User info:', userInfo); }, function(error) { console.error('Get user info error:', error); } ); ``` #### ionicReady() 标识前端应用已就绪。调用此方法后,原生代码中的事件管理器会触发 `ionicReady` 事件。 ```javascript cordova.plugins.ShutoApi.ionicReady(); ``` 建议在应用初始化完成后调用: ```javascript document.addEventListener('deviceready', function() { // 应用初始化逻辑... // 通知原生代码前端已就绪 cordova.plugins.ShutoApi.ionicReady(); }, false); ``` ### 事件 #### navigate 当后台需要前端导航到指定路由时触发。 **事件数据:** - `route`: 需要导航到的路由路径 - `params`: 导航参数(可选,对象类型) #### uploadLog 当后台需要前端上传日志时触发。前端从本地存储获取日志数据并上传,完成后需要通过 callback 返回上传结果。 **事件数据:** - 无参数(前端从本地获取日志数据) #### syncTodo 当后台需要前端同步待办事项时触发。前端接收用户信息参数,同步待办事项数据后通过 callback 返回结果。 **事件数据:** - `userInfo`: 用户信息对象,包含用户标识等信息 ## 事件监听示例 ### 基本用法(无回调事件) ```javascript // 监听导航事件 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); }); ``` ### 带回调的事件 如果事件需要前端处理后返回结果,可以使用带回调的事件: ```javascript // 监听需要回调的事件 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); }); }); ``` ### 移除事件监听 ```javascript // 定义事件处理函数 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. 导入头文件 ```objective-c #import "ShutoEventManager.h" ``` #### 2. 注册事件监听 ```objective-c // 让类遵循 ShutoEventListener 协议 @interface YourViewController () @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. 移除事件监听 ```objective-c // 移除特定事件的监听 [[ShutoEventManager sharedInstance] removeListenerForEvent:@"ionicReady" listener:self]; // 移除所有事件的监听 [[ShutoEventManager sharedInstance] removeListener:self]; ``` #### 4. 触发自定义事件 ```objective-c // 触发事件(可带数据) NSDictionary *eventData = @{ @"key": @"value", @"timestamp": @([NSDate timeIntervalSinceReferenceDate]) }; [[ShutoEventManager sharedInstance] fireEvent:@"customEvent" data:eventData]; // 触发事件(不带数据) [[ShutoEventManager sharedInstance] fireEvent:@"customEvent" data:nil]; ``` #### 5. 通过插件实例触发事件(Cordova相关) 在iOS原生代码中,可以通过以下方式触发事件: ```objective-c // 假设你有一个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. 导入类 ```java import cn.shuto.feishuapi.ShutoEventManager; import cn.shuto.feishuapi.ShutoEventListener; ``` #### 2. 注册事件监听 ```java 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 data) { if ("ionicReady".equals(eventName)) { Log.d("YourActivity", "前端已就绪,可以执行后续操作"); // 在这里处理前端就绪后的逻辑 } } @Override protected void onDestroy() { super.onDestroy(); // 移除所有事件监听 ShutoEventManager.getInstance().removeListener(this); } } ``` #### 3. 移除事件监听 ```java // 移除特定事件的监听 ShutoEventManager.getInstance().removeListener("ionicReady", this); // 移除所有事件的监听 ShutoEventManager.getInstance().removeListener(this); ``` #### 4. 触发自定义事件 ```java // 触发事件(可带数据) Map eventData = new HashMap<>(); eventData.put("key", "value"); eventData.put("timestamp", System.currentTimeMillis()); ShutoEventManager.getInstance().fireEvent("customEvent", eventData); // 触发事件(不带数据) ShutoEventManager.getInstance().fireEvent("customEvent"); ``` #### 5. 通过插件实例触发事件(Cordova相关) 在Android原生代码中,可以通过以下方式触发事件: ```java // 假设你有一个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`事件后进行初始化: ```javascript document.addEventListener('deviceready', function() { // 在这里设置事件监听 cordova.plugins.ShutoApi.addEventListener('navigate', function(data) { // 处理导航事件 }); }, false); ``` 2. 当不再需要事件监听时,记得移除它,以避免内存泄漏。 3. 事件监听是持久化的,只要插件处于活动状态,就会保持监听。