Merge pull request #474 from NativeScript/connect

Resolved Issue #451: Improve the Network Stack
This commit is contained in:
Rossen Hristov
2015-07-24 09:48:10 +03:00
19 changed files with 504 additions and 51 deletions

View File

@ -79,6 +79,10 @@
<TypeScriptCompile Include="apps\action-bar-demo\pages\data-binding.ts"> <TypeScriptCompile Include="apps\action-bar-demo\pages\data-binding.ts">
<DependentUpon>data-binding.xml</DependentUpon> <DependentUpon>data-binding.xml</DependentUpon>
</TypeScriptCompile> </TypeScriptCompile>
<TypeScriptCompile Include="apps\notifications-demo\app.ts" />
<TypeScriptCompile Include="apps\notifications-demo\main-page.ts">
<DependentUpon>main-page.xml</DependentUpon>
</TypeScriptCompile>
<TypeScriptCompile Include="apps\connectivity-demo\app.ts" /> <TypeScriptCompile Include="apps\connectivity-demo\app.ts" />
<TypeScriptCompile Include="apps\connectivity-demo\main-page.ts"> <TypeScriptCompile Include="apps\connectivity-demo\main-page.ts">
<DependentUpon>main-page.xml</DependentUpon> <DependentUpon>main-page.xml</DependentUpon>
@ -102,6 +106,9 @@
<Content Include="apps\action-bar-demo\pages\center-view-segmented.xml" /> <Content Include="apps\action-bar-demo\pages\center-view-segmented.xml" />
<Content Include="apps\action-bar-demo\pages\center-view.xml" /> <Content Include="apps\action-bar-demo\pages\center-view.xml" />
<Content Include="apps\action-bar-demo\pages\data-binding.xml" /> <Content Include="apps\action-bar-demo\pages\data-binding.xml" />
<Content Include="apps\notifications-demo\main-page.xml">
<SubType>Designer</SubType>
</Content>
<Content Include="apps\connectivity-demo\main-page.xml"> <Content Include="apps\connectivity-demo\main-page.xml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Content> </Content>
@ -1752,6 +1759,9 @@
<Content Include="apps\connectivity-demo\package.json"> <Content Include="apps\connectivity-demo\package.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="apps\notifications-demo\package.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="js-libs\esprima\LICENSE.BSD" /> <None Include="js-libs\esprima\LICENSE.BSD" />
<Content Include="source-control.md" /> <Content Include="source-control.md" />
<Content Include="ui\segmented-bar\package.json"> <Content Include="ui\segmented-bar\package.json">
@ -1844,7 +1854,7 @@
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile> <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties> </WebProjectProperties>
</FlavorProperties> </FlavorProperties>
<UserProperties ui_2scroll-view_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2editable-text-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2absolute-layout-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2gallery-app_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2content-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2web-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2linear-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2absolute-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2dock-layout_2package_1json__JSONSchema="" ui_2layouts_2grid-layout_2package_1json__JSONSchema="" ui_2layouts_2wrap-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" /> <UserProperties ui_2layouts_2wrap-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2grid-layout_2package_1json__JSONSchema="" ui_2layouts_2dock-layout_2package_1json__JSONSchema="" ui_2layouts_2absolute-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2layouts_2linear-layout_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2web-view_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2content-view_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2gallery-app_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2absolute-layout-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" apps_2editable-text-demo_2package_1json__JSONSchema="http://json.schemastore.org/package" ui_2scroll-view_2package_1json__JSONSchema="http://json.schemastore.org/package" />
</VisualStudio> </VisualStudio>
</ProjectExtensions> </ProjectExtensions>
</Project> </Project>

View File

@ -209,7 +209,62 @@ export class AndroidApplication extends observable.Observable implements dts.And
this._eventsToken = initEvents(); this._eventsToken = initEvents();
this.nativeApp.registerActivityLifecycleCallbacks(this._eventsToken); 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);
}
} }
} }

View File

