diff --git a/plugin.xml b/plugin.xml
index 72ddbb5..b661917 100644
--- a/plugin.xml
+++ b/plugin.xml
@@ -34,6 +34,7 @@
+
@@ -43,6 +44,7 @@
+
diff --git a/src/ios/CordovaHttpPlugin.m b/src/ios/CordovaHttpPlugin.m
index 8277a27..ddc4517 100644
--- a/src/ios/CordovaHttpPlugin.m
+++ b/src/ios/CordovaHttpPlugin.m
@@ -3,6 +3,7 @@
#import "TextResponseSerializer.h"
#import "TextRequestSerializer.h"
#import "AFHTTPSessionManager.h"
+#import "SDNetworkActivityIndicator.h"
@interface CordovaHttpPlugin()
@@ -175,6 +176,7 @@
CordovaHttpPlugin* __weak weakSelf = self;
manager.responseSerializer = [TextResponseSerializer serializer];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
@try {
[manager POST:url parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject) {
@@ -183,15 +185,18 @@
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
}
@catch (NSException *exception) {
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[self handleException:exception withCommand:command];
}
}
@@ -213,6 +218,7 @@
CordovaHttpPlugin* __weak weakSelf = self;
manager.responseSerializer = [TextResponseSerializer serializer];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
@try {
[manager GET:url parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject) {
@@ -221,15 +227,18 @@
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
}
@catch (NSException *exception) {
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[self handleException:exception withCommand:command];
}
}
@@ -251,6 +260,7 @@
CordovaHttpPlugin* __weak weakSelf = self;
manager.responseSerializer = [TextResponseSerializer serializer];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
@try {
[manager PUT:url parameters:parameters success:^(NSURLSessionTask *task, id responseObject) {
@@ -259,15 +269,18 @@
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
}
@catch (NSException *exception) {
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[self handleException:exception withCommand:command];
}
}
@@ -289,6 +302,7 @@
CordovaHttpPlugin* __weak weakSelf = self;
manager.responseSerializer = [TextResponseSerializer serializer];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
@try {
[manager PATCH:url parameters:parameters success:^(NSURLSessionTask *task, id responseObject) {
@@ -297,15 +311,18 @@
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
}
@catch (NSException *exception) {
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[self handleException:exception withCommand:command];
}
}
@@ -326,6 +343,7 @@
CordovaHttpPlugin* __weak weakSelf = self;
manager.responseSerializer = [TextResponseSerializer serializer];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
@try {
[manager DELETE:url parameters:parameters success:^(NSURLSessionTask *task, id responseObject) {
@@ -334,15 +352,18 @@
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
}
@catch (NSException *exception) {
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[self handleException:exception withCommand:command];
}
}
@@ -361,6 +382,7 @@
CordovaHttpPlugin* __weak weakSelf = self;
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
@try {
[manager HEAD:url parameters:parameters success:^(NSURLSessionTask *task) {
@@ -370,15 +392,18 @@
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
}
@catch (NSException *exception) {
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[self handleException:exception withCommand:command];
}
}
@@ -402,6 +427,7 @@
CordovaHttpPlugin* __weak weakSelf = self;
manager.responseSerializer = [TextResponseSerializer serializer];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
@try {
[manager POST:url parameters:parameters constructingBodyWithBlock:^(id formData) {
@@ -413,6 +439,7 @@
[dictionary setObject:@"Could not add file to post body." forKey:@"error"];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
return;
}
} progress:nil success:^(NSURLSessionTask *task, id responseObject) {
@@ -421,15 +448,18 @@
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
}
@catch (NSException *exception) {
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[self handleException:exception withCommand:command];
}
}
@@ -455,6 +485,7 @@
CordovaHttpPlugin* __weak weakSelf = self;
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
@try {
[manager GET:url parameters:parameters progress:nil success:^(NSURLSessionTask *task, id responseObject) {
@@ -495,6 +526,7 @@
}
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
return;
}
NSData *data = (NSData *)responseObject;
@@ -504,6 +536,7 @@
[dictionary setObject:@"Could not write the data to the given filePath." forKey:@"error"];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
return;
}
@@ -514,6 +547,7 @@
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];
@@ -521,9 +555,11 @@
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
}
@catch (NSException *exception) {
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
[self handleException:exception withCommand:command];
}
}
diff --git a/src/ios/SDNetworkActivityIndicator/LICENSE b/src/ios/SDNetworkActivityIndicator/LICENSE
new file mode 100644
index 0000000..6a88659
--- /dev/null
+++ b/src/ios/SDNetworkActivityIndicator/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2010 Olivier Poitrey
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/src/ios/SDNetworkActivityIndicator/README.md b/src/ios/SDNetworkActivityIndicator/README.md
new file mode 100644
index 0000000..1fb11cf
--- /dev/null
+++ b/src/ios/SDNetworkActivityIndicator/README.md
@@ -0,0 +1,52 @@
+# SDNetworkActivityIndicator
+
+Handle showing / hiding of the iOS network activity indicator to allow multiple concurrent threads to show / hide the indicator such that the indicator remains visible until all the requests have completed and requested the indicator to be hidden.
+
+## Requirements
+
+* iOS 5.0 or later.
+* ARC memory management.
+
+## Installation
+
+The easiest way to install it is by copying the following files to your project:
+
+* SDNetworkActivityIndicator.h
+* SDNetworkActivityIndicator.m
+
+## Usage
+
+* When you start a network activity (will show the network activity indicator):
+
+ [[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];
+
+* When you finish a network activity (will hide the network activity indicator only if the number of calls to `stopActivity` matches the number of calls to `startActivity`):
+
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
+
+* To hide the network activity indicator regardless of whether all activities have finished (without having to call `stopActivity` for each `startActivity` called):
+
+ [[SDNetworkActivityIndicator sharedActivityIndicator] stopAllActivity];
+
+
+## License
+Copyright (c) 2010 Olivier Poitrey
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/src/ios/SDNetworkActivityIndicator/SDNetworkActivityIndicator.h b/src/ios/SDNetworkActivityIndicator/SDNetworkActivityIndicator.h
new file mode 100644
index 0000000..2c43aa6
--- /dev/null
+++ b/src/ios/SDNetworkActivityIndicator/SDNetworkActivityIndicator.h
@@ -0,0 +1,18 @@
+/*
+ * This file is part of the SDNetworkActivityIndicator package.
+ * (c) Olivier Poitrey
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+#import
+
+@interface SDNetworkActivityIndicator : NSObject
+
++ (id)sharedActivityIndicator;
+- (void)startActivity;
+- (void)stopActivity;
+- (void)stopAllActivity;
+
+@end
diff --git a/src/ios/SDNetworkActivityIndicator/SDNetworkActivityIndicator.m b/src/ios/SDNetworkActivityIndicator/SDNetworkActivityIndicator.m
new file mode 100644
index 0000000..c917b9a
--- /dev/null
+++ b/src/ios/SDNetworkActivityIndicator/SDNetworkActivityIndicator.m
@@ -0,0 +1,70 @@
+/*
+ * This file is part of the SDNetworkActivityIndicator package.
+ * (c) Olivier Poitrey
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+#import "SDNetworkActivityIndicator.h"
+
+@interface SDNetworkActivityIndicator()
+{
+ @private NSUInteger counter;
+}
+@end
+
+
+@implementation SDNetworkActivityIndicator
+
++ (instancetype) sharedActivityIndicator
+{
+ static id _sharedInstance = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ _sharedInstance = [[self alloc] init];
+ });
+
+ return _sharedInstance;
+}
+
+- (id)init
+{
+ if ((self = [super init]))
+ {
+ counter = 0;
+ }
+
+ return self;
+}
+
+- (void)startActivity
+{
+ @synchronized(self)
+ {
+ counter++;
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
+ }
+}
+
+- (void)stopActivity
+{
+ @synchronized(self)
+ {
+ if (counter > 0 && --counter == 0)
+ {
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
+ }
+ }
+}
+
+- (void)stopAllActivity
+{
+ @synchronized(self)
+ {
+ counter = 0;
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
+ }
+}
+
+@end