Skip to content
This repository has been archived by the owner on Jul 30, 2024. It is now read-only.

Commit

Permalink
Upgrade to 0.62 and bump package to 0.5.0
Browse files Browse the repository at this point in the history
- Upgrade stale packages
- Upgrade example app to work with 0.62, it also now targets release RN
  instead of master making it easier for people to test
- Update README to make using the package easier
  • Loading branch information
Akshet Pandey authored and akshetpandey committed Mar 30, 2020
1 parent 4f895ce commit 4863912
Show file tree
Hide file tree
Showing 44 changed files with 4,876 additions and 6,522 deletions.
165 changes: 96 additions & 69 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,99 @@
module.exports = {
// Airbnb is the base, prettier is here so that eslint doesn't conflict with prettier
extends: ['airbnb', 'prettier', 'prettier/react'],
parser: '@typescript-eslint/parser',
plugins: ['react', 'react-native', 'import', '@typescript-eslint'],
rules: {
'no-console': 'off',
// Lines will be broken before binary operators
'operator-linebreak': ['error', 'before'],
// Allow imports from dev and peer dependencies
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true, peerDependencies: true },
],
'react/jsx-filename-extension': ['error', { extensions: ['.tsx'] }],
// This rule doesn't play nice with Prettier
'react/jsx-one-expression-per-line': 'off',
// This rule doesn't play nice with Prettier
'react/jsx-wrap-multilines': 'off',
// Remove this rule because we only destructure props, but never state
'react/destructuring-assignment': 'off',
'react/prop-types': 'off',
'@typescript-eslint/adjacent-overload-signatures': 'error',
'@typescript-eslint/array-type': ['error', {default: 'array'}],
'@typescript-eslint/consistent-type-assertions': 'error',
'@typescript-eslint/generic-type-naming': ['error', '^[a-zA-Z]+$'],
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-empty-interface': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-extraneous-class': 'error',
'@typescript-eslint/no-inferrable-types': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-namespace': 'error',
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/no-parameter-properties': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-type-alias': [
'error',
{
allowAliases: 'always',
allowCallbacks: 'always',
allowMappedTypes: 'always',
},
],
'@typescript-eslint/no-unused-vars': [
'error',
{ ignoreRestSiblings: true },
],
'@typescript-eslint/prefer-namespace-keyword': 'error',
'@typescript-eslint/type-annotation-spacing': 'error',
},
settings: {
'import/resolver': {
node: {
extensions: [
'.js',
'.android.js',
'.ios.js',
'.jsx',
'.android.jsx',
'.ios.jsx',
'.tsx',
'.ts',
'.android.tsx',
'.android.ts',
'.ios.tsx',
'.ios.ts',
],
},
root: true,
// Airbnb is the base, prettier is here so that eslint doesn't conflict with prettier
extends: ['airbnb', 'prettier', 'prettier/react'],
parser: '@typescript-eslint/parser',
plugins: ['react', 'react-native', 'import', '@typescript-eslint'],
rules: {
'no-console': 'off',
'no-else-return': 'off',
// Lines will be broken before binary operators
'operator-linebreak': ['error', 'before'],
// Allow imports from dev and peer dependencies
'import/no-extraneous-dependencies': [
'error',
{ devDependencies: true, peerDependencies: true },
],
'react/jsx-filename-extension': ['error', { extensions: ['.tsx', '.jsx'] }],
// This rule doesn't play nice with Prettier
'react/jsx-one-expression-per-line': 'off',
// This rule doesn't play nice with Prettier
'react/jsx-wrap-multilines': 'off',
// Remove this rule because we only destructure props, but never state
'react/destructuring-assignment': 'off',
'react/prop-types': 'off',
'react/jsx-props-no-spreading': 'off',
'react/static-property-placement': 'off',
'react/state-in-constructor': 'off',
'@typescript-eslint/adjacent-overload-signatures': 'error',
'@typescript-eslint/array-type': [
'error',
{
default: 'array',
},
],
'@typescript-eslint/generic-type-naming': ['error', '^[a-zA-Z]+$'],
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-empty-interface': 'error',
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-extraneous-class': 'error',
'@typescript-eslint/no-inferrable-types': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-namespace': 'error',
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/consistent-type-assertions': [
'error',
{
assertionStyle: 'as',
},
],
'@typescript-eslint/no-parameter-properties': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/triple-slash-reference': [
'error',
{ path: 'never', types: 'never', lib: 'never' },
],
'@typescript-eslint/no-type-alias': [
'error',
{
allowAliases: 'always',
allowCallbacks: 'always',
allowMappedTypes: 'always',
},
],
'@typescript-eslint/no-unused-vars': [
'error',
{ ignoreRestSiblings: true },
],
'@typescript-eslint/consistent-type-definitions': [
'error',
'interface',
],
'@typescript-eslint/prefer-namespace-keyword': 'error',
'@typescript-eslint/type-annotation-spacing': 'error',
},
settings: {
'import/resolver': {
node: {
extensions: [
'.js',
'.android.js',
'.ios.js',
'.jsx',
'.android.jsx',
'.ios.jsx',
'.tsx',
'.ts',
'.android.tsx',
'.android.ts',
'.ios.tsx',
'.ios.ts',
],
},
},
};
},
globals: {
fetch: false,
HermesInternal: false,
}
};
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# specific for windows script files
*.bat text eol=crlf

