【问题标题】:Load file downloaded iOS app created in Unity在 Unity 中创建的加载文件下载 iOS 应用程序
【发布时间】:2016-10-21 15:15:59
【问题描述】:

我正在尝试加载下载并保存在 iOS 设备的 persistentDataPath 中的 json 文件。下载和保存效果很好。但是我认为我在加载文件时遇到了很大的问题。事实上,当我尝试在 Xcode 中编译项目时,我会收到一些错误消息。

首先是我的 C# 代码:

using UnityEngine;
using System.Collections;
using System.IO;
using System.Net;
using UnityEngine.UI;

public class ReadJson : MonoBehaviour
{
    public Text City;
    public Text Temperature;
    public Image Weather;
    public Text WeatherUrl;

    [System.Serializable]
    public class CityInfo 
    {
        public string name;
    }

    [System.Serializable]
    public class CurrentCondition
    {
        public string date; 
        public string hour; 
        public int tmp; 
        public int wnd_spd; 
        public int wnd_gust; 
        public string wnd_dir; 
        public double pressure; 
        public int humidity; 
        public string condition; 
        public string icon; 
        public string icon_big;
    }

    [System.Serializable]
    public class RootObject
    {
        public CityInfo city_info;
        public CurrentCondition current_condition;
    }

    void Start () {

        WebClient client = new WebClient();
        File.Delete(Path.Combine (Application.persistentDataPath, "myjson.json"));
        client.DownloadFile ("http://www.myjsonurl", Path.Combine (Application.persistentDataPath, "myjson.json"));

        TextAsset asset = Resources.Load (Path.Combine (Application.dataPath + "/Documents", "myjson")) as TextAsset;

        RootObject m = JsonUtility.FromJson<RootObject> (asset.text);

        City.text = m.city_info.name;
        Temperature.text = (m.current_condition.tmp).ToString();

    }
}

现在是 xcode 控制台:

2016-10-21 17:01:20.766001 json[1404:516674] [DYMTLInitPlatform] platform initialization successful

2016-10-21 17:01:20.929950 json[1404:516508] -> registered mono modules 0xb95f70
2016-10-21 17:01:21.356590 json[1404:516508] You've implemented -[<UIApplicationDelegate> application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need to add "remote-notification" to the list of your supported UIBackgroundModes in your Info.plist.
-> applicationDidFinishLaunching()
2016-10-21 17:01:21.452967 json[1404:516508] Metal GPU Frame Capture Enabled
2016-10-21 17:01:21.453369 json[1404:516508] Metal API Validation Enabled
-> applicationDidBecomeActive()
Init: screen size 750x1334
Initializing Metal device caps
Initialize engine version: 5.3.4f1 (fdbb5133b820)
UnloadTime: 1.705875 ms
Salut/var/mobile/Containers/Data/Application/51A2490E-94EB-4904-9F2E-112AD5632A98/Documents

(Filename: /Users/builduser/buildslave/unity/build/artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)

NullReferenceException: A null value was found where an object instance was required.


(Filename: currently not available on il2cpp Line: -1)

Setting up 1 worker threads for Enlighten.
  Thread -> id: 19f17000 -> priority: 1 

如果有人有想法。提前非常感谢。

【问题讨论】:

  • 您说最大的问题是加载文件。然后你说当你尝试在 Xcode 中编译项目时,你有一些错误信息......你的问题是哪一个?这能编译吗?如果没有编译,那么这与加载json文件无关。
  • 该项目编译得很好,但是在应用程序加载后,它会崩溃并显示错误消息。所以问题来自json文件加载。

标签: c# ios json xcode unity3d


【解决方案1】:

您的代码的问题出在这一行:

TextAsset asset = Resources.Load(Path.Combine(Application.dataPath + "/Documents", "myjson")) as TextAsset;

我认为您不了解如何以及何时使用Resources.Load。如果您想使用Resources.Load 功能,您必须从编辑器中创建一个特殊文件夹。此文件夹应位于&lt;ProjectDirectory&gt;/Assets/Resources。您可以从编辑器将内容放入/写入此文件夹。在 iOS 上构建后你不能这样做。构建后它变为只读。然后可以使用Resources.Load 函数读取此特殊文件夹。

替换:

TextAsset asset = Resources.Load(Path.Combine(Application.dataPath + "/Documents", "myjson")) as TextAsset;

string text = File.ReadAllText(Path.Combine(Application.persistentDataPath, "myjson.json"));
RootObject m = JsonUtility.FromJson<RootObject>(text);
City.text = m.city_info.name;
Temperature.text = (m.current_condition.tmp).ToString();

应该可以解决你的问题。

另一个不应使用的 API 是 WebClient。除非您有充分的理由使用它,否则您不应该使用它。您应该使用WWWUnityWebRequest(更新和推荐)API。

如果没有WebClient,您的代码应该是这样的:

void Start()
{
    StartCoroutine(DownloadAndloadJson());
}

IEnumerator DownloadAndloadJson()
{
    string url = "http://www.myjsonurl";

    UnityWebRequest www = UnityWebRequest.Get(url);
    yield return www.Send();

    if (www.isError)
    {
        Debug.Log(www.error);
    }
    else
    {
        //Sucessfully downloaded the Json File
        Debug.Log("Json: " + www.downloadHandler.text);

        string jsonFile = www.downloadHandler.text;

        //Delete old json file. Don't know why but this was in your original code
        File.Delete(Path.Combine(Application.persistentDataPath, "myjson.json"));

        //Save the downloaded data as File
        File.WriteAllText(Path.Combine(Application.persistentDataPath, "myjson.json"), jsonFile);

        //Load the downloaded data 
        string text = File.ReadAllText(Path.Combine(Application.persistentDataPath, "myjson.json"));

        Debug.Log(text);
        RootObject m = JsonUtility.FromJson<RootObject>(text);
        City.text = m.city_info.name;
        Temperature.text = (m.current_condition.tmp).ToString();
    }
}

如果您有问题,请更新到 Unity 5.4。 UnityWebRequest API 应该用于此,它是在 5.3 中引入的,但在 5.4 中修复了错误。您需要using UnityEngine.Networking; 才能使用UnityWebRequest

【讨论】:

  • 非常感谢,它可以很好地替换您所说的代码。也感谢第二个解决方案,我会尝试但首先我需要更新 Unity ;-)
  • 您不必为第二个解决方案更新 Unity,因为 Unity 5.3 支持该解决方案,但我建议在出现问题时进行更新。您当前使用WebClient 的解决方案会在下载内容时冻结您的应用程序。您现在可能不会注意到,但是当要下载的数据很大时,您会注意到它。还有其他原因,例如 App Store 现在禁止不支持 https 的应用程序。这个带有WebClient 的 Unity 版本不支持它,因此您的应用程序将被拒绝。不客气!
  • 好的,我刚刚使用您的第二个解决方案进行了测试。效果很好。一次又一次的感谢。关于应用商店的条件,您是对的。最好这样。此时 Unity 5.3 没有问题
  • 不错。编码愉快!
猜你喜欢
  • 2012-05-17
  • 2014-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
相关资源
最近更新 更多