I have prepared xml files with some content and want to load it while playing on iOS device but also I want to change loaded data and serialize it in the same file again.
In Unity Editor (Windows) it works perfectly, but when I test it on iOS device it seems that I can read from StreamingAssets using WWW class, but I can't write into it.
Also I have found that I can read and write into path created by Application.persistentDataPath. But it seems that location somewhere in device and I can't put my xml into that location and users have access to that folder so that isn't good solution, isn't it?
Here code that I use to load and save the data.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using System.Xml;
public class testxml : MonoBehaviour {
public Text result;
public InputField firstPart, secondPart;
public Toggle toggle;
private List<int> listToSave;
// Use this for initialization
void Start () {
listToSave = new List<int>();
}
public void Save()
{
Serialize();
}
public void Load()
{
StartCoroutine(Deserialize());
}
private void Serialize()
{
string path = GetPath();
try
{
Debug.Log("trying to save");
var serializer = new XmlSerializer(typeof(List<int>));
using (var fs = new FileStream(path, FileMode.OpenOrCreate))
{
serializer.Serialize(fs, listToSave);
}
}
catch (XmlException e)
{
result.text = "error";
Debug.LogError(path + " with " + (toggle.isOn ? "persistent data path" : "data path"));
Debug.LogError("xml exc while des file : " + e.Message);
}
catch (System.Exception e)
{
result.text = "error";
Debug.LogError("exc while des file : " + e.Message);
Debug.LogError(path + " with " + (toggle.isOn ? "persistent data path" : "data path"));
System.Exception exc = e.InnerException;
int i = 0;
while (exc != null)
{
Debug.Log("inner " + i + ": " + exc.Message);
i++;
exc = exc.InnerException;
}
}
}
private IEnumerator Deserialize()
{
Debug.Log("trying to load");
string path = GetPath();
var www = new WWW(path);
yield return www;
if (www.isDone && string.IsNullOrEmpty(www.error))
{
try
{
var serializer = new XmlSerializer(typeof(List<int>));
MemoryStream ms = new MemoryStream(www.bytes);
listToSave = serializer.Deserialize(ms) as List<int>;
ms.Close();
result.text += "Done\n";
foreach (var i in listToSave)
result.text += i + "\n";
}
catch (XmlException e)
{
result.text = "error";
Debug.LogError(path + " with " + (toggle.isOn?"persistent data path":"data path"));
Debug.LogError("xml exc while des file : " + e.Message);
}
catch (System.Exception e)
{
result.text = "error";
Debug.LogError("exc while des file : " + e.Message);
Debug.LogError(path + " with " + (toggle.isOn ? "persistent data path" : "data path"));
System.Exception exc = e.InnerException;
int i = 0;
while(exc!=null)
{
Debug.Log("inner "+i+": " + exc.Message);
i++;
exc = exc.InnerException;
}
}
yield break;
}
else
{
Debug.LogError("www exc while des file " + www.error);
Debug.LogError(path + " with " + (toggle.isOn ? "persistent data path" : "data path"));
yield break;
}
}
private string GetPath()
{
string path = firstPart.text;
if (toggle.isOn)
{
path += Application.persistentDataPath;
}
else
path += Application.dataPath;
path += secondPart.text;
return path;
}
}
"I want to put my xml file in this folder, and then read it. It's like default info for game"
easy, just put it in your assets. go like this...
public TextAsset myXMLFile;
in Inspector drag the file there. You're done.
"but then I also want to change that file and save"
Fair enough. What you have to do is
(1) make a path p = Application.persistentDataPath + "values.txt"
(2) program launches.
(3) check if "p" exists. if yes, read it and go to (6)
(4) IF NOT, read the textasset and save that to "p"
(5) go to point (3)
(6) you're done.
It's the only way to do it. This is indeed the normal procedure in Unity, you do it in every Unity app. There's no other way!
Related
It is necessary to replace the direct connection to the database with API.
I use this code to directly connect to MySQL db and change pin information:
public async void DatabaseConnection(List<CustomPin> pins)
{
string ConnectionString = "server=192.168.0.1;uid=user;port=4444;pwd=pass;database=dbName;";
MySqlConnection Conn = new MySqlConnection(ConnectionString);
try
{
Conn.Open();
string query = "SELECT * FROM sel_alert_level s;";
MySqlCommand myCommand = new MySqlCommand(query, Conn);
MySqlDataReader myReader;
myReader = myCommand.ExecuteReader();
try
{
while (myReader.Read())
{
int codeNum = myReader.GetInt32(4);
int level = myReader.GetInt32(3);
int mapCode = myReader.GetInt32(0);
foreach (var item in pins)
{
if (item.CodeNum == codeNum)
{
item.AlertLevel = level;
item.CodeNum = codeNum;
item.MapCode = mapCode;
//await DisplayAlert("Alert", mapCode.ToString(), "ok");
}
}
//await DisplayAlert("Database Connection", "Connected .." + Environment.NewLine + myReader.GetInt32(0) + Environment.NewLine + myReader.GetString(1) + Environment.NewLine + myReader.GetString(2) + Environment.NewLine + myReader.GetInt32(3) + Environment.NewLine + myReader.GetInt32(4), "OK");
}
}
finally
{
myReader.Close();
Conn.Close();
}
}
catch (Exception ex)
{
await DisplayAlert("Database Connection", "Not Connected ..." + Environment.NewLine + ex.ToString(), "OK");
}
}
With this code I successfully update the pin information.
Now I create the same method with API Response and what to do the same like DatabaseConnection(); just try to update the information, but not work for me :(
public async void APIConnection(List<CustomPin> pins)
{
try
{
WaterBindingData waterData = await _restServiceData.GetWaterDataForecast(GenerateRequestUriStations(Constants.EndPoint), GenerateRequestUri(Constants.EndPoint));
foreach (var water in waterData.WaterStation.Stations)
{
foreach (var item in pins)
{
if (item.CodeNum == water.CodeNum)
{
item.AlertLevel = water.AlertLevelStation;
item.CodeNum = water.CodeNum;
item.MapCode = water.MapCode;
}
}
}
}
catch (Exception ex)
{
await DisplayAlert("Data Alert", "Error:" + Environment.NewLine + ex.ToString(), "OK");
}
}
I not have any errors here. waterData come with the data, but data not changed in the pins.. I don't know why...
And Now my information are not changed ..
MapCode and other variables not changed.
I call this two methods in the constructor like that:
DatabaseConnection(customMap.CustomPins);
APIConnection(customMap.CustomPins);
So... When I start the project I receive message like this:
/Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/bin/MSBuild/Current/bin/Microsoft.Common.CurrentVersion.targets(5,5): Warning MSB3276: Found conflicts between different versions of the same dependent assembly. Please set the "AutoGenerateBindingRedirects" property to true in the project file. For more information, see http://go.microsoft.com/fwlink/?LinkId=294190. (MSB3276) (MaritsaTundzhaForecast.iOS)
And I check this link but I not have properties option, because I use mac. I have only options on the projects.
Is it possible that this does not change the content in the pins аnd what would be the reason it didn't work ?
I checked the if statement in the loop and she work:
Since it is an asynchronous method , I suggest you try to assign customMap.CustomPins in APIConnection method .
Something like that
//constructor
List<CustomPin> pins = xxxxx;
APIConnection(pins);
public async void APIConnection(List<CustomPin> pins)
{
try
{
WaterBindingData waterData = await _restServiceData.GetWaterDataForecast(GenerateRequestUriStations(Constants.EndPoint), GenerateRequestUri(Constants.EndPoint));
foreach (var water in waterData.WaterStation.Stations)
{
foreach (var item in pins)
{
if (item.CodeNum == water.CodeNum)
{
item.AlertLevel = water.AlertLevelStation;
item.CodeNum = water.CodeNum;
item.MapCode = water.MapCode;
}
}
}
customMap.CustomPins = pins; //assign the value in this line
}
catch (Exception ex)
{
await DisplayAlert("Data Alert", "Error:" + Environment.NewLine + ex.ToString(), "OK");
}
}
We are executing multiple test cases in selenium grid where hub is connected to 2 machines, but every time I am running the grid, I get an error.
Error creating a webdriver. Exception message:
Session [(null externalkey)] not available and is not among the last 1000 terminated sessions.
Active sessions are[]
Command duration or timeout: 0 milliseconds
Code:
private static List<WebDriver> m_listOfWebDrivers = Collections.synchronizedList(new ArrayList<WebDriver>());
private static ThreadLocal<WebDriver> m_driverForThread = new ThreadLocal<WebDriver>() {
#Override
protected WebDriver initialValue() {
WebDriver driver = null;
try {
driver = loadDesktopDriver();
} catch (Exception e) {
e.printStackTrace();
}
Log.info("Initializing Webdriver");
m_listOfWebDrivers.add(driver);
return driver;
}
};
protected static WebDriver loadDesktopDriver() throws Exception {
WebDriver driver = null;
Log.debug("Get Driver for Browser : " + m_browser);
try {
if (!m_runOnBrowserStack && null == m_browser) {
throw new IllegalArgumentException("Browser value should be provided for test");
}
driver = getNewDriver(m_browser, "", "", m_context);
**driver.manage().timeouts().implicitlyWait(50000, TimeUnit.MILLISECONDS);** /* this was added later, still didnt work*/
} catch (Exception e) {
Log.fatal("Error creating a webdriver. Exception message : " + e.getMessage());
throw e;
}
return driver;
}
public static WebDriver getNewDriver(String browserName, String browserVersion, String platform,
ITestContext context)
throws IOException, ComboBoxElementException, TextBoxElementException, ElementException, PageException {
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.BROWSER, Level.ALL);
/**
* These capabilities will need to be re assigned according to the
* browser we are going to be launched. This is required in case of
* running on Grid only but keeping it same normal execution to avoid
* code redundancy.
*/
DesiredCapabilities desiredCapabilities = null;
if (m_runOnBrowserStack) {
desiredCapabilities = new DesiredCapabilities();
JSONObject envs = (JSONObject) m_bsConfig.get("environment");
String bsEnvironment = context.getCurrentXmlTest().getParameter("bsEnvironment");
String testName = context.getCurrentXmlTest().getName();
Log.info("Environmnet details for Test [" + testName + "] is : " + bsEnvironment);
if (null == bsEnvironment)
throw new PageException(
"Environment name does not present in XML or not passed from CLI : " + bsEnvironment);
Map<String, String> envCapabilities = (Map<String, String>) envs.get(bsEnvironment);
if (null == envCapabilities)
throw new PageException("Environment name does not present in Config file : " + bsEnvironment);
Iterator<Entry<String, String>> it = envCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, ?> pair = (Map.Entry<String, ?>) it.next();
desiredCapabilities.setCapability(pair.getKey().toString(), pair.getValue().toString());
}
Map<String, String> commonCapabilities = (Map<String, String>) m_bsConfig.get("capabilities");
it = commonCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, ?> pair = (Map.Entry<String, ?>) it.next();
if (desiredCapabilities.getCapability(pair.getKey().toString()) == null) {
desiredCapabilities.setCapability(pair.getKey().toString(), pair.getValue().toString());
}
}
browserName = (String) desiredCapabilities.getCapability("browser");
}
DriverSupportedBrowsers driverType = DriverSupportedBrowsers.valueOf(browserName.toUpperCase());
if (null != m_gridUrl && !m_gridUrl.isEmpty()) {
m_gridUrl += "/wd/hub";
}
switch (driverType) {
case CHROME:
String chromeDriverPath = driverHome + File.separator + FrameworkConstants.chromeDriverExeName;
if (m_runOnBrowserStack || CommonHelper.isFileExists(chromeDriverPath)) {
if (!m_runOnBrowserStack)
desiredCapabilities = DesiredCapabilities.chrome();
desiredCapabilities.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
options.addArguments("--disable-extensions");
// To start browser in private mode
// options.addArguments("incognito");
desiredCapabilities.setCapability(ChromeOptions.CAPABILITY, options);
System.setProperty("webdriver.chrome.driver", chromeDriverPath);
if (null != m_gridUrl && !m_gridUrl.isEmpty()) {// for runs on
// grid
return new RemoteWebDriver(new URL(m_gridUrl), desiredCapabilities);
} else
return new RemoteWebDriver(service.getUrl(), desiredCapabilities); /* The code fails here generally with the failure*/
} else {
throw new FileNotFoundException(
"Chrome Driver path : " + chromeDriverPath + "\n\"" + FrameworkConstants.chromeDriverExeName
+ "\" not found in driver home path declared in System Environment Variable \""
+ driverHome + "\"");
}
#Parameters({ "bsEnvironment" })
#BeforeMethod(alwaysRun = true)
public void initialize(ITestContext context, Method method, #Optional String bsEnvironment)
throws IOException {
String customer = context.getCurrentXmlTest().getParameter("customer");
String testName = context.getCurrentXmlTest().getName();
setTestName(testName);
String methodName = "";
m_testMethod = method.getName();
methodName = testName + "_" + method.getName() + "_" + customer;
CommonHelper.renameRetryLog(m_logDir, methodName);
Log.setLog(m_logDir, methodName);
m_context = context;
if (m_runOnBrowserStack) {
if (null == context.getCurrentXmlTest().getParameter("bsEnvironment")
|| context.getCurrentXmlTest().getParameter("bsEnvironment").isEmpty()) {
Log.info("Adding bsEnvironment parameter for run on BrowserStack");
context.getCurrentXmlTest().addParameter("bsEnvironment", bsEnvironment);
}
}
try {
WebDriver driver = getDriverInstanceForThread();
if (null == driver)
throw new PageException("Driver is null. Initialization problem!!");
// Logging browser name and version parameters, driver and thread
// instances
String browserName = null;
String browserVersion = null;
try {
Capabilities webDriverCapablities = ((RemoteWebDriver) driver).getCapabilities();
browserName = webDriverCapablities.getBrowserName();
browserVersion = webDriverCapablities.getVersion();
} catch (ClassCastException e) {
Log.error("Unable to cast driver to RemoteWebdriver");
browserName = m_browser;
browserVersion = "NA";
}
Log.info("\n ****************** START OF TEST CASE " + method.getName() + " " + customer + ":"
+ browserName + ":" + browserVersion + "\t THREAD:" + Thread.currentThread().getId()
+ "\t WEBDRIVER:" + driver + " ****************** \n");
// driver.manage().timeouts().pageLoadTimeout(CommonConstants.PAGE_LOAD_WAIT_SEC,
// TimeUnit.SECONDS);
if (null != m_gridUrl) {
// Log the remote node ip address where the test is running
Log.info("Remote Node IP: " + CommonHelper.getIPOfRemoteNode(driver));
}
} catch (Exception e) {
e.printStackTrace();
Log.warn(e.getMessage());
}
The CMD is triggered for Node giving timeout and browser timeout:
java -Dwebdriver.chrome.driver=D:/imp/iTAF_Driver_Home/chromedriver.exe -jar selenium-server-standalone-3.3.1.jar -port 5554 -role node -hub http://10.18.15.168:5550/grid/register -timeout 86400 -browserTimeout 86000
This issue is a recurring error.
I'm creating a set of Haxe functions that saves text and images to a file. These functions work just fine on Windows and Android; however, a tester has informed me that attempting to save an image produces this error on iOS and Mac:
ERROR: Failure type not string # ./File.cpp:123
Here's the code for the two functions.
public static function savePNG(path:String, image:BitmapData, ?whenDone:Bool->Void):Void {
if (path.substr(path.length - 4).toLowerCase() != ".png") { path += ".png"; }
// Flash: Not possible to save; error out
#if flash
trace("ERROR: File IO cannot be accessed on Flash.");
if (whenDone != null)
whenDone(false);
#elseif js
trace("ERROR: File IO cannot be accessed on HTML5.");
if (whenDone != null)
whenDone(false);
// Windows, Mac, Linux, iOS, and Android: Use the "saveText" function with the converted file
#else
var b:ByteArray = image.encode("png", 1);
saveText(path, b.toString(), whenDone);
#end
}
public static function saveText(path:String, content:String, ?whenDone:Bool->Void):Void {
var success:Bool = true;
var path2:String = "";
path = "/assets/data/" + path;
var a:Array<String> = DataUtils.subfold(path);
// Flash or HTML5: Not possible to save; error out
#if (flash || js)
success = false;
#if flash
trace("ERROR: File IO cannot be accessed on Flash.");
#else
trace("ERROR: File IO cannot be accessed on HTML5.");
#end
// iOS and Android: Attempt to save to the storage directory
#elseif mobile
if (!FileSystem.exists(SystemPath.userDirectory + "/" + a[0])) {
FileSystem.createDirectory(SystemPath.userDirectory + "/" + a[0]);
}
path2 = SystemPath.userDirectory + "/" + a[0] + "/" + a[1];
try {
File.saveContent(path2, Std.string(content));
} catch (e:Dynamic) {
success = false;
trace("ERROR: " + e);
errorify(e);
}
// Windows, Mac, and Linux: Save straight to the "assets/data/" folder
#else
if (!FileSystem.exists(FileSystem.fullPath(a[0]))) {
FileSystem.createDirectory(FileSystem.fullPath(a[0]));
}
path2 = FileSystem.fullPath(a[0] + "/" + a[1]);
try {
File.saveContent(path2, Std.string(content));
} catch (e:Dynamic) {
success = false;
trace("ERROR: " + e);
errorify(e);
}
#end
if (whenDone != null)
whenDone(success);
}
The error is coming from the last trace("ERROR: " + e); line. I would troubleshoot myself, but I don't have a Mac or iOS device, and I'm not sure what information I need from the tester.
Bottom line: If there is an apparent error in this code, how can it be fixed? If not, for what troubleshooting information do I need to ask?
My guess is that something is messing up during Bytes->String conversion which is completely unnecessary here. I suggest you to remove it and use binary version of the FileOutput. If you are using the latest version of lime you can cast your ByteArray to Bytes (since ByteArray underlying type is Bytes) and write that to the FileOutput. Here is how the 'write' part should look like
/**
* Save bytes as a file
* #param path
* #param content
* #return true if succeed, false overwise
*/
static function saveBytes(path:String, content:Bytes):Bool
{
var success = false;
var fo:FileOutput = null;
try {
//open binary file and write bytes
fo = File.write(path, true);
fo.writeBytes(content, 0, content.length);
success = true;
} catch (e:Dynamic) {
trace("ERROR: " + e);
errorify(e);
}
//file output should be closed in any case
try {
if (fo != null)
fo.close();
} catch (e:Dynamic) {
trace("ERROR: " + e);
errorify(e);
}
return success;
}
Also, encoding part
/* insert your path construction here */
var b:ByteArray = image.encode("png", 1);
var success = saveBytes(path, (b:Bytes));
if (whenDone != null)
whenDone(success);
I have a form an one button on it,
below is very really simple my code:
private void ConnectDb()
{
try
{
connect = new OleDbConnection();
connect.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.15.0;Data Source=MySong.accdb;Persist Security Info=false;";
connect.Open();
statusText.Text = "Database connected";
command = connect.CreateCommand();
}
catch (Exception)
{
statusText.Text = "ERROR::Database failed";
}
}
private void CloseConnectDb()
{
if (connect != null)
{
connect.Close();
statusText.Text = "Database Closed";
}
}
private void btnTambah_Click(object sender, EventArgs e)
{
DateTime tanggal = DateTime.Today;
Band = txtArtis.Text;
Title = txtJudul.Text;
this.ConnectDb();
command.CommandText = "INSERT INTO TableLagu (Tanggal, Artis, Title, Status) VALUES ('" + tanggal + "', '" + Band + "', '" + Title + "', 'Belum ada')";
if (command.ExecuteNonQuery() != 0) //executenonquery returns number of row affected
{
statusText.Text = "ADD--Data Success inserted";
txtArtis.Text = "";
txtJudul.Text = "";
}
else statusText.Text = "ERROR::Insert failed";
this.CloseConnectDb();
}
When i click on my 'btnTambah' button, it always say "object reference not set to an instance of an object" and display "ERROR::Database failed" on its statusText.
any solution??
i think this code doesn't run while try to call ConnectDb method.
you can see my connection string
Provider=Microsoft.ACE.OLEDB.15.0;
actually, when i creating it, i have microsoft access database 2013 installed on my machine. it works good.
now, i'm trying to run my application on my friends computer that microsoft access installed version 2007. and got an error like above.
I am trying to extract header and body information from email, the following code retrieves the header and body in their raw form. I have an email object that contains the fields from, subject, date, and body. I would like to extract these values from the email and assign them to the email object. How do I get around it? I have tried several ways like getting the header info and using a streamReader.ReadLine() to get a line but I got illegal path exceptions. I know I can use a library but I need to achieve it this way.
What I mean is this, IMAP command returns header information. And I want to extract subject value, date value, sender e-amil, etc. and assign them to my email objects corresponding values like
emailObject.subject = "subjectValue"
public class Imap
{
static void Main(string[] args)
{
try
{
path = Environment.CurrentDirectory + "\\emailresponse.txt";
if (System.IO.File.Exists(path))
System.IO.File.Delete(path);
sw = new System.IO.StreamWriter(System.IO.File.Create(path));
tcpc = new System.Net.Sockets.TcpClient("imap.gmail.com", 993);
ssl = new System.Net.Security.SslStream(tcpc.GetStream());
ssl.AuthenticateAsClient("imap.gmail.com");
receiveResponse("");
Console.WriteLine("username : ");
username = Console.ReadLine();
Console.WriteLine("password : ");
password = Console.ReadLine();
receiveResponse("$ LOGIN " + username + " " + password + " \r\n");
Console.Clear();
receiveResponse("$ LIST " + "\"\"" + " \"*\"" + "\r\n");
receiveResponse("$ SELECT INBOX\r\n");
receiveResponse("$ STATUS INBOX (MESSAGES)\r\n");
Console.WriteLine("enter the email number to fetch :");
int number = int.Parse(Console.ReadLine());
Console.WriteLine("*************Header************");
Console.WriteLine("");
// receiveResponse("$ FETCH " + number + " body[header]\r\n");
// BODY.PEEK[HEADER.FIELDS (SUBJECT)]
// StringBuilder sb = receiveResponse("$ FETCH " + number + " BODY.PEEK[HEADER.FIELDS (From Subject Date)]\r\n");
StringBuilder sb= receiveResponse("$ FETCH " + number + " body.peek[header]\r\n");
Console.WriteLine(sb);
Console.WriteLine("");
Console.WriteLine("Body");
sb = new StringBuilder();
sb=receiveResponse("$ FETCH " + number + " body[text]\r\n");
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] serverbuff = new Byte[1024];
int count = 0;
string retval = enc.GetString(serverbuff, 0, count);
Console.WriteLine(sb.ToString());
receiveResponse("$ LOGOUT\r\n");
}
catch (Exception ex)
{
Console.WriteLine("error: " + ex.Message);
}
finally
{
if (sw != null)
{
sw.Close();
sw.Dispose();
}
if (ssl != null)
{
ssl.Close();
ssl.Dispose();
}
if (tcpc != null)
{
tcpc.Close();
}
}
Console.ReadKey();
}
static StringBuilder receiveResponse(string command)
{
sb = new StringBuilder();
try
{
if (command != "")
{
if (tcpc.Connected)
{
dummy = Encoding.ASCII.GetBytes(command);
ssl.Write(dummy, 0, dummy.Length);
}
else
{
throw new ApplicationException("TCP CONNECTION DISCONNECTED");
}
}
ssl.Flush();
buffer = new byte[2048];
bytes = ssl.Read(buffer, 0, 2048);
sb.Append(Encoding.ASCII.GetString(buffer));
// Console.WriteLine(sb.ToString());
sw.WriteLine(sb.ToString());
// sb = new StringBuilder();
return sb;
}
catch (Exception ex)
{
throw new ApplicationException(ex.Message);
}
}
You said you do not want to use an IMAP library. This means that you will have to implement your own. You should start by reading RFC 3501 because there is no chance you could get the protocol right without reading the docs carefuly. In particular, you're issuing a STATUS command on the currently selected mailbox, which is explicitly forbidden by the protocol specification. The rest of the code supports the assumption that you have not read the RFC yet.