I am trying to communicate from an iOS app to get some data from the server. For that I sub-classed a xojo.Net.HTTPSocket. The first communication works perfectly. The code used is the following:
[code] Dim dic As New xojo.Core.Dictionary
dic.Value(“DataType”) = “Categories”
Dim json As Text = xojo.Data.GenerateJSON(dic)
Dim data As MemoryBlock
data = TextEncoding.UTF8.ConvertTextToData(json)
However, if the response method initiates a second communication the App exist unceremoniously.
If I don’t try to start another communication, everything continues to work perfectly.
The Web services is another Xojo App (Web Application) and it seems to work perfectly (I am using the HanldeSpecialUrl event).
What am I missing? Should I do something? Is it maybe that the response is called in a thread that cannot initiate another HTTP Connection?
Any insight will be greatly appreciated.
The HTTPSocket can only handle one request at a time, so perhaps that is why you are having an issue? You could check the crash logs to try to find out for certain. My web services consuming iOS app calls many web services one after another and requests can often still be executing or awaiting a response when another call is made. To do this, I instantiate a new instance of my calling class every time I use it; so I have multiple instances of what you’re calling “ivConnection” in your code, each one doing its own thing. I hope that helps.
Thank you Jason, that should be the problem…
How do you think is best to keep the instances in scope for all the time they should stay in scope?
Also, do you let them go out of scope, or do you “close” the instance yourself?
I let them go out of scope and there are a number of ways to handle this. In my case I have a local enumeration in my “API” class that defines the type of service that it represents (I have a set of only about 20 services from our wider API that my iOS app uses so this method is fairly manageable for me). I declare a local instance of the “API” where I need something from a service and in the constructor I pass in the service type. Then I forget about it. In the PageReceived event I take the appropriate action with the response. I also use a mixture of AddHandler and Delegates in cases where I need to do different things with the responses. For example I have a service that returns a thumbnail image. In one instance this is called by a user control that needs to know when the image is available, so it passes in a delegate method when calling the class which is then called back.
Thank you Jason, I will use a separate instance which seems is the correct approach.
Where do you instantiate the HTTPSocket Subclass in order to remain in scope for the desired time?
I suppose it needs to stay alive until the PageReceived event is called. Am I correct?
That’s a very good question Fotis. I have just been declaring an instance of it in local scope, i.e. within a method where I need it, and then forgetting about it, i.e. letting it go out of scope, and so far it seems that the framework doesn’t kill it until the code finishes executing. Or else I’ve been very, very lucky. Perhaps somebody with more knowledge of this side of things could comment on this? But for me, in any case, that has been working well. Of course another way to deal with it would be to make it a property of the View or some other property that stays in scope but as “declare-and-forget” has been working for me I haven’t considered doing this.
I seem to be getting some mixed results if I initiate the second transfer from a method called from the PageReceived event, if the HTTPSocket subclass is a local variable the second communication (the one called from the PagedReceived called method) doesn’t fire.
The first communication works either way. Probably this says something…
I suppose that you initiate the communications separately and not one from the other, so you probably don’t see this…
If you need to call another service in PageReceived, make sure you are instantiating a new instance of your HTTPSocket-based class and not just calling the Send method for the instance that is currently executing. I do that (call new instances within PageReceived) and it works.
Jason you are right. I had forgotten to set up the delegate managing the PageReceived (which was set in the instance in lazy instantiation). When I fixed that, everything works Ok.
Thank you very much for your help.