问题描述
我一直在尝试使用weatherbit.io API访问我的android应用程序中的AQI信息。脚本AqiInfoScript
用于访问API,Update AQI
脚本用于将值打印出来。
AqiInfoScript:
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using SimpleJSON;
public class AqiInfoScript : MonoBehavIoUr
{
private float timer;
public float minutesBetweenUpdate;
private float latitude;
private float longitude;
private bool locationInitialized;
public static string cityName;
public static double currentAqi;
private readonly string baseWeatherbitURL = "https://api.weatherbit.io/v2.0/current/airquality?";
private readonly string key = "*********************";
public void Begin()
{
latitude = GPS.latitude;
longitude = GPS.longitude;
locationInitialized = true;
}
void Update()
{
if (locationInitialized)
{
if (timer <= 0)
{
StartCoroutine(GetAqi());
timer = minutesBetweenUpdate * 60;
}
else
{
timer -= Time.deltaTime;
}
}
}
private IEnumerator GetAqi()
{
string weatherbitURL = baseWeatherbitURL + "lat=" + latitude + "&lon=" + longitude + "&key="
+ key;
UnityWebRequest aqiInfoRequest = UnityWebRequest.Get(weatherbitURL);
yield return aqiInfoRequest.SendWebRequest();
//error
if (aqiInfoRequest.isNetworkError || aqiInfoRequest.isHttpError)
{
Debug.LogError(aqiInfoRequest.error);
yield break;
}
JSONNode aqiInfo = JSON.Parse(aqiInfoRequest.downloadHandler.text);
cityName = aqiInfo["city_name"];
currentAqi = aqiInfo["data"]["aqi"];
}
}
更新AQI脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UpdateAQI : MonoBehavIoUr
{
public Text airquality;
//public Text coordinates;
private void Update()
{
airquality.text = "Current Aqi: " + AqiInfoScript.currentAqi.ToString();
}
}
当前输出:当前AQI:0 所需的输出:当前AQI:129.0000
解决方法
问题
如我所见,API返回your request,例如用于lat=42,lon=-7
以下JSON
{
"data":[
{
"mold_level":1,"aqi":54,"pm10":7.71189,"co":298.738,"o3":115.871,"predominant_pollen_type":"Molds","so2":0.952743,"pollen_level_tree":1,"pollen_level_weed":1,"no2":0.233282,"pm25":6.7908,"pollen_level_grass":1
}
],"city_name":"Pías","lon":-7,"timezone":"Europe\/Madrid","lat":42,"country_code":"ES","state_code":"55"
}
如您所见,"data"
实际上是一个数组。您将其视为单个值。
幕后花絮
不幸的是,您正在使用的SmipleJson库很容易出错,因为它不会为拼写错误引发任何异常,而是默默地失败并使用默认值。
例如,您可以看到在
public override JSONNode this[string aKey]
{
get
{
if (m_Dict.ContainsKey(aKey))
return m_Dict[aKey];
else
return new JSONLazyCreator(this,aKey);
}
....
}
和
public static implicit operator double(JSONNode d)
{
return (d == null) ? 0 : d.AsDouble;
}
解决方案
应该是
cityName = aqiInfo["city_name"];
currentAqi = aqiInfo["data"][0]["aqi"].AsDouble;
Debug.Log($"cityName = {cityName}\ncurrentAqi = {currentAqi}");
通常,我建议使用JsonUtility.FromJson
而不是在c#中实现所需的数据结构,例如:
[Serializable]
public class Data
{
public int mold_level;
public double aqi;
public double pm10;
public double co;
public double o3;
public string predominant_pollen_type;
public double so2;
public int pollen_level_tree;
public int pollen_level_weed;
public double no2;
public double pm25;
public int pollen_level_grass;
}
[Serializable]
public class Root
{
public List<Data> data;
public string city_name;
public int lon;
public string timezone;
public int lat;
public string country_code;
public string state_code;
}
然后您将使用
var aqiInfo = JsonUtility.FromJson<Root>(aqiInfoRequest.downloadHandler.text);
cityName = aqiInfo.city_name;
currentAqi = aqiInfo.data[0].aqi;
Debug.Log($"cityName = {cityName}\ncurrentAqi = {currentAqi}");
对我来说,两次伪值lat=42,lon=-7
都按预期打印出来
cityName = Pías
currentAqi = 54
UnityEngine.Debug:Log(Object)
<GetAqi>d__18:MoveNext() (at Assets/Example.cs:109)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator,IntPtr)