This question is about wrapping RestKit requests in custom objects, and whether or not I can guarantee that an object sending the RestKit request will also be used as a delegate when the response is returned.
I'm working with an abstruse REST API (Salesforce), and RestKit doesn't appear to handle some of Salesforce's peculiarities well -- for example, when you make a call to the Salesforce REST API, you might get back a partial dataset, and then be given a "nextRecordsUrl" that you must follow to get the next chunk. Others working with Salesforce and REST have run into the same issue (ref https://groups.google.com/forum/#!msg/restkit/HJNjB7I6WVM/8u5n7nHoJQUJ). I created a class to wrap the calls to Salesforce and automatically follow these links, and process the returned data sets correctly. The class instance registers itself as the delegate for the REST call.
The class I wrote works great on its own (when there's a single instance), but I'll be creating other classes and have several instances that will need to handle their data independently. I've read through the documentation and code (it's been a learning experience, I've only worked with ios for about a month now), but I can't see if it's guaranteed that a particular instance will respond as the delegate for its requests alone, or if it might accidentally pick up the responses for another instance.
For example, suppose I have instances A and B, both of which are making requests using RKObjectLoader, and which set themselves as delegates using loader.delegate = self;. Both are running simultaneously (asynchronous). Here's a potential flow I see:
A's RKObjectLoader makes call, registers self as delegate for response
RestKit framework sends request for A
B's RKObjectLoader makes call, registers self as delegate for response
RestKit framework sends request for B
... wait ...
RestKit framework gets response, and somehow determines that this response was from B's request, calling B as the delegate
B delegate methods get called
RestKit framework gets response, and somehow determines that this response was from A's request, calling A as the delegate
A delegate methods get called
I couldn't see how the RestKit framework would distinguish between responses from requests, and thereby ensure that the correct delegate instances get called. In other words, it appears to me that RestKit might get a response to a request, and then call any delegate it wants ... but that seems counterintuitive, and the framework author appears to be very sharp.
So, my questions:
If I have a class instance using RKObjectLoader and setting itself as the delegate, can I be guaranteed that it will be called when the response for that request comes in?
Can you point me to the actual implementation in the RestKit framework that handles this, so I can learn how it's done?
Thanks very much!
I haven't received an answer to this question, but in case somebody has the same question and comes across this, here's the answer: yes, RestKit does appear to match the correct delegate with the outgoing request.
I created a small class (with an (NSString*) identifier property that calls a service, and in the delegates I printed out the instance's identifier with the result. I confirmed that instance A's delegate method was handling instance A's call, and B's was handling B's, with several simultaneous calls.
Related
I am writing a service where the client makes an API call to my service, and my service then augments the request payload, then passes it on to another service. For my API, what should the HTTP method be if it's not interacting with a database?
what should the HTTP method be
Key idea: the fact that your server communicates with another API, rather than a database, or a filesystem, is an implementation detail; details of your implementation are not supposed to be leaking into your messages.
Given that the incoming request has a message body; GET, HEAD, DELETE are all right out, because those methods have no defined semantics for a payload.
POST/PUT/PATCH are all possible.
Ideally, you would match the method token that you are using to talk to your back end. This is essentially how a reverse proxy works. You're just playing man in the middle, after all, so it shouldn't be too much of a surprise that the request semantics match.
They don't always, of course - and you might want to inject your own semantics if you find that the API you are calling has made poor method choices in its own design.
When in doubt, it is okay to use POST
One of the REST principles — namely, ‘Layered System’ constraint — implies that:
each component cannot "see" beyond the immediate layer with which they are interacting
So you actually should not make any difference between ‘simple’ and ‘proxied’ API calls.
I'm just starting to use the IB API in python. I'm able to retrieve all the desired results I want. However, one big problem arise to me. I don't fully understand how the linkage between the EClient class and a particular callback is made within the EWrapper class.
As of now I understand the workflow like this (high level):
An EClient instance makes a call to IB Gateway.
IB Gateway itself reach out to the IB Data centers to fetch data
Data comes back to IB Gateway
IB Gateway calls the callback, which is the interface
As far as I understand, IB Gateway triggers the correct Callback function. What I don't see from the documentation / source code is the connection between a EClient method and a the interface (callback) I override in my EWrapper class. When I trigger a specific method in step 1 above. How does IB Gateway know, which callback to run? Is this specified somewhere?
The callback functions which handle responses to each function called in EClient are hard-coded and detailed in the TWS API Reference Guide.
For instance, calling EClient.reqAccountUpdates causes responses to be returned in EWrapper::updateAccountValue and EWrapper::updatePortfolio, and you would need to override those functions in your own code.
TWS Python API Traders Academy Course
IBKR Recorded Webinars
OK, I am building an application that will be using ASIHttpRequest in several places to either get JSON data from a web service or will be posting to a web service. I have it working, but really don't like having several instantiations of the request object sprinkled around the different view controllers (Login view controller, a tableview controller, and a detail view controller. I would like to move all my ASIHttpRequest methods to one class and just get back a dictionary of values that came back from the web service. The problem with this is that the delegate methods don't return that I need to have returned.
What would be some suggestions on how I can consolidate all the methods that will create an HTTPRequest and return values when the request is finished.
I can post code if need be, but this is really more of a general question and not a specific issue. If there are any tutorials on how this should be done, I would appreciate it. I want my code to be efficient and pretty :)
Thanks!
Your problem is going to be asynchronousity. I'm not sure what you mean by consolidate, but you can have a singleton (you can just use your app delegate) to call the requests. So you would do something like this:
[(MyAppDelegateClass *)[UIApplication sharedApplication].delegate doLoginStuff:(NSDictionary *)params delegate:self];
If you're doing all this asynchronously, you can't just call this method and have it return something. You'll be stuck with having some sort of callback to your view controller, which is the way ASI works out of the box essentially. At best, you can minimize the code to generate the request and set any repetitive properties.
I'm not sure what you mean by having the instantiations floating throughout. If it's memory you're worried about, it would be no different reusing the same object. ASI typically uses an autoreleased request, so it would be the same as creating it in a "consolidated" method. If it's just clean code, I would do a singleton way and maybe make a shortcut c-based method call in some type of Utilities class that you create and import in with your prefix file. But again, you need the callback methods in your view controller so it doesn't get too much cleaner than it already is meant to work. I share your pain though.
When any request comes back, I almost always have a method that parses the results. Typically I'm only working with one type of web service, so have a method that parses the results and (also logs it to NSLog for debugging purposes) also gives me back an NSDictionary or NSArray.
My iOS app does a lot of different requests to a Web service. Each request is a call to a method of a ConnectionManager object. When the response arrives from the Web service, a delegate's method is called to notify an interested receiver. Moreover, to maintain the session active, a polling every X seconds is required.
Said so, in your opinion it is better if ConnectionManager is a Singleton or not?
The singleton is simpler (because I do not have to pass a ConnectionManager's reference to all those who need to do a request to the Web service or I do not have to create more ConnectionManagers). Moreover, it is easy to handle the issue of polling: I just add two methods startPolling and stopPolling on the ConnectionManager. But I do not like to use the delegates with a singleton (because there can be only one delegate, and what happens if a response comes when there is not one set?) and at the same time I do not like to use the notifications. I do not like the singleton, too :)
Do you have advice on alternative patterns?
I went through similar thinking as you and ended up with this pattern:
ConnectionManager [singleton] - responsible for maintaining a connection to the server and submitting & receiving requests
ConnectionQueue [singleton] - Stores a stack of Requests waiting to be fulfilled
Request - Created each time something is needed from the server. It contains all the request data (urls, params etc) and a reference to the delegate.
Response - A container for the data retrieved from the server along with the original request.
Hooking it all together...
The ConnectionManager is started at startup and it creates the ConnectionQueue
When a call to the server is needed create a Request object, pass in all required params and add it to the ConnectionQueue
The queue lets the manager know there's a request that needs to be processed
The manager removes the request from the queue & makes the call to the server
Data is received
The manager creates the response and sends it back to the delegate.
You can see this other post:.
I think it can be useful.
I have an idea, but I need help implementing it.
WCF does not support delegates in its contracts.
Instead it has a cumbersome callback contracts mechanism, and I'm looking for a way to overcome this limitation.
I thought about using a IDataContractSurrogate to replace each delegate in the contract with a token that will be serialized to the remote endpoint. There, the token will be deserialized into a generated delegate. This generated delegate will send a generic callback message which encapsulates all the arguments (that the delegate was invoked with).
The generic callback message will reach the first endpoint, and there the original delegate would be invoked with the arguments.
Here is the purposed (simplified) sequence:
A calls B-proxy.Foo(callback)
callback is serialized through a DelegateSurrogate.
The DelegateSurrogate stores the delegate in a dedicated delegate storage and replaces it with a token
The message arrives to B's endpoint
the token is deserialized through a DelegateSurrogate
The DelegateSurrogate constructs a generated delegate
B.Foo(generatedCallback) is invoked
Later, B is invoking generatedCallback(args)
generatedCallback(args) calls a dedicated generic contract on A's endpoint: CallbackContract-proxy.GenericCallback(args)
CallbackContract.GenericCallback(args) is invoked on A's endpoint
The original callback is retrieved from the storage and is invoked: callback(args)
I have already implemented this previously using service bus (NServiceBus), but I want to adapt the idea to WCF and I'm having hard time. I know how to implement steps 3,6,9 and 11. I don't know yet how to wire everything in WCF - especially the surrogate part.
That's it - I hope my question made sense, and that the collective wisdom here will be able to help me build this up.
Here's a sample usage for my desired solution:
// client side
remoteSvc.GetEmployeeById(17, emp =>
{
employees.Add(emp);
logger.log("Result received");
});
// server side
public void GetEmployeeById(int id, Action<Employee> callback)
{
var emp = getEmpFromDb(id);
callback(emp);
}
Actually, in this scenario I would look into the Expression API. Unlike a delegate, an Expression can be deconstructed at runtime. You can't serialize them by default, but a lot of work has been done in that space. It is also a bit like what a lot of LINQ providers do in the background, for example WCF Data Services.
Of course, another approach is simply to use a lambda expression as the hook for RPC, which is what I describe here. The code that implements this is freely available in the protobuf-net tree. You could customize this by using an attribute to associate your token with the method, and obtain the attribute from the MethodInfo.
IMO, the problem with delegates is that they are too tightly coupled to the implementation, so you can't have different implementations at each end (which is a common requirement).
Expressions have the advantage that lambdas still support intellisense etc, so you can do things like:
client.Invoke(svc => svc.Foo(123, "abc"));
and from that obtain Foo (the MethodInfo), 123 and "abc" separately, including captured variables, ref/out, etc. It all works.