I'm creating an app that needs to be updated periodically (for chats, notifications, contact detail changes, etc). Xcode 4.2 IOS 5
I'm using sudzc generated code to consume the webservices. Those method calls are async as expected. I thought i could call all the update webservices within an NSOperation. However, i've discovered that the lifetime of an NSOperation is too short for any handler methods to be called. I've seen some "solutions" to that problem...but none them use the sudzc soap client generated classes. I also need to call the set of webservices periodically (like every 10 or so seconds).
So basically i need to call the webservices periodically and in a separate thread from the main thread. I'll also need to use the return values to update UI's.
Can someone please give me some advice.
Thanks :)
Related
I'm working with an iPhone developer on an application. I know very little about the iPhone. I'm writing the server-side code in Grails. I'm wondering what is available to me as far as approaches to using a RESTful JSON service with an occasional poll of the service.
From the iPhone:
Is there a way to put these calls on a background thread? when the data comes back is there a callback mechanism? Looking for some basic information on how to accomplish this on the iPhone / Objective-C.
Yes, typically you either provide a delegate that is notified when an asynchronous request has some kind of event (e.g. more data comes in, the request fails, etc.), spawn a background thread that performs synchronous requests, or pass success/failure blocks to an asynchronous request that executes them when appropriate.
But if you are working with an iPhone developer, shouldn't he be dealing with this, not you?
Have a look at NSURLConnection. It automatically puts the request on a background thread and has some callback methods that get called on its delegate.
I prefer using the ASIHttpRequest library for my integrations with RESTful rails apps. One of many advantages is the completion block:
request.completionBlock = ^{ NSLog(#"I'm finally complete!"; };
[request startAsynchronous];
Background:
I am in the early stages of an an iPhone App and REST WebService product. Basically, I have a database on the a server and have written some REST APIs to access this database. I have a companion iphone app that will consume these REST APIs.
Questions:
What is the best approach to place the code for accessing the REST Apis? Should I create a separate subclass of NSObject and place the interface and implementation details there? I would like to reduce the amount of code duplication throughout the application in the various ViewControllers that would interact with the REST API.
For Example:
My app would start up and make a REST API call to determine the current state of local information on the device by comparing the value returned from the API vs local. Then I would initiate an update request from the API to refresh the local datastore.
Now if I have all of this logic in the start-up ViewController I have multiple calls using NSURLConnection which only has on delegate. I don't know how to make these separate calls in the same ViewController.
What are some approaches to solving this problem?
I generally create custom objects which use ASIHTTPRequest (using composition, not subclassing) which can be initialised with any required parameters, and use that to manage requests to the RESTful service. The custom object will provide a delegate protocol for handling success, failure and other custom notifications so that I can use this feedback to update the application UI while the request is performed asynchronously.
If you need to parse large amount of data returned from a request, make sure you launch a separate thread to do this, rather than doing it in your HTTP request success callback, otherwise this will keep the network activity spinner active longer than it actually should be.
If you need to manage multiple requests of the same type, you could add a "tag" property to your custom request, so that when your success/failure delegate response is called, you can easily identify which request it belongs to without having to keep an instance variable to the original request.
First of all, I am a a very new Objective C/Cocoa iOS Developer but I've written C/C++ applications before.
So I managed to run the Rabbitmq-c (http://hg.rabbitmq.com/rabbitmq-c/) client inside my iPhone App, and I can connect to Rabbitmq directly from my app and even consume a queue item. So all's good.
Now my problem is, my iPhone app needs to use the rabbitmq-c library to poll for incoming messages in from the server. Probably there will be, an almost infinite while loop.
Do I have to take this to a new thread? Ideally, I want to wrap the rabbitmq-c class as an Async objective C class and use NSNotification (or something similar) to notify my UI. I'm a bit leery of creating a new thread, as I read about stuffs like Runloop etc can solve a lot of problems without using an extra thread.
What is the best way for me to go about this? Any examples of code or directions would be helpful. Please remember, I am not dealing with an Objective C code/Coca rabbitmq library here, I'm using C code inside my iPhone app.
Thanks
Subrat
don't block the main thread with your server polling.
since the operation never ends, create your own thread and run loop for this server polling. you can potentially use the run loop (each thread has one) instead of the infinite while. the alternatives involve regularly spawning threads. it's easiest to just use one thread for this.
once you have an update, post the notification (if you choose NSNotification) from the main thread -- UIKit is meant to operate from the main thread only.
for samples, i'd begin with samples related to NSRunLoop and CFRunLoop.
good luck
You can also create custom delegates for updating the UI, or the stuff related to UIKit.
Notifications might be a little easier to code and offer the advantage that multiple objects can observe one notification. With delegates, such a thing cannot be done without modifying the delegating object (and is unusual).
Some advantages of delegating:
The connection between delegating object and delegate is made clearer, especially if implementing the delegate is mandatory.
If more than one type of message has to be passed from delegatee to delegate, delegating can make this clearer by specifying one delegate method per message.
Or other way is to write method to receive messages. This method can have infinite loop.
Later you can put this method in background thread like this.
[self performSelectorInBackground:#selector(receiveMessages) withObject:nil];
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.
I have an app that makes SOAP calls. To keep the UI from blocking, we are putting each SOAP call into a subclass of NSOperation. This works well, but we have a ton of different types of SOAP calls. So if we use 3 WSDLs each with 10 Ports or Operations, then we 30 different calls in SOAP and if we put each of those in a thread using NSOperation, we end up with 30 NSOperation subclasses.
This may not be a bad thing, but we are trying to create a reusable library, so we have one object per WSDL which encapsulates the calls. This is nice because we are using WSDL2ObjC and this encapsulates all that logic. But it seems odd then to have a nice api that we wrap calls to in these many NSOperations. Also, we are doing the threading in the api itself, so that the invoker can use it how he/she sees fit.
Any suggestions would be great.
If I'm understanding you correctly you already have objects that encapsulate the calls to the SOAP service and you just want to cut down on the NSOperation subclasses.
Have you checked into NSInvocationOperation? It's a subclass of NSOperation that let's you make a message send to an object as an NSOperation call. So you still getting the non blocking operation, but you don't need multiple subclasses of NSOperation.