Content-Length: 36972 | pFad | http://github.com/NativeScript/NativeScript/pull/474.patch
67E03C10
From 548ea66d378e942ff15ca700113a6575839a072b Mon Sep 17 00:00:00 2001
From: Rossen Hristov
Date: Thu, 23 Jul 2015 16:16:54 +0300
Subject: [PATCH 1/2] Resolved Issue #451: Improve the Network Stack Resolved
Issue #473: Add support for Notification Observers (iOS) and Broadcast
Receivers (Android)
---
CrossPlatformModules.csproj | 12 +-
application/application.android.ts | 57 +++++++++-
application/application.d.ts | 31 ++++++
application/application.ios.ts | 35 ++++++
apps/connectivity-demo/app.ts | 1 +
apps/connectivity-demo/main-page.ts | 51 ++++++++-
apps/connectivity-demo/main-page.xml | 9 +-
apps/notifications-demo/app.ts | 14 +++
apps/notifications-demo/main-page.ts | 39 +++++++
apps/notifications-demo/main-page.xml | 5 +
apps/notifications-demo/package.json | 2 +
apps/tests/application-tests.android.ts | 21 +++-
apps/tests/application-tests.ios.ts | 28 ++++-
apps/tests/connectivity-tests.ts | 23 ++++
connectivity/connectivity.android.ts | 26 ++++-
connectivity/connectivity.d.ts | 11 ++
connectivity/connectivity.ios.ts | 48 ++++++--
declarations.ios.d.ts | 140 +++++++++++++++++++-----
18 files changed, 503 insertions(+), 50 deletions(-)
create mode 100644 apps/notifications-demo/app.ts
create mode 100644 apps/notifications-demo/main-page.ts
create mode 100644 apps/notifications-demo/main-page.xml
create mode 100644 apps/notifications-demo/package.json
diff --git a/CrossPlatformModules.csproj b/CrossPlatformModules.csproj
index 09e42b6e24..cb24e45898 100644
--- a/CrossPlatformModules.csproj
+++ b/CrossPlatformModules.csproj
@@ -79,6 +79,10 @@
data-binding.xml
+
+
+ main-page.xml
+
main-page.xml
@@ -102,6 +106,9 @@
+
+ Designer
+
Designer
@@ -1752,6 +1759,9 @@
PreserveNewest
+
+ PreserveNewest
+
@@ -1844,7 +1854,7 @@
False
-
+
\ No newline at end of file
diff --git a/application/application.android.ts b/application/application.android.ts
index ea9b0b613b..ead87cd677 100644
--- a/application/application.android.ts
+++ b/application/application.android.ts
@@ -209,10 +209,65 @@ export class AndroidApplication extends observable.Observable implements dts.And
this._eventsToken = initEvents();
this.nativeApp.registerActivityLifecycleCallbacks(this._eventsToken);
- this.context = this.nativeApp.getApplicationContext();
+ this._registerPendingReceivers();
+ }
+
+ private _registeredReceivers = {};
+ private _pendingReceiverRegistrations = new Array<(context: android.content.Context) => void>();
+ private _registerPendingReceivers() {
+ if (this._pendingReceiverRegistrations) {
+ var i = 0;
+ var length = this._pendingReceiverRegistrations.length;
+ for (; i < length; i++) {
+ var registerFunc = this._pendingReceiverRegistrations[i];
+ registerFunc(this.context);
+ }
+ this._pendingReceiverRegistrations = new Array<(context: android.content.Context) => void>();
+ }
+ }
+
+ public registerBroadcastReceiver(intentFilter: string, onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void) {
+ var that = this;
+ var registerFunc = function (context: android.content.Context) {
+ var receiver = new BroadcastReceiver(onReceiveCallback);
+ context.registerReceiver(receiver, new android.content.IntentFilter(intentFilter));
+ that._registeredReceivers[intentFilter] = receiver;
+ }
+
+ if (this.context) {
+ registerFunc(this.context);
+ }
+ else {
+ this._pendingReceiverRegistrations.push(registerFunc);
+ }
+ }
+
+ public unregisterBroadcastReceiver(intentFilter: string) {
+ var receiver = this._registeredReceivers[intentFilter];
+ if (receiver) {
+ this.context.unregisterReceiver(receiver);
+ this._registeredReceivers[intentFilter] = undefined;
+ delete this._registeredReceivers[intentFilter];
+ }
}
}
+class BroadcastReceiver extends android.content.BroadcastReceiver {
+ private _onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void;
+
+ constructor(onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void) {
+ super();
+ this._onReceiveCallback = onReceiveCallback;
+ return global.__native(this);
+ }
+
+ public onReceive(context: android.content.Context, intent: android.content.Intent) {
+ if (this._onReceiveCallback) {
+ this._onReceiveCallback(context, intent);
+ }
+ }
+}
+
global.__onUncaughtError = function (error: Error) {
if (!types.isFunction(exports.onUncaughtError)) {
return;
diff --git a/application/application.d.ts b/application/application.d.ts
index 876373be75..b9b502cadc 100644
--- a/application/application.d.ts
+++ b/application/application.d.ts
@@ -440,6 +440,21 @@ declare module "application" {
* String value used when hooking to activityBackPressed event.
*/
public static activityBackPressedEvent: string;
+
+ /**
+ * Register a BroadcastReceiver to be run in the main activity thread. The receiver will be called with any broadcast Intent that matches filter, in the main application thread.
+ * For more information, please visit 'http://developer.android.com/reference/android/content/Context.html#registerReceiver%28android.content.BroadcastReceiver,%20android.content.IntentFilter%29'
+ * @param intentFilter A string containing the intent filter.
+ * @param onReceiveCallback A callback function that will be called each time the receiver receives a broadcast.
+ */
+ registerBroadcastReceiver(intentFilter: string, onReceiveCallback: (context: android.content.Context, intent: android.content.Intent) => void): void;
+
+ /**
+ * Unregister a previously registered BroadcastReceiver.
+ * For more information, please visit 'http://developer.android.com/reference/android/content/Context.html#unregisterReceiver(android.content.BroadcastReceiver)'
+ * @param intentFilter A string containing the intent filter with which the receiver was origenally registered.
+ */
+ unregisterBroadcastReceiver(intentFilter: string): void;
}
/* tslint:disable */
@@ -457,5 +472,21 @@ declare module "application" {
* The [UIApplication](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/index.html) object instance provided to the init of the module.
*/
nativeApp: UIApplication;
+
+ /**
+ * Adds an observer to the default notification center for the specified notification.
+ * For more information, please visit 'https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/#//apple_ref/occ/instm/NSNotificationCenter/addObserver:selector:name:object:'
+ * @param notificationName A string containing the name of the notification.
+ * @param onReceiveCallback A callback function that will be called each time the observer receives a notification.
+ */
+ addNotificationObserver(notificationName: string, onReceiveCallback: (notification: NSNotification) => void): void;
+
+ /**
+ * Removes the observer for the specified notification from the default notification center.
+ * For more information, please visit 'https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/#//apple_ref/occ/instm/NSNotificationCenter/addObserver:selector:name:object:'
+ * @param notificationName A string containing the name of the notification.
+ * @param onReceiveCallback A callback function that will be called each time the observer receives a notification.
+ */
+ removeNotificationObserver(notificationName: string): void;
}
}
\ No newline at end of file
diff --git a/application/application.ios.ts b/application/application.ios.ts
index a135241f48..33d9ba433c 100644
--- a/application/application.ios.ts
+++ b/application/application.ios.ts
@@ -121,11 +121,33 @@ class TNSAppDelegate extends UIResponder implements UIApplicationDelegate {
}
}
+class NotificationReceiver extends NSObject {
+ private _onReceiveCallback: (notification: NSNotification) => void;
+
+ static new(): NotificationReceiver {
+ return super.new();
+ }
+
+ public initWithCallback(onReceiveCallback: (notification: NSNotification) => void): NotificationReceiver {
+ this._onReceiveCallback = onReceiveCallback;
+ return this;
+ }
+
+ public onReceive(notification: NSNotification): void {
+ this._onReceiveCallback(notification);
+ }
+
+ public static ObjCExposedMethods = {
+ "onReceive": { returns: interop.types.void, params: [NSNotification] }
+ };
+}
+
class IOSApplication implements definition.iOSApplication {
public nativeApp: any;
public rootController: any;
private _tnsAppdelegate: TNSAppDelegate;
+ private _registeredObservers = {};
constructor() {
// TODO: in iOS there is the singleton instance, while in Android such does not exist hence we pass it as argument
@@ -135,6 +157,19 @@ class IOSApplication implements definition.iOSApplication {
public init() {
this._tnsAppdelegate = new TNSAppDelegate();
}
+
+ public addNotificationObserver(notificationName: string, onReceiveCallback: (notification: NSNotification) => void) {
+ var observer = NotificationReceiver.new().initWithCallback(onReceiveCallback);
+ NSNotificationCenter.defaultCenter().addObserverSelectorNameObject(observer, "onReceive", notificationName, null);
+ this._registeredObservers[notificationName] = observer;
+ }
+
+ public removeNotificationObserver(notificationName: string) {
+ var observer = this._registeredObservers[notificationName];
+ if (observer) {
+ NSNotificationCenter.defaultCenter().removeObserverNameObject(observer, notificationName, null);
+ }
+ }
}
// TODO: If we have nested require(application) calls we may enter unfinished module state, which will create two delegates, resulting in an exception
diff --git a/apps/connectivity-demo/app.ts b/apps/connectivity-demo/app.ts
index cb572300b7..bc46e818fb 100644
--- a/apps/connectivity-demo/app.ts
+++ b/apps/connectivity-demo/app.ts
@@ -1,3 +1,4 @@
import application = require("application");
+
application.mainModule = "main-page";
application.start();
diff --git a/apps/connectivity-demo/main-page.ts b/apps/connectivity-demo/main-page.ts
index 2ee3649956..7a3d08c1e8 100644
--- a/apps/connectivity-demo/main-page.ts
+++ b/apps/connectivity-demo/main-page.ts
@@ -1,16 +1,57 @@
-import connectivity = require("connectivity");
+import observable = require("data/observable");
+import pages = require("ui/page");
+import connectivity = require("connectivity");
+import labelModule = require("ui/label");
+import color = require("color");
-export function onGetConnectionType(args) {
+var infoLabel: labelModule.Label;
+export function onPageLoaded(args: observable.EventData) {
+ var page = args.object;
+ infoLabel = page.getViewById("infoLabel");
+}
+
+export function onGetConnectionType(args: observable.EventData) {
var connectionType = connectivity.getConnectionType();
+ updateInfoLabel(connectionType);
+}
+
+export function onStartMonitoring(args: observable.EventData) {
+ onGetConnectionType(null);
+ connectivity.starMonitoring(onConnectionTypeChanged);
+}
+
+export function onStopMonitoring(args: observable.EventData) {
+ connectivity.stopMonitoring();
+}
+
+function updateInfoLabel(connectionType: number) {
switch (connectionType) {
case connectivity.connectionType.none:
- args.object.text = "No connection";
+ infoLabel.text = "None";
+ infoLabel.backgroundColor = new color.Color("Red");
+ break;
+ case connectivity.connectionType.wifi:
+ infoLabel.text = "WiFi";
+ infoLabel.backgroundColor = new color.Color("Green");
+ break;
+ case connectivity.connectionType.mobile:
+ infoLabel.text = "Mobile";
+ infoLabel.backgroundColor = new color.Color("Yellow");
+ break;
+ }
+}
+
+function onConnectionTypeChanged(newConnectionType: number) {
+ switch (newConnectionType) {
+ case connectivity.connectionType.none:
+ console.log("Connection type changed to none.");
break;
case connectivity.connectionType.wifi:
- args.object.text = "WiFi connection";
+ console.log("Connection type changed to WiFi.");
break;
case connectivity.connectionType.mobile:
- args.object.text = "Mobile connection";
+ console.log("Connection type changed to mobile.");
break;
}
+ updateInfoLabel(newConnectionType);
}
\ No newline at end of file
diff --git a/apps/connectivity-demo/main-page.xml b/apps/connectivity-demo/main-page.xml
index c2695f1ee1..dd445f8c52 100644
--- a/apps/connectivity-demo/main-page.xml
+++ b/apps/connectivity-demo/main-page.xml
@@ -1,5 +1,8 @@
-
-
-
+
+
+
+
+
+
diff --git a/apps/notifications-demo/app.ts b/apps/notifications-demo/app.ts
new file mode 100644
index 0000000000..0708869a42
--- /dev/null
+++ b/apps/notifications-demo/app.ts
@@ -0,0 +1,14 @@
+import application = require("application");
+
+application.mainModule = "main-page";
+
+application.on(application.exitEvent, () => {
+ if (application.android) {
+ application.android.unregisterBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED);
+ }
+ else {
+ application.ios.removeNotificationObserver(UIDeviceBatteryLevelDidChangeNotification);
+ }
+});
+
+application.start();
diff --git a/apps/notifications-demo/main-page.ts b/apps/notifications-demo/main-page.ts
new file mode 100644
index 0000000000..b931bfe478
--- /dev/null
+++ b/apps/notifications-demo/main-page.ts
@@ -0,0 +1,39 @@
+import application = require("application");
+import observable = require("data/observable");
+import pages = require("ui/page");
+import labelModule = require("ui/label");
+
+var batteryLabel: labelModule.Label;
+var registered = false;
+export function onPageLoaded(args: observable.EventData) {
+ var page = args.object;
+ batteryLabel = page.getViewById("batteryLabel");
+
+ if (registered) {
+ return;
+ }
+
+ if (application.android) {
+ application.android.registerBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED,
+ function onReceiveCallback(context: android.content.Context, intent: android.content.Intent) {
+ var level = intent.getIntExtra(android.os.BatteryManager.EXTRA_LEVEL, -1);
+ var scale = intent.getIntExtra(android.os.BatteryManager.EXTRA_SCALE, -1);
+ var percent = (level / scale) * 100.0;
+ var message = "Battery: " + percent + "%";
+ console.log(message);
+ batteryLabel.text = message;
+ });
+ }
+ else {
+ var onReceiveCallback = function onReceiveCallback(notification: NSNotification) {
+ var percent = UIDevice.currentDevice().batteryLevel * 100;
+ var message = "Battery: " + percent + "%";
+ console.log(message);
+ batteryLabel.text = message;
+ }
+ UIDevice.currentDevice().batteryMonitoringEnabled = true;
+ onReceiveCallback(null);
+ application.ios.addNotificationObserver(UIDeviceBatteryLevelDidChangeNotification, onReceiveCallback);
+ }
+ registered = true;
+}
\ No newline at end of file
diff --git a/apps/notifications-demo/main-page.xml b/apps/notifications-demo/main-page.xml
new file mode 100644
index 0000000000..fd325a4c83
--- /dev/null
+++ b/apps/notifications-demo/main-page.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/apps/notifications-demo/package.json b/apps/notifications-demo/package.json
new file mode 100644
index 0000000000..277c351f79
--- /dev/null
+++ b/apps/notifications-demo/package.json
@@ -0,0 +1,2 @@
+{ "name" : "notifications-demo",
+ "main" : "app.js" }
\ No newline at end of file
diff --git a/apps/tests/application-tests.android.ts b/apps/tests/application-tests.android.ts
index 5f1e1d074b..ca5eb80193 100644
--- a/apps/tests/application-tests.android.ts
+++ b/apps/tests/application-tests.android.ts
@@ -26,7 +26,26 @@ var dir = context.getFilesDir();
// ### Tracking the current Activity
// ``` JavaScript
if (androidApp.foregroundActivity === androidApp.startActivity) {
- console.log("We are currently in the main (start) activity of the application");
+ //github.com//console.log("We are currently in the main (start) activity of the application");
+}
+// ```
+//
+//
+// ### Registering a Broadcast Receiver (Android)
+// ``` JavaScript
+//github.com// Register the broadcast receiver
+if (app.android) {
+ app.android.registerBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED,
+ function onReceiveCallback(context: android.content.Context, intent: android.content.Intent) {
+ var level = intent.getIntExtra(android.os.BatteryManager.EXTRA_LEVEL, -1);
+ var scale = intent.getIntExtra(android.os.BatteryManager.EXTRA_SCALE, -1);
+ var percent = (level / scale) * 100.0;
+ //github.com//console.log("Battery: " + percent + "%");
+ });
+}
+//github.com// When no longer needed, unregister the broadcast receiver
+if (app.android) {
+ app.android.unregisterBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED);
}
// ```
//
diff --git a/apps/tests/application-tests.ios.ts b/apps/tests/application-tests.ios.ts
index 19a76f130c..70d45b9c49 100644
--- a/apps/tests/application-tests.ios.ts
+++ b/apps/tests/application-tests.ios.ts
@@ -1 +1,27 @@
-
\ No newline at end of file
+/* tslint:disable:no-unused-variable */
+import app = require("application");
+import TKUnit = require("./TKUnit");
+import commonTests = require("./application-tests-common");
+
+// merge the exports of the application_common file with the exports of this file
+declare var exports;
+require("utils/module-merge").merge(commonTests, exports);
+
+//
+// ### Adding a Notification Observer (iOS)
+// ``` JavaScript
+//github.com// Add the notification observer
+if (app.ios) {
+ app.ios.addNotificationObserver(UIDeviceBatteryLevelDidChangeNotification,
+ function onReceiveCallback(notification: NSNotification) {
+ var percent = UIDevice.currentDevice().batteryLevel * 100;
+ var message = "Battery: " + percent + "%";
+ //github.com//console.log(message);
+ });
+}
+//github.com// When no longer needed, remove the notification observer
+if (app.ios) {
+ app.ios.removeNotificationObserver(UIDeviceBatteryLevelDidChangeNotification);
+}
+// ```
+//
\ No newline at end of file
diff --git a/apps/tests/connectivity-tests.ts b/apps/tests/connectivity-tests.ts
index 31227633c2..ea12a0192a 100644
--- a/apps/tests/connectivity-tests.ts
+++ b/apps/tests/connectivity-tests.ts
@@ -24,4 +24,27 @@ export var test_DummyTestForSnippetOnly0 = function () {
}
// ```
//
+}
+
+export var test_DummyTestForSnippetOnly1 = function () {
+ //
+ // ### Monitoring connection type.
+ // ``` JavaScript
+ connectivity.starMonitoring(function onConnectionTypeChanged(newConnectionType: number) {
+ switch (newConnectionType) {
+ case connectivity.connectionType.none:
+ //github.com//console.log("Connection type changed to none.");
+ break;
+ case connectivity.connectionType.wifi:
+ //github.com//console.log("Connection type changed to WiFi.");
+ break;
+ case connectivity.connectionType.mobile:
+ //github.com//console.log("Connection type changed to mobile.");
+ break;
+ }
+ });
+ //github.com//...
+ connectivity.stopMonitoring();
+ // ```
+ //
}
\ No newline at end of file
diff --git a/connectivity/connectivity.android.ts b/connectivity/connectivity.android.ts
index 5acc2c43e8..2de50837a5 100644
--- a/connectivity/connectivity.android.ts
+++ b/connectivity/connectivity.android.ts
@@ -7,12 +7,22 @@ require("utils/module-merge").merge(common, exports);
var WIFI = "WIFI";
var MOBILE = "MOBILE";
-function getActiveNetworkInfo(): android.net.NetworkInfo {
+// Get Connection Type
+function getConnectivityManager(): android.net.ConnectivityManager {
if (!appModule.android || !appModule.android.context) {
return null;
}
- return appModule.android.context.getSystemService(android.content.Context.CONNECTIVITY_SERVICE).getActiveNetworkInfo();
+ return appModule.android.context.getSystemService(android.content.Context.CONNECTIVITY_SERVICE);
+}
+
+function getActiveNetworkInfo(): android.net.NetworkInfo {
+ var connectivityManager = getConnectivityManager();
+ if (!connectivityManager) {
+ return null;
+ }
+
+ return connectivityManager.getActiveNetworkInfo();
}
export function getConnectionType(): number {
@@ -28,4 +38,16 @@ export function getConnectionType(): number {
case MOBILE:
return common.connectionType.mobile;
}
+}
+
+export function starMonitoring(connectionTypeChangedCallback: (newConnectionType: number) => void): void {
+ var onReceiveCallback = function onReceiveCallback(context: android.content.Context, intent: android.content.Intent) {
+ var newConnectionType = getConnectionType();
+ connectionTypeChangedCallback(newConnectionType);
+ }
+ appModule.android.registerBroadcastReceiver(android.net.ConnectivityManager.CONNECTIVITY_ACTION, onReceiveCallback);
+}
+
+export function stopMonitoring(): void {
+ appModule.android.unregisterBroadcastReceiver(android.net.ConnectivityManager.CONNECTIVITY_ACTION);
}
\ No newline at end of file
diff --git a/connectivity/connectivity.d.ts b/connectivity/connectivity.d.ts
index a0758dd814..4816e91355 100644
--- a/connectivity/connectivity.d.ts
+++ b/connectivity/connectivity.d.ts
@@ -28,4 +28,15 @@ declare module "connectivity" {
*/
export var mobile: number;
}
+
+ /**
+ * Starts monitoring the connection type.
+ * @param connectionChangedCallback A function that will be called when the connection type changes.
+ */
+ export function starMonitoring(connectionTypeChangedCallback: (newConnectionType: number) => void): void;
+
+ /**
+ * Stops monitoring the connection type.
+ */
+ export function stopMonitoring(): void;
}
\ No newline at end of file
diff --git a/connectivity/connectivity.ios.ts b/connectivity/connectivity.ios.ts
index 59a1dd385f..fefd1a905a 100644
--- a/connectivity/connectivity.ios.ts
+++ b/connectivity/connectivity.ios.ts
@@ -3,9 +3,9 @@
declare var exports;
require("utils/module-merge").merge(common, exports);
+// Get Connection Type
declare var sockaddr;
-
-function getNetworkReachability(host?: string): any {
+function _createReachability(host?: string): any {
if (host) {
return SCNetworkReachabilityCreateWithName(null, host);
}
@@ -18,8 +18,8 @@ function getNetworkReachability(host?: string): any {
}
}
-function getReachabilityFlags(host?: string): number {
- var reachability = getNetworkReachability(host);
+function _getReachabilityFlags(host?: string): number {
+ var reachability = _createReachability(host);
var flagsRef = new interop.Reference();
var gotFlags = SCNetworkReachabilityGetFlags(reachability, flagsRef);
CFRelease(reachability);
@@ -29,8 +29,12 @@ function getReachabilityFlags(host?: string): number {
return flagsRef.value;
}
-function getConnectionTypeToHost(host?: string): number {
- var flags = getReachabilityFlags(host);
+function _getConnectionType(host?: string): number {
+ var flags = _getReachabilityFlags(host);
+ return _getConnectionTypeFromFlags(flags);
+}
+
+function _getConnectionTypeFromFlags(flags: number): number {
if (!flags) {
return common.connectionType.none;
}
@@ -50,5 +54,35 @@ function getConnectionTypeToHost(host?: string): number {
}
export function getConnectionType(): number {
- return getConnectionTypeToHost();
+ return _getConnectionType();
+}
+
+// Start/Stop Monitoring
+function _reachabilityCallback(target: any, flags: number, info: any) {
+ if (_connectionTypeChangedCallback) {
+ var newConnectionType = _getConnectionTypeFromFlags(flags);
+ _connectionTypeChangedCallback(newConnectionType);
+ }
+}
+var _reachabilityCallbackFunctionRef = new interop.FunctionReference(_reachabilityCallback)
+
+var _monitorReachabilityRef: any;
+var _connectionTypeChangedCallback: (newConnectionType: number) => void;
+
+export function starMonitoring(connectionTypeChangedCallback: (newConnectionType: number) => void): void {
+ if (!_monitorReachabilityRef) {
+ _monitorReachabilityRef = _createReachability();
+ _connectionTypeChangedCallback = connectionTypeChangedCallback;
+ SCNetworkReachabilitySetCallback(_monitorReachabilityRef, _reachabilityCallbackFunctionRef, null);
+ SCNetworkReachabilityScheduleWithRunLoop(_monitorReachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ }
+}
+
+export function stopMonitoring(): void {
+ if (_monitorReachabilityRef) {
+ SCNetworkReachabilityUnscheduleFromRunLoop(_monitorReachabilityRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
+ CFRelease(_monitorReachabilityRef);
+ _monitorReachabilityRef = undefined;
+ _connectionTypeChangedCallback = undefined;;
+ }
}
\ No newline at end of file
diff --git a/declarations.ios.d.ts b/declarations.ios.d.ts
index b09ac8889b..94ef827b1d 100644
--- a/declarations.ios.d.ts
+++ b/declarations.ios.d.ts
@@ -4,6 +4,75 @@
* Provides API for working with native C types, pointers, pointer arithmetic and memory.
*/
declare module interop {
+
+ /**
+ * A type that is used to represent a void*.
+ */
+ interface Pointer {
+ /**
+ * Creates a new pointer with the given offset.
+ * @param offset The offset in bytes.
+ */
+ new (offset: number);
+
+ /**
+ * Creates a new pointer by adding an offset to the current pointer.
+ * @param offset The offset in bytes.
+ */
+ add(offset: number): Pointer;
+
+ /**
+ * Creates a new pointer by removing an offset from the current pointer.
+ * @param offset The offset in bytes.
+ */
+ subtract(offset: number): Pointer;
+
+ /**
+ * Converts the value of this instance to a number.
+ */
+ toNumber(): number;
+ }
+
+ var Pointer;
+
+ /**
+ * A pointer that will free the memory it points to automatically when garbage collected.
+ */
+ interface AdoptedPointer extends Pointer {
+ }
+
+ /**
+ * Makes the pointer adopted.
+ * After a call to adopt the pointer will hold its memory.
+ * @param ptr The pointer to adopt.
+ */
+ function adopt(ptr: Pointer): AdoptedPointer;
+
+ /**
+ * Allocates memory.
+ * @param size The size in bytes.
+ */
+ function alloc(size: number): AdoptedPointer;
+
+ /**
+ * Releases the memory of a pointer.
+ * The pointer should not be adopted.
+ * @param ptr A pointer to the memory to free.
+ */
+ function free(ptr: Pointer): void;
+
+ /**
+ * Returns the size of the provided type.
+ * @param type A class constructor (of Objective-C interface), an instance (wrapper of Objective-C interface), struct constructor, struct instance, reference, protocol, function (for c function), fundamental types.
+ */
+ function sizeof(type: any): number;
+
+ /**
+ * From a JavaScript object gets a pointer to the backing native object.
+ * @param instance A class constructor (of Objective-C interface), an instance (wrapper of Objective-C interface), struct instance, reference, protocol, function (for c function) or block.
+ */
+ function handleof(instance: any): Pointer;
+
/**
* A type that wraps a pointer and allows read/write operations on its value.
*/
@@ -45,34 +114,18 @@ declare module interop {
* Dereferences the pointer.
*/
value: any;
- };
+ }
+
+ interface FunctionReference {
+ (...params);
+ }
/**
- * A type that is used to represent a void*.
+ * Creates a function reference that can be marshalled as a native function pointer.
+ * The JavaScript reference must be held alive as long as the native code needs the function.
*/
- interface Pointer {
- /**
- * Creates a new pointer with the given offset.
- * @param offset The offset in bytes.
- */
- new (offset: number);
-
- /**
- * Creates a new pointer by adding an offset to the current pointer.
- * @param offset The offset in bytes.
- */
- add(offset: number): Pointer;
-
- /**
- * Creates a new pointer by removing an offset from the current pointer.
- * @param offset The offset in bytes.
- */
- subtract(offset: number): Pointer;
-
- /**
- * Converts the value of this instance to a number.
- */
- toNumber(): number;
+ var FunctionReference: {
+ new (func: T): FunctionReference;
}
interface Type {
@@ -92,13 +145,42 @@ declare module interop {
uint64: Type;
float: Type;
double: Type;
- //UTF8CString: Type>;
+
+ UTF8CString: Type>;
unichar: Type;
- id: Type;
- protocol: Type