Skip to content

Commit

Permalink
Release/8.2.6 (#274)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
salmamali authored May 2, 2019
1 parent 77c6dcc commit 4a17a2a
Show file tree
Hide file tree
Showing 14 changed files with 580 additions and 9 deletions.
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ pod install
react-native link instabug-reactnative
```
### Upgrading from 8.0.3 to 8.x
### Upgrading in version 8
When upgrading from 8.0.3 to 8.x, please make sure you do the following steps:
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:
1. Unlink the project before upgrading to the new version
```bash
Expand Down Expand Up @@ -197,6 +197,18 @@ export INSTABUG_APP_TOKEN="YOUR_APP_TOKEN"
bash "../node_modules/instabug-reactnative/ios/upload_sourcemap.sh"
```
## Network Logging
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:
```javascript
import { NetworkLogger } from 'instabug-reactnative';
```
```javascript
NetworkLogger.setEnabled(false);
```
## Documentation
For more details about the supported APIs and how to use them, check our [**Documentation**](https://docs.instabug.com/docs/react-native-overview).
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ android {

dependencies {
implementation 'com.facebook.react:react-native:+'
api ('com.instabug.library:instabug:8.2.2'){
api ('com.instabug.library:instabug:8.2.2.0'){
exclude group: 'com.android.support:appcompat-v7'
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableMap;
Expand Down Expand Up @@ -73,6 +74,8 @@
import java.util.Locale;
import java.util.Map;

import static com.instabug.reactlibrary.utils.InstabugUtil.getMethod;


/**
* The type Rn instabug reactnative module.
Expand Down Expand Up @@ -490,7 +493,7 @@ public void setCrashReportingEnabled(boolean isEnabled) {
private void sendJSCrashByReflection(String exceptionObject, boolean isHandled) {
try {
JSONObject newJSONObject = new JSONObject(exceptionObject);
Method method = InstabugUtil.getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class);
Method method = getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class);
if (method != null) {
method.invoke(null, newJSONObject, isHandled);
}
Expand Down Expand Up @@ -1885,6 +1888,53 @@ public void setEmailFieldRequiredForFeatureRequests(boolean isEmailRequired, Rea
}
}

/**
* Extracts HTTP connection properties. Request method, Headers, Date, Url and Response code
*
* @param jsonObject the JSON object containing all HTTP connection properties
* @throws JSONException
*/
@ReactMethod
public void networkLog(String jsonObject) throws JSONException {
NetworkLog networkLog = new NetworkLog();
String date = System.currentTimeMillis()+"";
networkLog.setDate(date);
JSONObject newJSONObject = new JSONObject(jsonObject);
networkLog.setUrl(newJSONObject.getString("url"));
networkLog.setRequest(newJSONObject.getString("requestBody"));
networkLog.setResponse(newJSONObject.getString("responseBody"));
networkLog.setMethod(newJSONObject.getString("method"));
networkLog.setResponseCode(newJSONObject.getInt("responseCode"));
networkLog.setRequestHeaders(newJSONObject.getString("requestHeaders"));
networkLog.setResponseHeaders(newJSONObject.getString("responseHeaders"));
networkLog.insert();
}


@ReactMethod
public void setSecureViews(ReadableArray ids) {
int[] arrayOfIds = new int[ids.size()];
for (int i = 0; i < ids.size(); i++) {
int viewId = (int) ids.getDouble(i);
arrayOfIds[i] = viewId;
}
Method method = null;
try {
method = InstabugUtil.getMethod(Class.forName("com.instabug.library.Instabug"), "setSecureViewsId", int[].class);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (method != null) {
try {
method.invoke(null, arrayOfIds);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

private InstabugCustomTextPlaceHolder.Key getStringToKeyConstant(String key) {
switch (key) {
case SHAKE_HINT:
Expand Down
6 changes: 6 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ export namespace Surveys {
): void;
function setShouldShowWelcomeScreen(shouldShowWelcomeScreen: boolean): void;
}
export namespace NetworkLogger {
function setEnabled(isEnabled: boolean): void;
function setNetworkDataObfuscationHandler(handler: () => void): void;
function setRequestFilterExpression(expression: string): void;
function setProgressHandlerForRequest(handler: () => void): void;
}
export function startWithToken(
token: string,
invocationEvent: invocationEvent[]
Expand Down
22 changes: 19 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
NativeAppEventEmitter,
DeviceEventEmitter,
Platform,
findNodeHandle,
processColor
} from 'react-native';
let { Instabug } = NativeModules;
Expand All @@ -13,8 +14,10 @@ import FeatureRequests from './modules/FeatureRequests';
import Chats from './modules/Chats';
import Replies from './modules/Replies';
import CrashReporting from './modules/CrashReporting';
import NetworkLogger from './modules/NetworkLogger';

captureJsErrors();
NetworkLogger.setEnabled(true);

/**
* Instabug
Expand Down Expand Up @@ -220,7 +223,7 @@ const InstabugModule = {
* @param {color} primaryColor A color to set the UI elements of the SDK to.
*/
setPrimaryColor: function(primaryColor) {
Instabug.setPrimaryColor(primaryColor);
Instabug.setPrimaryColor(processColor(primaryColor));
},

/**
Expand Down Expand Up @@ -692,6 +695,18 @@ const InstabugModule = {
}
},

/**
* Hides component from screenshots, screen recordings and view hierarchy.
* @param {Object} viewRef the ref of the component to hide
*/
setPrivateView: function(viewRef) {
const nativeTag = findNodeHandle(viewRef);
if (Platform.OS === 'ios') {
Instabug.hideView(nativeTag);
} else {
Instabug.setSecureViews([nativeTag]);
}
},
/**
* Shows default Instabug prompt.
*/
Expand Down Expand Up @@ -960,7 +975,8 @@ export {
FeatureRequests,
Chats,
Replies,
CrashReporting
}
CrashReporting,
NetworkLogger
};

export default InstabugModule;
45 changes: 44 additions & 1 deletion ios/RNInstabug/InstabugReactBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#import <React/RCTLog.h>
#import <os/log.h>
#import <Instabug/IBGTypes.h>
#import <React/RCTUIManager.h>

@implementation InstabugReactBridge

Expand All @@ -26,6 +27,7 @@ @implementation InstabugReactBridge
@"IBGWillShowSurvey",
@"IBGDidDismissSurvey",
@"IBGDidSelectPromptOptionHandler",
@"IBGSetNetworkDataObfuscationHandler",
@"IBGOnNewReplyReceivedCallback"
];
}
Expand All @@ -45,13 +47,15 @@ - (dispatch_queue_t)methodQueue {
[Instabug startWithToken:token invocationEvents:invocationEvents];
RCTAddLogFunction(InstabugReactLogFunction);
RCTSetLogThreshold(RCTLogLevelInfo);
IBGNetworkLogger.enabled = NO;

SEL setCrossPlatformSEL = NSSelectorFromString(@"setCrossPlatform:");
if ([[Instabug class] respondsToSelector:setCrossPlatformSEL]) {
[[Instabug class] performSelector:setCrossPlatformSEL withObject:@(true)];
}

IBGNetworkLogger.enabled = YES;
[self setBaseUrlForDeprecationLogs];

}

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

RCT_EXPORT_METHOD(networkLog:(NSDictionary *) networkData) {
NSString* url = networkData[@"url"];
NSString* method = networkData[@"method"];
NSString* requestBody = networkData[@"requestBody"];
NSString* responseBody = networkData[@"responseBody"];
int32_t responseCode = [networkData[@"responseCode"] integerValue];
NSDictionary* requestHeaders = networkData[@"requestHeaders"];
NSDictionary* responseHeaders = networkData[@"responseHeaders"];
NSString* contentType = networkData[@"contentType"];
double duration = [networkData[@"duration"] doubleValue];

SEL networkLogSEL = NSSelectorFromString(@"addNetworkLogWithUrl:method:requestBody:responseBody:responseCode:requestHeaders:responseHeaders:contentType:duration:");

if([[IBGNetworkLogger class] respondsToSelector:networkLogSEL]) {
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[IBGNetworkLogger class] methodSignatureForSelector:networkLogSEL]];
[inv setSelector:networkLogSEL];
[inv setTarget:[IBGNetworkLogger class]];

[inv setArgument:&(url) atIndex:2];
[inv setArgument:&(method) atIndex:3];
[inv setArgument:&(requestBody) atIndex:4];
[inv setArgument:&(responseBody) atIndex:5];
[inv setArgument:&(responseCode) atIndex:6];
[inv setArgument:&(requestHeaders) atIndex:7];
[inv setArgument:&(responseHeaders) atIndex:8];
[inv setArgument:&(contentType) atIndex:9];
[inv setArgument:&(duration) atIndex:10];

[inv invoke];
}
}

RCT_EXPORT_METHOD(hideView: (nonnull NSNumber *)reactTag) {
UIView* view = [self.bridge.uiManager viewForReactTag:reactTag];
view.instabug_privateView = true;

}

RCT_EXPORT_METHOD(show) {
[Instabug show];
}
Expand Down Expand Up @@ -583,6 +625,7 @@ - (dispatch_queue_t)methodQueue {
} else {
IBGReplies.didReceiveReplyHandler = nil;
}

}

- (NSDictionary *)constantsToExport
Expand Down
1 change: 1 addition & 0 deletions link_bridge.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
const exec = require('child_process').exec;
require('./link_gradle');
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\"");
116 changes: 116 additions & 0 deletions link_gradle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
'use strict';
var fs = require('fs');

const LOG_LEVEL_SUCCESS = 0;
const LOG_LEVEL_WARN = 1;

const CHAR_OPEN_PARAN = '{';
const CHAR_CLOSED_PARAN = '}';

const GRADLE_FILE_PATH = 'android/build.gradle';
const MAVEN_REPO_URL =
'https://sdks.instabug.com/nexus/repository/instabug-cp';

function getPosition(string, substring, occurrenceInString) {
return string.split(substring, occurrenceInString).join(substring).length;
}

function findRepositoriesBlockEnd(block) {
let repositoriesStartBlockIndex = getPosition(block, CHAR_OPEN_PARAN, 2);
let count = 1;
let blockEndIndex = -1;
for (let i = repositoriesStartBlockIndex + 1; i < block.length; i++) {
if (block.charAt(i) === CHAR_OPEN_PARAN) {
count++;
}

if (block.charAt(i) === CHAR_CLOSED_PARAN) {
count--;
}

if (count === 0) {
blockEndIndex = i;
break;
}
}

return blockEndIndex;
}

function readFile(filePath, success) {
fs.readFile(filePath, 'utf-8', function(err, data) {
if (err) {
console.log(process.cwd());
finish(
LOG_LEVEL_WARN,
`Linking process could not be completed because of\n${err.message}`
);
}
success(data);
});
}

function writeFile(data) {
fs.writeFile(GRADLE_FILE_PATH, data, err => {
if (err) {
finish(
LOG_LEVEL_WARN,
`Linking process could not be completed because of\n${err.message}`
);
}
finish(LOG_LEVEL_SUCCESS, 'Linking process completed successfully');
});
}

function finish(logLevel, message) {
if (logLevel === LOG_LEVEL_SUCCESS) {
console.info(message);
} else {
console.warn(message);
}

process.exit(0);
}

function generateNewGradleFile(data) {

if (data.includes(MAVEN_REPO_URL)) {
finish(LOG_LEVEL_SUCCESS, '');
}

const regex = /allprojects\ *\n*\ *{/;
if (!regex.test(data)) {
finish(
LOG_LEVEL_WARN,
'Something went wrong while trying to complete the linking process. '
);
}


const matchedRegex = data.match(regex);
const block = data.substring(matchedRegex.index, data.length);
const blockEndIndex = findRepositoriesBlockEnd(block);

if (blockEndIndex === -1) {
finish(
LOG_LEVEL_WARN,
'Something went wrong while trying to complete the linking process. '
);
}

let updatedBlock = `${block.substring(0, blockEndIndex)}\tmaven {
\t url "${MAVEN_REPO_URL}"
\t}
${block.substring(blockEndIndex, block.length)}`;
const newGradleFile = `${data.substring(
0,
matchedRegex.index
)}${updatedBlock}`;
return newGradleFile;
}


readFile(GRADLE_FILE_PATH, function(data) {
const newFile = generateNewGradleFile(data)
writeFile(newFile);
});
Loading

0 comments on commit 4a17a2a

Please sign in to comment.