Skip to content

Commit 4a17a2a

Browse files
authored
Release/8.2.6 (#274)
* Feature/private views (#57) * ✨ add private views for iOS * ✨ add setting private views for android * ✨ add automated link scripts to add the Instabug maven repo to the project level build.gradle * Feature/network logging (#26) * ✨ add networkDataObfuscationHandler and setRequestFilterPredicate * ✨ add XMLHttpRequest network interceptor * ✨ add setOnProgressForRequestHandler * ✨ add network log support for iOS * 📝 Move all network logging APIs to a separate NetworkLogger module * ✨ Enable network logging by default * ✨ Add typescript type defs for the NetworkLogger module * Add network logging guide to the README * ⬆️ update Android native SDK
1 parent 77c6dcc commit 4a17a2a

14 files changed

+580
-9
lines changed

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ pod install
139139
react-native link instabug-reactnative
140140
```
141141
142-
### Upgrading from 8.0.3 to 8.x
142+
### Upgrading in version 8
143143
144-
When upgrading from 8.0.3 to 8.x, please make sure you do the following steps:
144+
When doing an upgrade in these two cases, from 8.0.3 to 8.x or from an older version than 8.2.6 to 8.2.6 or higher, please make sure you do the following steps:
145145
146146
1. Unlink the project before upgrading to the new version
147147
```bash
@@ -197,6 +197,18 @@ export INSTABUG_APP_TOKEN="YOUR_APP_TOKEN"
197197
bash "../node_modules/instabug-reactnative/ios/upload_sourcemap.sh"
198198
```
199199
200+
## Network Logging
201+
202+
Instabug network logging is enabled by default. It intercepts any requests performed with `fetch` or `XMLHttpRequest` and attaches them to the report that will be sent to the dashboard. To disable network logs:
203+
204+
```javascript
205+
import { NetworkLogger } from 'instabug-reactnative';
206+
```
207+
208+
```javascript
209+
NetworkLogger.setEnabled(false);
210+
```
211+
200212
## Documentation
201213
202214
For more details about the supported APIs and how to use them, check our [**Documentation**](https://docs.instabug.com/docs/react-native-overview).

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ android {
2525

2626
dependencies {
2727
implementation 'com.facebook.react:react-native:+'
28-
api ('com.instabug.library:instabug:8.2.2'){
28+
api ('com.instabug.library:instabug:8.2.2.0'){
2929
exclude group: 'com.android.support:appcompat-v7'
3030
}
3131
}

android/src/main/java/com/instabug/reactlibrary/RNInstabugReactnativeModule.java

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.facebook.react.bridge.ReactMethod;
1313
import com.facebook.react.bridge.ReadableArray;
1414
import com.facebook.react.bridge.ReadableMap;
15+
import com.facebook.react.bridge.ReadableType;
1516
import com.facebook.react.bridge.WritableArray;
1617
import com.facebook.react.bridge.WritableNativeArray;
1718
import com.facebook.react.bridge.WritableMap;
@@ -73,6 +74,8 @@
7374
import java.util.Locale;
7475
import java.util.Map;
7576

77+
import static com.instabug.reactlibrary.utils.InstabugUtil.getMethod;
78+
7679

7780
/**
7881
* The type Rn instabug reactnative module.
@@ -490,7 +493,7 @@ public void setCrashReportingEnabled(boolean isEnabled) {
490493
private void sendJSCrashByReflection(String exceptionObject, boolean isHandled) {
491494
try {
492495
JSONObject newJSONObject = new JSONObject(exceptionObject);
493-
Method method = InstabugUtil.getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class);
496+
Method method = getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class);
494497
if (method != null) {
495498
method.invoke(null, newJSONObject, isHandled);
496499
}
@@ -1885,6 +1888,53 @@ public void setEmailFieldRequiredForFeatureRequests(boolean isEmailRequired, Rea
18851888
}
18861889
}
18871890

1891+
/**
1892+
* Extracts HTTP connection properties. Request method, Headers, Date, Url and Response code
1893+
*
1894+
* @param jsonObject the JSON object containing all HTTP connection properties
1895+
* @throws JSONException
1896+
*/
1897+
@ReactMethod
1898+
public void networkLog(String jsonObject) throws JSONException {
1899+
NetworkLog networkLog = new NetworkLog();
1900+
String date = System.currentTimeMillis()+"";
1901+
networkLog.setDate(date);
1902+
JSONObject newJSONObject = new JSONObject(jsonObject);
1903+
networkLog.setUrl(newJSONObject.getString("url"));
1904+
networkLog.setRequest(newJSONObject.getString("requestBody"));
1905+
networkLog.setResponse(newJSONObject.getString("responseBody"));
1906+
networkLog.setMethod(newJSONObject.getString("method"));
1907+
networkLog.setResponseCode(newJSONObject.getInt("responseCode"));
1908+
networkLog.setRequestHeaders(newJSONObject.getString("requestHeaders"));
1909+
networkLog.setResponseHeaders(newJSONObject.getString("responseHeaders"));
1910+
networkLog.insert();
1911+
}
1912+
1913+
1914+
@ReactMethod
1915+
public void setSecureViews(ReadableArray ids) {
1916+
int[] arrayOfIds = new int[ids.size()];
1917+
for (int i = 0; i < ids.size(); i++) {
1918+
int viewId = (int) ids.getDouble(i);
1919+
arrayOfIds[i] = viewId;
1920+
}
1921+
Method method = null;
1922+
try {
1923+
method = InstabugUtil.getMethod(Class.forName("com.instabug.library.Instabug"), "setSecureViewsId", int[].class);
1924+
} catch (ClassNotFoundException e) {
1925+
e.printStackTrace();
1926+
}
1927+
if (method != null) {
1928+
try {
1929+
method.invoke(null, arrayOfIds);
1930+
} catch (IllegalAccessException e) {
1931+
e.printStackTrace();
1932+
} catch (InvocationTargetException e) {
1933+
e.printStackTrace();
1934+
}
1935+
}
1936+
}
1937+
18881938
private InstabugCustomTextPlaceHolder.Key getStringToKeyConstant(String key) {
18891939
switch (key) {
18901940
case SHAKE_HINT:

index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ export namespace Surveys {
112112
): void;
113113
function setShouldShowWelcomeScreen(shouldShowWelcomeScreen: boolean): void;
114114
}
115+
export namespace NetworkLogger {
116+
function setEnabled(isEnabled: boolean): void;
117+
function setNetworkDataObfuscationHandler(handler: () => void): void;
118+
function setRequestFilterExpression(expression: string): void;
119+
function setProgressHandlerForRequest(handler: () => void): void;
120+
}
115121
export function startWithToken(
116122
token: string,
117123
invocationEvent: invocationEvent[]

index.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
NativeAppEventEmitter,
44
DeviceEventEmitter,
55
Platform,
6+
findNodeHandle,
67
processColor
78
} from 'react-native';
89
let { Instabug } = NativeModules;
@@ -13,8 +14,10 @@ import FeatureRequests from './modules/FeatureRequests';
1314
import Chats from './modules/Chats';
1415
import Replies from './modules/Replies';
1516
import CrashReporting from './modules/CrashReporting';
17+
import NetworkLogger from './modules/NetworkLogger';
1618

1719
captureJsErrors();
20+
NetworkLogger.setEnabled(true);
1821

1922
/**
2023
* Instabug
@@ -220,7 +223,7 @@ const InstabugModule = {
220223
* @param {color} primaryColor A color to set the UI elements of the SDK to.
221224
*/
222225
setPrimaryColor: function(primaryColor) {
223-
Instabug.setPrimaryColor(primaryColor);
226+
Instabug.setPrimaryColor(processColor(primaryColor));
224227
},
225228

226229
/**
@@ -692,6 +695,18 @@ const InstabugModule = {
692695
}
693696
},
694697

698+
/**
699+
* Hides component from screenshots, screen recordings and view hierarchy.
700+
* @param {Object} viewRef the ref of the component to hide
701+
*/
702+
setPrivateView: function(viewRef) {
703+
const nativeTag = findNodeHandle(viewRef);
704+
if (Platform.OS === 'ios') {
705+
Instabug.hideView(nativeTag);
706+
} else {
707+
Instabug.setSecureViews([nativeTag]);
708+
}
709+
},
695710
/**
696711
* Shows default Instabug prompt.
697712
*/
@@ -960,7 +975,8 @@ export {
960975
FeatureRequests,
961976
Chats,
962977
Replies,
963-
CrashReporting
964-
}
978+
CrashReporting,
979+
NetworkLogger
980+
};
965981

966982
export default InstabugModule;

ios/RNInstabug/InstabugReactBridge.m

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#import <React/RCTLog.h>
1515
#import <os/log.h>
1616
#import <Instabug/IBGTypes.h>
17+
#import <React/RCTUIManager.h>
1718

1819
@implementation InstabugReactBridge
1920

@@ -26,6 +27,7 @@ @implementation InstabugReactBridge
2627
@"IBGWillShowSurvey",
2728
@"IBGDidDismissSurvey",
2829
@"IBGDidSelectPromptOptionHandler",
30+
@"IBGSetNetworkDataObfuscationHandler",
2931
@"IBGOnNewReplyReceivedCallback"
3032
];
3133
}
@@ -45,13 +47,15 @@ - (dispatch_queue_t)methodQueue {
4547
[Instabug startWithToken:token invocationEvents:invocationEvents];
4648
RCTAddLogFunction(InstabugReactLogFunction);
4749
RCTSetLogThreshold(RCTLogLevelInfo);
48-
IBGNetworkLogger.enabled = NO;
50+
4951
SEL setCrossPlatformSEL = NSSelectorFromString(@"setCrossPlatform:");
5052
if ([[Instabug class] respondsToSelector:setCrossPlatformSEL]) {
5153
[[Instabug class] performSelector:setCrossPlatformSEL withObject:@(true)];
5254
}
5355

56+
IBGNetworkLogger.enabled = YES;
5457
[self setBaseUrlForDeprecationLogs];
58+
5559
}
5660

5761
RCT_EXPORT_METHOD(callPrivateApi:(NSString *)apiName apiParam: (NSString *) param) {
@@ -529,6 +533,44 @@ - (dispatch_queue_t)methodQueue {
529533
callback(@[[NSNumber numberWithBool:result]]);
530534
}
531535

536+
RCT_EXPORT_METHOD(networkLog:(NSDictionary *) networkData) {
537+
NSString* url = networkData[@"url"];
538+
NSString* method = networkData[@"method"];
539+
NSString* requestBody = networkData[@"requestBody"];
540+
NSString* responseBody = networkData[@"responseBody"];
541+
int32_t responseCode = [networkData[@"responseCode"] integerValue];
542+
NSDictionary* requestHeaders = networkData[@"requestHeaders"];
543+
NSDictionary* responseHeaders = networkData[@"responseHeaders"];
544+
NSString* contentType = networkData[@"contentType"];
545+
double duration = [networkData[@"duration"] doubleValue];
546+
547+
SEL networkLogSEL = NSSelectorFromString(@"addNetworkLogWithUrl:method:requestBody:responseBody:responseCode:requestHeaders:responseHeaders:contentType:duration:");
548+
549+
if([[IBGNetworkLogger class] respondsToSelector:networkLogSEL]) {
550+
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[IBGNetworkLogger class] methodSignatureForSelector:networkLogSEL]];
551+
[inv setSelector:networkLogSEL];
552+
[inv setTarget:[IBGNetworkLogger class]];
553+
554+
[inv setArgument:&(url) atIndex:2];
555+
[inv setArgument:&(method) atIndex:3];
556+
[inv setArgument:&(requestBody) atIndex:4];
557+
[inv setArgument:&(responseBody) atIndex:5];
558+
[inv setArgument:&(responseCode) atIndex:6];
559+
[inv setArgument:&(requestHeaders) atIndex:7];
560+
[inv setArgument:&(responseHeaders) atIndex:8];
561+
[inv setArgument:&(contentType) atIndex:9];
562+
[inv setArgument:&(duration) atIndex:10];
563+
564+
[inv invoke];
565+
}
566+
}
567+
568+
RCT_EXPORT_METHOD(hideView: (nonnull NSNumber *)reactTag) {
569+
UIView* view = [self.bridge.uiManager viewForReactTag:reactTag];
570+
view.instabug_privateView = true;
571+
572+
}
573+
532574
RCT_EXPORT_METHOD(show) {
533575
[Instabug show];
534576
}
@@ -583,6 +625,7 @@ - (dispatch_queue_t)methodQueue {
583625
} else {
584626
IBGReplies.didReceiveReplyHandler = nil;
585627
}
628+
586629
}
587630

588631
- (NSDictionary *)constantsToExport

link_bridge.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
const exec = require('child_process').exec;
2+
require('./link_gradle');
23
exec("ruby ./node_modules/instabug-reactnative/link.rb || echo \"Ruby doesn't exist, if you're building this for Android only, then feel free to ignore this error, otherwise please install Ruby and run 'react-native link instabug-reactnative' again\"");

link_gradle.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
'use strict';
2+
var fs = require('fs');
3+
4+
const LOG_LEVEL_SUCCESS = 0;
5+
const LOG_LEVEL_WARN = 1;
6+
7+
const CHAR_OPEN_PARAN = '{';
8+
const CHAR_CLOSED_PARAN = '}';
9+
10+
const GRADLE_FILE_PATH = 'android/build.gradle';
11+
const MAVEN_REPO_URL =
12+
'https://sdks.instabug.com/nexus/repository/instabug-cp';
13+
14+
function getPosition(string, substring, occurrenceInString) {
15+
return string.split(substring, occurrenceInString).join(substring).length;
16+
}
17+
18+
function findRepositoriesBlockEnd(block) {
19+
let repositoriesStartBlockIndex = getPosition(block, CHAR_OPEN_PARAN, 2);
20+
let count = 1;
21+
let blockEndIndex = -1;
22+
for (let i = repositoriesStartBlockIndex + 1; i < block.length; i++) {
23+
if (block.charAt(i) === CHAR_OPEN_PARAN) {
24+
count++;
25+
}
26+
27+
if (block.charAt(i) === CHAR_CLOSED_PARAN) {
28+
count--;
29+
}
30+
31+
if (count === 0) {
32+
blockEndIndex = i;
33+
break;
34+
}
35+
}
36+
37+
return blockEndIndex;
38+
}
39+
40+
function readFile(filePath, success) {
41+
fs.readFile(filePath, 'utf-8', function(err, data) {
42+
if (err) {
43+
console.log(process.cwd());
44+
finish(
45+
LOG_LEVEL_WARN,
46+
`Linking process could not be completed because of\n${err.message}`
47+
);
48+
}
49+
success(data);
50+
});
51+
}
52+
53+
function writeFile(data) {
54+
fs.writeFile(GRADLE_FILE_PATH, data, err => {
55+
if (err) {
56+
finish(
57+
LOG_LEVEL_WARN,
58+
`Linking process could not be completed because of\n${err.message}`
59+
);
60+
}
61+
finish(LOG_LEVEL_SUCCESS, 'Linking process completed successfully');
62+
});
63+
}
64+
65+
function finish(logLevel, message) {
66+
if (logLevel === LOG_LEVEL_SUCCESS) {
67+
console.info(message);
68+
} else {
69+
console.warn(message);
70+
}
71+
72+
process.exit(0);
73+
}
74+
75+
function generateNewGradleFile(data) {
76+
77+
if (data.includes(MAVEN_REPO_URL)) {
78+
finish(LOG_LEVEL_SUCCESS, '');
79+
}
80+
81+
const regex = /allprojects\ *\n*\ *{/;
82+
if (!regex.test(data)) {
83+
finish(
84+
LOG_LEVEL_WARN,
85+
'Something went wrong while trying to complete the linking process. '
86+
);
87+
}
88+
89+
90+
const matchedRegex = data.match(regex);
91+
const block = data.substring(matchedRegex.index, data.length);
92+
const blockEndIndex = findRepositoriesBlockEnd(block);
93+
94+
if (blockEndIndex === -1) {
95+
finish(
96+
LOG_LEVEL_WARN,
97+
'Something went wrong while trying to complete the linking process. '
98+
);
99+
}
100+
101+
let updatedBlock = `${block.substring(0, blockEndIndex)}\tmaven {
102+
\t url "${MAVEN_REPO_URL}"
103+
\t}
104+
${block.substring(blockEndIndex, block.length)}`;
105+
const newGradleFile = `${data.substring(
106+
0,
107+
matchedRegex.index
108+
)}${updatedBlock}`;
109+
return newGradleFile;
110+
}
111+
112+
113+
readFile(GRADLE_FILE_PATH, function(data) {
114+
const newFile = generateNewGradleFile(data)
115+
writeFile(newFile);
116+
});

0 commit comments

Comments
 (0)