summaryrefslogtreecommitdiff
path: root/StoneIsland/platforms/ios/Stone Island/Plugins
diff options
context:
space:
mode:
Diffstat (limited to 'StoneIsland/platforms/ios/Stone Island/Plugins')
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/README20
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/IonicKeyboard.h13
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/IonicKeyboard.m160
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/UIWebViewExtension.h4
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/UIWebViewExtension.m109
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-console/CDVLogger.h26
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-console/CDVLogger.m38
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-device/CDVDevice.h30
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-device/CDVDevice.m99
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-dialogs/CDVNotification.h37
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-dialogs/CDVNotification.m221
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-geolocation/CDVLocation.h70
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-geolocation/CDVLocation.m366
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVConnection.h34
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVConnection.m127
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVReachability.h85
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVReachability.m260
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVSplashScreen.h43
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVSplashScreen.m330
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVViewController+SplashScreen.h28
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVViewController+SplashScreen.m82
-rwxr-xr-xStoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-x-socialsharing/SocialSharing.h27
-rwxr-xr-xStoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-x-socialsharing/SocialSharing.m715
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/AppDelegate+notification.h21
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/AppDelegate+notification.m167
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/PushPlugin.h62
-rw-r--r--StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/PushPlugin.m347
27 files changed, 3521 insertions, 0 deletions
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/README b/StoneIsland/platforms/ios/Stone Island/Plugins/README
new file mode 100644
index 00000000..87df09f2
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/README
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+Put the .h and .m files of your plugin here. The .js files of your plugin belong in the www folder.
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/IonicKeyboard.h b/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/IonicKeyboard.h
new file mode 100644
index 00000000..b54f430d
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/IonicKeyboard.h
@@ -0,0 +1,13 @@
+#import <Cordova/CDVPlugin.h>
+
+@interface IonicKeyboard : CDVPlugin <UIScrollViewDelegate> {
+ @protected
+ id _keyboardShowObserver, _keyboardHideObserver;
+}
+
+@property (readwrite, assign) BOOL hideKeyboardAccessoryBar;
+@property (readwrite, assign) BOOL disableScroll;
+//@property (readwrite, assign) BOOL styleDark;
+
+@end
+
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/IonicKeyboard.m b/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/IonicKeyboard.m
new file mode 100644
index 00000000..045cc65f
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/IonicKeyboard.m
@@ -0,0 +1,160 @@
+#import "IonicKeyboard.h"
+#import "UIWebViewExtension.h"
+#import <Cordova/CDVAvailability.h>
+
+@implementation IonicKeyboard
+
+@synthesize hideKeyboardAccessoryBar = _hideKeyboardAccessoryBar;
+@synthesize disableScroll = _disableScroll;
+//@synthesize styleDark = _styleDark;
+
+- (void)pluginInitialize {
+
+ NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
+ __weak IonicKeyboard* weakSelf = self;
+
+ //set defaults
+ self.hideKeyboardAccessoryBar = NO;
+ self.disableScroll = NO;
+ //self.styleDark = NO;
+
+ _keyboardShowObserver = [nc addObserverForName:UIKeyboardWillShowNotification
+ object:nil
+ queue:[NSOperationQueue mainQueue]
+ usingBlock:^(NSNotification* notification) {
+
+ CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
+ keyboardFrame = [self.viewController.view convertRect:keyboardFrame fromView:nil];
+
+ [weakSelf.commandDelegate evalJs:[NSString stringWithFormat:@"cordova.plugins.Keyboard.isVisible = true; cordova.fireWindowEvent('native.keyboardshow', { 'keyboardHeight': %@ }); ", [@(keyboardFrame.size.height) stringValue]]];
+
+ //deprecated
+ [weakSelf.commandDelegate evalJs:[NSString stringWithFormat:@"cordova.fireWindowEvent('native.showkeyboard', { 'keyboardHeight': %@ }); ", [@(keyboardFrame.size.height) stringValue]]];
+ }];
+
+ _keyboardHideObserver = [nc addObserverForName:UIKeyboardWillHideNotification
+ object:nil
+ queue:[NSOperationQueue mainQueue]
+ usingBlock:^(NSNotification* notification) {
+ [weakSelf.commandDelegate evalJs:@"cordova.plugins.Keyboard.isVisible = false; cordova.fireWindowEvent('native.keyboardhide'); "];
+
+ //deprecated
+ [weakSelf.commandDelegate evalJs:@"cordova.fireWindowEvent('native.hidekeyboard'); "];
+ }];
+}
+- (BOOL)disableScroll {
+ return _disableScroll;
+}
+
+- (void)setDisableScroll:(BOOL)disableScroll {
+ if (disableScroll == _disableScroll) {
+ return;
+ }
+ if (disableScroll) {
+ self.webView.scrollView.scrollEnabled = NO;
+ self.webView.scrollView.delegate = self;
+ }
+ else {
+ self.webView.scrollView.scrollEnabled = YES;
+ self.webView.scrollView.delegate = nil;
+ }
+
+ _disableScroll = disableScroll;
+}
+
+
+- (BOOL)hideKeyboardAccessoryBar {
+ return _hideKeyboardAccessoryBar;
+}
+
+- (void)setHideKeyboardAccessoryBar:(BOOL)hideKeyboardAccessoryBar {
+ if (hideKeyboardAccessoryBar == _hideKeyboardAccessoryBar) {
+ return;
+ }
+ if (hideKeyboardAccessoryBar) {
+ self.webView.hackishlyHidesInputAccessoryView = YES;
+ }
+ else {
+ self.webView.hackishlyHidesInputAccessoryView = NO;
+ }
+
+ _hideKeyboardAccessoryBar = hideKeyboardAccessoryBar;
+}
+
+/*
+- (BOOL)styleDark {
+ return _styleDark;
+}
+
+- (void)setStyleDark:(BOOL)styleDark {
+ if (styleDark == _styleDark) {
+ return;
+ }
+ if (styleDark) {
+ self.webView.styleDark = YES;
+ }
+ else {
+ self.webView.styleDark = NO;
+ }
+
+ _styleDark = styleDark;
+}
+*/
+
+
+/* ------------------------------------------------------------- */
+
+- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
+ [scrollView setContentOffset: CGPointZero];
+}
+
+/* ------------------------------------------------------------- */
+
+- (void)dealloc {
+ NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
+
+ [nc removeObserver:self name:UIKeyboardWillShowNotification object:nil];
+ [nc removeObserver:self name:UIKeyboardWillHideNotification object:nil];
+}
+
+/* ------------------------------------------------------------- */
+
+- (void) disableScroll:(CDVInvokedUrlCommand*)command {
+ if (!command.arguments || ![command.arguments count]){
+ return;
+ }
+ id value = [command.arguments objectAtIndex:0];
+
+ self.disableScroll = [value boolValue];
+}
+
+- (void) hideKeyboardAccessoryBar:(CDVInvokedUrlCommand*)command {
+ if (!command.arguments || ![command.arguments count]){
+ return;
+ }
+ id value = [command.arguments objectAtIndex:0];
+
+ self.hideKeyboardAccessoryBar = [value boolValue];
+}
+
+- (void) close:(CDVInvokedUrlCommand*)command {
+ [self.webView endEditing:YES];
+}
+
+- (void) show:(CDVInvokedUrlCommand*)command {
+ NSLog(@"Showing keyboard not supported in iOS due to platform limitations.");
+}
+
+/*
+- (void) styleDark:(CDVInvokedUrlCommand*)command {
+ if (!command.arguments || ![command.arguments count]){
+ return;
+ }
+ id value = [command.arguments objectAtIndex:0];
+
+ self.styleDark = [value boolValue];
+}
+*/
+
+@end
+
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/UIWebViewExtension.h b/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/UIWebViewExtension.h
new file mode 100644
index 00000000..1d6c293d
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/UIWebViewExtension.h
@@ -0,0 +1,4 @@
+@interface UIWebView (HackishAccessoryHiding)
+@property (nonatomic, assign) BOOL hackishlyHidesInputAccessoryView;
+//@property (nonatomic, assign) BOOL styleDark;
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/UIWebViewExtension.m b/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/UIWebViewExtension.m
new file mode 100644
index 00000000..25403e6f
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/com.ionic.keyboard/UIWebViewExtension.m
@@ -0,0 +1,109 @@
+#import <objc/runtime.h>
+#import <UIKit/UIKit.h>
+#import "UIWebViewExtension.h"
+
+//Credit: https://gist.github.com/bjhomer/2048571
+//Also: http://stackoverflow.com/a/23398487/1091751
+@implementation UIWebView (HackishAccessoryHiding)
+
+static const char * const hackishFixClassName = "UIWebBrowserViewMinusAccessoryView";
+static Class hackishFixClass = Nil;
+
+- (UIView *)hackishlyFoundBrowserView {
+ UIScrollView *scrollView = self.scrollView;
+
+ UIView *browserView = nil;
+ for (UIView *subview in scrollView.subviews) {
+ if ([NSStringFromClass([subview class]) hasPrefix:@"UIWebBrowserView"]) {
+ browserView = subview;
+ break;
+ }
+ }
+ return browserView;
+}
+
+- (id)methodReturningNil {
+ return nil;
+}
+
+- (void)ensureHackishSubclassExistsOfBrowserViewClass:(Class)browserViewClass {
+ if (!hackishFixClass) {
+ Class newClass = objc_allocateClassPair(browserViewClass, hackishFixClassName, 0);
+ IMP nilImp = [self methodForSelector:@selector(methodReturningNil)];
+ class_addMethod(newClass, @selector(inputAccessoryView), nilImp, "@@:");
+ objc_registerClassPair(newClass);
+
+ hackishFixClass = newClass;
+ }
+}
+
+- (BOOL) hackishlyHidesInputAccessoryView {
+ UIView *browserView = [self hackishlyFoundBrowserView];
+ return [browserView class] == hackishFixClass;
+}
+
+- (void) setHackishlyHidesInputAccessoryView:(BOOL)value {
+ UIView *browserView = [self hackishlyFoundBrowserView];
+ if (browserView == nil) {
+ return;
+ }
+ [self ensureHackishSubclassExistsOfBrowserViewClass:[browserView class]];
+
+ if (value) {
+ object_setClass(browserView, hackishFixClass);
+ }
+ else {
+ Class normalClass = objc_getClass("UIWebBrowserView");
+ object_setClass(browserView, normalClass);
+ }
+ [browserView reloadInputViews];
+}
+/* ---------------------------------------------------------------- */
+
+/*
+- (UIKeyboardAppearance) darkKeyboardAppearanceTemplateMethod {
+ return UIKeyboardAppearanceDark;
+}
+
+- (UIKeyboardAppearance) lightKeyboardAppearanceTemplateMethod {
+ return UIKeyboardAppearanceLight;
+}
+
+- (BOOL) styleDark {
+ UIView *browserView = [self hackishlyFoundBrowserView];
+ if (browserView == nil) {
+ return false;
+ }
+
+ Method m = class_getInstanceMethod( [self class], @selector( darkKeyboardAppearanceTemplateMethod ) );
+ IMP imp = method_getImplementation( m );
+
+ Method m2 = class_getInstanceMethod( [browserView class], @selector(keyboardAppearance) );
+ IMP imp2 = method_getImplementation( m2 );
+
+ return imp == imp2;
+}
+
+- (void) setStyleDark:(BOOL)styleDark {
+ UIView *browserView = [self hackishlyFoundBrowserView];
+ if (browserView == nil) {
+ return;
+ }
+
+ if ( styleDark ) {
+ Method m = class_getInstanceMethod( [self class], @selector( darkKeyboardAppearanceTemplateMethod ) );
+ IMP imp = method_getImplementation( m );
+ const char* typeEncoding = method_getTypeEncoding( m );
+ class_replaceMethod( [browserView class], @selector(keyboardAppearance), imp, typeEncoding );
+ }
+ else {
+ Method m = class_getInstanceMethod( [self class], @selector( lightKeyboardAppearanceTemplateMethod ) );
+ IMP imp = method_getImplementation( m );
+ const char* typeEncoding = method_getTypeEncoding( m );
+ class_replaceMethod( [browserView class], @selector(keyboardAppearance), imp, typeEncoding );
+ }
+}
+*/
+
+@end
+
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-console/CDVLogger.h b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-console/CDVLogger.h
new file mode 100644
index 00000000..7cfb3063
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-console/CDVLogger.h
@@ -0,0 +1,26 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Cordova/CDVPlugin.h>
+
+@interface CDVLogger : CDVPlugin
+
+- (void)logLevel:(CDVInvokedUrlCommand*)command;
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-console/CDVLogger.m b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-console/CDVLogger.m
new file mode 100644
index 00000000..ccfa3a51
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-console/CDVLogger.m
@@ -0,0 +1,38 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CDVLogger.h"
+#import <Cordova/CDV.h>
+
+@implementation CDVLogger
+
+/* log a message */
+- (void)logLevel:(CDVInvokedUrlCommand*)command
+{
+ id level = [command argumentAtIndex:0];
+ id message = [command argumentAtIndex:1];
+
+ if ([level isEqualToString:@"LOG"]) {
+ NSLog(@"%@", message);
+ } else {
+ NSLog(@"%@: %@", level, message);
+ }
+}
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-device/CDVDevice.h b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-device/CDVDevice.h
new file mode 100644
index 00000000..a146d882
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-device/CDVDevice.h
@@ -0,0 +1,30 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <UIKit/UIKit.h>
+#import <Cordova/CDVPlugin.h>
+
+@interface CDVDevice : CDVPlugin
+{}
+
++ (NSString*)cordovaVersion;
+
+- (void)getDeviceInfo:(CDVInvokedUrlCommand*)command;
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-device/CDVDevice.m b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-device/CDVDevice.m
new file mode 100644
index 00000000..5a3f4708
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-device/CDVDevice.m
@@ -0,0 +1,99 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#import <Cordova/CDV.h>
+#import "CDVDevice.h"
+
+@implementation UIDevice (ModelVersion)
+
+- (NSString*)modelVersion
+{
+ size_t size;
+
+ sysctlbyname("hw.machine", NULL, &size, NULL, 0);
+ char* machine = malloc(size);
+ sysctlbyname("hw.machine", machine, &size, NULL, 0);
+ NSString* platform = [NSString stringWithUTF8String:machine];
+ free(machine);
+
+ return platform;
+}
+
+@end
+
+@interface CDVDevice () {}
+@end
+
+@implementation CDVDevice
+
+- (NSString*)uniqueAppInstanceIdentifier:(UIDevice*)device
+{
+ NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
+ static NSString* UUID_KEY = @"CDVUUID";
+
+ NSString* app_uuid = [userDefaults stringForKey:UUID_KEY];
+
+ if (app_uuid == nil) {
+ CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
+ CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, uuidRef);
+
+ app_uuid = [NSString stringWithString:(__bridge NSString*)uuidString];
+ [userDefaults setObject:app_uuid forKey:UUID_KEY];
+ [userDefaults synchronize];
+
+ CFRelease(uuidString);
+ CFRelease(uuidRef);
+ }
+
+ return app_uuid;
+}
+
+- (void)getDeviceInfo:(CDVInvokedUrlCommand*)command
+{
+ NSDictionary* deviceProperties = [self deviceProperties];
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:deviceProperties];
+
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+}
+
+- (NSDictionary*)deviceProperties
+{
+ UIDevice* device = [UIDevice currentDevice];
+ NSMutableDictionary* devProps = [NSMutableDictionary dictionaryWithCapacity:4];
+
+ [devProps setObject:@"Apple" forKey:@"manufacturer"];
+ [devProps setObject:[device modelVersion] forKey:@"model"];
+ [devProps setObject:@"iOS" forKey:@"platform"];
+ [devProps setObject:[device systemVersion] forKey:@"version"];
+ [devProps setObject:[self uniqueAppInstanceIdentifier:device] forKey:@"uuid"];
+ [devProps setObject:[[self class] cordovaVersion] forKey:@"cordova"];
+
+ NSDictionary* devReturn = [NSDictionary dictionaryWithDictionary:devProps];
+ return devReturn;
+}
+
++ (NSString*)cordovaVersion
+{
+ return CDV_VERSION;
+}
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-dialogs/CDVNotification.h b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-dialogs/CDVNotification.h
new file mode 100644
index 00000000..9253f6a9
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-dialogs/CDVNotification.h
@@ -0,0 +1,37 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+#import <AudioToolbox/AudioServices.h>
+#import <Cordova/CDVPlugin.h>
+
+@interface CDVNotification : CDVPlugin <UIAlertViewDelegate>{}
+
+- (void)alert:(CDVInvokedUrlCommand*)command;
+- (void)confirm:(CDVInvokedUrlCommand*)command;
+- (void)prompt:(CDVInvokedUrlCommand*)command;
+- (void)beep:(CDVInvokedUrlCommand*)command;
+
+@end
+
+@interface CDVAlertView : UIAlertView {}
+@property (nonatomic, copy) NSString* callbackId;
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-dialogs/CDVNotification.m b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-dialogs/CDVNotification.m
new file mode 100644
index 00000000..1581ad3c
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-dialogs/CDVNotification.m
@@ -0,0 +1,221 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CDVNotification.h"
+
+#define DIALOG_TYPE_ALERT @"alert"
+#define DIALOG_TYPE_PROMPT @"prompt"
+
+static void soundCompletionCallback(SystemSoundID ssid, void* data);
+
+@implementation CDVNotification
+
+/*
+ * showDialogWithMessage - Common method to instantiate the alert view for alert, confirm, and prompt notifications.
+ * Parameters:
+ * message The alert view message.
+ * title The alert view title.
+ * buttons The array of customized strings for the buttons.
+ * defaultText The input text for the textbox (if textbox exists).
+ * callbackId The commmand callback id.
+ * dialogType The type of alert view [alert | prompt].
+ */
+- (void)showDialogWithMessage:(NSString*)message title:(NSString*)title buttons:(NSArray*)buttons defaultText:(NSString*)defaultText callbackId:(NSString*)callbackId dialogType:(NSString*)dialogType
+{
+
+ NSUInteger count = [buttons count];
+#ifdef __IPHONE_8_0
+ if (NSClassFromString(@"UIAlertController")) {
+
+ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
+
+ if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.3) {
+
+ CGRect alertFrame = [UIScreen mainScreen].applicationFrame;
+
+ if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
+ // swap the values for the app frame since it is now in landscape
+ CGFloat temp = alertFrame.size.width;
+ alertFrame.size.width = alertFrame.size.height;
+ alertFrame.size.height = temp;
+ }
+
+ alertController.view.frame = alertFrame;
+ }
+
+ for (int n = 0; n < count; n++) {
+
+ UIAlertAction* action = [UIAlertAction actionWithTitle:[buttons objectAtIndex:n] style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
+ {
+ CDVPluginResult* result;
+
+ if ([dialogType isEqualToString:DIALOG_TYPE_PROMPT]) {
+
+ NSString* value0 = [[alertController.textFields objectAtIndex:0] text];
+ NSDictionary* info = @{
+ @"buttonIndex":@(n + 1),
+ @"input1":(value0 ? value0 : [NSNull null])
+ };
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:info];
+
+ } else {
+
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(int)(n + 1)];
+
+ }
+
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+
+ }];
+ [alertController addAction:action];
+
+ }
+
+ if ([dialogType isEqualToString:DIALOG_TYPE_PROMPT]) {
+
+ [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
+ textField.text = defaultText;
+ }];
+ }
+
+
+
+ [self.viewController presentViewController:alertController animated:YES completion:nil];
+
+ } else {
+#endif
+ CDVAlertView* alertView = [[CDVAlertView alloc]
+ initWithTitle:title
+ message:message
+ delegate:self
+ cancelButtonTitle:nil
+ otherButtonTitles:nil];
+
+ alertView.callbackId = callbackId;
+
+
+
+ for (int n = 0; n < count; n++) {
+ [alertView addButtonWithTitle:[buttons objectAtIndex:n]];
+ }
+
+ if ([dialogType isEqualToString:DIALOG_TYPE_PROMPT]) {
+ alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
+ UITextField* textField = [alertView textFieldAtIndex:0];
+ textField.text = defaultText;
+ }
+
+ [alertView show];
+#ifdef __IPHONE_8_0
+ }
+#endif
+
+}
+
+- (void)alert:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ NSString* message = [command argumentAtIndex:0];
+ NSString* title = [command argumentAtIndex:1];
+ NSString* buttons = [command argumentAtIndex:2];
+
+ [self showDialogWithMessage:message title:title buttons:@[buttons] defaultText:nil callbackId:callbackId dialogType:DIALOG_TYPE_ALERT];
+}
+
+- (void)confirm:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ NSString* message = [command argumentAtIndex:0];
+ NSString* title = [command argumentAtIndex:1];
+ NSArray* buttons = [command argumentAtIndex:2];
+
+ [self showDialogWithMessage:message title:title buttons:buttons defaultText:nil callbackId:callbackId dialogType:DIALOG_TYPE_ALERT];
+}
+
+- (void)prompt:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ NSString* message = [command argumentAtIndex:0];
+ NSString* title = [command argumentAtIndex:1];
+ NSArray* buttons = [command argumentAtIndex:2];
+ NSString* defaultText = [command argumentAtIndex:3];
+
+ [self showDialogWithMessage:message title:title buttons:buttons defaultText:defaultText callbackId:callbackId dialogType:DIALOG_TYPE_PROMPT];
+}
+
+/**
+ * Callback invoked when an alert dialog's buttons are clicked.
+ */
+- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+ CDVAlertView* cdvAlertView = (CDVAlertView*)alertView;
+ CDVPluginResult* result;
+
+ // Determine what gets returned to JS based on the alert view type.
+ if (alertView.alertViewStyle == UIAlertViewStyleDefault) {
+ // For alert and confirm, return button index as int back to JS.
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(int)(buttonIndex + 1)];
+ } else {
+ // For prompt, return button index and input text back to JS.
+ NSString* value0 = [[alertView textFieldAtIndex:0] text];
+ NSDictionary* info = @{
+ @"buttonIndex":@(buttonIndex + 1),
+ @"input1":(value0 ? value0 : [NSNull null])
+ };
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:info];
+ }
+ [self.commandDelegate sendPluginResult:result callbackId:cdvAlertView.callbackId];
+}
+
+static void playBeep(int count) {
+ SystemSoundID completeSound;
+ NSInteger cbDataCount = count;
+ NSURL* audioPath = [[NSBundle mainBundle] URLForResource:@"CDVNotification.bundle/beep" withExtension:@"wav"];
+ #if __has_feature(objc_arc)
+ AudioServicesCreateSystemSoundID((__bridge CFURLRef)audioPath, &completeSound);
+ #else
+ AudioServicesCreateSystemSoundID((CFURLRef)audioPath, &completeSound);
+ #endif
+ AudioServicesAddSystemSoundCompletion(completeSound, NULL, NULL, soundCompletionCallback, (void*)(cbDataCount-1));
+ AudioServicesPlaySystemSound(completeSound);
+}
+
+static void soundCompletionCallback(SystemSoundID ssid, void* data) {
+ int count = (int)data;
+ AudioServicesRemoveSystemSoundCompletion (ssid);
+ AudioServicesDisposeSystemSoundID(ssid);
+ if (count > 0) {
+ playBeep(count);
+ }
+}
+
+- (void)beep:(CDVInvokedUrlCommand*)command
+{
+ NSNumber* count = [command argumentAtIndex:0 withDefault:[NSNumber numberWithInt:1]];
+ playBeep([count intValue]);
+}
+
+
+@end
+
+@implementation CDVAlertView
+
+@synthesize callbackId;
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-geolocation/CDVLocation.h b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-geolocation/CDVLocation.h
new file mode 100644
index 00000000..cce2738f
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-geolocation/CDVLocation.h
@@ -0,0 +1,70 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <UIKit/UIKit.h>
+#import <CoreLocation/CoreLocation.h>
+#import <Cordova/CDVPlugin.h>
+
+enum CDVLocationStatus {
+ PERMISSIONDENIED = 1,
+ POSITIONUNAVAILABLE,
+ TIMEOUT
+};
+typedef NSUInteger CDVLocationStatus;
+
+// simple object to keep track of location information
+@interface CDVLocationData : NSObject {
+ CDVLocationStatus locationStatus;
+ NSMutableArray* locationCallbacks;
+ NSMutableDictionary* watchCallbacks;
+ CLLocation* locationInfo;
+}
+
+@property (nonatomic, assign) CDVLocationStatus locationStatus;
+@property (nonatomic, strong) CLLocation* locationInfo;
+@property (nonatomic, strong) NSMutableArray* locationCallbacks;
+@property (nonatomic, strong) NSMutableDictionary* watchCallbacks;
+
+@end
+
+@interface CDVLocation : CDVPlugin <CLLocationManagerDelegate>{
+ @private BOOL __locationStarted;
+ @private BOOL __highAccuracyEnabled;
+ CDVLocationData* locationData;
+}
+
+@property (nonatomic, strong) CLLocationManager* locationManager;
+@property (nonatomic, strong) CDVLocationData* locationData;
+
+- (void)getLocation:(CDVInvokedUrlCommand*)command;
+- (void)addWatch:(CDVInvokedUrlCommand*)command;
+- (void)clearWatch:(CDVInvokedUrlCommand*)command;
+- (void)returnLocationInfo:(NSString*)callbackId andKeepCallback:(BOOL)keepCallback;
+- (void)returnLocationError:(NSUInteger)errorCode withMessage:(NSString*)message;
+- (void)startLocation:(BOOL)enableHighAccuracy;
+
+- (void)locationManager:(CLLocationManager*)manager
+ didUpdateToLocation:(CLLocation*)newLocation
+ fromLocation:(CLLocation*)oldLocation;
+
+- (void)locationManager:(CLLocationManager*)manager
+ didFailWithError:(NSError*)error;
+
+- (BOOL)isLocationServicesEnabled;
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-geolocation/CDVLocation.m b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-geolocation/CDVLocation.m
new file mode 100644
index 00000000..8b543c8e
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-geolocation/CDVLocation.m
@@ -0,0 +1,366 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CDVLocation.h"
+
+#pragma mark Constants
+
+#define kPGLocationErrorDomain @"kPGLocationErrorDomain"
+#define kPGLocationDesiredAccuracyKey @"desiredAccuracy"
+#define kPGLocationForcePromptKey @"forcePrompt"
+#define kPGLocationDistanceFilterKey @"distanceFilter"
+#define kPGLocationFrequencyKey @"frequency"
+
+#pragma mark -
+#pragma mark Categories
+
+@implementation CDVLocationData
+
+@synthesize locationStatus, locationInfo, locationCallbacks, watchCallbacks;
+- (CDVLocationData*)init
+{
+ self = (CDVLocationData*)[super init];
+ if (self) {
+ self.locationInfo = nil;
+ self.locationCallbacks = nil;
+ self.watchCallbacks = nil;
+ }
+ return self;
+}
+
+@end
+
+#pragma mark -
+#pragma mark CDVLocation
+
+@implementation CDVLocation
+
+@synthesize locationManager, locationData;
+
+- (void)pluginInitialize
+{
+ self.locationManager = [[CLLocationManager alloc] init];
+ self.locationManager.delegate = self; // Tells the location manager to send updates to this object
+ __locationStarted = NO;
+ __highAccuracyEnabled = NO;
+ self.locationData = nil;
+}
+
+- (BOOL)isAuthorized
+{
+ BOOL authorizationStatusClassPropertyAvailable = [CLLocationManager respondsToSelector:@selector(authorizationStatus)]; // iOS 4.2+
+
+ if (authorizationStatusClassPropertyAvailable) {
+ NSUInteger authStatus = [CLLocationManager authorizationStatus];
+#ifdef __IPHONE_8_0
+ if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { //iOS 8.0+
+ return (authStatus == kCLAuthorizationStatusAuthorizedWhenInUse) || (authStatus == kCLAuthorizationStatusAuthorizedAlways) || (authStatus == kCLAuthorizationStatusNotDetermined);
+ }
+#endif
+ return (authStatus == kCLAuthorizationStatusAuthorized) || (authStatus == kCLAuthorizationStatusNotDetermined);
+ }
+
+ // by default, assume YES (for iOS < 4.2)
+ return YES;
+}
+
+- (BOOL)isLocationServicesEnabled
+{
+ BOOL locationServicesEnabledInstancePropertyAvailable = [self.locationManager respondsToSelector:@selector(locationServicesEnabled)]; // iOS 3.x
+ BOOL locationServicesEnabledClassPropertyAvailable = [CLLocationManager respondsToSelector:@selector(locationServicesEnabled)]; // iOS 4.x
+
+ if (locationServicesEnabledClassPropertyAvailable) { // iOS 4.x
+ return [CLLocationManager locationServicesEnabled];
+ } else if (locationServicesEnabledInstancePropertyAvailable) { // iOS 2.x, iOS 3.x
+ return [(id)self.locationManager locationServicesEnabled];
+ } else {
+ return NO;
+ }
+}
+
+- (void)startLocation:(BOOL)enableHighAccuracy
+{
+ if (![self isLocationServicesEnabled]) {
+ [self returnLocationError:PERMISSIONDENIED withMessage:@"Location services are not enabled."];
+ return;
+ }
+ if (![self isAuthorized]) {
+ NSString* message = nil;
+ BOOL authStatusAvailable = [CLLocationManager respondsToSelector:@selector(authorizationStatus)]; // iOS 4.2+
+ if (authStatusAvailable) {
+ NSUInteger code = [CLLocationManager authorizationStatus];
+ if (code == kCLAuthorizationStatusNotDetermined) {
+ // could return POSITION_UNAVAILABLE but need to coordinate with other platforms
+ message = @"User undecided on application's use of location services.";
+ } else if (code == kCLAuthorizationStatusRestricted) {
+ message = @"Application's use of location services is restricted.";
+ }
+ }
+ // PERMISSIONDENIED is only PositionError that makes sense when authorization denied
+ [self returnLocationError:PERMISSIONDENIED withMessage:message];
+
+ return;
+ }
+
+#ifdef __IPHONE_8_0
+ NSUInteger code = [CLLocationManager authorizationStatus];
+ if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) { //iOS8+
+ __highAccuracyEnabled = enableHighAccuracy;
+ if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
+ [self.locationManager requestAlwaysAuthorization];
+ } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
+ [self.locationManager requestWhenInUseAuthorization];
+ } else {
+ NSLog(@"[Warning] No NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key is defined in the Info.plist file.");
+ }
+ return;
+ }
+#endif
+
+ // Tell the location manager to start notifying us of location updates. We
+ // first stop, and then start the updating to ensure we get at least one
+ // update, even if our location did not change.
+ [self.locationManager stopUpdatingLocation];
+ [self.locationManager startUpdatingLocation];
+ __locationStarted = YES;
+ if (enableHighAccuracy) {
+ __highAccuracyEnabled = YES;
+ // Set distance filter to 5 for a high accuracy. Setting it to "kCLDistanceFilterNone" could provide a
+ // higher accuracy, but it's also just spamming the callback with useless reports which drain the battery.
+ self.locationManager.distanceFilter = 5;
+ // Set desired accuracy to Best.
+ self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
+ } else {
+ __highAccuracyEnabled = NO;
+ // TODO: Set distance filter to 10 meters? and desired accuracy to nearest ten meters? arbitrary.
+ self.locationManager.distanceFilter = 10;
+ self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
+ }
+}
+
+- (void)_stopLocation
+{
+ if (__locationStarted) {
+ if (![self isLocationServicesEnabled]) {
+ return;
+ }
+
+ [self.locationManager stopUpdatingLocation];
+ __locationStarted = NO;
+ __highAccuracyEnabled = NO;
+ }
+}
+
+- (void)locationManager:(CLLocationManager*)manager
+ didUpdateToLocation:(CLLocation*)newLocation
+ fromLocation:(CLLocation*)oldLocation
+{
+ CDVLocationData* cData = self.locationData;
+
+ cData.locationInfo = newLocation;
+ if (self.locationData.locationCallbacks.count > 0) {
+ for (NSString* callbackId in self.locationData.locationCallbacks) {
+ [self returnLocationInfo:callbackId andKeepCallback:NO];
+ }
+
+ [self.locationData.locationCallbacks removeAllObjects];
+ }
+ if (self.locationData.watchCallbacks.count > 0) {
+ for (NSString* timerId in self.locationData.watchCallbacks) {
+ [self returnLocationInfo:[self.locationData.watchCallbacks objectForKey:timerId] andKeepCallback:YES];
+ }
+ } else {
+ // No callbacks waiting on us anymore, turn off listening.
+ [self _stopLocation];
+ }
+}
+
+- (void)getLocation:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ BOOL enableHighAccuracy = [[command argumentAtIndex:0] boolValue];
+
+ if ([self isLocationServicesEnabled] == NO) {
+ NSMutableDictionary* posError = [NSMutableDictionary dictionaryWithCapacity:2];
+ [posError setObject:[NSNumber numberWithInt:PERMISSIONDENIED] forKey:@"code"];
+ [posError setObject:@"Location services are disabled." forKey:@"message"];
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:posError];
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+ } else {
+ if (!self.locationData) {
+ self.locationData = [[CDVLocationData alloc] init];
+ }
+ CDVLocationData* lData = self.locationData;
+ if (!lData.locationCallbacks) {
+ lData.locationCallbacks = [NSMutableArray arrayWithCapacity:1];
+ }
+
+ if (!__locationStarted || (__highAccuracyEnabled != enableHighAccuracy)) {
+ // add the callbackId into the array so we can call back when get data
+ if (callbackId != nil) {
+ [lData.locationCallbacks addObject:callbackId];
+ }
+ // Tell the location manager to start notifying us of heading updates
+ [self startLocation:enableHighAccuracy];
+ } else {
+ [self returnLocationInfo:callbackId andKeepCallback:NO];
+ }
+ }
+}
+
+- (void)addWatch:(CDVInvokedUrlCommand*)command
+{
+ NSString* callbackId = command.callbackId;
+ NSString* timerId = [command argumentAtIndex:0];
+ BOOL enableHighAccuracy = [[command argumentAtIndex:1] boolValue];
+
+ if (!self.locationData) {
+ self.locationData = [[CDVLocationData alloc] init];
+ }
+ CDVLocationData* lData = self.locationData;
+
+ if (!lData.watchCallbacks) {
+ lData.watchCallbacks = [NSMutableDictionary dictionaryWithCapacity:1];
+ }
+
+ // add the callbackId into the dictionary so we can call back whenever get data
+ [lData.watchCallbacks setObject:callbackId forKey:timerId];
+
+ if ([self isLocationServicesEnabled] == NO) {
+ NSMutableDictionary* posError = [NSMutableDictionary dictionaryWithCapacity:2];
+ [posError setObject:[NSNumber numberWithInt:PERMISSIONDENIED] forKey:@"code"];
+ [posError setObject:@"Location services are disabled." forKey:@"message"];
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:posError];
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+ } else {
+ if (!__locationStarted || (__highAccuracyEnabled != enableHighAccuracy)) {
+ // Tell the location manager to start notifying us of location updates
+ [self startLocation:enableHighAccuracy];
+ }
+ }
+}
+
+- (void)clearWatch:(CDVInvokedUrlCommand*)command
+{
+ NSString* timerId = [command argumentAtIndex:0];
+
+ if (self.locationData && self.locationData.watchCallbacks && [self.locationData.watchCallbacks objectForKey:timerId]) {
+ [self.locationData.watchCallbacks removeObjectForKey:timerId];
+ if([self.locationData.watchCallbacks count] == 0) {
+ [self _stopLocation];
+ }
+ }
+}
+
+- (void)stopLocation:(CDVInvokedUrlCommand*)command
+{
+ [self _stopLocation];
+}
+
+- (void)returnLocationInfo:(NSString*)callbackId andKeepCallback:(BOOL)keepCallback
+{
+ CDVPluginResult* result = nil;
+ CDVLocationData* lData = self.locationData;
+
+ if (lData && !lData.locationInfo) {
+ // return error
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageToErrorObject:POSITIONUNAVAILABLE];
+ } else if (lData && lData.locationInfo) {
+ CLLocation* lInfo = lData.locationInfo;
+ NSMutableDictionary* returnInfo = [NSMutableDictionary dictionaryWithCapacity:8];
+ NSNumber* timestamp = [NSNumber numberWithDouble:([lInfo.timestamp timeIntervalSince1970] * 1000)];
+ [returnInfo setObject:timestamp forKey:@"timestamp"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.speed] forKey:@"velocity"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.verticalAccuracy] forKey:@"altitudeAccuracy"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.horizontalAccuracy] forKey:@"accuracy"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.course] forKey:@"heading"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.altitude] forKey:@"altitude"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.coordinate.latitude] forKey:@"latitude"];
+ [returnInfo setObject:[NSNumber numberWithDouble:lInfo.coordinate.longitude] forKey:@"longitude"];
+
+ result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:returnInfo];
+ [result setKeepCallbackAsBool:keepCallback];
+ }
+ if (result) {
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+ }
+}
+
+- (void)returnLocationError:(NSUInteger)errorCode withMessage:(NSString*)message
+{
+ NSMutableDictionary* posError = [NSMutableDictionary dictionaryWithCapacity:2];
+
+ [posError setObject:[NSNumber numberWithUnsignedInteger:errorCode] forKey:@"code"];
+ [posError setObject:message ? message:@"" forKey:@"message"];
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:posError];
+
+ for (NSString* callbackId in self.locationData.locationCallbacks) {
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+ }
+
+ [self.locationData.locationCallbacks removeAllObjects];
+
+ for (NSString* callbackId in self.locationData.watchCallbacks) {
+ [self.commandDelegate sendPluginResult:result callbackId:callbackId];
+ }
+}
+
+- (void)locationManager:(CLLocationManager*)manager didFailWithError:(NSError*)error
+{
+ NSLog(@"locationManager::didFailWithError %@", [error localizedFailureReason]);
+
+ CDVLocationData* lData = self.locationData;
+ if (lData && __locationStarted) {
+ // TODO: probably have to once over the various error codes and return one of:
+ // PositionError.PERMISSION_DENIED = 1;
+ // PositionError.POSITION_UNAVAILABLE = 2;
+ // PositionError.TIMEOUT = 3;
+ NSUInteger positionError = POSITIONUNAVAILABLE;
+ if (error.code == kCLErrorDenied) {
+ positionError = PERMISSIONDENIED;
+ }
+ [self returnLocationError:positionError withMessage:[error localizedDescription]];
+ }
+
+ if (error.code != kCLErrorLocationUnknown) {
+ [self.locationManager stopUpdatingLocation];
+ __locationStarted = NO;
+ }
+}
+
+//iOS8+
+-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
+{
+ if(!__locationStarted){
+ [self startLocation:__highAccuracyEnabled];
+ }
+}
+
+- (void)dealloc
+{
+ self.locationManager.delegate = nil;
+}
+
+- (void)onReset
+{
+ [self _stopLocation];
+ [self.locationManager stopUpdatingHeading];
+}
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVConnection.h b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVConnection.h
new file mode 100644
index 00000000..8add0279
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVConnection.h
@@ -0,0 +1,34 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Foundation/Foundation.h>
+#import <Cordova/CDVPlugin.h>
+#import "CDVReachability.h"
+
+@interface CDVConnection : CDVPlugin {
+ NSString* type;
+ NSString* _callbackId;
+
+ CDVReachability* internetReach;
+}
+
+@property (copy) NSString* connectionType;
+@property (strong) CDVReachability* internetReach;
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVConnection.m b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVConnection.m
new file mode 100644
index 00000000..37497675
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVConnection.m
@@ -0,0 +1,127 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CDVConnection.h"
+#import "CDVReachability.h"
+
+@interface CDVConnection (PrivateMethods)
+- (void)updateOnlineStatus;
+- (void)sendPluginResult;
+@end
+
+@implementation CDVConnection
+
+@synthesize connectionType, internetReach;
+
+- (void)getConnectionInfo:(CDVInvokedUrlCommand*)command
+{
+ _callbackId = command.callbackId;
+ [self sendPluginResult];
+}
+
+- (void)sendPluginResult
+{
+ CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:self.connectionType];
+
+ [result setKeepCallbackAsBool:YES];
+ [self.commandDelegate sendPluginResult:result callbackId:_callbackId];
+}
+
+- (NSString*)w3cConnectionTypeFor:(CDVReachability*)reachability
+{
+ NetworkStatus networkStatus = [reachability currentReachabilityStatus];
+
+ switch (networkStatus) {
+ case NotReachable:
+ return @"none";
+
+ case ReachableViaWWAN:
+ {
+ BOOL isConnectionRequired = [reachability connectionRequired];
+ if (isConnectionRequired) {
+ return @"none";
+ } else {
+ return @"cellular";
+ }
+ }
+ case ReachableViaWiFi:
+ return @"wifi";
+
+ default:
+ return @"unknown";
+ }
+}
+
+- (BOOL)isCellularConnection:(NSString*)theConnectionType
+{
+ return [theConnectionType isEqualToString:@"2g"] ||
+ [theConnectionType isEqualToString:@"3g"] ||
+ [theConnectionType isEqualToString:@"4g"] ||
+ [theConnectionType isEqualToString:@"cellular"];
+}
+
+- (void)updateReachability:(CDVReachability*)reachability
+{
+ if (reachability) {
+ // check whether the connection type has changed
+ NSString* newConnectionType = [self w3cConnectionTypeFor:reachability];
+ if ([newConnectionType isEqualToString:self.connectionType]) { // the same as before, remove dupes
+ return;
+ } else {
+ self.connectionType = [self w3cConnectionTypeFor:reachability];
+ }
+ }
+ [self sendPluginResult];
+}
+
+- (void)updateConnectionType:(NSNotification*)note
+{
+ CDVReachability* curReach = [note object];
+
+ if ((curReach != nil) && [curReach isKindOfClass:[CDVReachability class]]) {
+ [self updateReachability:curReach];
+ }
+}
+
+- (void)onPause
+{
+ [self.internetReach stopNotifier];
+}
+
+- (void)onResume
+{
+ [self.internetReach startNotifier];
+ [self updateReachability:self.internetReach];
+}
+
+- (void)pluginInitialize
+{
+ self.connectionType = @"none";
+ self.internetReach = [CDVReachability reachabilityForInternetConnection];
+ self.connectionType = [self w3cConnectionTypeFor:self.internetReach];
+ [self.internetReach startNotifier];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateConnectionType:)
+ name:kReachabilityChangedNotification object:nil];
+ if (&UIApplicationDidEnterBackgroundNotification && &UIApplicationWillEnterForegroundNotification) {
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onPause) name:UIApplicationDidEnterBackgroundNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResume) name:UIApplicationWillEnterForegroundNotification object:nil];
+ }
+}
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVReachability.h b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVReachability.h
new file mode 100644
index 00000000..01a95c35
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVReachability.h
@@ -0,0 +1,85 @@
+/*
+
+ File: Reachability.h
+ Abstract: Basic demonstration of how to use the SystemConfiguration Reachability APIs.
+ Version: 2.2
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under
+ Apple's copyrights in this original Apple software (the "Apple Software"), to
+ use, reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions
+ of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+ to endorse or promote products derived from the Apple Software without specific
+ prior written permission from Apple. Except as expressly stated in this notice,
+ no other rights or licenses, express or implied, are granted by Apple herein,
+ including but not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software may be
+ incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+ DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+ CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+ APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2010 Apple Inc. All Rights Reserved.
+
+*/
+
+#import <Foundation/Foundation.h>
+#import <SystemConfiguration/SystemConfiguration.h>
+#import <netinet/in.h>
+
+typedef enum {
+ NotReachable = 0,
+ ReachableViaWWAN, // this value has been swapped with ReachableViaWiFi for Cordova backwards compat. reasons
+ ReachableViaWiFi // this value has been swapped with ReachableViaWWAN for Cordova backwards compat. reasons
+} NetworkStatus;
+#define kReachabilityChangedNotification @"kNetworkReachabilityChangedNotification"
+
+@interface CDVReachability : NSObject
+{
+ BOOL localWiFiRef;
+ SCNetworkReachabilityRef reachabilityRef;
+}
+
+// reachabilityWithHostName- Use to check the reachability of a particular host name.
++ (CDVReachability*)reachabilityWithHostName:(NSString*)hostName;
+
+// reachabilityWithAddress- Use to check the reachability of a particular IP address.
++ (CDVReachability*)reachabilityWithAddress:(const struct sockaddr_in*)hostAddress;
+
+// reachabilityForInternetConnection- checks whether the default route is available.
+// Should be used by applications that do not connect to a particular host
++ (CDVReachability*)reachabilityForInternetConnection;
+
+// reachabilityForLocalWiFi- checks whether a local wifi connection is available.
++ (CDVReachability*)reachabilityForLocalWiFi;
+
+// Start listening for reachability notifications on the current run loop
+- (BOOL)startNotifier;
+- (void)stopNotifier;
+
+- (NetworkStatus)currentReachabilityStatus;
+// WWAN may be available, but not active until a connection has been established.
+// WiFi may require a connection for VPN on Demand.
+- (BOOL)connectionRequired;
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVReachability.m b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVReachability.m
new file mode 100644
index 00000000..c60261ae
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-network-information/CDVReachability.m
@@ -0,0 +1,260 @@
+/*
+
+ File: Reachability.m
+ Abstract: Basic demonstration of how to use the SystemConfiguration Reachability APIs.
+ Version: 2.2
+
+ Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc.
+ ("Apple") in consideration of your agreement to the following terms, and your
+ use, installation, modification or redistribution of this Apple software
+ constitutes acceptance of these terms. If you do not agree with these terms,
+ please do not use, install, modify or redistribute this Apple software.
+
+ In consideration of your agreement to abide by the following terms, and subject
+ to these terms, Apple grants you a personal, non-exclusive license, under
+ Apple's copyrights in this original Apple software (the "Apple Software"), to
+ use, reproduce, modify and redistribute the Apple Software, with or without
+ modifications, in source and/or binary forms; provided that if you redistribute
+ the Apple Software in its entirety and without modifications, you must retain
+ this notice and the following text and disclaimers in all such redistributions
+ of the Apple Software.
+ Neither the name, trademarks, service marks or logos of Apple Inc. may be used
+ to endorse or promote products derived from the Apple Software without specific
+ prior written permission from Apple. Except as expressly stated in this notice,
+ no other rights or licenses, express or implied, are granted by Apple herein,
+ including but not limited to any patent rights that may be infringed by your
+ derivative works or by other works in which the Apple Software may be
+ incorporated.
+
+ The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
+ WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+ WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+ COMBINATION WITH YOUR PRODUCTS.
+
+ IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
+ DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
+ CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+ APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ Copyright (C) 2010 Apple Inc. All Rights Reserved.
+
+*/
+
+#import <sys/socket.h>
+#import <netinet/in.h>
+#import <netinet6/in6.h>
+#import <arpa/inet.h>
+#import <ifaddrs.h>
+#import <netdb.h>
+
+#import <CoreFoundation/CoreFoundation.h>
+
+#import "CDVReachability.h"
+
+#define kShouldPrintReachabilityFlags 0
+
+static void CDVPrintReachabilityFlags(SCNetworkReachabilityFlags flags, const char* comment)
+{
+#if kShouldPrintReachabilityFlags
+ NSLog(@"Reachability Flag Status: %c%c %c%c%c%c%c%c%c %s\n",
+ (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
+ (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
+
+ (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
+ (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
+ (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
+ (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
+ (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
+ (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
+ (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-',
+ comment
+ );
+#endif
+}
+
+@implementation CDVReachability
+
+static void CDVReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
+{
+#pragma unused (target, flags)
+ // NSCAssert(info != NULL, @"info was NULL in ReachabilityCallback");
+ // NSCAssert([(NSObject*) info isKindOfClass: [Reachability class]], @"info was wrong class in ReachabilityCallback");
+
+ // Converted the asserts above to conditionals, with safe return from the function
+ if (info == NULL) {
+ NSLog(@"info was NULL in ReachabilityCallback");
+ return;
+ }
+
+ if (![(__bridge NSObject*)info isKindOfClass :[CDVReachability class]]) {
+ NSLog(@"info was wrong class in ReachabilityCallback");
+ return;
+ }
+
+ // We're on the main RunLoop, so an NSAutoreleasePool is not necessary, but is added defensively
+ // in case someon uses the Reachability object in a different thread.
+ @autoreleasepool {
+ CDVReachability* noteObject = (__bridge CDVReachability*)info;
+ // Post a notification to notify the client that the network reachability changed.
+ [[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification object:noteObject];
+ }
+}
+
+- (BOOL)startNotifier
+{
+ BOOL retVal = NO;
+ SCNetworkReachabilityContext context = {0, (__bridge void*)(self), NULL, NULL, NULL};
+
+ if (SCNetworkReachabilitySetCallback(reachabilityRef, CDVReachabilityCallback, &context)) {
+ if (SCNetworkReachabilityScheduleWithRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) {
+ retVal = YES;
+ }
+ }
+ return retVal;
+}
+
+- (void)stopNotifier
+{
+ if (reachabilityRef != NULL) {
+ SCNetworkReachabilityUnscheduleFromRunLoop(reachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ }
+}
+
+- (void)dealloc
+{
+ [self stopNotifier];
+ if (reachabilityRef != NULL) {
+ CFRelease(reachabilityRef);
+ }
+}
+
++ (CDVReachability*)reachabilityWithHostName:(NSString*)hostName;
+{
+ CDVReachability* retVal = NULL;
+ SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, [hostName UTF8String]);
+ if (reachability != NULL) {
+ retVal = [[self alloc] init];
+ if (retVal != NULL) {
+ retVal->reachabilityRef = reachability;
+ retVal->localWiFiRef = NO;
+ }
+ }
+ return retVal;
+}
+
++ (CDVReachability*)reachabilityWithAddress:(const struct sockaddr_in*)hostAddress;
+{
+ SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
+ CDVReachability* retVal = NULL;
+ if (reachability != NULL) {
+ retVal = [[self alloc] init];
+ if (retVal != NULL) {
+ retVal->reachabilityRef = reachability;
+ retVal->localWiFiRef = NO;
+ }
+ }
+ return retVal;
+}
+
++ (CDVReachability*)reachabilityForInternetConnection;
+{
+ struct sockaddr_in zeroAddress;
+ bzero(&zeroAddress, sizeof(zeroAddress));
+ zeroAddress.sin_len = sizeof(zeroAddress);
+ zeroAddress.sin_family = AF_INET;
+ return [self reachabilityWithAddress:&zeroAddress];
+}
+
++ (CDVReachability*)reachabilityForLocalWiFi;
+{
+ struct sockaddr_in localWifiAddress;
+ bzero(&localWifiAddress, sizeof(localWifiAddress));
+ localWifiAddress.sin_len = sizeof(localWifiAddress);
+ localWifiAddress.sin_family = AF_INET;
+ // IN_LINKLOCALNETNUM is defined in <netinet/in.h> as 169.254.0.0
+ localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
+ CDVReachability* retVal = [self reachabilityWithAddress:&localWifiAddress];
+ if (retVal != NULL) {
+ retVal->localWiFiRef = YES;
+ }
+ return retVal;
+}
+
+#pragma mark Network Flag Handling
+
+- (NetworkStatus)localWiFiStatusForFlags:(SCNetworkReachabilityFlags)flags
+{
+ CDVPrintReachabilityFlags(flags, "localWiFiStatusForFlags");
+
+ BOOL retVal = NotReachable;
+ if ((flags & kSCNetworkReachabilityFlagsReachable) && (flags & kSCNetworkReachabilityFlagsIsDirect)) {
+ retVal = ReachableViaWiFi;
+ }
+ return retVal;
+}
+
+- (NetworkStatus)networkStatusForFlags:(SCNetworkReachabilityFlags)flags
+{
+ CDVPrintReachabilityFlags(flags, "networkStatusForFlags");
+ if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) {
+ // if target host is not reachable
+ return NotReachable;
+ }
+
+ NetworkStatus retVal = NotReachable;
+
+ if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) {
+ // if target host is reachable and no connection is required
+ // then we'll assume (for now) that your on Wi-Fi
+ retVal = ReachableViaWiFi;
+ }
+
+ if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand) != 0) ||
+ ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))) {
+ // ... and the connection is on-demand (or on-traffic) if the
+ // calling application is using the CFSocketStream or higher APIs
+
+ if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) {
+ // ... and no [user] intervention is needed
+ retVal = ReachableViaWiFi;
+ }
+ }
+
+ if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) {
+ // ... but WWAN connections are OK if the calling application
+ // is using the CFNetwork (CFSocketStream?) APIs.
+ retVal = ReachableViaWWAN;
+ }
+ return retVal;
+}
+
+- (BOOL)connectionRequired;
+{
+ NSAssert(reachabilityRef != NULL, @"connectionRequired called with NULL reachabilityRef");
+ SCNetworkReachabilityFlags flags;
+ if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
+ return flags & kSCNetworkReachabilityFlagsConnectionRequired;
+ }
+ return NO;
+}
+
+- (NetworkStatus)currentReachabilityStatus
+{
+ NSAssert(reachabilityRef != NULL, @"currentNetworkStatus called with NULL reachabilityRef");
+ NetworkStatus retVal = NotReachable;
+ SCNetworkReachabilityFlags flags;
+ if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
+ if (localWiFiRef) {
+ retVal = [self localWiFiStatusForFlags:flags];
+ } else {
+ retVal = [self networkStatusForFlags:flags];
+ }
+ }
+ return retVal;
+}
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVSplashScreen.h b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVSplashScreen.h
new file mode 100644
index 00000000..0d6ae397
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVSplashScreen.h
@@ -0,0 +1,43 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Foundation/Foundation.h>
+#import <Cordova/CDVPlugin.h>
+
+typedef struct {
+ BOOL iPhone;
+ BOOL iPad;
+ BOOL iPhone5;
+ BOOL iPhone6;
+ BOOL iPhone6Plus;
+ BOOL retina;
+
+} CDV_iOSDevice;
+
+@interface CDVSplashScreen : CDVPlugin {
+ UIActivityIndicatorView* _activityView;
+ UIImageView* _imageView;
+ NSString* _curImageName;
+ BOOL _visible;
+}
+
+- (void)show:(CDVInvokedUrlCommand*)command;
+- (void)hide:(CDVInvokedUrlCommand*)command;
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVSplashScreen.m b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVSplashScreen.m
new file mode 100644
index 00000000..43b356ad
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVSplashScreen.m
@@ -0,0 +1,330 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CDVSplashScreen.h"
+#import <Cordova/CDVViewController.h>
+#import <Cordova/CDVScreenOrientationDelegate.h>
+#import "CDVViewController+SplashScreen.h"
+
+#define kSplashScreenDurationDefault 0.25f
+
+
+@implementation CDVSplashScreen
+
+- (void)pluginInitialize
+{
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pageDidLoad) name:CDVPageDidLoadNotification object:self.webView];
+
+ [self setVisible:YES];
+}
+
+- (void)show:(CDVInvokedUrlCommand*)command
+{
+ [self setVisible:YES];
+}
+
+- (void)hide:(CDVInvokedUrlCommand*)command
+{
+ [self setVisible:NO];
+}
+
+- (void)pageDidLoad
+{
+ id autoHideSplashScreenValue = [self.commandDelegate.settings objectForKey:[@"AutoHideSplashScreen" lowercaseString]];
+
+ // if value is missing, default to yes
+ if ((autoHideSplashScreenValue == nil) || [autoHideSplashScreenValue boolValue]) {
+ [self setVisible:NO];
+ }
+}
+
+- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
+{
+ [self updateImage];
+}
+
+- (void)createViews
+{
+ /*
+ * The Activity View is the top spinning throbber in the status/battery bar. We init it with the default Grey Style.
+ *
+ * whiteLarge = UIActivityIndicatorViewStyleWhiteLarge
+ * white = UIActivityIndicatorViewStyleWhite
+ * gray = UIActivityIndicatorViewStyleGray
+ *
+ */
+
+ // Determine whether rotation should be enabled for this device
+ // Per iOS HIG, landscape is only supported on iPad and iPhone 6+
+ CDV_iOSDevice device = [self getCurrentDevice];
+ BOOL autorotateValue = (device.iPad || device.iPhone6Plus) ?
+ [(CDVViewController *)self.viewController shouldAutorotateDefaultValue] :
+ NO;
+
+ [(CDVViewController *)self.viewController setEnabledAutorotation:autorotateValue];
+
+ NSString* topActivityIndicator = [self.commandDelegate.settings objectForKey:[@"TopActivityIndicator" lowercaseString]];
+ UIActivityIndicatorViewStyle topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;
+
+ if ([topActivityIndicator isEqualToString:@"whiteLarge"]) {
+ topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhiteLarge;
+ } else if ([topActivityIndicator isEqualToString:@"white"]) {
+ topActivityIndicatorStyle = UIActivityIndicatorViewStyleWhite;
+ } else if ([topActivityIndicator isEqualToString:@"gray"]) {
+ topActivityIndicatorStyle = UIActivityIndicatorViewStyleGray;
+ }
+
+ UIView* parentView = self.viewController.view;
+ parentView.userInteractionEnabled = NO; // disable user interaction while splashscreen is shown
+ _activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:topActivityIndicatorStyle];
+ _activityView.center = CGPointMake(parentView.bounds.size.width / 2, parentView.bounds.size.height / 2);
+ _activityView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin
+ | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin;
+ [_activityView startAnimating];
+
+ // Set the frame & image later.
+ _imageView = [[UIImageView alloc] init];
+ [parentView addSubview:_imageView];
+
+ id showSplashScreenSpinnerValue = [self.commandDelegate.settings objectForKey:[@"ShowSplashScreenSpinner" lowercaseString]];
+ // backwards compatibility - if key is missing, default to true
+ if ((showSplashScreenSpinnerValue == nil) || [showSplashScreenSpinnerValue boolValue]) {
+ [parentView addSubview:_activityView];
+ }
+
+ // Frame is required when launching in portrait mode.
+ // Bounds for landscape since it captures the rotation.
+ [parentView addObserver:self forKeyPath:@"frame" options:0 context:nil];
+ [parentView addObserver:self forKeyPath:@"bounds" options:0 context:nil];
+
+ [self updateImage];
+}
+
+- (void)destroyViews
+{
+ [(CDVViewController *)self.viewController setEnabledAutorotation:[(CDVViewController *)self.viewController shouldAutorotateDefaultValue]];
+
+ [_imageView removeFromSuperview];
+ [_activityView removeFromSuperview];
+ _imageView = nil;
+ _activityView = nil;
+ _curImageName = nil;
+
+ self.viewController.view.userInteractionEnabled = YES; // re-enable user interaction upon completion
+ [self.viewController.view removeObserver:self forKeyPath:@"frame"];
+ [self.viewController.view removeObserver:self forKeyPath:@"bounds"];
+}
+
+- (CDV_iOSDevice) getCurrentDevice
+{
+ CDV_iOSDevice device;
+
+ UIScreen* mainScreen = [UIScreen mainScreen];
+ CGFloat mainScreenHeight = mainScreen.bounds.size.height;
+ CGFloat mainScreenWidth = mainScreen.bounds.size.width;
+
+ int limit = MAX(mainScreenHeight,mainScreenWidth);
+
+ device.iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
+ device.iPhone = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone);
+ device.retina = ([mainScreen scale] == 2.0);
+ device.iPhone5 = (device.iPhone && limit == 568.0);
+ // note these below is not a true device detect, for example if you are on an
+ // iPhone 6/6+ but the app is scaled it will prob set iPhone5 as true, but
+ // this is appropriate for detecting the runtime screen environment
+ device.iPhone6 = (device.iPhone && limit == 667.0);
+ device.iPhone6Plus = (device.iPhone && limit == 736.0);
+
+ return device;
+}
+
+- (NSString*)getImageName:(UIInterfaceOrientation)currentOrientation delegate:(id<CDVScreenOrientationDelegate>)orientationDelegate device:(CDV_iOSDevice)device
+{
+ // Use UILaunchImageFile if specified in plist. Otherwise, use Default.
+ NSString* imageName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UILaunchImageFile"];
+
+ NSUInteger supportedOrientations = [orientationDelegate supportedInterfaceOrientations];
+
+ // Checks to see if the developer has locked the orientation to use only one of Portrait or Landscape
+ BOOL supportsLandscape = (supportedOrientations & UIInterfaceOrientationMaskLandscape);
+ BOOL supportsPortrait = (supportedOrientations & UIInterfaceOrientationMaskPortrait || supportedOrientations & UIInterfaceOrientationMaskPortraitUpsideDown);
+ // this means there are no mixed orientations in there
+ BOOL isOrientationLocked = !(supportsPortrait && supportsLandscape);
+
+ if (imageName) {
+ imageName = [imageName stringByDeletingPathExtension];
+ } else {
+ imageName = @"Default";
+ }
+
+ if (device.iPhone5) { // does not support landscape
+ imageName = [imageName stringByAppendingString:@"-568h"];
+ } else if (device.iPhone6) { // does not support landscape
+ imageName = [imageName stringByAppendingString:@"-667h"];
+ } else if (device.iPhone6Plus) { // supports landscape
+ if (isOrientationLocked) {
+ imageName = [imageName stringByAppendingString:(supportsLandscape ? @"-Landscape" : @"")];
+ } else {
+ switch (currentOrientation) {
+ case UIInterfaceOrientationLandscapeLeft:
+ case UIInterfaceOrientationLandscapeRight:
+ imageName = [imageName stringByAppendingString:@"-Landscape"];
+ break;
+ default:
+ break;
+ }
+ }
+ imageName = [imageName stringByAppendingString:@"-736h"];
+
+ } else if (device.iPad) { // supports landscape
+ if (isOrientationLocked) {
+ imageName = [imageName stringByAppendingString:(supportsLandscape ? @"-Landscape" : @"-Portrait")];
+ } else {
+ switch (currentOrientation) {
+ case UIInterfaceOrientationLandscapeLeft:
+ case UIInterfaceOrientationLandscapeRight:
+ imageName = [imageName stringByAppendingString:@"-Landscape"];
+ break;
+
+ case UIInterfaceOrientationPortrait:
+ case UIInterfaceOrientationPortraitUpsideDown:
+ default:
+ imageName = [imageName stringByAppendingString:@"-Portrait"];
+ break;
+ }
+ }
+ }
+
+ return imageName;
+}
+
+// Sets the view's frame and image.
+- (void)updateImage
+{
+ NSString* imageName = [self getImageName:[[UIApplication sharedApplication] statusBarOrientation] delegate:(id<CDVScreenOrientationDelegate>)self.viewController device:[self getCurrentDevice]];
+
+ if (![imageName isEqualToString:_curImageName]) {
+ UIImage* img = [UIImage imageNamed:imageName];
+ _imageView.image = img;
+ _curImageName = imageName;
+ }
+
+ // Check that splash screen's image exists before updating bounds
+ if (_imageView.image) {
+ [self updateBounds];
+ } else {
+ NSLog(@"WARNING: The splashscreen image named %@ was not found", imageName);
+ }
+}
+
+- (void)updateBounds
+{
+ UIImage* img = _imageView.image;
+ CGRect imgBounds = (img) ? CGRectMake(0, 0, img.size.width, img.size.height) : CGRectZero;
+
+ CGSize screenSize = [self.viewController.view convertRect:[UIScreen mainScreen].bounds fromView:nil].size;
+ UIInterfaceOrientation orientation = self.viewController.interfaceOrientation;
+ CGAffineTransform imgTransform = CGAffineTransformIdentity;
+
+ /* If and only if an iPhone application is landscape-only as per
+ * UISupportedInterfaceOrientations, the view controller's orientation is
+ * landscape. In this case the image must be rotated in order to appear
+ * correctly.
+ */
+ BOOL isIPad = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;
+ if (UIInterfaceOrientationIsLandscape(orientation) && !isIPad) {
+ imgTransform = CGAffineTransformMakeRotation(M_PI / 2);
+ imgBounds.size = CGSizeMake(imgBounds.size.height, imgBounds.size.width);
+ }
+
+ // There's a special case when the image is the size of the screen.
+ if (CGSizeEqualToSize(screenSize, imgBounds.size)) {
+ CGRect statusFrame = [self.viewController.view convertRect:[UIApplication sharedApplication].statusBarFrame fromView:nil];
+ if (!(IsAtLeastiOSVersion(@"7.0"))) {
+ imgBounds.origin.y -= statusFrame.size.height;
+ }
+ } else if (imgBounds.size.width > 0) {
+ CGRect viewBounds = self.viewController.view.bounds;
+ CGFloat imgAspect = imgBounds.size.width / imgBounds.size.height;
+ CGFloat viewAspect = viewBounds.size.width / viewBounds.size.height;
+ // This matches the behaviour of the native splash screen.
+ CGFloat ratio;
+ if (viewAspect > imgAspect) {
+ ratio = viewBounds.size.width / imgBounds.size.width;
+ } else {
+ ratio = viewBounds.size.height / imgBounds.size.height;
+ }
+ imgBounds.size.height *= ratio;
+ imgBounds.size.width *= ratio;
+ }
+
+ _imageView.transform = imgTransform;
+ _imageView.frame = imgBounds;
+}
+
+- (void)setVisible:(BOOL)visible
+{
+ if (visible == _visible) {
+ return;
+ }
+ _visible = visible;
+
+ id fadeSplashScreenValue = [self.commandDelegate.settings objectForKey:[@"FadeSplashScreen" lowercaseString]];
+ id fadeSplashScreenDuration = [self.commandDelegate.settings objectForKey:[@"FadeSplashScreenDuration" lowercaseString]];
+
+ float fadeDuration = fadeSplashScreenDuration == nil ? kSplashScreenDurationDefault : [fadeSplashScreenDuration floatValue];
+
+ if ((fadeSplashScreenValue == nil) || ![fadeSplashScreenValue boolValue]) {
+ fadeDuration = 0;
+ }
+
+ // Never animate the showing of the splash screen.
+ if (visible) {
+ if (_imageView == nil) {
+ [self createViews];
+ }
+ } else if (fadeDuration == 0) {
+ [self destroyViews];
+ } else {
+ __weak __typeof(self) weakSelf = self;
+
+ [UIView transitionWithView:self.viewController.view
+ duration:fadeDuration
+ options:UIViewAnimationOptionTransitionNone
+ animations:^(void) {
+ __typeof(self) strongSelf = weakSelf;
+ if (strongSelf != nil) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [strongSelf->_activityView setAlpha:0];
+ [strongSelf->_imageView setAlpha:0];
+ });
+ }
+ }
+ completion:^(BOOL finished) {
+ if (finished) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [weakSelf destroyViews];
+ });
+ }
+ }
+ ];
+ }
+}
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVViewController+SplashScreen.h b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVViewController+SplashScreen.h
new file mode 100644
index 00000000..a948ea31
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVViewController+SplashScreen.h
@@ -0,0 +1,28 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import <Cordova/CDVViewController.h>
+
+@interface CDVViewController (SplashScreen)
+
+@property (nonatomic, assign) BOOL enabledAutorotation;
+@property (nonatomic, readonly) BOOL shouldAutorotateDefaultValue;
+
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVViewController+SplashScreen.m b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVViewController+SplashScreen.m
new file mode 100644
index 00000000..5736b6f2
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-splashscreen/CDVViewController+SplashScreen.m
@@ -0,0 +1,82 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+
+#import "CDVViewController+SplashScreen.h"
+#import <objc/runtime.h>
+
+@implementation CDVViewController (SplashScreen)
+
+@dynamic enabledAutorotation;
+
+- (void)setEnabledAutorotation:(BOOL)value
+{
+ objc_setAssociatedObject(self,
+ @selector(enabledAutorotation),
+ [NSNumber numberWithBool:value],
+ OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (BOOL)enabledAutorotation
+{
+ NSNumber *number = (NSNumber *)objc_getAssociatedObject(self, @selector(enabledAutorotation));
+ return [number boolValue];
+}
+
++ (void)load
+{
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ Class class = [self class];
+
+ SEL originalSelector = @selector(shouldAutorotate);
+ SEL swizzledSelector = @selector(splash_shouldAutorotate);
+
+ Method originalMethod = class_getInstanceMethod(class, originalSelector);
+ Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
+
+ BOOL didAddMethod = class_addMethod(class,
+ originalSelector,
+ method_getImplementation(swizzledMethod),
+ method_getTypeEncoding(swizzledMethod));
+
+ if (didAddMethod) {
+ class_replaceMethod(class,
+ swizzledSelector,
+ method_getImplementation(originalMethod),
+ method_getTypeEncoding(originalMethod));
+ } else {
+ method_exchangeImplementations(originalMethod, swizzledMethod);
+ }
+ });
+}
+
+#pragma mark - Method Swizzling
+
+- (BOOL)splash_shouldAutorotate
+{
+ return self.enabledAutorotation;
+}
+
+
+- (BOOL)shouldAutorotateDefaultValue
+{
+ return [self splash_shouldAutorotate];
+}
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-x-socialsharing/SocialSharing.h b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-x-socialsharing/SocialSharing.h
new file mode 100755
index 00000000..b51474d3
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-x-socialsharing/SocialSharing.h
@@ -0,0 +1,27 @@
+#import <Cordova/CDV.h>
+#import <MessageUI/MFMailComposeViewController.h>
+
+@interface SocialSharing : CDVPlugin <UIPopoverControllerDelegate, MFMailComposeViewControllerDelegate, UIDocumentInteractionControllerDelegate>
+
+@property (nonatomic, strong) MFMailComposeViewController *globalMailComposer;
+@property (retain) UIDocumentInteractionController * documentInteractionController;
+@property (retain) NSString * tempStoredFile;
+@property (retain) CDVInvokedUrlCommand * command;
+
+- (void)available:(CDVInvokedUrlCommand*)command;
+- (void)setIPadPopupCoordinates:(CDVInvokedUrlCommand*)command;
+- (void)share:(CDVInvokedUrlCommand*)command;
+- (void)canShareVia:(CDVInvokedUrlCommand*)command;
+- (void)canShareViaEmail:(CDVInvokedUrlCommand*)command;
+- (void)shareVia:(CDVInvokedUrlCommand*)command;
+- (void)shareViaTwitter:(CDVInvokedUrlCommand*)command;
+- (void)shareViaFacebook:(CDVInvokedUrlCommand*)command;
+- (void)shareViaFacebookWithPasteMessageHint:(CDVInvokedUrlCommand*)command;
+- (void)shareViaWhatsApp:(CDVInvokedUrlCommand*)command;
+- (void)shareViaSMS:(CDVInvokedUrlCommand*)command;
+- (void)shareViaEmail:(CDVInvokedUrlCommand*)command;
+- (void)shareViaInstagram:(CDVInvokedUrlCommand*)command;
+
+- (void)saveToPhotoAlbum:(CDVInvokedUrlCommand*)command;
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-x-socialsharing/SocialSharing.m b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-x-socialsharing/SocialSharing.m
new file mode 100755
index 00000000..cd0913a4
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/cordova-plugin-x-socialsharing/SocialSharing.m
@@ -0,0 +1,715 @@
+#import "SocialSharing.h"
+#import <Cordova/CDV.h>
+#import <Social/Social.h>
+#import <Foundation/NSException.h>
+#import <MessageUI/MFMessageComposeViewController.h>
+#import <MessageUI/MFMailComposeViewController.h>
+#import <MobileCoreServices/MobileCoreServices.h>
+
+@implementation SocialSharing {
+ UIPopoverController *_popover;
+ NSString *_popupCoordinates;
+}
+
+- (void)pluginInitialize {
+ if ([self isEmailAvailable]) {
+ [self cycleTheGlobalMailComposer];
+ }
+}
+
+- (void)available:(CDVInvokedUrlCommand*)command {
+ BOOL avail = NO;
+ if (NSClassFromString(@"UIActivityViewController")) {
+ avail = YES;
+ }
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:avail];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+}
+
+- (NSString*)getIPadPopupCoordinates {
+ if (_popupCoordinates != nil) {
+ return _popupCoordinates;
+ }
+ if ([self.webView respondsToSelector:@selector(stringByEvaluatingJavaScriptFromString:)]) {
+ return [(UIWebView*)self.webView stringByEvaluatingJavaScriptFromString:@"window.plugins.socialsharing.iPadPopupCoordinates();"];
+ } else {
+ // prolly a wkwebview, ignoring for now
+ return nil;
+ }
+}
+
+- (void)setIPadPopupCoordinates:(CDVInvokedUrlCommand*)command {
+ _popupCoordinates = [command.arguments objectAtIndex:0];
+}
+
+- (CGRect)getPopupRectFromIPadPopupCoordinates:(NSArray*)comps {
+ CGRect rect = CGRectZero;
+ if ([comps count] == 4) {
+ rect = CGRectMake([[comps objectAtIndex:0] integerValue], [[comps objectAtIndex:1] integerValue], [[comps objectAtIndex:2] integerValue], [[comps objectAtIndex:3] integerValue]);
+ }
+ return rect;
+}
+
+- (void)share:(CDVInvokedUrlCommand*)command {
+ [self.commandDelegate runInBackground:^{ //avoid main thread block especially if sharing big files from url
+ if (!NSClassFromString(@"UIActivityViewController")) {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ return;
+ }
+
+ NSString *message = [command.arguments objectAtIndex:0];
+ NSString *subject = [command.arguments objectAtIndex:1];
+ NSArray *filenames = [command.arguments objectAtIndex:2];
+ NSString *urlString = [command.arguments objectAtIndex:3];
+
+ NSMutableArray *activityItems = [[NSMutableArray alloc] init];
+ [activityItems addObject:message];
+
+ NSMutableArray *files = [[NSMutableArray alloc] init];
+ if (filenames != (id)[NSNull null] && filenames.count > 0) {
+ for (NSString* filename in filenames) {
+ NSObject *file = [self getImage:filename];
+ if (file == nil) {
+ file = [self getFile:filename];
+ }
+ if (file != nil) {
+ [files addObject:file];
+ }
+ }
+ [activityItems addObjectsFromArray:files];
+ }
+
+ if (urlString != (id)[NSNull null]) {
+ [activityItems addObject:[NSURL URLWithString:urlString]];
+ }
+
+ UIActivity *activity = [[UIActivity alloc] init];
+ NSArray *applicationActivities = [[NSArray alloc] initWithObjects:activity, nil];
+ UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:applicationActivities];
+ if (subject != (id)[NSNull null]) {
+ [activityVC setValue:subject forKey:@"subject"];
+ }
+
+ // TODO deprecated in iOS 8.0, change this some day
+ [activityVC setCompletionHandler:^(NSString *activityType, BOOL completed) {
+ [self cleanupStoredFiles];
+ NSLog(@"SocialSharing app selected: %@", activityType);
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:completed];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }];
+
+ NSArray * socialSharingExcludeActivities = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"SocialSharingExcludeActivities"];
+ if (socialSharingExcludeActivities!=nil && [socialSharingExcludeActivities count] > 0) {
+ activityVC.excludedActivityTypes = socialSharingExcludeActivities;
+ }
+
+ dispatch_async(dispatch_get_main_queue(), ^(void){
+ // iPad on iOS >= 8 needs a different approach
+ if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
+ NSString* iPadCoords = [self getIPadPopupCoordinates];
+ if (iPadCoords != nil && ![iPadCoords isEqual:@"-1,-1,-1,-1"]) {
+ NSArray *comps = [iPadCoords componentsSeparatedByString:@","];
+ CGRect rect = [self getPopupRectFromIPadPopupCoordinates:comps];
+ if ([activityVC respondsToSelector:@selector(popoverPresentationController)]) {
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 // iOS 8.0 supported
+ activityVC.popoverPresentationController.sourceView = self.webView;
+ activityVC.popoverPresentationController.sourceRect = rect;
+#endif
+ } else {
+ _popover = [[UIPopoverController alloc] initWithContentViewController:activityVC];
+ _popover.delegate = self;
+ [_popover presentPopoverFromRect:rect inView:self.webView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
+ }
+ } else if ([activityVC respondsToSelector:@selector(popoverPresentationController)]) {
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 // iOS 8.0 supported
+ activityVC.popoverPresentationController.sourceView = self.webView;
+ // position the popup at the bottom, just like iOS < 8 did (and iPhone still does on iOS 8)
+ NSArray *comps = [NSArray arrayWithObjects:
+ [NSNumber numberWithInt:(self.viewController.view.frame.size.width/2)-200],
+ [NSNumber numberWithInt:self.viewController.view.frame.size.height],
+ [NSNumber numberWithInt:400],
+ [NSNumber numberWithInt:400],
+ nil];
+ CGRect rect = [self getPopupRectFromIPadPopupCoordinates:comps];
+ activityVC.popoverPresentationController.sourceRect = rect;
+#endif
+ }
+ }
+ [[self getTopMostViewController] presentViewController:activityVC animated:YES completion:nil];
+ });
+ }];
+}
+
+- (void)shareViaTwitter:(CDVInvokedUrlCommand*)command {
+ [self shareViaInternal:command type:SLServiceTypeTwitter];
+}
+
+- (void)shareViaFacebook:(CDVInvokedUrlCommand*)command {
+ [self shareViaInternal:command type:SLServiceTypeFacebook];
+}
+
+- (void)shareViaFacebookWithPasteMessageHint:(CDVInvokedUrlCommand*)command {
+ // If Fb app is installed a message is not prefilled.
+ // When shared through the default iOS widget (iOS Settings > Facebook) the message is prefilled already.
+ NSString *message = [command.arguments objectAtIndex:0];
+ if (message != (id)[NSNull null]) {
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1000 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
+ BOOL fbAppInstalled = [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"fb://"]]; // requires whitelisting on iOS9
+ if (fbAppInstalled) {
+ UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
+ [pasteboard setValue:message forPasteboardType:@"public.text"];
+ NSString *hint = [command.arguments objectAtIndex:4];
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:hint delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
+ [alert show];
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2800 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^{
+ [alert dismissWithClickedButtonIndex:-1 animated:YES];
+ });
+ }
+ });
+ }
+ [self shareViaInternal:command type:SLServiceTypeFacebook];
+}
+
+- (void)shareVia:(CDVInvokedUrlCommand*)command {
+ [self shareViaInternal:command type:[command.arguments objectAtIndex:4]];
+}
+
+- (void)canShareVia:(CDVInvokedUrlCommand*)command {
+ NSString *via = [command.arguments objectAtIndex:4];
+ CDVPluginResult * pluginResult;
+ if ([@"sms" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaSMS]) {
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ } else if ([@"email" caseInsensitiveCompare:via] == NSOrderedSame && [self isEmailAvailable]) {
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ } else if ([@"whatsapp" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaWhatsApp]) {
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ } else if ([@"instagram" caseInsensitiveCompare:via] == NSOrderedSame && [self canShareViaInstagram]) {
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ } else if ([self isAvailableForSharing:command type:via]) {
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ } else {
+ pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"];
+ }
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+}
+
+- (void)canShareViaEmail:(CDVInvokedUrlCommand*)command {
+ if ([self isEmailAvailable]) {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+- (bool)isEmailAvailable {
+ Class messageClass = (NSClassFromString(@"MFMailComposeViewController"));
+ return messageClass != nil && [messageClass canSendMail];
+}
+
+- (bool)isAvailableForSharing:(CDVInvokedUrlCommand*)command
+ type:(NSString *) type {
+ // isAvailableForServiceType returns true if you pass it a type that is not
+ // in the defined constants, this is probably a bug on apples part
+ if(!([type isEqualToString:SLServiceTypeFacebook]
+ || [type isEqualToString:SLServiceTypeTwitter]
+ || [type isEqualToString:SLServiceTypeTencentWeibo]
+ || [type isEqualToString:SLServiceTypeSinaWeibo])) {
+ return false;
+ }
+ // wrapped in try-catch, because isAvailableForServiceType may crash if an invalid type is passed
+ @try {
+ return [SLComposeViewController isAvailableForServiceType:type];
+ }
+ @catch (NSException* exception) {
+ return false;
+ }
+}
+
+- (void)shareViaInternal:(CDVInvokedUrlCommand*)command
+ type:(NSString *) type {
+
+ NSString *message = [command.arguments objectAtIndex:0];
+ // subject is not supported by the SLComposeViewController
+ NSArray *filenames = [command.arguments objectAtIndex:2];
+ NSString *urlString = [command.arguments objectAtIndex:3];
+
+ // boldly invoke the target app, because the phone will display a nice message asking to configure the app
+ SLComposeViewController *composeViewController = [SLComposeViewController composeViewControllerForServiceType:type];
+ if (message != (id)[NSNull null]) {
+ [composeViewController setInitialText:message];
+ }
+
+ for (NSString* filename in filenames) {
+ UIImage* image = [self getImage:filename];
+ if (image != nil) {
+ [composeViewController addImage:image];
+ }
+ }
+
+ if (urlString != (id)[NSNull null]) {
+ [composeViewController addURL:[NSURL URLWithString:urlString]];
+ }
+
+ [composeViewController setCompletionHandler:^(SLComposeViewControllerResult result) {
+ if (SLComposeViewControllerResultCancelled == result) {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"cancelled"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else if ([self isAvailableForSharing:command type:type]) {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:SLComposeViewControllerResultDone == result];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ } else {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+ // required for iOS6 (issues #162 and #167)
+ [self.viewController dismissViewControllerAnimated:YES completion:nil];
+ }];
+ [[self getTopMostViewController] presentViewController:composeViewController animated:YES completion:nil];
+}
+
+- (void)shareViaEmail:(CDVInvokedUrlCommand*)command {
+ if ([self isEmailAvailable]) {
+
+ if (TARGET_IPHONE_SIMULATOR && IsAtLeastiOSVersion(@"8.0")) {
+ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"SocialSharing plugin"
+ message:@"Sharing via email is not supported on the iOS 8 simulator."
+ delegate:nil
+ cancelButtonTitle:@"OK"
+ otherButtonTitles:nil];
+ [alert show];
+ return;
+ }
+
+ self.globalMailComposer.mailComposeDelegate = self;
+
+ if ([command.arguments objectAtIndex:0] != (id)[NSNull null]) {
+ NSString *message = [command.arguments objectAtIndex:0];
+ BOOL isHTML = [message rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch].location != NSNotFound;
+ [self.globalMailComposer setMessageBody:message isHTML:isHTML];
+ }
+
+ if ([command.arguments objectAtIndex:1] != (id)[NSNull null]) {
+ [self.globalMailComposer setSubject: [command.arguments objectAtIndex:1]];
+ }
+
+ if ([command.arguments objectAtIndex:2] != (id)[NSNull null]) {
+ [self.globalMailComposer setToRecipients:[command.arguments objectAtIndex:2]];
+ }
+
+ if ([command.arguments objectAtIndex:3] != (id)[NSNull null]) {
+ [self.globalMailComposer setCcRecipients:[command.arguments objectAtIndex:3]];
+ }
+
+ if ([command.arguments objectAtIndex:4] != (id)[NSNull null]) {
+ [self.globalMailComposer setBccRecipients:[command.arguments objectAtIndex:4]];
+ }
+
+ if ([command.arguments objectAtIndex:5] != (id)[NSNull null]) {
+ NSArray* attachments = [command.arguments objectAtIndex:5];
+ NSFileManager* fileManager = [NSFileManager defaultManager];
+ for (NSString* path in attachments) {
+ NSURL *file = [self getFile:path];
+ NSData* data = [fileManager contentsAtPath:file.path];
+
+ NSString* fileName;
+ NSString* mimeType;
+ NSString* basename = [self getBasenameFromAttachmentPath:path];
+
+ if ([basename hasPrefix:@"data:"]) {
+ mimeType = (NSString*)[[[basename substringFromIndex:5] componentsSeparatedByString: @";"] objectAtIndex:0];
+ fileName = @"attachment.";
+ fileName = [fileName stringByAppendingString:(NSString*)[[mimeType componentsSeparatedByString: @"/"] lastObject]];
+ NSString *base64content = (NSString*)[[basename componentsSeparatedByString: @","] lastObject];
+ data = [SocialSharing dataFromBase64String:base64content];
+ } else {
+ fileName = [basename pathComponents].lastObject;
+ mimeType = [self getMimeTypeFromFileExtension:[basename pathExtension]];
+ }
+ [self.globalMailComposer addAttachmentData:data mimeType:mimeType fileName:fileName];
+ }
+ }
+
+ // remember the command, because we need it in the didFinishWithResult method
+ _command = command;
+
+ [self.commandDelegate runInBackground:^{
+ [[self getTopMostViewController] presentViewController:self.globalMailComposer animated:YES completion:nil];
+ }];
+
+ } else {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+- (UIViewController*) getTopMostViewController {
+ UIViewController *presentingViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;
+ while (presentingViewController.presentedViewController != nil) {
+ presentingViewController = presentingViewController.presentedViewController;
+ }
+ return presentingViewController;
+}
+
+- (NSString*) getBasenameFromAttachmentPath:(NSString*)path {
+ if ([path hasPrefix:@"base64:"]) {
+ NSString* pathWithoutPrefix = [path stringByReplacingOccurrencesOfString:@"base64:" withString:@""];
+ return [pathWithoutPrefix substringToIndex:[pathWithoutPrefix rangeOfString:@"//"].location];
+ }
+ return path;
+}
+
+- (NSString*) getMimeTypeFromFileExtension:(NSString*)extension {
+ if (!extension) {
+ return nil;
+ }
+ // Get the UTI from the file's extension
+ CFStringRef ext = (CFStringRef)CFBridgingRetain(extension);
+ CFStringRef type = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL);
+ // Converting UTI to a mime type
+ NSString *result = (NSString*)CFBridgingRelease(UTTypeCopyPreferredTagWithClass(type, kUTTagClassMIMEType));
+ CFRelease(ext);
+ CFRelease(type);
+ return result;
+}
+
+/**
+ * Delegate will be called after the mail composer did finish an action
+ * to dismiss the view.
+ */
+- (void) mailComposeController:(MFMailComposeViewController*)controller
+ didFinishWithResult:(MFMailComposeResult)result
+ error:(NSError*)error {
+ bool ok = result == MFMailComposeResultSent;
+ [self.globalMailComposer dismissViewControllerAnimated:YES completion:^{[self cycleTheGlobalMailComposer];}];
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:ok];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:_command.callbackId];
+}
+
+-(void)cycleTheGlobalMailComposer {
+ // we are cycling the damned GlobalMailComposer: http://stackoverflow.com/questions/25604552/i-have-real-misunderstanding-with-mfmailcomposeviewcontroller-in-swift-ios8-in/25604976#25604976
+ self.globalMailComposer = nil;
+ self.globalMailComposer = [[MFMailComposeViewController alloc] init];
+}
+
+- (bool)canShareViaSMS {
+ Class messageClass = (NSClassFromString(@"MFMessageComposeViewController"));
+ return messageClass != nil && [messageClass canSendText];
+}
+
+- (void)shareViaSMS:(CDVInvokedUrlCommand*)command {
+ if ([self canShareViaSMS]) {
+ NSDictionary* options = [command.arguments objectAtIndex:0];
+ NSString *phonenumbers = [command.arguments objectAtIndex:1];
+ NSString *message = [options objectForKey:@"message"];
+ NSString *subject = [options objectForKey:@"subject"];
+ NSString *image = [options objectForKey:@"image"];
+
+ MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init];
+ picker.messageComposeDelegate = (id) self;
+ if (message != (id)[NSNull null]) {
+ picker.body = message;
+ }
+ if (subject != (id)[NSNull null]) {
+ [picker setSubject:subject];
+ }
+ if (image != nil && image != (id)[NSNull null]) {
+ BOOL canSendAttachments = [[MFMessageComposeViewController class] respondsToSelector:@selector(canSendAttachments)];
+ if (canSendAttachments) {
+ NSURL *file = [self getFile:image];
+ if (file != nil) {
+ [picker addAttachmentURL:file withAlternateFilename:nil];
+ }
+ }
+ }
+
+ if (phonenumbers != (id)[NSNull null]) {
+ [picker setRecipients:[phonenumbers componentsSeparatedByString:@","]];
+ }
+ // remember the command, because we need it in the didFinishWithResult method
+ _command = command;
+ [self.commandDelegate runInBackground:^{
+ picker.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
+ [[self getTopMostViewController] presentViewController:picker animated:YES completion:nil];
+ }];
+ } else {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+// Dismisses the SMS composition interface when users taps Cancel or Send
+- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
+ bool ok = result == MessageComposeResultSent;
+ [[self getTopMostViewController] dismissViewControllerAnimated:YES completion:nil];
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool:ok];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:_command.callbackId];
+}
+
+- (bool)canShareViaInstagram {
+ return [[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"instagram://app"]]; // requires whitelisting on iOS9
+}
+
+- (bool)canShareViaWhatsApp {
+ return [[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString:@"whatsapp://app"]]; // requires whitelisting on iOS9
+}
+
+// this is only an internal test method for now, can be used to open a share sheet with 'Open in xx' links for tumblr, drive, dropbox, ..
+- (void)openImage:(NSString *)imageName {
+ UIImage* image =[self getImage:imageName];
+ if (image != nil) {
+ NSString * savePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/myTempImage.jpg"];
+ [UIImageJPEGRepresentation(image, 1.0) writeToFile:savePath atomically:YES];
+ _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]];
+ _documentInteractionController.UTI = @""; // TODO find the scheme for google drive and create a shareViaGoogleDrive function
+ [_documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.viewController.view animated: YES];
+ }
+}
+
+- (void)shareViaInstagram:(CDVInvokedUrlCommand*)command {
+
+ // on iOS9 canShareVia('instagram'..) will only work if instagram:// is whitelisted.
+ // If it's not, this method will ask permission to the user on iOS9 for opening the app,
+ // which is of course better than Instagram sharing not working at all because you forgot to whitelist it.
+ // Tradeoff: on iOS9 this method will always return true, so make sure to whitelist it and call canShareVia('instagram'..)
+ if (!IsAtLeastiOSVersion(@"9.0")) {
+ if (![self canShareViaInstagram]) {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ return;
+ }
+ }
+
+ NSString *message = [command.arguments objectAtIndex:0];
+ // subject is not supported by the SLComposeViewController
+ NSArray *filenames = [command.arguments objectAtIndex:2];
+
+ // only use the first image (for now.. maybe we can share in a loop?)
+ UIImage* image = nil;
+ for (NSString* filename in filenames) {
+ image = [self getImage:filename];
+ break;
+ }
+
+// NSData *imageObj = [NSData dataFromBase64String:objectAtIndex0];
+ NSString *tmpDir = NSTemporaryDirectory();
+ NSString *path = [tmpDir stringByAppendingPathComponent:@"instagram.igo"];
+ [UIImageJPEGRepresentation(image, 1.0) writeToFile:path atomically:YES];
+
+ _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:path]];
+ _documentInteractionController.delegate = self;
+ _documentInteractionController.UTI = @"com.instagram.exclusivegram";
+
+ if (message != (id)[NSNull null]) {
+ // no longer working, so ..
+ _documentInteractionController.annotation = @{@"InstagramCaption" : message};
+
+ // .. we put the message on the clipboard (you app can prompt the user to paste it)
+ UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
+ [pasteboard setValue:message forPasteboardType:@"public.text"];
+ }
+
+ // remember the command for the delegate method
+ _command = command;
+ [_documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.webView animated:YES];
+}
+
+- (void)shareViaWhatsApp:(CDVInvokedUrlCommand*)command {
+
+ // on iOS9 canShareVia('whatsapp'..) will only work if whatsapp:// is whitelisted.
+ // If it's not, this method will ask permission to the user on iOS9 for opening the app,
+ // which is of course better than WhatsApp sharing not working at all because you forgot to whitelist it.
+ // Tradeoff: on iOS9 this method will always return true, so make sure to whitelist it and call canShareVia('whatsapp'..)
+ if (!IsAtLeastiOSVersion(@"9.0")) {
+ if (![self canShareViaWhatsApp]) {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"not available"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ return;
+ }
+ }
+
+ NSString *message = [command.arguments objectAtIndex:0];
+ // subject is not supported by the SLComposeViewController
+ NSArray *filenames = [command.arguments objectAtIndex:2];
+ NSString *urlString = [command.arguments objectAtIndex:3];
+
+ // only use the first image (for now.. maybe we can share in a loop?)
+ UIImage* image = nil;
+ for (NSString* filename in filenames) {
+ image = [self getImage:filename];
+ break;
+ }
+
+ // with WhatsApp, we can share an image OR text+url.. image wins if set
+ if (image != nil) {
+ NSString * savePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/whatsAppTmp.wai"];
+ [UIImageJPEGRepresentation(image, 1.0) writeToFile:savePath atomically:YES];
+ _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:[NSURL fileURLWithPath:savePath]];
+ _documentInteractionController.UTI = @"net.whatsapp.image";
+ _documentInteractionController.delegate = self;
+ _command = command;
+ [_documentInteractionController presentOpenInMenuFromRect:CGRectZero inView:self.viewController.view animated: YES];
+ } else {
+ // append an url to a message, if both are passed
+ NSString * shareString = @"";
+ if (message != (id)[NSNull null]) {
+ shareString = message;
+ }
+ if (urlString != (id)[NSNull null]) {
+ if ([shareString isEqual: @""]) {
+ shareString = urlString;
+ } else {
+ shareString = [NSString stringWithFormat:@"%@ %@", shareString, urlString];
+ }
+ }
+ NSString * encodedShareString = [shareString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+ // also encode the '=' character
+ encodedShareString = [encodedShareString stringByReplacingOccurrencesOfString:@"=" withString:@"%3D"];
+ encodedShareString = [encodedShareString stringByReplacingOccurrencesOfString:@"&" withString:@"%26"];
+ NSString * encodedShareStringForWhatsApp = [NSString stringWithFormat:@"whatsapp://send?text=%@", encodedShareString];
+
+ NSURL *whatsappURL = [NSURL URLWithString:encodedShareStringForWhatsApp];
+ [[UIApplication sharedApplication] openURL: whatsappURL];
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }
+}
+
+- (void)saveToPhotoAlbum:(CDVInvokedUrlCommand*)command {
+ self.command = command;
+ NSArray *filenames = [command.arguments objectAtIndex:0];
+ [self.commandDelegate runInBackground:^{
+ bool shared = false;
+ for (NSString* filename in filenames) {
+ UIImage* image = [self getImage:filename];
+ if (image != nil) {
+ shared = true;
+ UIImageWriteToSavedPhotosAlbum(image, self, @selector(thisImage:wasSavedToPhotoAlbumWithError:contextInfo:), nil);
+ }
+ }
+ if (!shared) {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"no valid image was passed"];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.command.callbackId];
+ }
+ }];
+}
+
+// called from saveToPhotoAlbum, note that we only send feedback for the first image that's being saved (not keeping the callback)
+// but since the UIImageWriteToSavedPhotosAlbum function is only called with valid images that should not be a problem
+- (void)thisImage:(UIImage *)image wasSavedToPhotoAlbumWithError:(NSError *)error contextInfo:(void*)ctxInfo {
+ if (error) {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:error.localizedDescription];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.command.callbackId];
+ } else {
+ CDVPluginResult * pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.command.callbackId];
+ }
+}
+
+-(UIImage*)getImage: (NSString *)imageName {
+ UIImage *image = nil;
+ if (imageName != (id)[NSNull null]) {
+ if ([imageName hasPrefix:@"http"]) {
+ image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageName]]];
+ } else if ([imageName hasPrefix:@"www/"]) {
+ image = [UIImage imageNamed:imageName];
+ } else if ([imageName hasPrefix:@"file://"]) {
+ image = [UIImage imageWithData:[NSData dataWithContentsOfFile:[[NSURL URLWithString:imageName] path]]];
+ } else if ([imageName hasPrefix:@"data:"]) {
+ // using a base64 encoded string
+ NSURL *imageURL = [NSURL URLWithString:imageName];
+ NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
+ image = [UIImage imageWithData:imageData];
+ } else if ([imageName hasPrefix:@"assets-library://"]) {
+ // use assets-library
+ NSURL *imageURL = [NSURL URLWithString:imageName];
+ NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
+ image = [UIImage imageWithData:imageData];
+ } else {
+ // assume anywhere else, on the local filesystem
+ image = [UIImage imageWithData:[NSData dataWithContentsOfFile:imageName]];
+ }
+ }
+ return image;
+}
+
+-(NSURL*)getFile: (NSString *)fileName {
+ NSURL *file = nil;
+ if (fileName != (id)[NSNull null]) {
+ if ([fileName hasPrefix:@"http"]) {
+ NSURL *url = [NSURL URLWithString:fileName];
+ NSData *fileData = [NSData dataWithContentsOfURL:url];
+ file = [NSURL fileURLWithPath:[self storeInFile:(NSString*)[[fileName componentsSeparatedByString: @"/"] lastObject] fileData:fileData]];
+ } else if ([fileName hasPrefix:@"www/"]) {
+ NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
+ NSString *fullPath = [NSString stringWithFormat:@"%@/%@", bundlePath, fileName];
+ file = [NSURL fileURLWithPath:fullPath];
+ } else if ([fileName hasPrefix:@"file://"]) {
+ // stripping the first 6 chars, because the path should start with / instead of file://
+ file = [NSURL fileURLWithPath:[fileName substringFromIndex:6]];
+ } else if ([fileName hasPrefix:@"data:"]) {
+ // using a base64 encoded string
+ // extract some info from the 'fileName', which is for example: data:text/calendar;base64,<encoded stuff here>
+ NSString *fileType = (NSString*)[[[fileName substringFromIndex:5] componentsSeparatedByString: @";"] objectAtIndex:0];
+ fileType = (NSString*)[[fileType componentsSeparatedByString: @"/"] lastObject];
+ NSString *base64content = (NSString*)[[fileName componentsSeparatedByString: @","] lastObject];
+ NSData *fileData = [SocialSharing dataFromBase64String:base64content];
+ file = [NSURL fileURLWithPath:[self storeInFile:[NSString stringWithFormat:@"%@.%@", @"file", fileType] fileData:fileData]];
+ } else {
+ // assume anywhere else, on the local filesystem
+ file = [NSURL fileURLWithPath:fileName];
+ }
+ }
+ return file;
+}
+
+-(NSString*) storeInFile: (NSString*) fileName
+ fileData: (NSData*) fileData {
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *documentsDirectory = [paths objectAtIndex:0];
+ NSString *filePath = [documentsDirectory stringByAppendingPathComponent:fileName];
+ [fileData writeToFile:filePath atomically:YES];
+ _tempStoredFile = filePath;
+ return filePath;
+}
+
+- (void) cleanupStoredFiles {
+ if (_tempStoredFile != nil) {
+ NSError *error;
+ [[NSFileManager defaultManager]removeItemAtPath:_tempStoredFile error:&error];
+ }
+}
+
++ (NSData*) dataFromBase64String:(NSString*)aString {
+ return [[NSData alloc] initWithBase64EncodedString:aString options:0];
+}
+
+#pragma mark - UIPopoverControllerDelegate methods
+
+- (void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView **)view {
+ NSArray *comps = [[self getIPadPopupCoordinates] componentsSeparatedByString:@","];
+ CGRect newRect = [self getPopupRectFromIPadPopupCoordinates:comps];
+ rect->origin = newRect.origin;
+}
+
+- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
+ _popover = nil;
+}
+
+#pragma mark - UIDocumentInteractionControllerDelegate methods
+
+- (void) documentInteractionController: (UIDocumentInteractionController *) controller willBeginSendingToApplication: (NSString *) application {
+ // note that the application actually contains the app bundle id which was picked (for whatsapp and instagram only)
+ NSLog(@"SocialSharing app selected: %@", application);
+}
+
+- (void) documentInteractionControllerDidDismissOpenInMenu: (UIDocumentInteractionController *) controller {
+ if (self.command != nil) {
+ CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:result callbackId: self.command.callbackId];
+ }
+}
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/AppDelegate+notification.h b/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/AppDelegate+notification.h
new file mode 100644
index 00000000..be79903e
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/AppDelegate+notification.h
@@ -0,0 +1,21 @@
+//
+// AppDelegate+notification.h
+// pushtest
+//
+// Created by Robert Easterday on 10/26/12.
+//
+//
+
+#import "AppDelegate.h"
+
+@interface AppDelegate (notification)
+- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
+- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
+- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo;
+- (void)applicationDidBecomeActive:(UIApplication *)application;
+- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler;
+- (id) getCommandInstance:(NSString*)className;
+
+@property (nonatomic, retain) NSDictionary *launchNotification;
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/AppDelegate+notification.m b/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/AppDelegate+notification.m
new file mode 100644
index 00000000..8b4ed161
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/AppDelegate+notification.m
@@ -0,0 +1,167 @@
+//
+// AppDelegate+notification.m
+// pushtest
+//
+// Created by Robert Easterday on 10/26/12.
+//
+//
+
+#import "AppDelegate+notification.h"
+#import "PushPlugin.h"
+#import <objc/runtime.h>
+
+static char launchNotificationKey;
+
+@implementation AppDelegate (notification)
+
+- (id) getCommandInstance:(NSString*)className
+{
+ return [self.viewController getCommandInstance:className];
+}
+
+// its dangerous to override a method from within a category.
+// Instead we will use method swizzling. we set this up in the load call.
++ (void)load
+{
+ Method original, swizzled;
+
+ original = class_getInstanceMethod(self, @selector(init));
+ swizzled = class_getInstanceMethod(self, @selector(swizzled_init));
+ method_exchangeImplementations(original, swizzled);
+}
+
+- (AppDelegate *)swizzled_init
+{
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(createNotificationChecker:)
+ name:@"UIApplicationDidFinishLaunchingNotification" object:nil];
+
+ // This actually calls the original init method over in AppDelegate. Equivilent to calling super
+ // on an overrided method, this is not recursive, although it appears that way. neat huh?
+ return [self swizzled_init];
+}
+
+// This code will be called immediately after application:didFinishLaunchingWithOptions:. We need
+// to process notifications in cold-start situations
+- (void)createNotificationChecker:(NSNotification *)notification
+{
+ if (notification)
+ {
+ NSDictionary *launchOptions = [notification userInfo];
+ if (launchOptions)
+ self.launchNotification = [launchOptions objectForKey: @"UIApplicationLaunchOptionsRemoteNotificationKey"];
+ }
+}
+
+- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
+ PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"];
+ [pushHandler didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
+}
+
+- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
+ PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"];
+ [pushHandler didFailToRegisterForRemoteNotificationsWithError:error];
+}
+
+- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
+ NSLog(@"didReceiveNotification with fetchCompletionHandler");
+
+ // app is in the foreground so call notification callback
+ if (application.applicationState == UIApplicationStateActive) {
+ NSLog(@"app active");
+ PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"];
+ pushHandler.notificationMessage = userInfo;
+ pushHandler.isInline = YES;
+ [pushHandler notificationReceived];
+
+ completionHandler(UIBackgroundFetchResultNewData);
+ }
+ // app is in background or in stand by
+ else {
+ NSLog(@"app in-active");
+
+ // do some convoluted logic to find out if this should be a silent push.
+ long silent = 0;
+ id aps = [userInfo objectForKey:@"aps"];
+ id contentAvailable = [aps objectForKey:@"content-available"];
+ if ([contentAvailable isKindOfClass:[NSString class]] && [contentAvailable isEqualToString:@"1"]) {
+ silent = 1;
+ } else if ([contentAvailable isKindOfClass:[NSNumber class]]) {
+ silent = [contentAvailable integerValue];
+ }
+
+ if (silent == 1) {
+ NSLog(@"this should be a silent push");
+ void (^safeHandler)(UIBackgroundFetchResult) = ^(UIBackgroundFetchResult result){
+ dispatch_async(dispatch_get_main_queue(), ^{
+ completionHandler(result);
+ });
+ };
+
+ NSMutableDictionary* params = [NSMutableDictionary dictionaryWithCapacity:2];
+ [params setObject:safeHandler forKey:@"handler"];
+
+ PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"];
+ pushHandler.notificationMessage = userInfo;
+ pushHandler.isInline = NO;
+ pushHandler.handlerObj = params;
+ [pushHandler notificationReceived];
+ } else {
+ NSLog(@"just put it in the shade");
+ //save it for later
+ self.launchNotification = userInfo;
+
+ completionHandler(UIBackgroundFetchResultNewData);
+ }
+ }
+}
+
+- (void)applicationDidBecomeActive:(UIApplication *)application {
+
+ NSLog(@"active");
+
+ PushPlugin *pushHandler = [self getCommandInstance:@"PushNotification"];
+ if (pushHandler.clearBadge) {
+ NSLog(@"PushPlugin clearing badge");
+ //zero badge
+ application.applicationIconBadgeNumber = 0;
+ } else {
+ NSLog(@"PushPlugin skip clear badge");
+ }
+
+ if (self.launchNotification) {
+ pushHandler.isInline = NO;
+ pushHandler.notificationMessage = self.launchNotification;
+ self.launchNotification = nil;
+ [pushHandler performSelectorOnMainThread:@selector(notificationReceived) withObject:pushHandler waitUntilDone:NO];
+ }
+}
+
+//For interactive notification only
+- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
+{
+ //handle the actions
+ if ([identifier isEqualToString:@"declineAction"]){
+ }
+ else if ([identifier isEqualToString:@"answerAction"]){
+ }
+}
+
+
+// The accessors use an Associative Reference since you can't define a iVar in a category
+// http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/objectivec/Chapters/ocAssociativeReferences.html
+- (NSMutableArray *)launchNotification
+{
+ return objc_getAssociatedObject(self, &launchNotificationKey);
+}
+
+- (void)setLaunchNotification:(NSDictionary *)aDictionary
+{
+ objc_setAssociatedObject(self, &launchNotificationKey, aDictionary, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (void)dealloc
+{
+ self.launchNotification = nil; // clear the association and release the object
+}
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/PushPlugin.h b/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/PushPlugin.h
new file mode 100644
index 00000000..5b88398e
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/PushPlugin.h
@@ -0,0 +1,62 @@
+/*
+ Copyright 2009-2011 Urban Airship Inc. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ 2. Redistributions in binaryform must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided withthe distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE URBAN AIRSHIP INC``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ EVENT SHALL URBAN AIRSHIP INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import <Foundation/Foundation.h>
+#import <Cordova/CDV.h>
+#import <Cordova/CDVPlugin.h>
+
+@interface PushPlugin : CDVPlugin
+{
+ NSDictionary *notificationMessage;
+ BOOL isInline;
+ NSString *notificationCallbackId;
+ NSString *callback;
+ BOOL clearBadge;
+
+ NSDictionary *handlerObj;
+ void (^completionHandler)(UIBackgroundFetchResult);
+
+ BOOL ready;
+}
+
+@property (nonatomic, copy) NSString *callbackId;
+@property (nonatomic, copy) NSString *notificationCallbackId;
+@property (nonatomic, copy) NSString *callback;
+
+@property (nonatomic, strong) NSDictionary *notificationMessage;
+@property BOOL isInline;
+@property BOOL clearBadge;
+@property (nonatomic, strong) NSDictionary *handlerObj;
+
+- (void)init:(CDVInvokedUrlCommand*)command;
+- (void)unregister:(CDVInvokedUrlCommand*)command;
+
+- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
+- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
+
+- (void)setNotificationMessage:(NSDictionary *)notification;
+- (void)notificationReceived;
+
+@end
diff --git a/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/PushPlugin.m b/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/PushPlugin.m
new file mode 100644
index 00000000..40f494d1
--- /dev/null
+++ b/StoneIsland/platforms/ios/Stone Island/Plugins/phonegap-plugin-push/PushPlugin.m
@@ -0,0 +1,347 @@
+/*
+ Copyright 2009-2011 Urban Airship Inc. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ 2. Redistributions in binaryform must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided withthe distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE URBAN AIRSHIP INC``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ EVENT SHALL URBAN AIRSHIP INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import "PushPlugin.h"
+
+@implementation PushPlugin
+
+@synthesize notificationMessage;
+@synthesize isInline;
+
+@synthesize callbackId;
+@synthesize notificationCallbackId;
+@synthesize callback;
+@synthesize clearBadge;
+@synthesize handlerObj;
+
+- (void)unregister:(CDVInvokedUrlCommand*)command;
+{
+ self.callbackId = command.callbackId;
+
+ [[UIApplication sharedApplication] unregisterForRemoteNotifications];
+ [self successWithMessage:@"unregistered"];
+}
+
+- (void)init:(CDVInvokedUrlCommand*)command;
+{
+ [self.commandDelegate runInBackground:^ {
+
+ NSLog(@"Push Plugin register called");
+ self.callbackId = command.callbackId;
+
+ NSMutableDictionary* options = [command.arguments objectAtIndex:0];
+ NSMutableDictionary* iosOptions = [options objectForKey:@"ios"];
+
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+ UIUserNotificationType UserNotificationTypes = UIUserNotificationTypeNone;
+#endif
+ UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeNone;
+
+ id badgeArg = [iosOptions objectForKey:@"badge"];
+ id soundArg = [iosOptions objectForKey:@"sound"];
+ id alertArg = [iosOptions objectForKey:@"alert"];
+ id clearBadgeArg = [iosOptions objectForKey:@"clearBadge"];
+
+ if (([badgeArg isKindOfClass:[NSString class]] && [badgeArg isEqualToString:@"true"]) || [badgeArg boolValue])
+ {
+ notificationTypes |= UIRemoteNotificationTypeBadge;
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+ UserNotificationTypes |= UIUserNotificationTypeBadge;
+#endif
+ }
+
+ if (([soundArg isKindOfClass:[NSString class]] && [soundArg isEqualToString:@"true"]) || [soundArg boolValue])
+ {
+ notificationTypes |= UIRemoteNotificationTypeSound;
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+ UserNotificationTypes |= UIUserNotificationTypeSound;
+#endif
+ }
+
+ if (([alertArg isKindOfClass:[NSString class]] && [alertArg isEqualToString:@"true"]) || [alertArg boolValue])
+ {
+ notificationTypes |= UIRemoteNotificationTypeAlert;
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+ UserNotificationTypes |= UIUserNotificationTypeAlert;
+#endif
+ }
+
+ notificationTypes |= UIRemoteNotificationTypeNewsstandContentAvailability;
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+ UserNotificationTypes |= UIUserNotificationActivationModeBackground;
+#endif
+
+ if (clearBadgeArg == nil || ([clearBadgeArg isKindOfClass:[NSString class]] && [clearBadgeArg isEqualToString:@"false"]) || ![clearBadgeArg boolValue]) {
+ NSLog(@"PushPlugin.register: setting badge to false");
+ clearBadge = NO;
+ } else {
+ NSLog(@"PushPlugin.register: setting badge to true");
+ clearBadge = YES;
+ [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
+ }
+ NSLog(@"PushPlugin.register: clear badge is set to %d", clearBadge);
+
+ if (notificationTypes == UIRemoteNotificationTypeNone)
+ NSLog(@"PushPlugin.register: Push notification type is set to none");
+
+ isInline = NO;
+
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+ if ([[UIApplication sharedApplication]respondsToSelector:@selector(registerUserNotificationSettings:)]) {
+ UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UserNotificationTypes categories:nil];
+ [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
+ [[UIApplication sharedApplication] registerForRemoteNotifications];
+ } else {
+ [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
+ (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
+ }
+#else
+ [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
+ (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
+#endif
+
+ if (notificationMessage) // if there is a pending startup notification
+ [self notificationReceived]; // go ahead and process it
+
+ }];
+}
+
+- (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
+ if (self.callbackId == nil) {
+ NSLog(@"Unexpected call to didRegisterForRemoteNotificationsWithDeviceToken, ignoring: %@", deviceToken);
+ return;
+ }
+ NSLog(@"Push Plugin register success: %@", deviceToken);
+
+ NSMutableDictionary *results = [NSMutableDictionary dictionary];
+ NSString *token = [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""]
+ stringByReplacingOccurrencesOfString:@">" withString:@""]
+ stringByReplacingOccurrencesOfString: @" " withString: @""];
+ [results setValue:token forKey:@"deviceToken"];
+
+#if !TARGET_IPHONE_SIMULATOR
+ // Get Bundle Info for Remote Registration (handy if you have more than one app)
+ [results setValue:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"] forKey:@"appName"];
+ [results setValue:[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] forKey:@"appVersion"];
+
+ // Check what Notifications the user has turned on. We registered for all three, but they may have manually disabled some or all of them.
+#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
+
+ NSUInteger rntypes;
+ if (!SYSTEM_VERSION_LESS_THAN(@"8.0")) {
+ rntypes = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
+ } else {
+ rntypes = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
+ }
+
+ // Set the defaults to disabled unless we find otherwise...
+ NSString *pushBadge = @"disabled";
+ NSString *pushAlert = @"disabled";
+ NSString *pushSound = @"disabled";
+
+ // Check what Registered Types are turned on. This is a bit tricky since if two are enabled, and one is off, it will return a number 2... not telling you which
+ // one is actually disabled. So we are literally checking to see if rnTypes matches what is turned on, instead of by number. The "tricky" part is that the
+ // single notification types will only match if they are the ONLY one enabled. Likewise, when we are checking for a pair of notifications, it will only be
+ // true if those two notifications are on. This is why the code is written this way
+ if(rntypes & UIRemoteNotificationTypeBadge){
+ pushBadge = @"enabled";
+ }
+ if(rntypes & UIRemoteNotificationTypeAlert) {
+ pushAlert = @"enabled";
+ }
+ if(rntypes & UIRemoteNotificationTypeSound) {
+ pushSound = @"enabled";
+ }
+
+ [results setValue:pushBadge forKey:@"pushBadge"];
+ [results setValue:pushAlert forKey:@"pushAlert"];
+ [results setValue:pushSound forKey:@"pushSound"];
+
+ // Get the users Device Model, Display Name, Token & Version Number
+ UIDevice *dev = [UIDevice currentDevice];
+ [results setValue:dev.name forKey:@"deviceName"];
+ [results setValue:dev.model forKey:@"deviceModel"];
+ [results setValue:dev.systemVersion forKey:@"deviceSystemVersion"];
+
+ // Send result to trigger 'registration' event but keep callback
+ NSMutableDictionary* message = [NSMutableDictionary dictionaryWithCapacity:1];
+ [message setObject:token forKey:@"registrationId"];
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message];
+ [pluginResult setKeepCallbackAsBool:YES];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
+#endif
+}
+
+- (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
+{
+ if (self.callbackId == nil) {
+ NSLog(@"Unexpected call to didFailToRegisterForRemoteNotificationsWithError, ignoring: %@", error);
+ return;
+ }
+ NSLog(@"Push Plugin register failed");
+ [self failWithMessage:@"" withError:error];
+}
+
+- (void)notificationReceived {
+ NSLog(@"Notification received");
+
+ if (notificationMessage && self.callbackId != nil)
+ {
+ NSMutableDictionary* message = [NSMutableDictionary dictionaryWithCapacity:4];
+ NSMutableDictionary* additionalData = [NSMutableDictionary dictionaryWithCapacity:4];
+
+
+ for (id key in notificationMessage) {
+ if ([key isEqualToString:@"aps"]) {
+ id aps = [notificationMessage objectForKey:@"aps"];
+
+ for(id key in aps) {
+ NSLog(@"Push Plugin key: %@", key);
+ id value = [aps objectForKey:key];
+
+ if ([key isEqualToString:@"alert"]) {
+ if ([value isKindOfClass:[NSDictionary class]]) {
+ for (id messageKey in value) {
+ id messageValue = [value objectForKey:messageKey];
+ if ([messageKey isEqualToString:@"body"]) {
+ [message setObject:messageValue forKey:@"message"];
+ } else if ([messageKey isEqualToString:@"title"]) {
+ [message setObject:messageValue forKey:@"title"];
+ } else {
+ [additionalData setObject:messageValue forKey:messageKey];
+ }
+ }
+ }
+ else {
+ [message setObject:value forKey:@"message"];
+ }
+ } else if ([key isEqualToString:@"title"]) {
+ [message setObject:value forKey:@"title"];
+ } else if ([key isEqualToString:@"badge"]) {
+ [message setObject:value forKey:@"count"];
+ } else if ([key isEqualToString:@"sound"]) {
+ [message setObject:value forKey:@"sound"];
+ } else if ([key isEqualToString:@"image"]) {
+ [message setObject:value forKey:@"image"];
+ } else {
+ [additionalData setObject:value forKey:key];
+ }
+ }
+ } else {
+ [additionalData setObject:[notificationMessage objectForKey:key] forKey:key];
+ }
+ }
+
+ if (isInline) {
+ [additionalData setObject:[NSNumber numberWithBool:YES] forKey:@"foreground"];
+ } else {
+ [additionalData setObject:[NSNumber numberWithBool:NO] forKey:@"foreground"];
+ }
+
+ [message setObject:additionalData forKey:@"additionalData"];
+
+ // send notification message
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:message];
+ [pluginResult setKeepCallbackAsBool:YES];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:self.callbackId];
+
+ self.notificationMessage = nil;
+ }
+}
+
+- (void)setApplicationIconBadgeNumber:(CDVInvokedUrlCommand *)command
+{
+ NSMutableDictionary* options = [command.arguments objectAtIndex:0];
+ int badge = [[options objectForKey:@"badge"] intValue] ?: 0;
+
+ [[UIApplication sharedApplication] setApplicationIconBadgeNumber:badge];
+
+ NSString* message = [NSString stringWithFormat:@"app badge count set to %d", badge];
+ CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message];
+ [self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];
+}
+
+- (void)getApplicationIconBadgeNumber:(CDVInvokedUrlCommand *)command
+{
+ NSInteger badge = [UIApplication sharedApplication].applicationIconBadgeNumber;
+
+ CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsInt:(int)badge];
+ [self.commandDelegate sendPluginResult:commandResult callbackId:command.callbackId];
+}
+
+-(void)successWithMessage:(NSString *)message
+{
+ if (self.callbackId != nil)
+ {
+ CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:message];
+ [self.commandDelegate sendPluginResult:commandResult callbackId:self.callbackId];
+ }
+}
+
+-(void)failWithMessage:(NSString *)message withError:(NSError *)error
+{
+ NSString *errorMessage = (error) ? [NSString stringWithFormat:@"%@ - %@", message, [error localizedDescription]] : message;
+ CDVPluginResult *commandResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:errorMessage];
+
+ [self.commandDelegate sendPluginResult:commandResult callbackId:self.callbackId];
+}
+
+-(void) finish:(CDVInvokedUrlCommand*)command
+{
+ NSLog(@"Push Plugin finish called");
+
+ [self.commandDelegate runInBackground:^ {
+ UIApplication *app = [UIApplication sharedApplication];
+ float finishTimer = (app.backgroundTimeRemaining > 20.0) ? 20.0 : app.backgroundTimeRemaining;
+
+ [NSTimer scheduledTimerWithTimeInterval:finishTimer
+ target:self
+ selector:@selector(stopBackgroundTask:)
+ userInfo:nil
+ repeats:NO];
+
+ CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
+ [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
+ }];
+}
+
+-(void)stopBackgroundTask:(NSTimer*)timer
+{
+ UIApplication *app = [UIApplication sharedApplication];
+
+ NSLog(@"Push Plugin stopBackgroundTask called");
+
+ if (handlerObj) {
+ NSLog(@"Push Plugin handlerObj");
+ completionHandler = [handlerObj[@"handler"] copy];
+ if (completionHandler) {
+ NSLog(@"Push Plugin: stopBackgroundTask (remaining t: %f)", app.backgroundTimeRemaining);
+ completionHandler(UIBackgroundFetchResultNewData);
+ completionHandler = nil;
+ }
+ }
+}
+
+@end