refactor(ios): 优化事件回调处理并添加详细日志

添加ShutoApiProtocol协议明确接口定义
移除不必要的__attribute__修饰符
在关键路径添加详细日志记录
增加对空错误消息的检查
This commit is contained in:
2026-01-19 12:50:23 +08:00
parent 25e4560fd9
commit a06c7abfc8
2 changed files with 67 additions and 49 deletions

View File

@@ -50,13 +50,10 @@ cordova.plugins.ShutoApi.getUserInfo(
- `params`: 导航参数(可选,对象类型)
#### uploadLog
当后台需要前端上传日志时触发。前端处理完成后需要通过 callback 返回上传结果。
当后台需要前端上传日志时触发。前端从本地存储获取日志数据并上传,完成后需要通过 callback 返回上传结果。
**事件数据:**
- `logType`: 日志类型(如 "error", "warning", "info" 等
- `message`: 日志消息内容
- `timestamp`: 日志时间戳(可选)
- `extra`: 额外的日志数据(可选,对象类型)
- 无参数(前端从本地获取日志数据
## 事件监听示例
@@ -80,27 +77,40 @@ cordova.plugins.ShutoApi.addEventListener('navigate', function(data) {
});
// 监听日志上传事件(需要回调)
cordova.plugins.ShutoApi.addEventListener('uploadLog', function(data, callback) {
console.log('日志类型:', data.logType);
console.log('日志消息:', data.message);
console.log('时间戳:', data.timestamp);
console.log('额外数据:', data.extra);
cordova.plugins.ShutoApi.addEventListener('uploadLog', function(_, callback) {
console.log('触发日志上传');
// 在这里实现日志上传逻辑
// 例如,发送到日志服务器
uploadToLogServer(data)
.then(function(result) {
// 上传成功,返回结果
callback({
// 从本地存储获取日志数据
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: result.recordId
});
})
.catch(function(error) {
// 上传失败,返回错误
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 秒的网络延迟
});
```
@@ -178,22 +188,15 @@ NSDictionary* params = @{
[pluginInstance navigateToRoute:@"/user/profile" parameters:params];
// 触发带回调的事件 - 日志上传
NSDictionary* logData = @{
@"logType": @"error",
@"message": @"Network request failed",
@"timestamp": @([[NSDate date] timeIntervalSince1970]),
@"extra": @{
@"url": @"https://api.example.com/data",
@"statusCode": @500
}
};
[pluginInstance fireEventWithCallback:@"uploadLog" parameters:logData callback:^(NSDictionary* result, NSError* error) {
[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);
// 处理上传结果
}
}];
@@ -247,23 +250,15 @@ try {
pluginInstance.navigateToRoute("/user/profile", params);
// 触发带回调的事件 - 日志上传
JSONObject logData = new JSONObject();
logData.put("logType", "error");
logData.put("message", "Network request failed");
logData.put("timestamp", System.currentTimeMillis() / 1000.0);
JSONObject extra = new JSONObject();
extra.put("url", "https://api.example.com/data");
extra.put("statusCode", 500);
logData.put("extra", extra);
pluginInstance.fireEventWithCallback("uploadLog", logData, new ShutoApi.EventCallback() {
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();

View File

@@ -4,7 +4,12 @@
#import <WebKit/WebKit.h>
#import "SGGC_Log.h"
@interface ShutoApi : CDVPlugin <NSObject> {
@protocol ShutoApiProtocol <NSObject>
- (void)fireEvent:(NSString*)type parameters:(NSDictionary*)parameters;
- (void)fireEventWithCallback:(NSString*)eventName parameters:(NSDictionary*)parameters callback:(void (^)(NSDictionary* result, NSError* error))callback;
@end
@interface ShutoApi : CDVPlugin <ShutoApiProtocol> {
// ID
NSString* _eventCallbackId;
//
@@ -17,9 +22,9 @@
- (void)registerEvent:(CDVInvokedUrlCommand*)command;
- (void)getUserInfo:(CDVInvokedUrlCommand*)command;
- (void)setUserInfo:(CDVInvokedUrlCommand*)command;
- (void)navigateToRoute:(NSString*)route parameters:(NSDictionary*)parameters __attribute__((objc_method_family(none)));
- (void)fireEvent:(NSString*)type parameters:(NSDictionary*)parameters __attribute__((objc_method_family(none)));
- (void)fireEventWithCallback:(NSString*)eventName parameters:(NSDictionary*)parameters callback:(void (^)(NSDictionary* result, NSError* error))callback __attribute__((objc_method_family(none)));
- (void)navigateToRoute:(NSString*)route parameters:(NSDictionary*)parameters;
- (void)fireEvent:(NSString*)type parameters:(NSDictionary*)parameters;
- (void)fireEventWithCallback:(NSString*)eventName parameters:(NSDictionary*)parameters callback:(void (^)(NSDictionary* result, NSError* error))callback;
- (void)eventCallback:(CDVInvokedUrlCommand*)command;
@end
@@ -139,16 +144,20 @@
//
- (void)fireEventWithCallback:(NSString*)eventName parameters:(NSDictionary*)parameters callback:(void (^)(NSDictionary* result, NSError* error))callback {
[SGGC_Log log:@"SGGC_CDVFile" message:[NSString stringWithFormat:@"ShutoApi: fireEventWithCallback called, eventName=%@, parameters=%@", eventName, parameters]];
if (!_eventCallbackId) {
[SGGC_Log log:@"SGGC_CDVFile" message:(@"ShutoApi: No event callback registered")];
[SGGC_Log log:@"SGGC_CDVFile" message:@"ShutoApi: No event callback registered"];
if (callback) callback(nil, [NSError errorWithDomain:@"ShutoApi" code:-1 userInfo:@{NSLocalizedDescriptionKey:@"No event callback registered"}]);
return;
}
NSString* callbackId = [[NSUUID UUID] UUIDString];
[SGGC_Log log:@"SGGC_CDVFile" message:[NSString stringWithFormat:@"ShutoApi: Generated callbackId=%@", callbackId]];
if (callback) {
_eventCallbacks[callbackId] = callback;
[SGGC_Log log:@"SGGC_CDVFile" message:[NSString stringWithFormat:@"ShutoApi: Callback saved, _eventCallbacks count=%lu", (unsigned long)_eventCallbacks.count]];
}
NSMutableDictionary* eventData = [NSMutableDictionary dictionary];
@@ -159,6 +168,8 @@
[eventData setObject:parameters forKey:@"params"];
}
[SGGC_Log log:@"SGGC_CDVFile" message:[NSString stringWithFormat:@"ShutoApi: Sending event to webview, eventData=%@", eventData]];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:eventData];
[pluginResult setKeepCallbackAsBool:YES];
[self.commandDelegate sendPluginResult:pluginResult callbackId:_eventCallbackId];
@@ -166,20 +177,32 @@
//
- (void)eventCallback:(CDVInvokedUrlCommand*)command {
[SGGC_Log log:@"SGGC_CDVFile" message:[NSString stringWithFormat:@"ShutoApi: eventCallback called with arguments: %@", command.arguments]];
NSString* callbackId = command.arguments[0];
NSDictionary* result = command.arguments[1];
NSString* errorMessage = command.arguments[2];
[SGGC_Log log:@"SGGC_CDVFile" message:[NSString stringWithFormat:@"ShutoApi: callbackId=%@, result=%@, errorMessage=%@", callbackId, result, errorMessage]];
[SGGC_Log log:@"SGGC_CDVFile" message:[NSString stringWithFormat:@"ShutoApi: _eventCallbacks count=%lu", (unsigned long)_eventCallbacks.count]];
void (^callback)(NSDictionary* result, NSError* error) = _eventCallbacks[callbackId];
if (callback) {
[SGGC_Log log:@"SGGC_CDVFile" message:[NSString stringWithFormat:@"ShutoApi: Found callback for callbackId=%@", callbackId]];
NSError* error = nil;
if (errorMessage) {
if (errorMessage && ![errorMessage isKindOfClass:[NSNull class]]) {
error = [NSError errorWithDomain:@"ShutoApi" code:-1 userInfo:@{NSLocalizedDescriptionKey:errorMessage}];
}
callback(result, error);
[_eventCallbacks removeObjectForKey:callbackId];
[SGGC_Log log:@"SGGC_CDVFile" message:@"ShutoApi: Callback executed and removed"];
} else {
[SGGC_Log log:@"SGGC_CDVFile" message:[NSString stringWithFormat:@"ShutoApi: No callback found for callbackId=%@", callbackId]];
}
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];