Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
HTTP POST request fails on iOS — Gideros Forum

HTTP POST request fails on iOS

joelghilljoelghill Member
edited November 2012 in Bugs and issues
Hello,

I have almost finished preparing my first game for an iOS release, however there is one small bug that I cannot seem to fix on my own.

I am using the url loader in Gideros to submit and retrieve scores from the Scoreoid leaderboard service. When running on an iOS device, it seems as though the HTTP POST request is failing when my app submits high scores for the user. This only seems to occur on actual iOS devices. When emulating through the Xcode iOS emulator, or running on Android, or when using the Gideros player the function seems to work without any issues.

In addition, the POST request does not always fail on the iPhone hardware. If the device is put in and out of airplane mode, POST requests to submit scores work for a little while, but eventually cease to function again.

If anyone has any insight into this issue I would love to know more. Thanks!

PS: It looks like this guy is having the same issue, but it's not clear to me as to whether or not they found a solution: http://stackoverflow.com/questions/12757039/my-app-fails-to-connect-to-the-server-some-times
Tagged:

Comments

  • JaviJavi Member
    edited November 2012
    @joelghill That latency... did you try connecting your iOS device to another router/WiFi?
    When that problem happens, does it receive any byte? any error?
    Do you have the option to use GET instead of POST to send the data?

    A quick work-around you can implement is to close the connection after, for example, 3 secs without reply of the server and retry the connection.
  • I've tried it using various wifi connections as well as 3G on a couple different devices.

    I think it's possible I misunderstood how POST and GET requests work.... I thought that since I was submitting data I had to use POST..... is that not the case? I may be a able to use GET.
  • JaviJavi Member
    edited November 2012
    I've visited the Scoreoid webpage and it only uses POST.

    If it's not a router or device problem I'd check if you are receiving data or any error when that happens.

    FYI: In order to send data with GET you must include it directly in the URL, for example, "http://example.com/script.php?id=123&text=hello" This send the params "id" and "text" to script.php.
    But, as I've said, Scoreoid uses POST.
  • On closer inspection, I'm not sure if I can use a GET method since I'm submitting a score to the server rather than just retrieving data. I've been trying to use GET, and it just dosen't seem to play nice with the web API.

    Could the latency be solved by using certain headers in the POST request? Would that help in any way?
  • On closer inspection, I'm not sure if I can use a GET method since I'm submitting a score to the server rather than just retrieving data. I've been trying to use GET, and it just dosen't seem to play nice with the web API.
    See my last post (I replied from my new time machine) ;))

    It seems that the protocol of Scoreoid needs these two headers:

    ["Authorization"] = "Basic"
    ["Content-Type"] = "application/x-www-form-urlencoded"

    I'd add too:

    ["Content-length"] = body:len()
    ["Connection"] = "close"
  • joelghilljoelghill Member
    edited November 2012
    Hey @Javi,

    Just an update if you're interested. For every url event I have a string set to print on the console so I know what the url loader is up to. For example, when the url launches Event.COMPLETE I have a string the prints "urloader done".

    I've noticed that when running the app on the Gideros player, more often than not, nothing prints out to the console. Oddly enough, when nothing prints, Scoreoid usually receives the data anyway.

    So.... it looks like when the UrlLoader works, but the events do not trigger as they should? Not sure what's happening there.

    EDIT: Just saw your reply. Seems like I'm a little out of sync with your responses :P
  • ["Content-length"] = body:len() seems to cause an error with the UrlLoader class.

    ["Connection"] = "close" may or may not be helping. I don't have an iOS device to test on.
  • JaviJavi Member
    edited November 2012
    If nothing prints out in Event.COMPLETE after receiving data then the server is not closing the connection. The header ["Connection"] = "close" is to tell the server to close it after sending.

    And, the header ["Content-length"] is to inform of the length of the data sent (it's a requirement to use it with POST in the standard HTTP protocol).

    Note: "body:len()" was an example, headers must be sent as strings, and be sure you are using the string where you have the data to send. For example:

    local myData = "...data to send..."

    ["Content-length"] = tostring(myData:len())

  • @joelghill I must leave now. Test it and tell me later if the problem on iOS is gone. I think now it will work OK.
  • joelghilljoelghill Member
    edited November 2012
    I still haven't had the opportunity to test on an iOS device, however I seem to be having trouble with the "Content-Length" header. The function I'm using:
    function createScore(n, s) -- accepts string and number
     
    	local score = tostring(s)
    	print("The score as a string is:  "..score)
    	local username = n
     
     
    	--POST method
    	local method = UrlLoader.POST
    	local body = "api_key="..api.."&game_id="..gID.."&response="..response.."&username="..username.."&score="..score
    	local url = "<a href="https://www.scoreoid.com/api/createScore&quot" rel="nofollow">https://www.scoreoid.com/api/createScore&quot</a>;
     
    	local headers = {
    	["Authorization"] = "Basic",
    	["Content-Type"]  = "application/x-www-form-urlencoded",
    	["Content-Length"] = tostring(body:len()),
    	["Connection"] = "close",
    	}
     
    	local loader = UrlLoader.new(url, method, headers, body)
     
     
    	local function onComplete(event)
    		print(event.data)
    		print("Urlloader complete")
    	end
     
    	local function onError()
    		print("error")
    		end
     
    	local function onProgress(event)
    		print("progress: " .. event.bytesLoaded .. " of " .. event.bytesTotal)
    	end
     
    	loader:addEventListener(Event.COMPLETE, onComplete)
    	loader:addEventListener(Event.ERROR, onError)
    	loader:addEventListener(Event.PROGRESS, onProgress)
     
    end
    When calling this function, the Urlloader class throws an error event. If I remove "Content-Length", it works just fine. Do I have some sort of mistake somewhere in my code?
  • JaviJavi Member
    edited November 2012
    Your code is correct.

    I've checked UrlLoader(...) in my server.
    Include only the header "Connection = close", UrlLoader(...) does not close the connections by default.
    And do not include the content-length header, it's not necessary (UrlLoader(...) inserts this header automatically).
Sign In or Register to comment.