升级至SDK 4.2.4后Garmin MonkeyC Communications.makeWebRequest失效求助
问题解决:Garmin SDK中
makeWebRequest回调类型不匹配错误 错误详情
编译时触发类型不匹配错误:
ERROR: fenix6: C:\....\OtherView.mc:90,8: Invalid '$.Toybox.Lang.Method(responseCode as $.Toybox.Lang.Number, data as Null or $.Toybox.Lang.Dictionary) as Void' passed as parameter 4 of type 'PolyType<(callback(responseCode as $.Toybox.Lang.Number, data as Null or $.Toybox.Lang.Dictionary or $.Toybox.Lang.String) as Void) or (callback(responseCode as $.Toybox.Lang.Number, data as Null or $.Toybox.Lang.Dictionary or $.Toybox.Lang.String, context as $.Toybox.Lang.Object) as Void)>'.
问题原因
新版Garmin SDK更新了Communications.makeWebRequest的回调签名要求:
- 回调的
data参数类型从原有的Null or Dictionary扩展为Null or Dictionary or String(当JSON解析失败时,服务器返回的非JSON内容会以字符串形式传入) - 同时支持两种回调形式:带
context参数或不带,但参数类型必须严格匹配
你的旧代码中onReceive方法的data参数仅定义为Dictionary?(即Null or Dictionary),不符合新版SDK的类型规范,因此触发编译错误。
解决方案
修改onReceive方法的参数签名,将data的类型扩展为Null or Dictionary or String,无需额外参数的话可以忽略context,但类型必须匹配要求。
修改后的代码示例
class HttpRequest { protected var onAfterReceive; public function initialize(onAfterReceiveArg) { onAfterReceive = onAfterReceiveArg; } // 调整data参数类型,兼容新版SDK要求 function onReceive(responseCode as Number, data as Null or Dictionary or String) as Void { if (responseCode == 200) { Ui.popView(Ui.SLIDE_IMMEDIATE); System.println("Request Successful"); // 因设置了JSON响应类型,正常情况data为Dictionary,增加类型判断处理异常 if (data is Dictionary) { Extensions.setPropertyAndStorage("test", data["test"]); Extensions.setPropertyAndStorage("test1", data["test1"] + "/" + data["test2"]); self.onAfterReceive.invoke(); } else { // 处理JSON解析失败场景 System.println("Invalid JSON response: " + data); self.onAfterReceive.invoke("Request failed: Invalid response format"); } } else { Ui.popView(Ui.SLIDE_IMMEDIATE); System.println("Response: " + responseCode); self.onAfterReceive.invoke("Can't connect:" + responseCode + "\n" + Extensions.getPropertyOrStorage("test1")); } } function makeRequest() as Void { Ui.pushView( new LoadingView(), null, Ui.SLIDE_IMMEDIATE); var url = "https://removed"; var app = Application.getApp(); var params = { //"definedParams" => "123456789abcdefg" }; var options = { :method => Communications.HTTP_REQUEST_METHOD_GET, :headers => { "Authorization" => app.getProperty("apikey"), "Content-Type" => Communications.REQUEST_CONTENT_TYPE_URL_ENCODED }, :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON }; var responseCallback = method(:onReceive); Communications.makeWebRequest(url, params, options, responseCallback); } }
额外说明
如果需要传递额外数据,可以使用带context参数的回调形式:
function onReceive(responseCode as Number, data as Null or Dictionary or String, context as Object) as Void { // 你的业务逻辑 }
调用时补充传入context参数:
Communications.makeWebRequest(url, params, options, responseCallback, yourContextObject);
内容的提问来源于stack exchange,提问作者jarekj9
相关产品推荐
相关产品推荐

