├── .gitignore
├── LICENSE
├── README.md
├── android
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── robinpowered
│ └── react
│ └── vitals
│ ├── RNVitalsModule.java
│ └── RNVitalsPackage.java
├── entry.android.js
├── entry.ios.js
├── index.js
├── ios
├── RNVitals.h
├── RNVitals.m
├── RNVitals.xcodeproj
│ └── project.pbxproj
├── SSMemoryInfo.h
└── SSMemoryInfo.m
├── package.json
├── react-native-vitals.podspec
└── vitals.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | ############
61 | # Android
62 | ############
63 | # Built application files
64 | *.apk
65 | *.ap_
66 |
67 | # Files for the Dalvik VM
68 | *.dex
69 |
70 | # Java class files
71 | *.class
72 |
73 | # Generated files
74 | android/bin/
75 | android/gen/
76 | android/out/
77 |
78 | # Gradle files
79 | android/.gradle/
80 | android/build/
81 |
82 | # Local configuration file (sdk path, etc)
83 | local.properties
84 |
85 | # Proguard folder generated by Eclipse
86 | android/proguard/
87 |
88 | # Log Files
89 | *.log
90 |
91 | # Android Studio Navigation editor temp files
92 | android/.navigation/
93 |
94 | # Android Studio captures folder
95 | android/captures/
96 |
97 | # Intellij
98 | *.iml
99 |
100 | # Keystore files
101 | *.jks
102 |
103 | # Gradle
104 | /build/
105 | /RNTester/android/app/build/
106 | /RNTester/android/app/gradle/
107 | /RNTester/android/app/gradlew
108 | /RNTester/android/app/gradlew.bat
109 | /ReactAndroid/build/
110 |
111 | # Xcode
112 | !**/*.xcodeproj
113 | !**/*.pbxproj
114 | !**/*.xcworkspacedata
115 | !**/*.xcsettings
116 | !**/*.xcscheme
117 | *.pbxuser
118 | !default.pbxuser
119 | *.mode1v3
120 | !default.mode1v3
121 | *.mode2v3
122 | !default.mode2v3
123 | *.perspectivev3
124 | !default.perspectivev3
125 | xcuserdata
126 | *.xccheckout
127 | *.moved-aside
128 | DerivedData
129 | *.hmap
130 | *.ipa
131 | *.xcuserstate
132 | project.xcworkspace
133 |
134 | ################
135 | # JetBrains
136 | ################
137 | .idea
138 |
139 | ## File-based project format:
140 | *.iws
141 |
142 | ## Plugin-specific files:
143 |
144 | # IntelliJ
145 | /out/
146 |
147 | # mpeltonen/sbt-idea plugin
148 | .idea_modules/
149 |
150 | # JIRA plugin
151 | atlassian-ide-plugin.xml
152 |
153 | # Crashlytics plugin (for Android Studio and IntelliJ)
154 | com_crashlytics_export_strings.xml
155 | crashlytics.properties
156 | crashlytics-build.properties
157 | fabric.properties
158 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Ying Hang Eng
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-vitals
2 |
3 | React Native package that provides memory/storage usage info of a device.
4 |
5 | ## Usage
6 | ```javascript
7 | import Vitals from 'react-native-vitals';
8 |
9 | Vitals.getMemory().then(memory => {
10 | var {
11 | appUsed,
12 | systemTotal,
13 | systemFree,
14 | systemUsed
15 | } = memory;
16 | });
17 |
18 | Vitals.getStorage().then(storage => {
19 | var {
20 | total,
21 | free,
22 | used
23 | } = storage;
24 | });
25 |
26 | Vitals.addLowMemoryListener(memory => {
27 | console.log('Low memory warning triggered');
28 | var {
29 | appUsed,
30 | systemTotal,
31 | systemFree,
32 | systemUsed
33 | } = memory;
34 | })
35 | ```
36 |
37 | ## Getting started
38 |
39 | `$ npm install react-native-vitals --save`
40 |
41 | ### Mostly automatic installation
42 |
43 | `$ react-native link react-native-vitals`
44 |
45 | ### Manual installation
46 |
47 |
48 | #### iOS
49 |
50 | 1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`
51 | 2. Go to `node_modules` ➜ `react-native-vitals` and add `RNVitals.xcodeproj`
52 | 3. In XCode, in the project navigator, select your project. Add `libRNVitals.a` to your project's `Build Phases` ➜ `Link Binary With Libraries`
53 | 4. Run your project (`Cmd+R`)
54 |
55 | #### iOS (using [CocoaPods](https://cocoapods.org/))
56 |
57 | Alternatively, you can use CocoaPods to manage your native dependencies, just add this inside your `Podfile`:
58 | ```
59 | pod 'react-native-vitals', :path => '../node_modules/react-native-vitals'
60 | ```
61 |
62 | After adding this, you need to run `pod install` inside the `ios`-folder of your RN application.
63 |
64 | #### Android
65 |
66 | 1. Open up `android/app/src/main/java/[...]/MainActivity.java`
67 | - Add `import com.robinpowered.react.vitals.RNVitalsPackage;` to the imports at the top of the file
68 | - Add `new RNVitalsPackage()` to the list returned by the `getPackages()` method
69 | 2. Append the following lines to `android/settings.gradle`:
70 | ```
71 | include ':react-native-vitals'
72 | project(':react-native-vitals').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vitals/android')
73 | ```
74 | 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:
75 | ```
76 | compile project(':react-native-vitals')
77 | ```
78 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | jcenter()
4 | }
5 |
6 | dependencies {
7 | classpath 'com.android.tools.build:gradle:1.3.1'
8 | }
9 | }
10 |
11 | apply plugin: 'com.android.library'
12 |
13 | def safeExtGet(prop, fallback) {
14 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
15 | }
16 |
17 | android {
18 | compileSdkVersion safeExtGet('compileSdkVersion', '23')
19 | buildToolsVersion safeExtGet('buildToolsVersion', '23.0.1')
20 |
21 | defaultConfig {
22 | minSdkVersion safeExtGet('minSdkVersion', '16')
23 | targetSdkVersion safeExtGet('targetSdkVersion', '22')
24 | versionCode 1
25 | versionName "1.0"
26 | }
27 | lintOptions {
28 | abortOnError false
29 | }
30 | }
31 |
32 | repositories {
33 | mavenCentral()
34 | }
35 |
36 | dependencies {
37 | implementation 'com.facebook.react:react-native:+'
38 | }
39 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/src/main/java/com/robinpowered/react/vitals/RNVitalsModule.java:
--------------------------------------------------------------------------------
1 | package com.robinpowered.react.vitals;
2 |
3 | import android.os.Environment;
4 | import android.os.StatFs;
5 | import android.os.Build;
6 | import android.os.Debug;
7 | import android.content.ComponentCallbacks2;
8 | import android.content.res.Configuration;
9 | import android.app.ActivityManager;
10 | import android.content.Context;
11 |
12 | import com.facebook.react.bridge.LifecycleEventListener;
13 | import com.facebook.react.bridge.ReactApplicationContext;
14 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
15 | import com.facebook.react.bridge.ReactMethod;
16 | import com.facebook.react.bridge.Promise;
17 | import com.facebook.react.bridge.WritableMap;
18 | import com.facebook.react.bridge.Arguments;
19 | import com.facebook.react.modules.core.DeviceEventManagerModule;
20 | import java.util.Map;
21 | import java.util.HashMap;
22 | import javax.annotation.Nullable;
23 |
24 | import java.io.File;
25 |
26 | public class RNVitalsModule extends ReactContextBaseJavaModule implements ComponentCallbacks2, LifecycleEventListener {
27 |
28 | public static final String MODULE_NAME = "RNVitals";
29 | public static final String LOW_MEMORY = "LOW_MEMORY";
30 | public static final String MEMORY_LEVEL_KEY = "MemoryLevel";
31 |
32 | public static final int MEMORY_MODERATE = TRIM_MEMORY_RUNNING_MODERATE;
33 | public static final int MEMORY_LOW = TRIM_MEMORY_RUNNING_LOW;
34 | public static final int MEMORY_CRITICAL = TRIM_MEMORY_RUNNING_CRITICAL;
35 |
36 |
37 | public RNVitalsModule(ReactApplicationContext reactContext) {
38 | super(reactContext);
39 | }
40 |
41 | private double toMB(long num) {
42 | return (double) (num / 1024 / 1024);
43 | }
44 |
45 | @Override
46 | public String getName() {
47 | return MODULE_NAME;
48 | }
49 |
50 | @Override
51 | public @Nullable Map getConstants() {
52 | HashMap memoryLevelConstants = new HashMap();
53 | memoryLevelConstants.put("CRITICAL", MEMORY_CRITICAL);
54 | memoryLevelConstants.put("LOW", MEMORY_LOW);
55 | memoryLevelConstants.put("MODERATE", MEMORY_MODERATE);
56 |
57 | HashMap constants = new HashMap();
58 | constants.put(LOW_MEMORY, LOW_MEMORY);
59 | constants.put(MEMORY_LEVEL_KEY, memoryLevelConstants);
60 |
61 | return constants;
62 | }
63 |
64 | private WritableMap getMemoryInfo() {
65 | ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
66 | ActivityManager activityManager = (ActivityManager) getReactApplicationContext()
67 | .getSystemService(Context.ACTIVITY_SERVICE);
68 | activityManager.getMemoryInfo(mi);
69 |
70 | Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
71 | Debug.getMemoryInfo(memInfo);
72 | long appUsed = memInfo.getTotalPss() * 1024L;
73 |
74 | WritableMap info = Arguments.createMap();
75 | info.putDouble("systemTotal", toMB(mi.totalMem));
76 | info.putDouble("appUsed", toMB(appUsed));
77 | info.putDouble("systemFree", toMB(mi.availMem));
78 | info.putDouble("systemUsed", toMB(mi.totalMem - mi.availMem));
79 | return info;
80 | }
81 |
82 | @Override
83 | public void onTrimMemory(int level) {
84 | ReactApplicationContext context = getReactApplicationContext();
85 | if (context.hasActiveCatalystInstance()) {
86 | WritableMap memoryInfo = getMemoryInfo();
87 | memoryInfo.putInt("memoryLevel", level);
88 | context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(LOW_MEMORY, memoryInfo);
89 | }
90 | }
91 |
92 | @Override
93 | public void onLowMemory() {
94 | // no-op
95 | }
96 |
97 | @Override
98 | public void initialize() {
99 | getReactApplicationContext().addLifecycleEventListener(this);
100 | getReactApplicationContext().registerComponentCallbacks(this);
101 | }
102 |
103 | @Override
104 | public void onHostResume() {
105 | getReactApplicationContext().registerComponentCallbacks(this);
106 | }
107 |
108 | @Override
109 | public void onHostPause() {
110 | getReactApplicationContext().unregisterComponentCallbacks(this);
111 | }
112 |
113 | @Override
114 | public void onHostDestroy() {
115 | getReactApplicationContext().unregisterComponentCallbacks(this);
116 | getReactApplicationContext().removeLifecycleEventListener(this);
117 | }
118 |
119 | @Override
120 | public void onConfigurationChanged(Configuration newConfig) {
121 | // no-op
122 | }
123 |
124 | @ReactMethod
125 | public void getStorage(Promise promise) {
126 | File path = Environment.getDataDirectory();
127 | StatFs stat = new StatFs(path.getPath());
128 |
129 | long totalSpace;
130 | long freeSpace;
131 |
132 | if (Build.VERSION.SDK_INT >= 18) {
133 | totalSpace = stat.getTotalBytes();
134 | freeSpace = stat.getFreeBytes();
135 | } else {
136 | long blockSize = stat.getBlockSize();
137 | totalSpace = blockSize * stat.getBlockCount();
138 | freeSpace = blockSize * stat.getAvailableBlocks();
139 | }
140 |
141 | WritableMap info = Arguments.createMap();
142 | info.putDouble("total", toMB(totalSpace));
143 | info.putDouble("free", toMB(freeSpace));
144 | long usedSpace = totalSpace - freeSpace;
145 | info.putDouble("used", toMB(usedSpace));
146 |
147 | promise.resolve(info);
148 | }
149 |
150 | @ReactMethod
151 | public void getMemory(Promise promise) {
152 | promise.resolve(getMemoryInfo());
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/android/src/main/java/com/robinpowered/react/vitals/RNVitalsPackage.java:
--------------------------------------------------------------------------------
1 | package com.robinpowered.react.vitals;
2 |
3 | import java.util.Arrays;
4 | import java.util.Collections;
5 | import java.util.List;
6 |
7 | import com.facebook.react.ReactPackage;
8 | import com.facebook.react.bridge.NativeModule;
9 | import com.facebook.react.bridge.ReactApplicationContext;
10 | import com.facebook.react.uimanager.ViewManager;
11 | import com.facebook.react.bridge.JavaScriptModule;
12 | public class RNVitalsPackage implements ReactPackage {
13 | @Override
14 | public List createNativeModules(ReactApplicationContext reactContext) {
15 | return Arrays.asList(new RNVitalsModule(reactContext));
16 | }
17 |
18 | // Deprecated from RN 0.47
19 | public List> createJSModules() {
20 | return Collections.emptyList();
21 | }
22 |
23 | @Override
24 | public List createViewManagers(ReactApplicationContext reactContext) {
25 | return Collections.emptyList();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/entry.android.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import Vitals from './vitals';
4 | import {DeviceEventEmitter} from 'react-native';
5 |
6 | export default {
7 | ...Vitals,
8 | // Android overrides
9 | addLowMemoryListener(callback) {
10 | const wrappedCallback = memoryInfo => {
11 | if (memoryInfo.memoryLevel === Vitals.MemoryLevel.CRITICAL) {
12 | callback(memoryInfo);
13 | }
14 | };
15 |
16 | return DeviceEventEmitter.addListener(
17 | Vitals.LOW_MEMORY,
18 | wrappedCallback
19 | );
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/entry.ios.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | export {default} from './vitals';
4 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | export {default} from './entry';
4 |
--------------------------------------------------------------------------------
/ios/RNVitals.h:
--------------------------------------------------------------------------------
1 | #if __has_include()
2 | #import
3 | #elif __has_include("RCTBridgeModule.h")
4 | #import "RCTBridgeModule.h"
5 | #else
6 | #import "React/RCTBridgeModule.h"
7 | #endif
8 |
9 | @interface RNVitals : NSObject
10 | @end
11 |
--------------------------------------------------------------------------------
/ios/RNVitals.m:
--------------------------------------------------------------------------------
1 |
2 | #import "RNVitals.h"
3 | #import "SSMemoryInfo.h"
4 | #import
5 | #import
6 |
7 | // Used to send events to JS
8 | #if __has_include()
9 | #import
10 | #import
11 | #elif __has_include("RCTBridge.h")
12 | #import "RCTBridge.h"
13 | #import "RCTEventDispatcher.h"
14 | #else
15 | #import "React/RCTBridge.h"
16 | #import "React/RCTEventDispatcher.h"
17 | #endif
18 |
19 | @implementation RNVitals
20 |
21 | @synthesize bridge = _bridge;
22 |
23 | static NSString * const LOW_MEMORY = @"LOW_MEMORY";
24 |
25 | - (instancetype)init
26 | {
27 | if ((self = [super init])) {
28 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
29 | }
30 |
31 | return self;
32 |
33 | }
34 |
35 | - (void)dealloc
36 | {
37 | [[NSNotificationCenter defaultCenter] removeObserver:self];
38 | }
39 |
40 | + (BOOL)requiresMainQueueSetup
41 | {
42 | return YES;
43 | }
44 |
45 | + (NSDictionary *)getMemoryInfo
46 | {
47 | struct mach_task_basic_info info;
48 | mach_msg_type_number_t size = sizeof(info);
49 | kern_return_t kerr = task_info(mach_task_self(),
50 | MACH_TASK_BASIC_INFO,
51 | (task_info_t)&info,
52 | &size);
53 |
54 | if (kerr != KERN_SUCCESS) {
55 | return nil;
56 | }
57 |
58 | double appUsed = (double) info.resident_size / 1024 / 1024;
59 |
60 | return @{
61 | @"systemTotal": @([SSMemoryInfo totalMemory]),
62 | @"appUsed": @(appUsed),
63 | @"systemUsed": @([SSMemoryInfo usedMemory:NO]),
64 | @"systemFree": @([SSMemoryInfo freeMemory:NO]),
65 | @"systemActive": @([SSMemoryInfo activeMemory:NO]),
66 | @"systemInactive": @([SSMemoryInfo inactiveMemory:NO]),
67 | @"systemWired": @([SSMemoryInfo wiredMemory:NO]),
68 | @"systemPurgable": @([SSMemoryInfo purgableMemory:NO])
69 | };
70 | }
71 |
72 | - (void)applicationDidReceiveMemoryWarning:(NSNotification *)notification
73 | {
74 | NSDictionary *memoryInfo = [RNVitals getMemoryInfo];
75 | [_bridge.eventDispatcher sendDeviceEventWithName:LOW_MEMORY
76 | body:memoryInfo];
77 | }
78 |
79 | RCT_EXPORT_MODULE()
80 |
81 | - (NSDictionary *)constantsToExport
82 | {
83 | return @{ @"LOW_MEMORY": LOW_MEMORY };
84 | }
85 |
86 | RCT_EXPORT_METHOD(getStorage:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
87 | {
88 | unsigned long long totalSpace = 0;
89 | unsigned long long totalFreeSpace = 0;
90 |
91 | __autoreleasing NSError *error = nil;
92 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
93 | NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error:&error];
94 |
95 | if (dictionary) {
96 | NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
97 | NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize];
98 | totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
99 | totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
100 | double used = (double) totalSpace - totalFreeSpace;
101 | resolve(@{
102 | @"total": @((double) totalSpace / 1024 / 1024),
103 | @"free": @((double) totalFreeSpace / 1024 / 1024),
104 | @"used": @(used / 1024 / 1024)
105 | });
106 | } else {
107 | reject(@"not-support", @"An error happened", nil);
108 | }
109 | }
110 |
111 | RCT_EXPORT_METHOD(getMemory:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
112 | {
113 | NSDictionary *memoryInfo = [RNVitals getMemoryInfo];
114 | if (memoryInfo == nil) {
115 | reject(@"not-support", @"An error happened", nil);
116 | } else {
117 | resolve(memoryInfo);
118 | }
119 |
120 | }
121 |
122 | @end
123 |
--------------------------------------------------------------------------------
/ios/RNVitals.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 909820951FCDB62700A7617D /* SSMemoryInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 909820931FCDB62700A7617D /* SSMemoryInfo.m */; };
11 | B3E7B58A1CC2AC0600A0062D /* RNVitals.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNVitals.m */; };
12 | /* End PBXBuildFile section */
13 |
14 | /* Begin PBXCopyFilesBuildPhase section */
15 | 58B511D91A9E6C8500147676 /* CopyFiles */ = {
16 | isa = PBXCopyFilesBuildPhase;
17 | buildActionMask = 2147483647;
18 | dstPath = "include/$(PRODUCT_NAME)";
19 | dstSubfolderSpec = 16;
20 | files = (
21 | );
22 | runOnlyForDeploymentPostprocessing = 0;
23 | };
24 | /* End PBXCopyFilesBuildPhase section */
25 |
26 | /* Begin PBXFileReference section */
27 | 134814201AA4EA6300B7C361 /* libRNVitals.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNVitals.a; sourceTree = BUILT_PRODUCTS_DIR; };
28 | 909820931FCDB62700A7617D /* SSMemoryInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSMemoryInfo.m; sourceTree = ""; };
29 | 909820941FCDB62700A7617D /* SSMemoryInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSMemoryInfo.h; sourceTree = ""; };
30 | B3E7B5881CC2AC0600A0062D /* RNVitals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNVitals.h; sourceTree = ""; };
31 | B3E7B5891CC2AC0600A0062D /* RNVitals.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNVitals.m; sourceTree = ""; };
32 | /* End PBXFileReference section */
33 |
34 | /* Begin PBXFrameworksBuildPhase section */
35 | 58B511D81A9E6C8500147676 /* Frameworks */ = {
36 | isa = PBXFrameworksBuildPhase;
37 | buildActionMask = 2147483647;
38 | files = (
39 | );
40 | runOnlyForDeploymentPostprocessing = 0;
41 | };
42 | /* End PBXFrameworksBuildPhase section */
43 |
44 | /* Begin PBXGroup section */
45 | 134814211AA4EA7D00B7C361 /* Products */ = {
46 | isa = PBXGroup;
47 | children = (
48 | 134814201AA4EA6300B7C361 /* libRNVitals.a */,
49 | );
50 | name = Products;
51 | sourceTree = "";
52 | };
53 | 58B511D21A9E6C8500147676 = {
54 | isa = PBXGroup;
55 | children = (
56 | B3E7B5881CC2AC0600A0062D /* RNVitals.h */,
57 | 909820941FCDB62700A7617D /* SSMemoryInfo.h */,
58 | 909820931FCDB62700A7617D /* SSMemoryInfo.m */,
59 | B3E7B5891CC2AC0600A0062D /* RNVitals.m */,
60 | 134814211AA4EA7D00B7C361 /* Products */,
61 | );
62 | sourceTree = "";
63 | };
64 | /* End PBXGroup section */
65 |
66 | /* Begin PBXNativeTarget section */
67 | 58B511DA1A9E6C8500147676 /* RNVitals */ = {
68 | isa = PBXNativeTarget;
69 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNVitals" */;
70 | buildPhases = (
71 | 58B511D71A9E6C8500147676 /* Sources */,
72 | 58B511D81A9E6C8500147676 /* Frameworks */,
73 | 58B511D91A9E6C8500147676 /* CopyFiles */,
74 | );
75 | buildRules = (
76 | );
77 | dependencies = (
78 | );
79 | name = RNVitals;
80 | productName = RCTDataManager;
81 | productReference = 134814201AA4EA6300B7C361 /* libRNVitals.a */;
82 | productType = "com.apple.product-type.library.static";
83 | };
84 | /* End PBXNativeTarget section */
85 |
86 | /* Begin PBXProject section */
87 | 58B511D31A9E6C8500147676 /* Project object */ = {
88 | isa = PBXProject;
89 | attributes = {
90 | LastUpgradeCheck = 0830;
91 | ORGANIZATIONNAME = Facebook;
92 | TargetAttributes = {
93 | 58B511DA1A9E6C8500147676 = {
94 | CreatedOnToolsVersion = 6.1.1;
95 | };
96 | };
97 | };
98 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNVitals" */;
99 | compatibilityVersion = "Xcode 3.2";
100 | developmentRegion = English;
101 | hasScannedForEncodings = 0;
102 | knownRegions = (
103 | en,
104 | );
105 | mainGroup = 58B511D21A9E6C8500147676;
106 | productRefGroup = 58B511D21A9E6C8500147676;
107 | projectDirPath = "";
108 | projectRoot = "";
109 | targets = (
110 | 58B511DA1A9E6C8500147676 /* RNVitals */,
111 | );
112 | };
113 | /* End PBXProject section */
114 |
115 | /* Begin PBXSourcesBuildPhase section */
116 | 58B511D71A9E6C8500147676 /* Sources */ = {
117 | isa = PBXSourcesBuildPhase;
118 | buildActionMask = 2147483647;
119 | files = (
120 | 909820951FCDB62700A7617D /* SSMemoryInfo.m in Sources */,
121 | B3E7B58A1CC2AC0600A0062D /* RNVitals.m in Sources */,
122 | );
123 | runOnlyForDeploymentPostprocessing = 0;
124 | };
125 | /* End PBXSourcesBuildPhase section */
126 |
127 | /* Begin XCBuildConfiguration section */
128 | 58B511ED1A9E6C8500147676 /* Debug */ = {
129 | isa = XCBuildConfiguration;
130 | buildSettings = {
131 | ALWAYS_SEARCH_USER_PATHS = NO;
132 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
133 | CLANG_CXX_LIBRARY = "libc++";
134 | CLANG_ENABLE_MODULES = YES;
135 | CLANG_ENABLE_OBJC_ARC = YES;
136 | CLANG_WARN_BOOL_CONVERSION = YES;
137 | CLANG_WARN_CONSTANT_CONVERSION = YES;
138 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
139 | CLANG_WARN_EMPTY_BODY = YES;
140 | CLANG_WARN_ENUM_CONVERSION = YES;
141 | CLANG_WARN_INFINITE_RECURSION = YES;
142 | CLANG_WARN_INT_CONVERSION = YES;
143 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
144 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
145 | CLANG_WARN_UNREACHABLE_CODE = YES;
146 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
147 | COPY_PHASE_STRIP = NO;
148 | ENABLE_STRICT_OBJC_MSGSEND = YES;
149 | ENABLE_TESTABILITY = YES;
150 | GCC_C_LANGUAGE_STANDARD = gnu99;
151 | GCC_DYNAMIC_NO_PIC = NO;
152 | GCC_NO_COMMON_BLOCKS = YES;
153 | GCC_OPTIMIZATION_LEVEL = 0;
154 | GCC_PREPROCESSOR_DEFINITIONS = (
155 | "DEBUG=1",
156 | "$(inherited)",
157 | );
158 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
159 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
160 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
161 | GCC_WARN_UNDECLARED_SELECTOR = YES;
162 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
163 | GCC_WARN_UNUSED_FUNCTION = YES;
164 | GCC_WARN_UNUSED_VARIABLE = YES;
165 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
166 | MTL_ENABLE_DEBUG_INFO = YES;
167 | ONLY_ACTIVE_ARCH = YES;
168 | SDKROOT = iphoneos;
169 | };
170 | name = Debug;
171 | };
172 | 58B511EE1A9E6C8500147676 /* Release */ = {
173 | isa = XCBuildConfiguration;
174 | buildSettings = {
175 | ALWAYS_SEARCH_USER_PATHS = NO;
176 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
177 | CLANG_CXX_LIBRARY = "libc++";
178 | CLANG_ENABLE_MODULES = YES;
179 | CLANG_ENABLE_OBJC_ARC = YES;
180 | CLANG_WARN_BOOL_CONVERSION = YES;
181 | CLANG_WARN_CONSTANT_CONVERSION = YES;
182 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
183 | CLANG_WARN_EMPTY_BODY = YES;
184 | CLANG_WARN_ENUM_CONVERSION = YES;
185 | CLANG_WARN_INFINITE_RECURSION = YES;
186 | CLANG_WARN_INT_CONVERSION = YES;
187 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
188 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
189 | CLANG_WARN_UNREACHABLE_CODE = YES;
190 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
191 | COPY_PHASE_STRIP = YES;
192 | ENABLE_NS_ASSERTIONS = NO;
193 | ENABLE_STRICT_OBJC_MSGSEND = YES;
194 | GCC_C_LANGUAGE_STANDARD = gnu99;
195 | GCC_NO_COMMON_BLOCKS = YES;
196 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
197 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
198 | GCC_WARN_UNDECLARED_SELECTOR = YES;
199 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
200 | GCC_WARN_UNUSED_FUNCTION = YES;
201 | GCC_WARN_UNUSED_VARIABLE = YES;
202 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
203 | MTL_ENABLE_DEBUG_INFO = NO;
204 | SDKROOT = iphoneos;
205 | VALIDATE_PRODUCT = YES;
206 | };
207 | name = Release;
208 | };
209 | 58B511F01A9E6C8500147676 /* Debug */ = {
210 | isa = XCBuildConfiguration;
211 | buildSettings = {
212 | HEADER_SEARCH_PATHS = (
213 | "$(inherited)",
214 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
215 | "$(SRCROOT)/../../../React/**",
216 | "$(SRCROOT)/../../react-native/React/**",
217 | );
218 | LIBRARY_SEARCH_PATHS = "$(inherited)";
219 | OTHER_LDFLAGS = "-ObjC";
220 | PRODUCT_NAME = RNVitals;
221 | SKIP_INSTALL = YES;
222 | };
223 | name = Debug;
224 | };
225 | 58B511F11A9E6C8500147676 /* Release */ = {
226 | isa = XCBuildConfiguration;
227 | buildSettings = {
228 | HEADER_SEARCH_PATHS = (
229 | "$(inherited)",
230 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
231 | "$(SRCROOT)/../../../React/**",
232 | "$(SRCROOT)/../../react-native/React/**",
233 | );
234 | LIBRARY_SEARCH_PATHS = "$(inherited)";
235 | OTHER_LDFLAGS = "-ObjC";
236 | PRODUCT_NAME = RNVitals;
237 | SKIP_INSTALL = YES;
238 | };
239 | name = Release;
240 | };
241 | /* End XCBuildConfiguration section */
242 |
243 | /* Begin XCConfigurationList section */
244 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNVitals" */ = {
245 | isa = XCConfigurationList;
246 | buildConfigurations = (
247 | 58B511ED1A9E6C8500147676 /* Debug */,
248 | 58B511EE1A9E6C8500147676 /* Release */,
249 | );
250 | defaultConfigurationIsVisible = 0;
251 | defaultConfigurationName = Release;
252 | };
253 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNVitals" */ = {
254 | isa = XCConfigurationList;
255 | buildConfigurations = (
256 | 58B511F01A9E6C8500147676 /* Debug */,
257 | 58B511F11A9E6C8500147676 /* Release */,
258 | );
259 | defaultConfigurationIsVisible = 0;
260 | defaultConfigurationName = Release;
261 | };
262 | /* End XCConfigurationList section */
263 | };
264 | rootObject = 58B511D31A9E6C8500147676 /* Project object */;
265 | }
266 |
--------------------------------------------------------------------------------
/ios/SSMemoryInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // SSMemoryInfo.h
3 | // SystemServicesDemo
4 | //
5 | // Created by Shmoopi LLC on 9/19/12.
6 | // Copyright (c) 2012 Shmoopi LLC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface SSMemoryInfo : NSObject
12 |
13 | // Memory Information
14 |
15 | // Total Memory
16 | + (double)totalMemory;
17 |
18 | // Free Memory
19 | + (double)freeMemory:(BOOL)inPercent;
20 |
21 | // Used Memory
22 | + (double)usedMemory:(BOOL)inPercent;
23 |
24 | // Active Memory
25 | + (double)activeMemory:(BOOL)inPercent;
26 |
27 | // Inactive Memory
28 | + (double)inactiveMemory:(BOOL)inPercent;
29 |
30 | // Wired Memory
31 | + (double)wiredMemory:(BOOL)inPercent;
32 |
33 | // Purgable Memory
34 | + (double)purgableMemory:(BOOL)inPercent;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/ios/SSMemoryInfo.m:
--------------------------------------------------------------------------------
1 | //
2 | // SSMemoryInfo.m
3 | // SystemServicesDemo
4 | //
5 | // Created by Shmoopi LLC on 9/19/12.
6 | // Copyright (c) 2012 Shmoopi LLC. All rights reserved.
7 | //
8 |
9 | #import "SSMemoryInfo.h"
10 |
11 | // stat
12 | #import
13 |
14 | // mach
15 | #import
16 |
17 | @implementation SSMemoryInfo
18 |
19 | // Total Memory
20 | + (double)totalMemory {
21 | // Find the total amount of memory
22 | @try {
23 | // Set up the variables
24 | double totalMemory = 0.00;
25 | double allMemory = [[NSProcessInfo processInfo] physicalMemory];
26 |
27 | // Total Memory (formatted)
28 | totalMemory = (allMemory / 1024.0) / 1024.0;
29 |
30 | // Round to the nearest multiple of 256mb - Almost all RAM is a multiple of 256mb (I do believe)
31 | int toNearest = 256;
32 | int remainder = (int)totalMemory % toNearest;
33 |
34 | if (remainder >= toNearest / 2) {
35 | // Round the final number up
36 | totalMemory = ((int)totalMemory - remainder) + 256;
37 | } else {
38 | // Round the final number down
39 | totalMemory = (int)totalMemory - remainder;
40 | }
41 |
42 | // Check to make sure it's valid
43 | if (totalMemory <= 0) {
44 | // Error, invalid memory value
45 | return -1;
46 | }
47 |
48 | // Completed Successfully
49 | return totalMemory;
50 | }
51 | @catch (NSException *exception) {
52 | // Error
53 | return -1;
54 | }
55 | }
56 |
57 | // Free Memory
58 | + (double)freeMemory:(BOOL)inPercent {
59 | // Find the total amount of free memory
60 | @try {
61 | // Set up the variables
62 | double totalMemory = 0.00;
63 | vm_statistics_data_t vmStats;
64 | mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
65 | kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount);
66 |
67 | if(kernReturn != KERN_SUCCESS) {
68 | return -1;
69 | }
70 |
71 | // Check if the user wants it in percent
72 | if (inPercent) {
73 | // Percent
74 | // Convert to doubles
75 | double fm = [self totalMemory];
76 | double am = ((vm_page_size * vmStats.free_count) / 1024.0) / 1024.0;
77 | // Get the percent
78 | totalMemory = (am * 100) / fm;
79 | } else {
80 | // Not in percent
81 | // Total Memory (formatted)
82 | totalMemory = ((vm_page_size * vmStats.free_count) / 1024.0) / 1024.0;
83 | }
84 |
85 | // Check to make sure it's valid
86 | if (totalMemory <= 0) {
87 | // Error, invalid memory value
88 | return -1;
89 | }
90 |
91 | // Completed Successfully
92 | return totalMemory;
93 | }
94 | @catch (NSException *exception) {
95 | // Error
96 | return -1;
97 | }
98 | }
99 |
100 | // Used Memory
101 | + (double)usedMemory:(BOOL)inPercent {
102 | // Find the total amount of used memory
103 | @try {
104 | // Set up the variables
105 | double totalUsedMemory = 0.00;
106 | mach_port_t host_port;
107 | mach_msg_type_number_t host_size;
108 | vm_size_t pagesize;
109 |
110 | // Get the variable values
111 | host_port = mach_host_self();
112 | host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
113 | host_page_size(host_port, &pagesize);
114 |
115 | vm_statistics_data_t vm_stat;
116 |
117 | // Check for any system errors
118 | if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
119 | // Error, failed to get Virtual memory info
120 | return -1;
121 | }
122 |
123 | // Memory statistics in bytes
124 | natural_t usedMemory = (natural_t)((vm_stat.active_count +
125 | vm_stat.inactive_count +
126 | vm_stat.wire_count) * pagesize);
127 | natural_t allMemory = [self totalMemory];
128 |
129 | // Check if the user wants it in percent
130 | if (inPercent) {
131 | // Percent
132 | // Convert to doubles
133 | double um = (usedMemory /1024) / 1024;
134 | double am = allMemory;
135 | // Get the percent
136 | totalUsedMemory = (um * 100) / am;
137 | } else {
138 | // Not in percent
139 | // Total Used Memory (formatted)
140 | totalUsedMemory = (usedMemory / 1024.0) / 1024.0;
141 | }
142 |
143 | // Check to make sure it's valid
144 | if (totalUsedMemory <= 0) {
145 | // Error, invalid memory value
146 | return -1;
147 | }
148 |
149 | // Completed Successfully
150 | return totalUsedMemory;
151 | }
152 | @catch (NSException *exception) {
153 | // Error
154 | return -1;
155 | }
156 | }
157 |
158 | // Active Memory
159 | + (double)activeMemory:(BOOL)inPercent {
160 | // Find the Active memory
161 | @try {
162 | // Set up the variables
163 | double totalMemory = 0.00;
164 | mach_port_t host_port;
165 | mach_msg_type_number_t host_size;
166 | vm_size_t pagesize;
167 |
168 | // Get the variable values
169 | host_port = mach_host_self();
170 | host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
171 | host_page_size(host_port, &pagesize);
172 |
173 | vm_statistics_data_t vm_stat;
174 |
175 | // Check for any system errors
176 | if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
177 | // Error, failed to get Virtual memory info
178 | return -1;
179 | }
180 |
181 | // Check if the user wants it in percent
182 | if (inPercent) {
183 | // Percent
184 | // Convert to doubles
185 | double FM = [self totalMemory];
186 | double AM = ((vm_stat.active_count * pagesize) / 1024.0) / 1024.0;
187 | // Get the percent
188 | totalMemory = (AM * 100) / FM;
189 | } else {
190 | // Not in percent
191 | // Total Memory (formatted)
192 | totalMemory = ((vm_stat.active_count * pagesize) / 1024.0) / 1024.0;
193 | }
194 |
195 | // Check to make sure it's valid
196 | if (totalMemory <= 0) {
197 | // Error, invalid memory value
198 | return -1;
199 | }
200 |
201 | // Completed Successfully
202 | return totalMemory;
203 | }
204 | @catch (NSException *exception) {
205 | // Error
206 | return -1;
207 | }
208 | }
209 |
210 | // Inactive Memory
211 | + (double)inactiveMemory:(BOOL)inPercent {
212 | // Find the Inactive memory
213 | @try {
214 | // Set up the variables
215 | double totalMemory = 0.00;
216 | mach_port_t host_port;
217 | mach_msg_type_number_t host_size;
218 | vm_size_t pagesize;
219 |
220 | // Get the variable values
221 | host_port = mach_host_self();
222 | host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
223 | host_page_size(host_port, &pagesize);
224 |
225 | vm_statistics_data_t vm_stat;
226 |
227 | // Check for any system errors
228 | if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
229 | // Error, failed to get Virtual memory info
230 | return -1;
231 | }
232 |
233 | // Check if the user wants it in percent
234 | if (inPercent) {
235 | // Percent
236 | // Convert to doubles
237 | double FM = [self totalMemory];
238 | double AM = ((vm_stat.inactive_count * pagesize) / 1024.0) / 1024.0;
239 | // Get the percent
240 | totalMemory = (AM * 100) / FM;
241 | } else {
242 | // Not in percent
243 | // Total Memory (formatted)
244 | totalMemory = ((vm_stat.inactive_count * pagesize) / 1024.0) / 1024.0;
245 | }
246 |
247 | // Check to make sure it's valid
248 | if (totalMemory <= 0) {
249 | // Error, invalid memory value
250 | return -1;
251 | }
252 |
253 | // Completed Successfully
254 | return totalMemory;
255 | }
256 | @catch (NSException *exception) {
257 | // Error
258 | return -1;
259 | }
260 | }
261 |
262 | // Wired Memory
263 | + (double)wiredMemory:(BOOL)inPercent {
264 | // Find the Wired memory
265 | @try {
266 | // Set up the variables
267 | double totalMemory = 0.00;
268 | mach_port_t host_port;
269 | mach_msg_type_number_t host_size;
270 | vm_size_t pagesize;
271 |
272 | // Get the variable values
273 | host_port = mach_host_self();
274 | host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
275 | host_page_size(host_port, &pagesize);
276 |
277 | vm_statistics_data_t vm_stat;
278 |
279 | // Check for any system errors
280 | if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
281 | // Error, failed to get Virtual memory info
282 | return -1;
283 | }
284 |
285 | // Check if the user wants it in percent
286 | if (inPercent) {
287 | // Percent
288 | // Convert to doubles
289 | double FM = [self totalMemory];
290 | double AM = ((vm_stat.wire_count * pagesize) / 1024.0) / 1024.0;
291 | // Get the percent
292 | totalMemory = (AM * 100) / FM;
293 | } else {
294 | // Not in percent
295 | // Total Memory (formatted)
296 | totalMemory = ((vm_stat.wire_count * pagesize) / 1024.0) / 1024.0;
297 | }
298 |
299 | // Check to make sure it's valid
300 | if (totalMemory <= 0) {
301 | // Error, invalid memory value
302 | return -1;
303 | }
304 |
305 | // Completed Successfully
306 | return totalMemory;
307 | }
308 | @catch (NSException *exception) {
309 | // Error
310 | return -1;
311 | }
312 | }
313 |
314 | // Purgable Memory
315 | + (double)purgableMemory:(BOOL)inPercent {
316 | // Find the Purgable memory
317 | @try {
318 | // Set up the variables
319 | double totalMemory = 0.00;
320 | mach_port_t host_port;
321 | mach_msg_type_number_t host_size;
322 | vm_size_t pagesize;
323 |
324 | // Get the variable values
325 | host_port = mach_host_self();
326 | host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t);
327 | host_page_size(host_port, &pagesize);
328 |
329 | vm_statistics_data_t vm_stat;
330 |
331 | // Check for any system errors
332 | if (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size) != KERN_SUCCESS) {
333 | // Error, failed to get Virtual memory info
334 | return -1;
335 | }
336 |
337 | // Check if the user wants it in percent
338 | if (inPercent) {
339 | // Percent
340 | // Convert to doubles
341 | double fm = [self totalMemory];
342 | double am = ((vm_stat.purgeable_count * pagesize) / 1024.0) / 1024.0;
343 | // Get the percent
344 | totalMemory = (am * 100) / fm;
345 | } else {
346 | // Not in percent
347 | // Total Memory (formatted)
348 | totalMemory = ((vm_stat.purgeable_count * pagesize) / 1024.0) / 1024.0;
349 | }
350 |
351 | // Check to make sure it's valid
352 | if (totalMemory <= 0) {
353 | // Error, invalid memory value
354 | return -1;
355 | }
356 |
357 | // Completed Successfully
358 | return totalMemory;
359 | }
360 | @catch (NSException *exception) {
361 | // Error
362 | return -1;
363 | }
364 | }
365 |
366 | @end
367 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-vitals",
3 | "version": "2.0.0",
4 | "description": "Memory and resource information Native Module for React Native",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "keywords": [
10 | "react-native",
11 | "memory",
12 | "storage"
13 | ],
14 | "author": {
15 | "name" : "Robin Powered",
16 | "email" : "engineering@robinpowered.com",
17 | "url" : "https://robinpowered.com"
18 | },
19 | "license": "MIT",
20 | "homepage": "https://github.com/robinpowered/react-native-vitals",
21 | "repository": {
22 | "type" : "git",
23 | "url" : "https://github.com/robinpowered/react-native-vitals.git"
24 | },
25 | "devDependencies": {
26 | "react-native": ">=0.27"
27 | },
28 | "peerDependencies": {
29 | "react-native": ">=0.27"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/react-native-vitals.podspec:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4 |
5 | Pod::Spec.new do |s|
6 | s.name = package['name']
7 | s.version = package['version']
8 | s.summary = package['description']
9 | s.license = package['license']
10 | s.homepage = package['homepage']
11 | s.author = { package['author']['name'] => package['author']['email'] }
12 | s.source = { :git => package['repository']['url'], :tag => "v#{s.version}" }
13 | s.source_files = 'ios/*.{h,m}'
14 | s.platform = :ios, '8.0'
15 |
16 | s.dependency 'React'
17 | end
18 |
--------------------------------------------------------------------------------
/vitals.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import {
4 | DeviceEventEmitter,
5 | NativeModules
6 | } from 'react-native';
7 |
8 | const {RNVitals} = NativeModules;
9 |
10 | export default {
11 | ...RNVitals,
12 | addLowMemoryListener (callback) {
13 | return DeviceEventEmitter.addListener(
14 | RNVitals.LOW_MEMORY,
15 | callback
16 | );
17 | }
18 | };
19 |
--------------------------------------------------------------------------------