ofxPoco Problem Android Studio

I am working on a project using ofxPoco and ofxHttpUtils.
Everything works fine in Visual Studio on Windows and in Xcode on MacOS.

In Android Studio (Windows v 3.1.2 and MacOS v 3.1.4) using OF 0.10.0, the includes regarding Poco (addons\ofxPoco\libs\poco\include\Poco) are not found, as for example
#include <Poco/DOM/Document.h> at line 9 of ofxPoco/src/ofxXmlPoco.h

To reproduce the problem copy paste the empty example and add ofxPoco using the project generator, then open from Android Studio and build it.

Thanks in advance for every answer.
Greetings.

can you open an issue on github?

ok, i have opened the issue.

Hi, did you get anywhere on this?

@arturo, any leads on what to look into to help solve this (just added to the git issue)

Hi Adam

I finally managed to use for all plattforms on my project OF 0.10.
The networking tools built in OF in this version are powerfull enough for my requirements
(transfer multiple files to server as POST and read answers in JSON).

https://openframeworks.cc/documentation/utils/ofURLFileLoader/

Kind regards,
Mathias

Cheers Mathias.

Was hoping for resolution on the ofxPoco Android thing, but glad to hear you found alternate lib for your project!

@mkrebs can you give an example of how you made a POST using ofURLFileLoader? I am not sure how to construct the post and add files.

Hi fresla,

Below i pasted code copied from my project for network requests.
I think this should be all you need, but maybe I missed something.

h - file
ofURLFileLoader http;

cpp - file

// Initialization.

CGame::CGame()
{
	// Setup http library for game object.
	ofRegisterURLNotification(this);
}

// Method to send requests.

void CGame::sendRequest(std::string address, std::string body)
{
	ofHttpRequest r1;
	r1.method = ofHttpRequest::POST;
	r1.url = address;
	r1.body = body;
	r1.timeoutSeconds = 15;
	r1.name = "dummy";
	r1.headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";

	// Id of request -> may help in case you make multiple requests at the same time
	int uniqueID = http.handleRequestAsync(r1);
}

// network response method, has to be in the same class where ofRegisterURLNotification has been called.
// name of method has to be urlResponse

void CGame::urlResponse(ofHttpResponse & response)
{

	if (response.status == 200)
	{
		// Get id of request.
		int uniqueID = response.request.getId();

		std::string network_response = response.data.getText();
	}

}

// Cleanup routine to call when application is closed.

void CGame::Terminate()
{
	ofUnregisterURLNotification(this);
	http.clear();
}

Amazing this is great, thanks so much for the help!

@mkrebs the post request works great for strings, but I cannot work out how to send files,
ofHttpRequest deos not seem to have a way to add files, can you share how you did this?

Fred

Below some more code, in order to transmit files to the server.

In a nutshell, you have to add the content of the file to the body of the request, using urlencode to ensure compliance. If you wan’t to send a binary file (like a jpeg), you probably will have to use base64 encode, see the attached files below.

base64.cpp (3,6 KB)
base64.h (1,4 KB)


ofFile f_handle;
f_handle.open(“myFile.txt”);

char* txt = NULL;
if (f_handle.is_open() == true)
{
	ofBuffer b = f_handle.readToBuffer();
	f_handle.close();

	txt = (char*)malloc(b.size() + 1);
	memset(txt, 0, b.size() + 1);
	strncpy(txt, b.getData(), b.size());

	b.clear();
}


if (txt != NULL)
{
	std::string fieldName = “myFileName”;
	char* url_value = urlencode(txt);
	
	std::string myBody = “”;
	myBody += "&";
	myBody += fieldName;
	myBody += "=";
	myBody += url_value;

	// Add body to request, see previous post for declaration of r1.
	r1.body = myBody;
	
	// Relase buffers.
	free((void*)url_value);
	free((void*)txt);
}
/* Returns a url-encoded version of str */
/* IMPORTANT: be sure to free() the returned string after use */
char* urlencode(char* str)
{
	int l_str = strlen(str);

	vector<char> v(l_str);
	v.clear();

	for (size_t i = 0, l = l_str; i < l; i++)
	{
		char c = str[i];
		if ((c >= '0' && c <= '9') ||
			(c >= 'a' && c <= 'z') ||
			(c >= 'A' && c <= 'Z') ||
			c == '-' || c == '_' || c == '.' || c == '!' || c == '~' ||
			c == '*' || c == '\'' || c == '(' || c == ')')
		{
			v.push_back(c);
		}
		else if (c == ' ')
		{
			v.push_back('+');
		}
		else
		{
			v.push_back('%');
			unsigned char d1, d2;
			hexchar(c, d1, d2);
			v.push_back(d1);
			v.push_back(d2);
		}
	}

	std::string out_buffer = string(v.cbegin(), v.cend());
	char* out_str;
	out_str = (char*)(malloc(out_buffer.size() + 1));
	memset(out_str, 0, out_buffer.size() + 1);
	sprintf(out_str, "%s", out_buffer.data());

	return out_str;
}

By the way, OF already contains a library for JSON handling, beeing very useful for me in this context.

#include "json.hpp" // comes with OF
void readHttpResponse(ofHttpResponse & response)
{
	nlohmann::json json_response;

	try
	{
		// Response could be incomplete in case of network problem.
		json_response = nlohmann::json::parse(response.data.getText());

		// Extract fields from json.
		std::string cstr_test1 = json_response["testfield_1"].get<std::string>();
		std::string cstr_test2 = json_response["testfield_2"].get<std::string>();

	}
	catch (std::invalid_argument)
	{
		// Catch by switching to network error.
	}

}