@ -440,6 +440,21 @@ declare module "application" {
* String value used when hooking to activityBackPressed event. * String value used when hooking to activityBackPressed event.
*/ */
public static activityBackPressedEvent: string; 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 originally registered.
*/
unregisterBroadcastReceiver(intentFilter: string): void;
} }
/* tslint:disable */ /* 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. * 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; 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;
} }
} }

View File

@ -121,11 +121,33 @@ class TNSAppDelegate extends UIResponder implements UIApplicationDelegate {
} }
} }
class NotificationReceiver extends NSObject {
private _onReceiveCallback: (notification: NSNotification) => void;
static new(): NotificationReceiver {
return <NotificationReceiver>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 { class IOSApplication implements definition.iOSApplication {
public nativeApp: any; public nativeApp: any;
public rootController: any; public rootController: any;
private _tnsAppdelegate: TNSAppDelegate; private _tnsAppdelegate: TNSAppDelegate;
private _registeredObservers = {};
constructor() { constructor() {
// TODO: in iOS there is the singleton instance, while in Android such does not exist hence we pass it as argument // 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() { public init() {
this._tnsAppdelegate = new TNSAppDelegate(); 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 // TODO: If we have nested require(application) calls we may enter unfinished module state, which will create two delegates, resulting in an exception

View File

@ -1,3 +1,4 @@
import application = require("application"); import application = require("application");
application.mainModule = "main-page"; application.mainModule = "main-page";
application.start(); application.start();

View File

@ -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 = <pages.Page>args.object;
infoLabel = page.getViewById<labelModule.Label>("infoLabel");
}
export function onGetConnectionType(args: observable.EventData) {
var connectionType = connectivity.getConnectionType(); 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) { switch (connectionType) {
case connectivity.connectionType.none: case connectivity.connectionType.none:
args.object.text = "No connection"; infoLabel.text = "None";
infoLabel.backgroundColor = new color.Color("Red");
break; break;
case connectivity.connectionType.wifi: case connectivity.connectionType.wifi:
args.object.text = "WiFi connection"; infoLabel.text = "WiFi";
infoLabel.backgroundColor = new color.Color("Green");
break; break;
case connectivity.connectionType.mobile: case connectivity.connectionType.mobile:
args.object.text = "Mobile connection"; infoLabel.text = "Mobile";
infoLabel.backgroundColor = new color.Color("Yellow");
break; break;
} }
} }
function onConnectionTypeChanged(newConnectionType: number) {
switch (newConnectionType) {
case connectivity.connectionType.none:
console.log("Connection type changed to none.");
break;
case connectivity.connectionType.wifi:
console.log("Connection type changed to WiFi.");
break;
case connectivity.connectionType.mobile:
console.log("Connection type changed to mobile.");
break;
}
updateInfoLabel(newConnectionType);
}

View File

@ -1,5 +1,8 @@
<Page xmlns="http://www.nativescript.org/tns.xsd" navigatedTo="onNavigatedTo"> <Page xmlns="http://www.nativescript.org/tns.xsd" loaded="onPageLoaded">
<StackLayout> <StackLayout id="stackLayout">
<Button text="Get Connection Type" tap="onGetConnectionType" style.fontSize="30"/> <Button text="Get Connection Type" tap="onGetConnectionType" style.fontSize="30" horizontalAlignment="stretch" textAlignment="center"/>
<Button text="Start Monitoring" tap="onStartMonitoring" style.fontSize="30" horizontalAlignment="stretch" textAlignment="center"/>
<Button text="Stop Monitoring" tap="onStopMonitoring" style.fontSize="30" horizontalAlignment="stretch" textAlignment="center"/>
<Label id="infoLabel" style.fontSize="30" horizontalAlignment="stretch" textAlignment="center" width="200" height="200"/>
</StackLayout> </StackLayout>
</Page> </Page>

View File

@ -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();

View File

@ -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 = <pages.Page>args.object;
batteryLabel = page.getViewById<labelModule.Label>("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;
}

View File

@ -0,0 +1,5 @@
<Page xmlns="http://www.nativescript.org/tns.xsd" loaded="onPageLoaded">
<StackLayout>
<Label id="batteryLabel" text="Battery" style.fontSize="30" horizontalAlignment="stretch" textAlignment="center"/>
</StackLayout>
</Page>

View File

@ -0,0 +1,2 @@
{ "name" : "notifications-demo",
"main" : "app.js" }

View File

@ -24,7 +24,7 @@ if (app.android) {
import TKUnit = require("./TKUnit"); import TKUnit = require("./TKUnit");
export var testInitialized = function () { export var testInitialized = function () {
if (android) { if (global.android) {
// we have the android defined // we have the android defined
TKUnit.assert(app.android, "Application module not properly intialized"); TKUnit.assert(app.android, "Application module not properly intialized");
} else if (NSObject) { } else if (NSObject) {

View File

@ -26,7 +26,26 @@ var dir = context.getFilesDir();
// ### Tracking the current Activity // ### Tracking the current Activity
// ``` JavaScript // ``` JavaScript
if (androidApp.foregroundActivity === androidApp.startActivity) { if (androidApp.foregroundActivity === androidApp.startActivity) {
console.log("We are currently in the main (start) activity of the application"); ////console.log("We are currently in the main (start) activity of the application");
}
// ```
// </snippet>
// <snippet module="application" title="application">
// ### Registering a Broadcast Receiver (Android)
// ``` JavaScript
//// 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;
////console.log("Battery: " + percent + "%");
});
}
//// When no longer needed, unregister the broadcast receiver
if (app.android) {
app.android.unregisterBroadcastReceiver(android.content.Intent.ACTION_BATTERY_CHANGED);
} }
// ``` // ```
// </snippet> // </snippet>

View File

@ -1 +1,27 @@
 /* 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);
// <snippet module="application" title="application">
// ### Adding a Notification Observer (iOS)
// ``` JavaScript
//// 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 + "%";
////console.log(message);
});
}
//// When no longer needed, remove the notification observer
if (app.ios) {
app.ios.removeNotificationObserver(UIDeviceBatteryLevelDidChangeNotification);
}
// ```
// </snippet>

View File

@ -25,3 +25,26 @@ export var test_DummyTestForSnippetOnly0 = function () {
// ``` // ```
// </snippet> // </snippet>
} }
export var test_DummyTestForSnippetOnly1 = function () {
// <snippet module="connectivity" title="connectivity">
// ### Monitoring connection type.
// ``` JavaScript
connectivity.starMonitoring(function onConnectionTypeChanged(newConnectionType: number) {
switch (newConnectionType) {
case connectivity.connectionType.none:
////console.log("Connection type changed to none.");
break;
case connectivity.connectionType.wifi:
////console.log("Connection type changed to WiFi.");
break;
case connectivity.connectionType.mobile:
////console.log("Connection type changed to mobile.");
break;
}
});
////...
connectivity.stopMonitoring();
// ```
// </snippet>
}

View File

@ -7,12 +7,22 @@ require("utils/module-merge").merge(common, exports);
var WIFI = "WIFI"; var WIFI = "WIFI";
var MOBILE = "MOBILE"; var MOBILE = "MOBILE";
function getActiveNetworkInfo(): android.net.NetworkInfo { // Get Connection Type
function getConnectivityManager(): android.net.ConnectivityManager {
if (!appModule.android || !appModule.android.context) { if (!appModule.android || !appModule.android.context) {
return null; 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 { export function getConnectionType(): number {
@ -29,3 +39,15 @@ export function getConnectionType(): number {
return common.connectionType.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);
}

View File

@ -28,4 +28,15 @@ declare module "connectivity" {
*/ */
export var mobile: number; 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;
} }

