mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-14 18:12:09 +08:00
feat(Utils): dataSerialize, dataDeserialize, numberHasDecimals, numberIs64Bit
This commit is contained in:
8
packages/core/index.d.ts
vendored
8
packages/core/index.d.ts
vendored
@ -105,8 +105,8 @@ export type { InstrumentationMode, TimerInfo } from './profiling';
|
|||||||
export { encoding } from './text';
|
export { encoding } from './text';
|
||||||
export * from './trace';
|
export * from './trace';
|
||||||
export * from './ui';
|
export * from './ui';
|
||||||
import { GC, isFontIconURI, isDataURI, isFileOrResourcePath, executeOnMainThread, mainThreadify, isMainThread, dispatchToMainThread, executeOnUIThread, releaseNativeObject, getModuleName, openFile, openUrl, isRealDevice, layout, ad as androidUtils, iOSNativeHelper as iosUtils, Source, escapeRegexSymbols, convertString, dismissSoftInput, queueMacrotask, queueGC, throttle, debounce } from './utils';
|
import { GC, isFontIconURI, isDataURI, isFileOrResourcePath, executeOnMainThread, mainThreadify, isMainThread, dispatchToMainThread, executeOnUIThread, releaseNativeObject, getModuleName, openFile, openUrl, isRealDevice, layout, ad as androidUtils, iOSNativeHelper as iosUtils, Source, escapeRegexSymbols, convertString, dismissSoftInput, queueMacrotask, queueGC, throttle, debounce, dataSerialize, dataDeserialize } from './utils';
|
||||||
import { ClassInfo, getClass, getBaseClasses, getClassInfo, isBoolean, isDefined, isFunction, isNullOrUndefined, isNumber, isObject, isString, isUndefined, toUIString, verifyCallback } from './utils/types';
|
import { ClassInfo, getClass, getBaseClasses, getClassInfo, isBoolean, isDefined, isFunction, isNullOrUndefined, isNumber, isObject, isString, isUndefined, toUIString, verifyCallback, numberHasDecimals, numberIs64Bit } from './utils/types';
|
||||||
export declare const Utils: {
|
export declare const Utils: {
|
||||||
GC: typeof GC;
|
GC: typeof GC;
|
||||||
RESOURCE_PREFIX: string;
|
RESOURCE_PREFIX: string;
|
||||||
@ -134,6 +134,10 @@ export declare const Utils: {
|
|||||||
android: typeof androidUtils;
|
android: typeof androidUtils;
|
||||||
ad: typeof androidUtils;
|
ad: typeof androidUtils;
|
||||||
ios: typeof iosUtils;
|
ios: typeof iosUtils;
|
||||||
|
dataSerialize: typeof dataSerialize;
|
||||||
|
dataDeserialize: typeof dataDeserialize;
|
||||||
|
numberHasDecimals: typeof numberHasDecimals;
|
||||||
|
numberIs64Bit: typeof numberIs64Bit;
|
||||||
setTimeout: typeof setTimeout;
|
setTimeout: typeof setTimeout;
|
||||||
setInterval: typeof setInterval;
|
setInterval: typeof setInterval;
|
||||||
clearInterval: typeof clearInterval;
|
clearInterval: typeof clearInterval;
|
||||||
|
@ -137,8 +137,8 @@ export * from './trace';
|
|||||||
|
|
||||||
export * from './ui';
|
export * from './ui';
|
||||||
|
|
||||||
import { GC, isFontIconURI, isDataURI, isFileOrResourcePath, executeOnMainThread, mainThreadify, isMainThread, dispatchToMainThread, executeOnUIThread, queueMacrotask, queueGC, debounce, throttle, releaseNativeObject, getModuleName, openFile, openUrl, isRealDevice, layout, ad as androidUtils, iOSNativeHelper as iosUtils, Source, RESOURCE_PREFIX, FILE_PREFIX, escapeRegexSymbols, convertString, dismissSoftInput } from './utils';
|
import { GC, isFontIconURI, isDataURI, isFileOrResourcePath, executeOnMainThread, mainThreadify, isMainThread, dispatchToMainThread, executeOnUIThread, queueMacrotask, queueGC, debounce, throttle, releaseNativeObject, getModuleName, openFile, openUrl, isRealDevice, layout, ad as androidUtils, iOSNativeHelper as iosUtils, Source, RESOURCE_PREFIX, FILE_PREFIX, escapeRegexSymbols, convertString, dismissSoftInput, dataDeserialize, dataSerialize } from './utils';
|
||||||
import { ClassInfo, getClass, getBaseClasses, getClassInfo, isBoolean, isDefined, isFunction, isNullOrUndefined, isNumber, isObject, isString, isUndefined, toUIString, verifyCallback } from './utils/types';
|
import { ClassInfo, getClass, getBaseClasses, getClassInfo, isBoolean, isDefined, isFunction, isNullOrUndefined, isNumber, isObject, isString, isUndefined, toUIString, verifyCallback, numberHasDecimals, numberIs64Bit } from './utils/types';
|
||||||
|
|
||||||
export const Utils = {
|
export const Utils = {
|
||||||
GC,
|
GC,
|
||||||
@ -170,6 +170,10 @@ export const Utils = {
|
|||||||
// legacy (a lot of plugins use the shorthand "ad" Utils.ad instead of Utils.android)
|
// legacy (a lot of plugins use the shorthand "ad" Utils.ad instead of Utils.android)
|
||||||
ad: androidUtils,
|
ad: androidUtils,
|
||||||
ios: iosUtils,
|
ios: iosUtils,
|
||||||
|
dataSerialize,
|
||||||
|
dataDeserialize,
|
||||||
|
numberHasDecimals,
|
||||||
|
numberIs64Bit,
|
||||||
setTimeout,
|
setTimeout,
|
||||||
setInterval,
|
setInterval,
|
||||||
clearInterval,
|
clearInterval,
|
||||||
|
@ -1,5 +1,143 @@
|
|||||||
import { getNativeApplication, android as androidApp } from '../application';
|
import { getNativeApplication, android as androidApp } from '../application';
|
||||||
import { Trace } from '../trace';
|
import { Trace } from '../trace';
|
||||||
|
import { numberHasDecimals, numberIs64Bit } from './types';
|
||||||
|
|
||||||
|
export function dataDeserialize(nativeData?: any) {
|
||||||
|
if (nativeData === null || typeof nativeData !== 'object') {
|
||||||
|
return nativeData;
|
||||||
|
}
|
||||||
|
let store;
|
||||||
|
|
||||||
|
switch (nativeData.getClass().getName()) {
|
||||||
|
case 'java.lang.String': {
|
||||||
|
return String(nativeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'java.lang.Boolean': {
|
||||||
|
return String(nativeData) === 'true';
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'java.lang.Float':
|
||||||
|
case 'java.lang.Integer':
|
||||||
|
case 'java.lang.Long':
|
||||||
|
case 'java.lang.Double':
|
||||||
|
case 'java.lang.Short': {
|
||||||
|
return Number(nativeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'org.json.JSONArray': {
|
||||||
|
store = [];
|
||||||
|
for (let j = 0; j < nativeData.length(); j++) {
|
||||||
|
store[j] = dataDeserialize(nativeData.get(j));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'org.json.JSONObject': {
|
||||||
|
store = {};
|
||||||
|
let i = nativeData.keys();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
let key = i.next();
|
||||||
|
store[key] = dataDeserialize(nativeData.get(key));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'androidx.collection.SimpleArrayMap': {
|
||||||
|
const count = nativeData.size();
|
||||||
|
for (let l = 0; l < count; l++) {
|
||||||
|
const key = nativeData.keyAt(l);
|
||||||
|
store[key] = dataDeserialize(nativeData.get(key));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'androidx.collection.ArrayMap':
|
||||||
|
case 'android.os.Bundle':
|
||||||
|
case 'java.util.HashMap':
|
||||||
|
case 'java.util.Map': {
|
||||||
|
store = {};
|
||||||
|
const keys = nativeData.keySet().toArray();
|
||||||
|
for (let k = 0; k < keys.length; k++) {
|
||||||
|
const key = keys[k];
|
||||||
|
store[key] = dataDeserialize(nativeData.get(key));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (typeof nativeData === 'object' && nativeData instanceof java.util.List) {
|
||||||
|
const array = [];
|
||||||
|
const size = nativeData.size();
|
||||||
|
for (let i = 0, n = size; i < n; i++) {
|
||||||
|
array[i] = dataDeserialize(nativeData.get(i));
|
||||||
|
}
|
||||||
|
store = array;
|
||||||
|
} else {
|
||||||
|
store = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dataSerialize(data?: any, wrapPrimitives?: boolean) {
|
||||||
|
let store;
|
||||||
|
switch (typeof data) {
|
||||||
|
case 'string':
|
||||||
|
case 'boolean': {
|
||||||
|
if (wrapPrimitives) {
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
return new java.lang.String(data);
|
||||||
|
}
|
||||||
|
return new java.lang.Boolean(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
case 'number': {
|
||||||
|
const hasDecimals = numberHasDecimals(data);
|
||||||
|
if (numberIs64Bit(data)) {
|
||||||
|
if (hasDecimals) {
|
||||||
|
return java.lang.Double.valueOf(data);
|
||||||
|
} else {
|
||||||
|
return java.lang.Long.valueOf(data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (hasDecimals) {
|
||||||
|
return java.lang.Float.valueOf(data);
|
||||||
|
} else {
|
||||||
|
return java.lang.Integer.valueOf(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'object': {
|
||||||
|
if (!data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data instanceof Date) {
|
||||||
|
return new java.util.Date(data.getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
store = new java.util.ArrayList();
|
||||||
|
data.forEach((item) => store.add(dataSerialize(item, wrapPrimitives)));
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.native) {
|
||||||
|
return data.native;
|
||||||
|
}
|
||||||
|
|
||||||
|
store = new java.util.HashMap();
|
||||||
|
Object.keys(data).forEach((key) => store.put(key, dataSerialize(data[key], wrapPrimitives)));
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We are using "ad" here to avoid namespace collision with the global android object
|
// We are using "ad" here to avoid namespace collision with the global android object
|
||||||
export namespace ad {
|
export namespace ad {
|
||||||
|
11
packages/core/utils/native-helper.d.ts
vendored
11
packages/core/utils/native-helper.d.ts
vendored
@ -1,3 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Data serialization from JS > Native
|
||||||
|
* @param wrapPrimitives Optionally wrap primitive types (Some APIs may require this)
|
||||||
|
*/
|
||||||
|
export function dataSerialize(data?: any, wrapPrimitives?: boolean): any;
|
||||||
|
/**
|
||||||
|
* Data deserialization from Native > JS
|
||||||
|
* @param nativeData Native platform data
|
||||||
|
*/
|
||||||
|
export function dataDeserialize(nativeData?: any): any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module with android specific utilities.
|
* Module with android specific utilities.
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Trace } from '../trace';
|
import { Trace } from '../trace';
|
||||||
import { getClass, isNullOrUndefined } from './types';
|
import { getClass, isNullOrUndefined, numberHasDecimals, numberIs64Bit } from './types';
|
||||||
|
|
||||||
declare let UIImagePickerControllerSourceType: any;
|
declare let UIImagePickerControllerSourceType: any;
|
||||||
|
|
||||||
@ -25,35 +25,6 @@ function openFileAtRootModule(filePath: string): boolean {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export namespace iOSNativeHelper {
|
|
||||||
// TODO: remove for NativeScript 7.0
|
|
||||||
export function getter<T>(_this: any, property: T | { (): T }): T {
|
|
||||||
console.log('utils.ios.getter() is deprecated; use the respective native property instead');
|
|
||||||
if (typeof property === 'function') {
|
|
||||||
return (<{ (): T }>property).call(_this);
|
|
||||||
} else {
|
|
||||||
return <T>property;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace collections {
|
|
||||||
export function jsArrayToNSArray<T>(str: T[]): NSArray<T> {
|
|
||||||
return NSArray.arrayWithArray(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nsArrayToJSArray<T>(a: NSArray<T>): Array<T> {
|
|
||||||
const arr = [];
|
|
||||||
if (a !== undefined) {
|
|
||||||
const count = a.count;
|
|
||||||
for (let i = 0; i < count; i++) {
|
|
||||||
arr.push(a.objectAtIndex(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return arr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function dataDeserialize(nativeData?: any) {
|
export function dataDeserialize(nativeData?: any) {
|
||||||
if (isNullOrUndefined(nativeData)) {
|
if (isNullOrUndefined(nativeData)) {
|
||||||
// some native values will already be js null values
|
// some native values will already be js null values
|
||||||
@ -87,24 +58,81 @@ export namespace iOSNativeHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function dataSerialize(data?: any) {
|
export function dataSerialize(data: any, wrapPrimitives: boolean = false) {
|
||||||
switch (typeof data) {
|
switch (typeof data) {
|
||||||
case 'number':
|
|
||||||
case 'string':
|
case 'string':
|
||||||
case 'boolean':
|
case 'boolean': {
|
||||||
return data;
|
return data;
|
||||||
case 'object':
|
}
|
||||||
if (Array.isArray(data)) {
|
case 'number': {
|
||||||
return NSArray.arrayWithArray(<any>data.map(dataSerialize));
|
const hasDecimals = numberHasDecimals(data);
|
||||||
|
if (numberIs64Bit(data)) {
|
||||||
|
if (hasDecimals) {
|
||||||
|
return NSNumber.alloc().initWithDouble(data);
|
||||||
|
} else {
|
||||||
|
return NSNumber.alloc().initWithLongLong(data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (hasDecimals) {
|
||||||
|
return NSNumber.alloc().initWithFloat(data);
|
||||||
|
} else {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let obj = {};
|
case 'object': {
|
||||||
for (let key of Object.keys(data)) {
|
if (data instanceof Date) {
|
||||||
obj[key] = dataSerialize(data[key]);
|
return NSDate.dateWithTimeIntervalSince1970(data.getTime() / 1000);
|
||||||
}
|
}
|
||||||
return NSDictionary.dictionaryWithDictionary(<any>obj);
|
|
||||||
|
if (!data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(data)) {
|
||||||
|
return NSArray.arrayWithArray((<any>data).map(dataSerialize));
|
||||||
|
}
|
||||||
|
|
||||||
|
let node = {} as any;
|
||||||
|
Object.keys(data).forEach(function (key) {
|
||||||
|
let value = data[key];
|
||||||
|
node[key] = dataSerialize(value, wrapPrimitives);
|
||||||
|
});
|
||||||
|
return NSDictionary.dictionaryWithDictionary(node);
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return NSNull.new();
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace iOSNativeHelper {
|
||||||
|
// TODO: remove for NativeScript 7.0
|
||||||
|
export function getter<T>(_this: any, property: T | { (): T }): T {
|
||||||
|
console.log('utils.ios.getter() is deprecated; use the respective native property instead');
|
||||||
|
if (typeof property === 'function') {
|
||||||
|
return (<{ (): T }>property).call(_this);
|
||||||
|
} else {
|
||||||
|
return <T>property;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export namespace collections {
|
||||||
|
export function jsArrayToNSArray<T>(str: T[]): NSArray<T> {
|
||||||
|
return NSArray.arrayWithArray(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function nsArrayToJSArray<T>(a: NSArray<T>): Array<T> {
|
||||||
|
const arr = [];
|
||||||
|
if (a !== undefined) {
|
||||||
|
const count = a.count;
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
arr.push(a.objectAtIndex(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
packages/core/utils/types.d.ts
vendored
12
packages/core/utils/types.d.ts
vendored
@ -61,6 +61,18 @@ export function isNullOrUndefined(value: any): boolean;
|
|||||||
*/
|
*/
|
||||||
export function verifyCallback(value: any): void;
|
export function verifyCallback(value: any): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the number has decimals
|
||||||
|
* @param value Number to check
|
||||||
|
*/
|
||||||
|
export function numberHasDecimals(value: number): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the number is 64 bit
|
||||||
|
* @param value Number to check
|
||||||
|
*/
|
||||||
|
export function numberIs64Bit(value: number): boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A function that gets the class name of an object.
|
* A function that gets the class name of an object.
|
||||||
* @param object The object.
|
* @param object The object.
|
||||||
|
@ -44,6 +44,14 @@ export function verifyCallback(value: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function numberHasDecimals(value: number): boolean {
|
||||||
|
return !(value % 1 === 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function numberIs64Bit(value: number): boolean {
|
||||||
|
return value < -Math.pow(2, 31) + 1 || value > Math.pow(2, 31) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
const classInfosMap = new Map<Function, ClassInfo>();
|
const classInfosMap = new Map<Function, ClassInfo>();
|
||||||
|
|
||||||
// ES3-5 type classes are "function blah()", new ES6+ classes can be "class blah"
|
// ES3-5 type classes are "function blah()", new ES6+ classes can be "class blah"
|
||||||
|
Reference in New Issue
Block a user