前言:
这周接了一个新的任务,开发一款把本地新版本的ab包上传到服务器的app,好像挺简单的,实际上也历经坎坷,里面涉及到了一些自己不熟悉的模块,不过最后还是按要求完成了任务,现在记录一下涉及到的知识点和解决方法,供以后回顾参考。
一、功能概述
需要实现的功能总的概述:
实现登陆服务器的功能,然后上传ab包对应的json文件,服务器通过上传的json文件与服务器旧的json文件,对比出需要上传的新ab包的名字,本地通过服务器传过来的ab包的名字,依次上传即可。
二、难点分析
- 不重新打包,就可更改配置:
用到了文件读取的功能,我选择的是配置json文件,使用LitJson自带的转对象的方法,把读取到的信息赋值给一个对象,实现此功能。
public class UploadParam
{
public Dictionary<int, string[]> allUrl;
public string loginUrl; //请求登陆url
public string getUpdateListUrl; //请求获取更新组列表Url
public string comparisoUpdateListUrl; //请求对比更新文件url
public string uploadMissingUrl; //上传待上传文件url
public string CheckUploadFileUrl; //检查文件url
public int surpassLoginDay; //上次登录时间过去多久就会重置密码
public int surpassInputDay; //上次登录时间过去多久就会重置密码
public int tryUploadCount; //如果数据丢失,尝试多少次就抛出异常
public string assetJsonPath;
public string localNeedUploadDirPath;
public string iosNamePath;
private static UploadParam instance = null;
private string uploadParamJsonPath = System.IO.Path.Combine(Application.streamingAssetsPath, "UploadParam.json");
public static UploadParam Instance
{
get
{
if (instance == null)
{
instance = new UploadParam();
}
return instance;
}
}
public UploadParam()
{
Encoding encode = Encoding.GetEncoding("utf-8");
if (File.Exists(uploadParamJsonPath))
{
StreamReader sr = new StreamReader(uploadParamJsonPath, encode);
UploadParamJson uploadParamJson = JsonMapper.ToObject<UploadParamJson>(sr);
allUrl = new Dictionary<int, string[]>();
for (int i = 0; i< uploadParamJson.allUrl.domainName.Length; i++)
{
allUrl.Add(i, new string[]{
uploadParamJson.allUrl.domainName[i],uploadParamJson.allUrl.domainUrl[i]
});
}
getUpdateListUrl = uploadParamJson.getUpdateListUrl;
comparisoUpdateListUrl = uploadParamJson.comparisoUpdateListUrl;
uploadMissingUrl = uploadParamJson.uploadMissingUrl;
CheckUploadFileUrl = uploadParamJson.CheckUploadFileUrl;
surpassLoginDay = uploadParamJson.surpassLoginDay;
surpassInputDay = uploadParamJson.surpassInputDay;
tryUploadCount = uploadParamJson.tryUploadCount;
assetJsonPath = uploadParamJson.assetJsonPath;
localNeedUploadDirPath = uploadParamJson.localNeedUploadDirPath;
iosNamePath = uploadParamJson.iosNamePath;
}
}
}
- 打开本地资源管理窗口,并保存选择好的文件夹或者文件路径,并且要支持Mac和Windows系统
最后,找了好久,最后在CSDN上搜到了一个插件。地址:https://download.csdn.net/download/s15100007883/10406823 - 与服务器的的通信,Get和Post
Get方法:
这是发送表单数据的默认方法,这种方法会以 “?name1=value1&name2=value2”的形式,将表单数据附加到URL的后面,提交到服务器处理,这种方法安全性不如post方法,因为表单数据会暴露在URL中,但是它的处理效率要比post方法高。
/// <summary>
/// 尝试向服务器获取更新列表
/// </summary>
/// <returns></returns>
private IEnumerator TryUpdateListGet()
{
//todo 传送的参数需要和服务端确认
UnityWebRequest webRequest = UnityWebRequest.Get(string.Format("{0}?os={1}",
DataManager.Instance.affirmUploadUrl + UploadParam.Instance.getUpdateListUrl, DataManager.Instance.targetOS));
yield return webRequest.SendWebRequest();
if (webRequest.isNetworkError || webRequest.isHttpError)
{
//网络错误
Debug.LogError("网络错误" + webRequest.error);
StartCoroutine(LoggerErrorMessage(MsgReminder.domainError));
}
else
{
//一般请求成功为200(404,500是Server Error)
if (webRequest.responseCode == 200)
{
string str = webRequest.downloadHandler.text;
Debug.Log("得到的原始数据" + str);
Groups groups = JsonMapper.ToObject<Groups>(str);
//分析返回的data 看看是否成功登录
}
}
}
post方法:
用这种方法提交的表单,数据将以数据块的形式提交到服务器,表单数据不会出现在URL中,所以用这种方式提交的表单数据是安全的。如果表单数据中包含类似于密码等数据,建议使用post方法。
添加表单是用WWWForm.AddField方法,注意重载方法的第三个参数是编码格式
WWWForm.AddBinaryData来传递大的数据(json、txt等等)使用方法:
WWWFORM.AddBinaryData(string fieldName,byte [] contents,string fileName = null,string mimeType = null);
包含四个参数重载:(参考:)
string fieldName:字段名(也就是表单元素的name,类似于html表单的) ;
byte [] contents:二进制数据(文件转换的二进制数据);
string fileName = null:文件名(即交托服务器的文件名称,包含文件后缀,如果为空,服务器会默认文件为dat类型);
/// <summary>
/// 上传asset文件
/// </summary>
private IEnumerator StartUploadAssetPost()
{
string assetJsonPath = DataManager.Instance.localUploadFolderPath + string.Format(UploadParam.Instance.assetJsonPath,
DataManager.Instance.targetOS, iosName);
Debug.LogError("Json的路径 " + assetJsonPath);
if (!File.Exists(assetJsonPath))
{
StartCoroutine(LoggerErrorMessage(MsgReminder.assetJsonPathError));
yield break;
}
WWWForm wwwForm = new WWWForm();
wwwForm.AddBinaryData("asset", AuthGetFileData(assetJsonPath), "asset.json");
UnityWebRequest webRequest = UnityWebRequest.Post(string.Format("{0}?groupid={1}&userName={2}&token={3}&version={4}",
DataManager.Instance.affirmUploadUrl + UploadParam.Instance.comparisoUpdateListUrl, DataManager.Instance.groupId,
DataManager.Instance.userName, DataManager.Instance.token, DataManager.Instance.localVersion), wwwForm);
yield return webRequest.SendWebRequest();
if (webRequest.isNetworkError || webRequest.isHttpError)
{
//网络错误
Debug.LogError("网络错误" + webRequest.error);
}
else
{
//一般请求成功为200(404,500是Server Error)
if (webRequest.responseCode == 200)
{
string str = webRequest.downloadHandler.text;
Debug.Log("得到的原始数据" + str);
NeedUploadFile needUploadFile = JsonMapper.ToObject<NeedUploadFile>(str);
//分析返回的data 看看是否成功登录
}
}
}
- LitJson的使用,主要用的是JsonMapper.ToObject<json类对应的自己写的类>(json数据);
public class LoginSuccess
{
public bool success;
public int code;
public string msg;
public LoginSuccessData data;
}
public class LoginSuccessData
{
public string domain;
public string htName;
public string token;
}
//str = "得到的json数据";
LoginSuccess loginSuccess = JsonMapper.ToObject<LoginSuccess>(str);
或者使用JsonData的方式,可以不写json数据对应的类,直接用json的方法调用即可,代码如下:
/*
public class LoginSuccess
{
public bool success;
public int code;
public string msg;
public LoginSuccessData data;
}
public class LoginSuccessData
{
public string domain;
public string htName;
public string token;
}
*/
string str = File.ReadAllText("jsonPath");
JsonData jsonData = new JsonData(str);
bool success = jsonData["success"].ToBoolean();
int code = jsonData["code"].ToInt32();
string domain = jsonData["data"]["domain"].ToString();
... ...