View File

@ -3,9 +3,9 @@
declare var exports; declare var exports;
require("utils/module-merge").merge(common, exports); require("utils/module-merge").merge(common, exports);
// Get Connection Type
declare var sockaddr; declare var sockaddr;
function _createReachability(host?: string): any {
function getNetworkReachability(host?: string): any {
if (host) { if (host) {
return SCNetworkReachabilityCreateWithName(null, host); return SCNetworkReachabilityCreateWithName(null, host);
} }
@ -18,8 +18,8 @@ function getNetworkReachability(host?: string): any {
} }
} }
function getReachabilityFlags(host?: string): number { function _getReachabilityFlags(host?: string): number {
var reachability = getNetworkReachability(host); var reachability = _createReachability(host);
var flagsRef = new interop.Reference<number>(); var flagsRef = new interop.Reference<number>();
var gotFlags = SCNetworkReachabilityGetFlags(reachability, flagsRef); var gotFlags = SCNetworkReachabilityGetFlags(reachability, flagsRef);
CFRelease(reachability); CFRelease(reachability);
@ -29,8 +29,12 @@ function getReachabilityFlags(host?: string): number {
return flagsRef.value; return flagsRef.value;
} }
function getConnectionTypeToHost(host?: string): number { function _getConnectionType(host?: string): number {
var flags = getReachabilityFlags(host); var flags = _getReachabilityFlags(host);
return _getConnectionTypeFromFlags(flags);
}
function _getConnectionTypeFromFlags(flags: number): number {
if (!flags) { if (!flags) {
return common.connectionType.none; return common.connectionType.none;
} }
@ -50,5 +54,35 @@ function getConnectionTypeToHost(host?: string): number {
} }
export function getConnectionType(): 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;;
}
} }

140
declarations.ios.d.ts vendored
View File

@ -4,6 +4,75 @@
* Provides API for working with native C types, pointers, pointer arithmetic and memory. * Provides API for working with native C types, pointers, pointer arithmetic and memory.
*/ */
declare module interop { 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. * A type that wraps a pointer and allows read/write operations on its value.
*/ */
@ -45,34 +114,18 @@ declare module interop {
* Dereferences the pointer. * Dereferences the pointer.
*/ */
value: any; value: any;
}; }
interface FunctionReference<T> {
(...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 { var FunctionReference: {
/** new <T>(func: T): FunctionReference<T>;
* 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;
} }
interface Type<T> { interface Type<T> {
@ -92,13 +145,42 @@ declare module interop {
uint64: Type<number>; uint64: Type<number>;
float: Type<number>; float: Type<number>;
double: Type<number>; double: Type<number>;
//UTF8CString: Type<Reference<types.int8>>;
UTF8CString: Type<Reference<number>>;
unichar: Type<string>; unichar: Type<string>;
id: Type<NSObject>;
protocol: Type<Object>; id: Type<any>;
"class": Type<NSObject>; protocol: Type<any>;
"class": Type<any>;
selector: Type<string>; selector: Type<string>;
} }
/**
* A type for JavaScript constructors for C structs.
*/
interface StructType<T> extends Type<T> {
/**
* Create a new instance of the struct.
*/
new (): T;
/**
* Create a new instance of the struct and initialize it from the fields of the provided object.
* @param obj Initializer.
*/
new (obj: T): T;
/**
* Create a new struct by copying the memory from the provided pointer.
*/
new (obj: Pointer): T;
/**
* Checks two structs for equality.
*/
equals(left: T, right: T): boolean;
}
} }
declare function __collect(): void; declare function __collect(): void;