*.pbxproj -text
3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,6 @@ scripts/examples_postinstall.js
tsconfig.json
yarn.lock
CODE_OF_CONDUCT.md
lib/
android/README.md
src/
97 changes: 58 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
# react-native-cronet
# react-native-cronet: Chrome's networking stack for your react-native application

[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
[![License](https://img.shields.io/github/license/akshetpandey/react-native-cronet)](https://github.com/akshetpandey/react-native-cronet)
[![Known Vulnerabilities](https://snyk.io/test/github/akshetpandey/react-native-cronet/badge.svg?style=flat-square)](https://snyk.io/test/github/akshetpandey/react-native-cronet)
[![NPM Version](https://img.shields.io/npm/v/react-native-cronet.svg?style=flat-square)](https://www.npmjs.com/package/react-native-cronet)

[Cronet](https://chromium.googlesource.com/chromium/src/+/master/components/cronet) is the [networking stack of Chromium](https://chromium.googlesource.com/chromium/src/+/master/net/docs/life-of-a-url-request.md) put into a library for use on mobile.
This is the same networking stack that is used in the Chrome browser by over a billion people.
It offers an easy-to-use, high performance, standards-compliant, and secure way to perform HTTP requests.
Cronet has support for both Android and iOS.

This module allows you to use the Cronet stack for your react native apps.
Checkout default android vs cronet comparison when loading many images
Checkout default react-native vs react-native-cronet comparison on android when loading many images on a high lateceny and packetloss network

![Preview](docs/CronetComp.gif)

## NOTE

For iOS, you will have to disable bitcode for your target.
## Support Matrix

In XCode, in the project navigator, select your project. `Build Settings``Enable Bitcode``No`
| React Native | react-native-cronet |
| :----------: | :-----------------: |
| >=0.62 | 0.5.0 |
| >=0.60 | 0.4.0 |
| <0.60 | unsupported |

## Getting started

Expand All @@ -30,14 +37,21 @@ or using yarn:
yarn add react-native-cronet
```

### Automatic installation

`react-native-cronet` will link automatically using the autolink.

Make sure to run `pod install` in your iOS folder to get the `Cronet.framework` dependency included.

### Manual installation

#### iOS

1. In XCode, in the project navigator, right click `Libraries``Add Files to [your project's name]`
2. Go to `node_modules``react-native-cronet` and add `RNCronet.xcodeproj`
3. In XCode, in the project navigator, select your project. Add `libRNCronet.a` to your project's `Build Phases``Link Binary With Libraries`
4. Run your project (`Cmd+R`)<
4. Add `pod 'Cronet'` as a dependency in your iOS `Podfile` and run `pod install`, alternatively manaually link [Cronet.framework](https://github.com/akshetpandey/Cronet.framework/releases/latest) to your project
5. Run your project (`Cmd+R`)<

#### Android

Expand All @@ -56,27 +70,32 @@ yarn add react-native-cronet
compile project(':react-native-cronet')
```

## Usage
## Basic Usage

### iOS

For iOS, you will have to disable bitcode for your target.

- In XCode, in the project navigator, select your project. `Build Settings``Enable Bitcode``No`

You don't have to do anything else for iOS. Cronet is used automatically for all react-native network request.
For Android, in your `MainApplication.java`, you will have to change how RN initializes `FrescoModule` internally by doing this:
### Android

For Android, in your `MainApplication.java`, you will have to change how RN initializes `FrescoModule` by adding these lines:

```java
import com.akshetpandey.rncronet.RNCronetFrescoImagePipelineConfig;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.react.shell.MainPackageConfig;
import com.akshetpandey.rncronet.RNCronetFrescoImagePipelineConfig; // <--- ADD THIS
import com.facebook.imagepipeline.core.ImagePipelineConfig; // <--- ADD THIS
import com.facebook.react.shell.MainPackageConfig; // <--- ADD THIS

public class MainApplication extends Application implements ReactApplication {

private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
//...
@Override
protected List<ReactPackage> getPackages() {
ImagePipelineConfig pipelineConfig = RNCronetFrescoImagePipelineConfig.build(getApplicationContext());
MainPackageConfig config = new MainPackageConfig.Builder().setFrescoConfig(pipelineConfig).build();
List<ReactPackage> packages = new PackageList(this, config).getPackages();
ImagePipelineConfig pipelineConfig = RNCronetFrescoImagePipelineConfig.build(getApplicationContext()); // <--- ADD THIS
MainPackageConfig config = new MainPackageConfig.Builder().setFrescoConfig(pipelineConfig).build(); // <--- ADD THIS
List<ReactPackage> packages = new PackageList(this, config).getPackages(); // <--- CHANGE THIS TO INCLUDE CONFIG
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new RNCronetNetworkingPackage());
return packages;
}
//...
Expand All @@ -89,12 +108,13 @@ public class MainApplication extends Application implements ReactApplication {
Although the library is capable of automatically configuring itself, you can also initialize the cronet engine based on your use case.
One reason to do this would be to provide QUIC hints for your domain that you know supports QUIC, or to customize cache size and type.

**Make sure this is done before the react native bridge gets initialized.**

Nothing needs to be done on the JS side.

### iOS

Somewhere in your app startup flow, ex. in AppDelegate, you can install an initializer block that can initialize the library for your requirements.
Make sure this is done before the react native bridge gets initialized.
Somewhere in your app startup flow, ex. in `AppDelegate.m`, you can install an initializer block that can initialize the library for your requirements.

iOS documentation for the cronet library initialization is sparse, but you can look at [Cronet/Cronet.h](https://chromium.googlesource.com/chromium/src/+/master/components/cronet/ios/Cronet.h)

Expand Down Expand Up @@ -124,33 +144,32 @@ iOS documentation for the cronet library initialization is sparse, but you can l

### Android

Somewhere in your app startup flow, ex in MainActivity, you can install an initializer block that can initialize the library for your requirements.
Make sure this is done before the react native bridge gets initialized.
Somewhere in your app startup flow, ex in `MainActivity.java`, you can install an initializer block that can initialize the library for your requirements.

Android documentation for the cronet library initialization is available in [CronetEngine.Builder](https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/CronetEngine.Builder.html)

```java
import org.chromium.net.CronetEngine;

public class MainActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
RNCronetNetworkingModule.setCustomCronetBuilder(context -> {
File cacheDir = new File(context.getCacheDir(), "cronet-cache");
cacheDir.mkdirs();
CronetEngine cronetEngine = new CronetEngine.Builder(context)
.enableBrotli(true)
.enableHttp2(true)
.enableQuic(true)
.setStoragePath(cacheDir.getAbsolutePath())
.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, 10 * 1024 * 1024)
.addQuicHint("www.google.com", 443, 443)
.build();
URL.setURLStreamHandlerFactory(cronetEngine.createURLStreamHandlerFactory());
return cronetEngine;
});
RNCronetNetworkingModule.setCustomCronetBuilder(context -> {
File cacheDir = new File(context.getCacheDir(), "cronet-cache");
cacheDir.mkdirs();
CronetEngine cronetEngine = new CronetEngine.Builder(context)
.enableBrotli(true)
.enableHttp2(true)
.enableQuic(true)
.setStoragePath(cacheDir.getAbsolutePath())
.enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, 10 * 1024 * 1024)
.addQuicHint("www.google.com", 443, 443)
.build();
URL.setURLStreamHandlerFactory(cronetEngine.createURLStreamHandlerFactory());
return cronetEngine;
});
// ...
}
}
}
```
Loading

0 comments on commit 4863912

Please sign in to comment.