So I've been reading about the pros and cons about using Singleton, and I have a scenario which I'm not sure if I should use one, and I thought consulting you guys.
I'm writing an Iphone app which once in a while have to communicate to the server (HTTP) information about the user logged in.
This web service is getting called from different parts of my application.
What I actually need are 2 type of classes:
Responsible for communication with the server - responsible for http setting,the url,header,parameters and etc.
2.classes for each type of web service api - for exmpale UpdateUserInfo Class or SendResults Class. This c
The 2nd class would use the 1st , and all through the app I would need many calles to the 2nd classes.
Should I use Singleton to any of theses ? What is the best way to design it ?
Thanks guys!
Edit:
Example for the 1st class(Let's call it DataDownloader) method would be :
(NSData *) downloadDataWithRequest:(NSURLRequest *)
{
ASIHTTPRequest *dlRequest = [[ASIHTTPRequest alloc] initWithURL:[request URL]];
[dlRequest setTimeOutSeconds:20];
if(retryNum < 1)
retryNum = 1;
[dlRequest setNumberOfTimesToRetryOnTimeout:retryNum];
// and more of the same
}
ASIHTTPRequest is something we're using as an HTTP wrapper.
Now I wouldn't want to call this sequence of function each time I want to send the server an HTTP request, So the option would be to put that inside a dedicated class and create a new instance, or using a singletion.
What I can do for example is Using something like that :
[[UpdateUserInfo sharedInstance] updateInfo:info]
Which can be implemented by setting up a NSURLRequest using the param info , and calling
[[DataDownloader sharedInstance] downloadDataWithRequest:InfoUrlRequest]
Now, assuming the http request are asynchronous , I still can spawn multiple at the same time.
I hope it's clearer now.
What do you think is the best way to design it ?
I wouldn't see the singleton pattern as being a useful solution to the problem you're trying to solve. It's really designed as a technique to control access to a single/finite resource, which isn't meaningfully the case from what I can tell.
For example, is there any reason why you wouldn't permit a user to carry out two network related activities at the same time?
Incidentally, out of interest have you looked at Cocoa classes such as NSURLConnection? I'm not sure you'd need a lower level class to manage the server communications as you're envisaging - this class might suffice. (Had to tell without knowing more about what you're trying to achieve.)
Also don't forget ASIHTTPRequest. It's a full featured network library
http://allseeing-i.com/ASIHTTPRequest/
I usually (and that's personal preference) have one singleton that controls the network management (a singleton and facade pattern in one) as to not having more than the 5 allowed connections. Could be possible for you as well. That would be a singleton for part of your task 1.
But as BobC has already pointed out, ASIHTTPRequest should do everything you need.
Don't reinvent the wheel!
I use the singleton pattern to control access to a web-based API that uses ASIHTTPRequest, and it works very well. ASI uses NSOperationQueues for asynchronous requests, so you don't need to worry about requests clobbering each other.
Because I don't know the order that requests are returned, I sometimes allow my public API methods to supply userInfo dictionaries so my callbacks have some context when they fire.
I would use the Service Locator pattern to obtain each of the services needed in your application. There are a couple different ways to create the service locator. I prefer configuration at initialization over configuration during runtime.
http://en.wikipedia.org/wiki/Service_locator_pattern
Related
What would be the most appropriate way to chain asynchronous NSURLConnections? For example, I need to register a user with a web service. The workflow would be as follows:
Get Register Token => Use token to Register => Get Login Token => Use token to Login.
I know how to create an asynchronous NSURLConnection, but I'm unsure how to make sure the previous connection has finished before moving on. I know I can achieve this using NSURLConnection sendSynchronousRequest but I don't like my main thread being blocked while these chained requests happen.
We did EXACTLYA this when we built our first version of SignMeOut for iPhone. We created a subclass of NSUrlconnection and gave it an identifying tag do in the connectionDidFinish you would be able to use a simple switch/case with an enum. Works great - you can see the whole flow and example and code in our blog
http://www.isignmeout.com/multiple-nsurlconnections-viewcontroller/
UPDATE
I've modified the NSURLConnection subclass into a much simpler Category. Most of the usage is the same but cleaner using the same class
https://github.com/Shein/Categories
You can look at connectionDidFinishLoading to start another asynchronous connection. For the conditions as to which connection ended, you can keep references to the connections in case other connections are also expected to finish(probably not needed in your case). Make your class follow the NSURLConnectionDelegate and fire the appropriate connections in the connectionDidFinishLoading delegate method. You can also use the connectionDidReceiveData: method to check for credentials, etc received from the service. Go through the documentation too.
You have different options:
create a queue using a mutable array or dictionary
create an NSOperationQueue kind of easy if you use it in combination
with the new only ios5 API for NSUrlConnection
third parties lib such as AFNetworking
Block GCD grouping them (hard for NSRunLoop reasons, pay attention in wich thread the connection is running in)
I'm working on a new iPhone/iPod app that includes the need to do web services requests. I've found methods for doing these requests synchronously, or asynchronously by setting the controller as the delegate. What I'd really like to be able to do, though, is to create a single class that can handle all web requests for the whole application, and just create an instance of that class when I need to use it. That way, cookies and common pieces of code can be handled in one place, rather than all over the app.
So far the only thing I thought of that could accomplish what I'm trying to do is to create a new thread that handles the request synchronously within itself, then sends a message back to the calling controller once the request is complete. Is there a better way to accomplish what I'm trying to do?
Cookies are already a shared resource.
I would suggest reading the URL Loading System Overview to get an idea of how Apple set everything up. From what you describe, you want something very similar to how they have set up the system, maybe with a Singleton class for the connection. You can also look at ASIHTTPRequests which is a good wrapper around all of the connections stuff.
I would not suggest writing my own code here. Lots and lots of people have solved this problem for you.
I have a few apps that I am trying to develop a reusable URL connection layer. I have done some research and am struggling between architectures. Specifically the APIs this layer utilizes.
In the past, I have used NSURLConnection and NSOperation on a separate RunLoop. This seems overkill. I've seen libraries that subclass NSURLConnection. Others have a singleton Engine object that manages all requests.
The Engine and/or NSURLConnection seem best to me. But I am asking for input before I go too far down one road. My goals would be:
Ability to cancel a request
Concurrent requests
Non-blocking
Data object of current open requests
Any direction or existing references with code samples would be greatly appreciated.
I'm not sure about a "data object of current open requests", but ASIHTTPRequest does the first three and is very easy to use.
Update
Actually, it looks like ASINetworkQueue may fulfill your last bullet point.
I personally use a singleton engine with my large Apps though it might not always be the best case. All the URL's I use require signing in first, figured it would be best if one Class handles all of the requests to prevent multiple URLS from signing into the one location.
I basically create a protocol for all my different connection classes into my singleton and pass the delegate of both the calling class and the singleton into it. If an error occurs its passed to the singleton so it can deal with it, if it completes it returns the data to the calling class.
Im using a large amount of very small web services in my app and I have been down a couple of roads that does not scale or work as desired.
The Design approach Im thinking about:
The task for the viewController is to ask for a set of data from a general webServicesClass, this task is started in a new NSThread -> this will instantiate an object which solely retrieves the xml and returns it to the webServicesClass -> the webServicesClass now instantiates an object which solely can Parse some XML coming from this particular web service. The Parser then returns a nice Entity object to the webServiceClass. The WebserviceClass now needs to inform the viewController about this data.
The viewController implements a webServiceClassDelegate and some delegate methods to see if the web service request went as planned. e.g. -(void)aWebserviceFailed and -(void)aWebserviceSuccess.
0.5 Since the WebserviceClass is running is a different NSThread, will it be a problem calling delegate methods on the main NSThread in the parent object?
1.0 I think this design is sound as it completely incapsulates the retrieval, parsing and returning of the Entity in different classes. But, I will have to write delegation methods and implement delegation protocols on each step of the way, for each different webservice. i.e. starting from the bottom, the WebserviceClass must implement delegation methods for both the object that retrieves the XML (start, fail, success), then for the object that parses the XML(start, fail, success) and the WebserviceClass must be able to delegate each of these responses to the viewController that again must implement delegation methods from the WebserviceClass(start, fail, success).
Is there a much simpler way to do this?
I have some design pattern experience, but not from languages that uses delegation so consistently as Objective C. In AS3 or Java I would have events that could bubble up through the objects and inform whoever was listening about changes. In all the Objective example code I have read I have only seen NSNotifications (which would be the equivalent of the AS3 or Java 'Event') used 0.1% of the times.
The Design I described will give me something that scales perfectly for many web services and gives me complete control over where a potential error/exception happens, but it seems to be a lot of code to obtain this loose coupling.
1.1 Or should I fully embrace the delegation approach and get to work:)
Thanks for any pointers or help given. Im not asking for source code or the likes, more a "this is considered best practice in Objective C in the every day situation you just described" :)
I'd recommend taking a look at ASIHttpRequest(obtainable here) and NSOperation + NSOperationQueue (docs here). I don't think you should run a long-lived thread to talk to your web service all the time, unless you absolutely need a constant connection.
Basically ASIHttpRequest and NSOperation both encapsulate all of the networking and threading stuff. Operations make multi-threading on the iPhone really nice. Essentially you create an operation (through a factory or whatnot for ease of use), pop it in a queue and do something with the result.
As for what you do with the result (this applies to your original scenario too and 0.5 and 1.1) what typically happens is your operation/thread will then call a didSucceedAtGettingWhatever or didFailWithError:(NSError*) method. Delegation is pretty much the defacto way of making requests on the phone. If there are multiple delegates, then you can just use subject-observer, like you would in Java.
As for 1.0, ultimately no. What we typically do is we have an OperationDelegate and OperationTypes. Based upon which OperationType succeeded or completed, we have different logic. It's not the greatest and there are a ton of different ways of doing this, but you will have to have separate logic for separate events regardless of what you do. Whether or not that's in one method or many methods is up to you.
Not even sure if the title is correct, however, what I'm trying to do is use the standard NSURLConnection class to handle responses from calling my webservice. I am using the POST method to update a database and the GET method to retrieve rows from the database. The problem I have is that these 2 actions may occur simultaneously so that the methods to handle the request may step on each other. In other words in my "connection didReceiveData" method I have 2 paths through the code depending on whether I'm handling a response from a GET or POST request.
I keep track on which request in being processed by an instance variable called requestType. The problem is that since the requests are being executed simultaneously the instance variable is being changed from GET to POST before the GET completes (or vice-versa). My question is how do I maintain 2 separate requests in this scenario? Do I synchronize the requests? Is there a way for threads to work here? Do I create 2 separate objects for each of the requests and have the logic in "didRecieveData" query for which object is being processed? Any help would be much appreciated!!
Dealt with a similar issue in one of our apps. The solution involved creating a class that represents a webservice call, responsible for calling its own url, loading its own data, etc. The call class had a delegate that would handle parsing the responses (in our case, a web service controller). Wound up getting rather complicated, but prevented the issue of NSURLConnections stepping on each other.
Seems like you've created a messy problem by having a class that tries to do too many things. I would suggest taking one of the following three approaches:
1) Write two classes, one for updates and one for retrievals. Each class creates it's own private NSURLConnection object and acts as the delegate for the async notifications received from the NSURLConnection. The classes could possible share some utility parsing code or extend a base object that has that parsing code in it. But the key being that the code calling these classes would instantiate one of them, make the call, and then release it. This will keep your code cleaner and will insure that the event notifications don't get intermingled.
2) Create a single class that, depending on initialization, does either a post or a get with it's own private instance of NSURLConnection. When a call needs to be made, instantiate the class, get the results, and then release the class.
3) Write your connection handling classes so they use the synchronous NSURLConnection method and call that call that class in a background thread.
Either way, clean code and clear object orientation will prevent messy scenarios like the one you're describing.
Create separate objects that handle the calls. If you want to issue multiple requests at once I would strongly recommend looking at NSOperationQueue, and making these objects subclasses of NSOperation... much nicer way to deal with multiple background requests.
A good example is here:
http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/
The idea there is that you use the non-asyncronous web calls, in operations that are run on separate threads. You can still use asynch calls in NSOperation as well, but doing so is a little trickier and for simple calls you probably do not need to.