Problems using notifications as a callback? - ios

I am trying to update a view when something happens in another class, and after some looking, it appeared that the most common way to do this was to use either delegates or blocks to create a callback. However, I was able to accomplish this task using notifications. What I want to know is: Is there a problem using notifications to trigger methods calls? Are there any risks I'm not aware of? Is there a reason I'd want to use blocks/delegates over notifications?
I'm new to Objective-C, so I'm not sure if the approach I'm taking is correct.
As an example, I'm trying to set the battery level of a BLE device on the ViewController. I have a BluetoothLEManager, which discovers the peripheral, its services/characteristics, etc. But to do this, I need to initiate the "connection" in the detailViewController, then update the battery level once I find it.
Here is some example code of what I'm doing:
DetailViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NSLog(#"Selected tag UUID: %#", [selectedTag.tagUUID UUIDString]);
tagName.text = selectedTag.mtagName;
if(selectedTag.batteryLevel != nil){
batteryLife.text = selectedTag.batteryLevel;
}
uuidLabel.text = [selectedTag.tagUUID UUIDString];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(setBatteryLevel:) name:#"SetBatteryLevel" object:nil];
}
...
-(void)setBatteryLevel:(NSNotification*)notif{
NSMutableString* batLevel = [[NSMutableString alloc]initWithString:[NSString stringWithFormat:#"%#", selectedTag.batteryLevel]];
[batLevel appendString:#" %"];
selectedTag.batteryLevel = batLevel;
batteryLife.text = selectedTag.batteryLevel;
}
BluetoothLEManager.m:
...
-(void) getBatteryLevel:(CBCharacteristic *)characteristic error:(NSError *)error fetchTag:(FetchTag *)fetchTag
{
NSLog(#"Getting battery Level...");
NSData* data = characteristic.value;
const uint8_t* reportData = [data bytes];
uint16_t batteryLevel = reportData[0];
selectedTag.batteryLevel = [NSString stringWithFormat:#"%i", batteryLevel];
NSLog(#"Battery Level is %#", [NSString stringWithFormat:#"%i", batteryLevel]);
[[NSNotificationCenter defaultCenter] postNotificationName:#"SetBatteryLevel" object:nil];
}
...
Let me know if you need any other code, but this is the basics of it all.

Each approach has different strengths and weaknesses.
Delegates and protocols require a defined interface between the object and it's delegate, a one-to-one relationship, and that the object have specific knowledge of the delegate object it's going to call.
Methods with completion blocks involve a similar one-to-one relationship between an object and the object that invokes the method. However since blocks inherit the scope in which they're defined, you have more flexibility as to the context that's available in the completion block. Blocks also allow the caller to define the completion code in same place that the call takes place, making you code more self-documenting.
In both cases, the object that is notifying the delegate or invoking the completion block has to know who it's talking to, or what code is being executed.
A delegate call is like an auto shop calling you back to let you know your car is done. The service manager has to have your phone number and know that you want a call.
A block is more like a recipe you give to a chef. Give the chef a different recipe and he/she performs a different task for you.
Notifications are much less tightly coupled. It's like a town crier, yelling announcements in a crowded public square. The crier doesn't need to know who's listening, or how many people are listening.
Likewise, when you send a notification, you don't know who, if anybody, is listening, or how many listeners there are. You don't need to know. If 10 objects care about the message you are broadcasting, they can all listen for it, and they'll all be notified. The message sender doesn't have to know or care who's listening.
Sometimes you want tighter coupling, and sometimes you want looser coupling. It depends on the problem you're trying to solve.

Related

Reading long characteristic values using CoreBluetooth

I have a characteristic value which contains the data for an image. In the peripheral I setup the value like this:
_photoUUID = [CBUUID UUIDWithString:bPhotoCharacteristicUUID];
_photoCharacteristic = [[CBMutableCharacteristic alloc] initWithType:_photoUUID
properties:CBCharacteristicPropertyRead
value:Nil
permissions:CBAttributePermissionsReadable];
My understanding is that when this value is requested, the didReceiveReadRequest callback will be called:
-(void) peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request {
if ([request.characteristic.UUID isEqual:_photoUUID]) {
if (request.offset > request.characteristic.value.length) {
[_peripheralManager respondToRequest:request withResult:CBATTErrorInvalidOffset];
return;
}
else {
// Get the photos
if (request.offset == 0) {
_photoData = [NSKeyedArchiver archivedDataWithRootObject:_myProfile.photosImmutable];
}
request.value = [_photoData subdataWithRange:NSMakeRange(request.offset, request.characteristic.value.length - request.offset)];
[_peripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
}
}
}
This comes pretty much from Apple's documentation. On the Central side in the didDiscoverCharacteristic callback I have the following code:
if ([characteristic.UUID isEqual:_photoUUID]) {
_photoCharacteristic = characteristic;
[peripheral readValueForCharacteristic:characteristic];
}
Which in turn calls the didUpdateValueForCharacteristic callback:
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
NSLog(#"updated value for characteristic");
if ([characteristic.UUID isEqual:_photoUUID]) {
NSArray * photos = [NSKeyedUnarchiver unarchiveObjectWithData:characteristic.value];
}
}
All of the callbacks are called but when I try to re-construct the array, it's corrupted because not all of the data is transferred correctly. I would expect the didRecieveReadRequest callback to be called multiple times with a different offset each time. However it's only called once.
I was wondering if anyone knew what I'm doing wrong?
I'm guessing you're bumping up against the 512 byte limit on characteristic length. You'll need to move to subscriptions to characteristics and processing of updates to get around this:
On the central:
Subscribe to the characteristic by calling -[CBPeripheral setNotifyValue:forCharacteristic] (with YES as the notify value).
In -peripheral:didUpdateValueForCharacteristic:error, every update will either be data to append, or something you choose to use on the peripheral side to indicate end-of-data (I use an empty NSData for this). Update your -peripheral:didUpdateValueForCharacteristic:error code so that:
If you're starting to read a value, initialize a sink for the incoming bytes (e.g. an NSMutableData).
If you're in the middle of reading a value, you append to the sink.
If you see the EOD marker, you consider the transfer complete. You may wish to unsubscribe from the characteristic at this state, by calling -[CBPeripheral setNotifyValue:forCharacteristic] with a notify value of NO.
-peripheral:didUpdateNotificationStateForCharacteristic:error: is a good spot to manage the initialization and later use of the sink into which you read chunks. If characteristic.isNotifying is updated to YES, you have a new subscription; if it's updated to NO then you're done reading. At this point, you can use NSKeyedUnarchiver to unarchive the data.
On the peripheral:
In -[CBMutableCharacteristic initWithType:properties:value:permissions], make sure the properties value includes CBCharacteristicPropertyNotify.
Use -peripheralManager:central:didSubscribeToCharacteristic: to kick off the chunking send of your data, rather than -peripheral:didReceiveReadRequest:result:.
When chunking your data, make sure your chunk size is no larger than central.maximumUpdateValueLength. On iOS7, between an iPad 3 and iPhone 5, I've typically seen 132 bytes. If you're sending to multiple centrals, use the least common value.
You'll want to check the return code of -updateValue:forCharacteristic:onSubscribedCentrals; if underlying queue backs up, this will return NO, and you'll have to wait for a callback on -peripheralManagerIsReadyToUpdateSubscribers: before continuing (this is one of the burrs in an otherwise smooth API, I think). Depending upon how you handle this, you could paint yourself into a corner because:
If you're constructing and sending your chunks on the same queue that the peripheral is using for its operations, AND doing the right thing and checking the return value from -updateValue:forCharacteristic:onSubscribedCentrals:, it's easy to back yourself into a non-obvious deadlock. You'll either want to make sure that you yield the queue after each call to -updateValue:forCharacteristic:onSubscribedCentrals:, perform your chunking loop on a different queue than the peripheral's queue (-updateValue:forCharacteristic:onSubscribedCentrals: will make sure its work is done in the right place). Or you could get fancier; just be mindful of this.
To see this in action, the WWDC 2012 Advanced Core Bluetooth video contains an example (sharing VCards) that covers most of this. It doesn't however, check the return value on the update, so they avoid the pitfalls in #4 altogether.
Hope that helps.
I tried the approach described by Cora Middleton, but couldn't get it to work. If I understand her approach correctly, she would send all partial data through the update notifications. The problem for me seemed to be that there was no guarantee each update would be read by the central if the values in these notifications would change often in short succession.
So because that approach didn't work, I did the following:
There's some characteristic that I use to keep track of the state of the peripheral. This characteristic would only contain some flags and would send out notifications if one or more flags change. Interactions by the user on the peripheral would change the state and there's one action on the peripheral that the user can perform to trigger a download from a connected central.
The data to be downloaded from the central is added to a stack on the peripheral. The last item on the stack is a terminator indicator (an empty NSData object)
The central registers to receive notifications of the aforementioned state characteristic. If some flag is set, a download is triggered.
On the peripheral side, every time I receive a read request for a certain characteristic, I remove 1 item from the stack and return this item.
On the central side I add all data that is returned from the read requests. If the empty data value is retrieved, then I create an object from the returned data (in my case it's a JSON string).
On the peripheral side I also know the download is finished after returning the empty NSData object, so afterwards I can change the state once again for the peripheral.

How to avoid deallocated objects being accessed in callbacks/etc?

The issue has been discussed here and here, but I wonder if there is a more solid way to solve this whether you have delegates or not - when a function is called after a delay.
At a certain point in a program, at a button push, an object - a CCLayer - is created. That layer creates several objects, some of them at callbacks. That created object layer has a "back" button which destroys it. I am running into a problem when the callbacks, etc are triggered AFTER that object is destructed and try to access objects that don't exist anymore - where the "message sent to deallocated instance 0x258ba480" gives me this good news. How do I avoid that?
1) Is there a way to kill the callbacks (because I obviously don't need them anymore)
2) should/can I test for the existence of these possibly non-existent objects at the callbacks themselves
3) something else?
(My callback is code for checking for an internet connection that I copied from this illustrious website - may it live long and prosper-, using Reachability, and I could solve the problem by simply moving it to the main view and setting a flag on the child view, but I don't want to.)
- (void)testInternetConnection
{
internetReachableFoo = [Reachability reachabilityWithHostname:#"www.google.com"];
// Internet is reachable
internetReachableFoo.reachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Yayyy, we have the interwebs!");
//I do the net stuff here
});
};
// Internet is not reachable
internetReachableFoo.unreachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Someone broke the internet :(");
noNetMessageLabel.visible=true; //<-------this goes kaboom
noNetFlag=true;
});
};
[internetReachableFoo startNotifier];
}
There are basically two ways to avoid deallocated delegates from being messaged:
Hold onto the objects you want to message later. That way they won’t get deallocated. This is the case with block callbacks – if a block references some object, the object gets retained until the block ceases to exist. If you message some objects from a block and hit a deallocated object, you must have screwed up the memory management somewhere.
Clear the delegation link before you release the delegate. Nowadays this is usually done using weak, zeroing properties that are automatically set to nil when the referenced object is deallocated. Very convenient. Not your case.
You might consider several options:
First, you may just check for existence of an object before passing message to it:
if (noNetMessageLabel)
noNetMessageLabel.visible = true;
But personally I consider that as a bad architecture.
More wise decision, from my point of view, would be move the code of displaying any alert regarding internet connectivity to the model.
Create method like this in AppDelegate or in the model:
- (NSError*)presentConnectivityAlert
{
if () //any error condition checking appropriate
[[NSNotificationCenter defaultCenter]
postNotificationName:#"connectivityAlert"
object:self
userInfo:userInfo];
}
Also you may consider moving internet checking code to the model too.
In the ViewControllers of your app implement listening to this notification.
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(didReceiveRemoteNotification:)
name:#"connectivityAlert"
object:nil];
}
- (void)viewDidUnload {
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:#"connectivityAlert"
object:nil];
}
-(void)didReceiveRemoteNotification:(NSDictionary *)userInfo {
if (self.isViewLoaded && self.view.window) {
//Present the user with alert
}
}
Thus you have more general and quite versatile approach to handle connectivity issues throughout all your application.
Is there a way to kill the callbacks
It's not possible to cancel block (in your case), but it's possible to cancel NSOperation in NSOperationQueue. But that will require to rewrite your implementation of Reachability.

Sending Notifications from Model to Controller in iOS

I made a class, called Timer. Its designated initializer starts a timer with a value in seconds. It works great. However I am having trouble updating the controller w/e the timer ticks.
Right now, for every tick I am sending a NSNotificationCenter with a userInfo that is a simple dictionary with the current time, which does not sound the best way to do it...
NSDictionary *dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithFloat:self.timerCount] forKey:#"timerCount"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"TimerCountChanged"
object:self
userInfo:dict];
Should I be using some other technique or am I doing it the right way?
Thank you in advance!
EDIT:
I need to initialize different Timers, using different values. I tried to use Delegates, but I only had one method in my controller to update the UI for all those Timers!
Would it be bad if I do something like? Passing a UIButton to my Model also does not seem to be the best solution but it works.
-(void)timer:(Timer *)timer didTriggerAt:(NSTimeInterval)time andButton:(UIButton *)button
{
[button setTitle:[NSString stringWithFormat:#"%.0f", time] forState:UIControlStateNormal];
}
- (IBAction)startCountDown:(UIButton *)sender
{
self.timer1 = [[Timer alloc] initWithTimeInSeconds:10 andButton:sender];
self.timer1.delegate = self;
}
I have 3 Timers in my MainView, the user can start them whenever he wants. They can also have different times, which is also defined by the user.
Sending Notifications is good, but you may not observe it as in regular time.
Sometimes it gets delayed and you may observe them in irregular time interval.
You can use
Delegate Pattern.
Call method by selector
EDIT:
From
Apple documentation on Performance CodeSpeed on Notifications.
The fewer notifications you send, the smaller the impact on your
application’s performance. Depending on the implementation, the cost
to dispatch a single notification could be very high. For example, in
the case of Core Foundation and Cocoa notifications, the code that
posts a notification must wait until all observers finish processing
the notification. If there are numerous observers, or each performs a
significant amount of work, the delay could be significant.
If you only have one client object for each Timer instance, then you should use the delegate pattern. You would define a TimerDelegate protocol with a method that a Timer object can call whenever the timer ticks.
e.g.
#class Timer;
#protocol TimerDelegate
- (void) timer:(Timer *)timer didTriggerAt:(NSTimeInterval)time;
#end
#interface Timer
...
#property (assign) id<TimerDelegate> delegate;
...
#end
If you indeed require multiple listeners each time a Timer instance ticks, then the NSNotificationCenter approach would be a better fit. Instead of passing info in the userInfo dictionary, I probably would expose an #property on Timer called currentTime, so that when a client object gets the notification, they could simply access currentTime on the notifying Timer, instead of (IMO clunkily) reading data out of userInfo.

Control access to webservice method from multiple UIViewControllers

I have an iOS app with a tabbar and 3 different UIViewControllers, one for each tab. The app uses SudzC to interface with a C# .NET webservice to pull data from a database.
There is one webservice method that is called from all three view controllers, but I want to enforce that only one view controller can call the method at any point in time and no other view controller can call it until the data has been returned.
I tried to solve this by defining a NSLock in the AppDelegate, and then implementing the following code in each viewController:
if([SharedAppDelegate.loginLock lockBeforeDate:[[[NSDate alloc] init] dateByAddingTimeInterval:30.0]])
{
// got the lock so call the webservice method
SDZiOSWebService* webService = [SDZiOSWebService service];
[webService Login:self action:#selector(handleRelogin:) username:userName password:password];
}
else
{
// can't get lock so logout
self->reloginInProgress = false;
[SharedAppDelegate doLogout];
}
The handler for the webservice return is defined as (truncated for clarity)
-(void)handleRelogin: (id) result {
SDZLoginResult *loginResult = (SDZLoginResult*)result;
if(loginResult.Status)
{
SharedAppPersist.key = loginResult.key;
}
else
{
SharedAppPersist.key = #"";
}
[SharedAppDelegate.loginLock unlock];
}
My understanding is that the first UIViewController would get a lock and the others would block for up to 30 seconds waiting to get hold of the lock. However in the rare instances where more than one viewController tries to access the lock at the same time I get the following error instantly:
*** -[NSLock lockBeforeDate:]: deadlock (<NSLock: 0x2085df90> '(null)')
Can anyone tell me what I am doing wrong? I have a good understanding of locks in C/C++ but these Objective-C locks have be stumped.
In my opinion you shouldn't use locks (which are "evil") for this simple case.
What you can try to use is a NSOperationQueue, set to manage 1 concurrent operation at a time, and then let the view controllers to enqueue their web service calls: the operation queue will guarantee that only one operation at a time will be performed.
The other advantage of the operation queue is that a view controller can check if the queue is empty or not and then decide to enqueue its call or not, based on the current status.
Finally you can use KVO to observer the queue status so each view controller can simply check this before submitting a new request.
Another possibility, similar to using NSOperationQueue, is to create a private GCD serial queue and again enqueue all web service requests (wrapped inside a block). While GCD serial queues are more straightforward to implement than NSOperationQueues (IMHO) they don't offer the same advantages of observability and the possibility to cancel operations.
If its just that you want 1 view to access the web-service at a time. you can make use of Singleton Classes.
Here's a link to one of the examples out the many on the net.
http://www.galloway.me.uk/tutorials/singleton-classes/
also you can use NSUserDefaults to store a bool value to inform you if a view is using the web-service or not.
A simple example will be:
To Store Value
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"active_connection"];
[NSUserDefaults synchronize];
To Retrieve
if(![[NSUserDefaults standardUserDefaults] boolForKey:#"active_connection"]) {
[[NSUserDefaults standardUserDefaults] setBool:NO forKey:#"active_connection"];
[NSUserDefaults synchronize];
// Send request to web-service
}
I hope this helps you. Happy Coding.!!

How to make program wait for asynchronous NSURLConnection to finish before proceeding with next command?

How can I make my program wait for an asynchronous NSURLConnection to finish before going to the next line of code?
SetDelegate *sjd= [SetDelegate alloc];
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:post delegate:sjd];
[connection start];
This is how I start the connection and I handle the data received in the delegate but I want to wait for the connection to end before proceeding mainly because this is in a for loop and it has to run for each element in my database.
I need to put data from the phones database to a remote database and after the data was successfully put in the data in the phones database is deleted. I am going through each element in the phone's database and start a connection that's why I don't see how the next stuff can be done from the loop. I'm a beginner when it comes to objective-c programming so I'm not sure if this is the right way or not to do it
Making the call synchronous is not an option because it blocks the program and i have a progress bar that should show.
Your question is a bit odd. You have impossibly constrained the issue. You cannot have a line of code "wait" for a process to finish w/o it blocking something, in this case whatever thread the loop is running in.
You can use a synchronous call if you wanted to, it doesn't block your app, it only blocks the thread it is executed on. In your example, you have a loop that is continually getting remote data and you want your UI to reflect that until it is done. But you don't want your UI blocked. That means, this thread with your loop already MUST be on a background thread so you can feel free to do a synchronous call in the loop w/o blocking your UI thread. If the loop is on the UI thread you need to change this to do what you want.
You could also do this using an asynchronous connection. In that case, your operation may actual complete faster b/c you can have multiple requests in progress at the same time. If you do it that way, your loop can remain on the UI thread and you just need to track all of the connections so that when they are finished you can communicate that status to the relevant controllers. You'll need iVars to track the loading state and use either a protocol or NSNotification to communicate when loading is done.
EDIT: ADDED EXAMPLE OF SYNCHRONOUS CALL ON BACKGROUND THREAD
If you want the loop to finish completely only when all requests are finishes and not block your UI thread here's a simple example:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// post an NSNotification that loading has started
for (x = 0; x < numberOfRequests; x++) {
// create the NSURLRequest for this loop iteration
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
// do something with the data, response, error, etc
}
// post an NSNotification that loading is finished
});
Whatever objects need to show loading status should observe and handle the notifications you post here. The loop will churn through and make all your requests synchronously on a background thread and your UI thread will be unblocked and responsive. This isn't the only way to do this, and in fact, I would do it using async connections myself, but this is a simple example of how to get what you want.
If you just want to know when it's complete and don't really care about any data, simply use the NSNotificationCenter to post a notification and have your view subscribe to it.
Delegate - Post Notification upon completion
-(void) connectionDidFinishLoading:(NSURLConnection*)connection {
[[NSNotificationCenter defaultCenter] postNotificationName:#"NSURLConnectionDidFinish" object:nil];
}
View - Add observer and run some code when observed
-(void) viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(yourCleanupMethod)
name:#"NSURLConnectionDidFinish"
object:nil];
}
-(void) yourCleanupMethod {
// finish up
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Now, if you need to pass a simple object back as data you can try loading up the object parameter in your notification like this:
[[NSNotificationCenter defaultCenter] postNotificationName:#"NSURLConnectionDidFinish" object:yourDataObject];
Then change your view and cleanup signature like this:
-(void) viewDidLoad {
// Notice the addition to yourCleanupMethod
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(yourCleanupMethod:)
name:#"NSURLConnectionDidFinish"
object:nil];
}
-(void) yourCleanupMethod:(NSNotification *)notif {
// finish up
id yourDataObject = [notif object];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Now I found myself needing something a little more than this so I ended up creating a singleton to handle all of my requests. Since all of your delegate methods in NSURLConnectionDelegate give you and instance of the NSURLConnection for the specific connection, you can simply store a mutable data object in a dictionary and look it up each time by the connection. From there I have a method signature that takes and object and selector in that I associate with the connection so after everything has wrapped up, I can pass that mutable data object to the requestor by performing the selector on that object.
I won't include all of that code here but maybe that will help get you thinking about what is possible. I found that I had a lot of code tied up in making web service calls so wrapping everything up in a singleton gave me a nice clean way of getting data. Hope this helps!
If you really want it to wait, why use an asynchronous call at all? Use a synchronous call instead:
NSURLResponse* response = nil;
NSData* data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:nil]
This approach will block the thread it's executed, so you should be sure you want to do it! Did I mention that it will block? :)
You say you want to wait for an asynchronous call to complete, so I'm assuming you're calling the code you posted up in a separate thread.
I would recommend having a look at the new sendAsynchronourRequest method. I've posted up an example of how you can wrap this up in a class which would inform its delegate when the connection has completed / timed out / failed. I'm only referring you to this post because it sounds like you're trying to achieve something very similar to what I was at the time, and this DownloadWrapper class worked flawlessly for me. It's new in iOS5, mind you.
This golden nugget helped me!
I was using synchronous NSURL just fine until I decided I needed SSL for my connection between my client and my server. I took the approach of key pinning which is comparing the cert on the device to the cert on the server (read more on link above) and in order for it to work I needed to add code to the NSURL methods, which from my research you can't do with NSURL synchronous.
Until I found this ridiculously simple solution which worked for me:
NSString *connectionRunLoopMode = #"connectionRunLoopMode";
NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:urlRequest delegate:urlConnectionDelegate startImmediately:NO];
NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
[connection unscheduleFromRunLoop:currentRunLoop forMode:NSDefaultRunLoopMode];
[connection scheduleInRunLoop:currentRunLoop forMode:connectionRunLoopMode];
[connection start];
while ([currentRunLoop runMode:connectionRunLoopMode beforeDate:[NSDate distantFuture]]);
NSURLConnection is already asynchronous. Simply implement the delegate methods. If you want to update the UI on the MainThread (e.g. a progress bar), you can do so in didReceiveData.
or look at this

Resources