mirror of
https://github.com/expo/config-plugins.git
synced 2026-11-13 20:28:07 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
057c6bd978 | ||
|
|
3fbc237fd6 | ||
|
|
6603ab3215 | ||
|
|
9f49f02401 | ||
|
|
14dc560092 | ||
|
|
2dcaff6772 | ||
|
|
68190997b6 | ||
|
|
74f55fc342 | ||
|
|
e32378e8ed | ||
|
|
764a04710b | ||
|
|
837602af36 | ||
|
|
af22acc509 | ||
|
|
994fadc8dd |
No files matched your search
@@ -42,6 +42,7 @@ body:
|
||||
- '@config-plugins/react-native-google-cast'
|
||||
- '@config-plugins/react-native-pdf'
|
||||
- '@config-plugins/react-native-quick-actions'
|
||||
- '@config-plugins/react-native-siri-shortcut'
|
||||
- '@config-plugins/react-native-webrtc'
|
||||
validations:
|
||||
required: true
|
||||
|
||||
@@ -39,6 +39,9 @@ contact_links:
|
||||
- about: A react-native interface for Touch 3D home screen quick actions
|
||||
name: 📦 react-native-quick-actions issues
|
||||
url: https://github.com/jordanbyron/react-native-quick-actions/issues
|
||||
- about: A React Native library that enables you to use iOS 12+ Siri Shortcuts.
|
||||
name: 📦 react-native-siri-shortcut issues
|
||||
url: https://github.com/Gustash/react-native-siri-shortcut/issues
|
||||
- about: WebRTC for React Native
|
||||
name: 📦 react-native-webrtc issues
|
||||
url: https://github.com/react-native-webrtc/react-native-webrtc/issues
|
||||
@@ -83,6 +83,12 @@ updates:
|
||||
interval: daily
|
||||
time: '09:00'
|
||||
timezone: America/Los_Angeles
|
||||
- package-ecosystem: npm
|
||||
directory: packages/react-native-siri-shortcut
|
||||
schedule:
|
||||
interval: daily
|
||||
time: '09:00'
|
||||
timezone: America/Los_Angeles
|
||||
- package-ecosystem: npm
|
||||
directory: packages/react-native-webrtc
|
||||
schedule:
|
||||
|
||||
@@ -41,6 +41,7 @@ jobs:
|
||||
react-native-ble-plx,
|
||||
react-native-blob-util,
|
||||
react-native-branch,
|
||||
react-native-siri-shortcut,
|
||||
react-native-google-cast,
|
||||
react-native-pdf,
|
||||
# react-native-quick-actions,
|
||||
|
||||
@@ -23,11 +23,14 @@ Here is a list of known packages that have a built-in Config Plugin.
|
||||
- [@stripe/stripe-react-native](https://www.npmjs.com/package/@stripe/stripe-react-native)
|
||||
- [@react-native-voice/voice](https://www.npmjs.com/package/@react-native-voice/voice)
|
||||
- [react-native-imglysdk](https://www.npmjs.com/package/react-native-imglysdk)
|
||||
- [@viro-community/react-viro](https://github.com/virocommunity/viro)
|
||||
- [@viro-community/react-viro](https://github.com/virocommunity/viro) -- [Guide](https://viro-community.readme.io/docs/integrating-with-expo)
|
||||
- [react-native-msal](https://www.npmjs.com/package/react-native-msal)
|
||||
- [react-native-spotlight-search](https://www.npmjs.com/package/react-native-spotlight-search)
|
||||
- [newrelic-react-native-agent](https://www.npmjs.com/package/newrelic-react-native-agent)
|
||||
- [react-native-videoeditorsdk](https://www.npmjs.com/package/react-native-videoeditorsdk)
|
||||
- [notifee](https://notifee.app/)
|
||||
- [App Clips](https://github.com/bndkt/react-native-app-clip/)
|
||||
- [iOS Safari Extensions](https://github.com/andrew-levy/react-native-safari-extension/)
|
||||
|
||||
### Complementary
|
||||
|
||||
@@ -39,9 +42,20 @@ More out-of-tree plugins which can be used to configure more packages.
|
||||
- [config-plugin-react-native-intercom](https://www.npmjs.com/package/config-plugin-react-native-intercom) (for use with `intercom-react-native`)
|
||||
- [@allboatsrise/expo-marketingcloudsdk](https://www.npmjs.com/package/@allboatsrise/expo-marketingcloudsdk) (for use with `react-native-marketingcloudsdk`)
|
||||
- [@ouvio/react-native-background-location-plugin](https://www.npmjs.com/package/@ouvio/react-native-background-location-plugin) (for use with `react-native-background-location-plugin`)
|
||||
- [with-notifee](https://www.npmjs.com/package/with-notifee) (for use with [notifee](https://notifee.app/))
|
||||
- [expo-community-flipper](https://www.npmjs.com/package/expo-community-flipper) (for use with Flipper)
|
||||
|
||||
### No Plugin Required
|
||||
|
||||
Just install and rebuild! If a package doesn't require any futher setup then it most likely doesn't need an Expo config plugin. Most packages work without a config plugin (including packages not listed below):
|
||||
|
||||
- [react-native-share](https://github.com/react-native-share/react-native-share)
|
||||
- [@react-native-menu/menu](https://github.com/react-native-menu/menu)
|
||||
- [react-native-blurhash](https://github.com/mrousavy/react-native-blurhash)
|
||||
- [react-native-app-shortcuts](https://github.com/lokyoung/react-native-app-shortcuts)
|
||||
- [react-native-multiple-image-picker](https://github.com/baronha/react-native-multiple-image-picker)
|
||||
- [`@shopify/flash-list`](https://github.com/Shopify/flash-list)
|
||||
|
||||
> Feel free to [open a PR](https://github.com/expo/config-plugins/edit/main/README.md) with missing packages.
|
||||
|
||||
## Contributing!
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
node_modules/**/*
|
||||
.expo/*
|
||||
npm-debug.*
|
||||
*.jks
|
||||
*.p8
|
||||
*.p12
|
||||
*.key
|
||||
*.mobileprovision
|
||||
*.orig.*
|
||||
web-build/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
|
||||
|
||||
/artifacts
|
||||
|
||||
/scripts/start.command
|
||||
/ios
|
||||
/android
|
||||
# @generated expo-cli sync-e7dcf75f4e856f7b6f3239b3f3a7dd614ee755a8
|
||||
# The following patterns were generated by expo-cli
|
||||
|
||||
# OSX
|
||||
#
|
||||
.DS_Store
|
||||
|
||||
# Xcode
|
||||
#
|
||||
build/
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
xcuserdata
|
||||
*.xccheckout
|
||||
*.moved-aside
|
||||
DerivedData
|
||||
*.hmap
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
project.xcworkspace
|
||||
|
||||
# Android/IntelliJ
|
||||
#
|
||||
build/
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
*.hprof
|
||||
|
||||
# node.js
|
||||
#
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
# BUCK
|
||||
buck-out/
|
||||
\.buckd/
|
||||
*.keystore
|
||||
!debug.keystore
|
||||
|
||||
# Bundle artifacts
|
||||
*.jsbundle
|
||||
|
||||
# CocoaPods
|
||||
/ios/Pods/
|
||||
|
||||
# Expo
|
||||
.expo/
|
||||
web-build/
|
||||
dist/
|
||||
|
||||
# @end expo-cli
|
||||
Whitespace-only changes.
@@ -0,0 +1,16 @@
|
||||
const path = require("path");
|
||||
const folderName = path.basename(__dirname);
|
||||
const cleanName = folderName.replace(/[_\s-]/g, "");
|
||||
const appId = "dev.bacon." + cleanName;
|
||||
|
||||
module.exports = ({ config }) => {
|
||||
if (!config.extra) config.extra = {};
|
||||
// Expose CI env variables to the app
|
||||
config.extra.CI = process.env.CI;
|
||||
|
||||
if (!config.ios) config.ios = {};
|
||||
config.ios.bundleIdentifier = appId;
|
||||
if (!config.android) config.android = {};
|
||||
config.android.package = appId;
|
||||
return config;
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"expo": {
|
||||
"icon": "https://icogen.vercel.app/api/icon",
|
||||
"plugins": [
|
||||
[
|
||||
"@config-plugins/react-native-siri-shortcut",
|
||||
[
|
||||
"com.example.InitiateWorkout",
|
||||
"com.example.FinishWorkout"
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
module.exports = function(api) {
|
||||
api.cache(true);
|
||||
return {
|
||||
presets: ['babel-preset-expo'],
|
||||
};
|
||||
};
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import { registerRootComponent } from "expo";
|
||||
|
||||
import App from "./src/App";
|
||||
|
||||
registerRootComponent(App);
|
||||
@@ -0,0 +1,6 @@
|
||||
// Learn more https://docs.expo.io/guides/customizing-metro
|
||||
const { getDefaultConfig } = require("@expo/metro-config");
|
||||
|
||||
const config = getDefaultConfig(__dirname);
|
||||
|
||||
module.exports = config;
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "@config-plugins-app/react-native-siri-shortcut",
|
||||
"main": "./index.js",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "expo start --dev-client",
|
||||
"ios": "expo run:ios",
|
||||
"android": "expo run:android"
|
||||
},
|
||||
"dependencies": {
|
||||
"@config-plugins/react-native-siri-shortcut": "*",
|
||||
"expo": "^45.0.0",
|
||||
"expo-splash-screen": "~0.15.1",
|
||||
"react": "17.0.2",
|
||||
"react-native": "0.68.2",
|
||||
"react-native-siri-shortcut": "^3.1.0",
|
||||
"expo-status-bar": "~1.3.0",
|
||||
"react-dom": "17.0.2",
|
||||
"react-native-web": "0.17.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.9"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
StyleSheet,
|
||||
Text,
|
||||
ScrollView,
|
||||
Button,
|
||||
SafeAreaView,
|
||||
View,
|
||||
EmitterSubscription,
|
||||
} from 'react-native';
|
||||
import {
|
||||
ShortcutOptions,
|
||||
ShortcutData,
|
||||
ShortcutInfo,
|
||||
donateShortcut,
|
||||
suggestShortcuts,
|
||||
clearAllShortcuts,
|
||||
clearShortcutsWithIdentifiers,
|
||||
presentShortcut,
|
||||
getShortcuts,
|
||||
addShortcutListener,
|
||||
getInitialShortcut,
|
||||
AddToSiriButton,
|
||||
SiriButtonStyles,
|
||||
} from 'react-native-siri-shortcut';
|
||||
|
||||
const opts1: ShortcutOptions = {
|
||||
activityType: 'com.github.gustash.SiriShortcutsModuleExample.sayHello',
|
||||
title: 'Say Hi',
|
||||
userInfo: {
|
||||
foo: 1,
|
||||
bar: 'baz',
|
||||
baz: 34.5,
|
||||
},
|
||||
requiredUserInfoKeys: ['foo', 'bar', 'baz'],
|
||||
keywords: ['kek', 'foo', 'bar'],
|
||||
persistentIdentifier:
|
||||
'com.github.gustash.SiriShortcutsModuleExample.sayHello',
|
||||
isEligibleForSearch: true,
|
||||
isEligibleForPrediction: true,
|
||||
suggestedInvocationPhrase: 'Say something',
|
||||
needsSave: true,
|
||||
};
|
||||
|
||||
const opts2: ShortcutOptions = {
|
||||
activityType: 'com.github.gustash.SiriShortcutsModuleExample.somethingElse',
|
||||
title: 'Something Else',
|
||||
persistentIdentifier: 'some.persistent.identifier',
|
||||
isEligibleForSearch: true,
|
||||
isEligibleForPrediction: true,
|
||||
suggestedInvocationPhrase: "What's up?",
|
||||
description: 'Just a random description',
|
||||
};
|
||||
type State = {
|
||||
shortcutInfo: any | null,
|
||||
shortcutActivityType: string | null,
|
||||
addToSiriStyle: 0 | 1 | 2 | 3 | 4 | 5,
|
||||
shortcuts: Array<ShortcutData>,
|
||||
};
|
||||
|
||||
|
||||
|
||||
export default class App extends Component<void, State> {
|
||||
listener: EmitterSubscription | null = null;
|
||||
|
||||
state: State = {
|
||||
shortcutInfo: null,
|
||||
shortcutActivityType: null,
|
||||
addToSiriStyle: SiriButtonStyles.blackOutline,
|
||||
shortcuts: [],
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
this.handleInitialShortcut();
|
||||
this.listener = addShortcutListener(this.handleSiriShortcut.bind(this));
|
||||
|
||||
// This will suggest these two shortcuts so that they appear
|
||||
// in Settings > Siri & Search, even if they are not yet
|
||||
// donated. Suitable for shortcuts that you expect the user
|
||||
// may want to use. (https://developer.apple.com/documentation/sirikit/shortcut_management/suggesting_shortcuts_to_users)
|
||||
suggestShortcuts([opts1, opts2]);
|
||||
|
||||
this.updateShortcutList();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.listener) {
|
||||
this.listener.remove();
|
||||
}
|
||||
}
|
||||
|
||||
async handleInitialShortcut() {
|
||||
const initialShortcut = await getInitialShortcut();
|
||||
|
||||
if (!initialShortcut) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.handleSiriShortcut(initialShortcut);
|
||||
}
|
||||
|
||||
handleSiriShortcut({ userInfo, activityType }: ShortcutInfo) {
|
||||
this.setState({
|
||||
shortcutInfo: userInfo,
|
||||
shortcutActivityType: activityType,
|
||||
});
|
||||
}
|
||||
|
||||
setupShortcut1() {
|
||||
donateShortcut(opts1);
|
||||
}
|
||||
|
||||
setupShortcut2() {
|
||||
donateShortcut(opts2);
|
||||
}
|
||||
|
||||
async clearShortcut1() {
|
||||
try {
|
||||
await clearShortcutsWithIdentifiers([
|
||||
'com.github.gustash.SiriShortcutsModuleExample.sayHello',
|
||||
]);
|
||||
alert('Cleared Shortcut 1');
|
||||
} catch (e) {
|
||||
alert("You're not running iOS 12!");
|
||||
}
|
||||
}
|
||||
|
||||
async clearShortcut2() {
|
||||
try {
|
||||
await clearShortcutsWithIdentifiers(['some.persistent.identifier']);
|
||||
alert('Cleared Shortcut 2');
|
||||
} catch (e) {
|
||||
alert("You're not running iOS 12!");
|
||||
}
|
||||
}
|
||||
|
||||
async updateShortcutList() {
|
||||
try {
|
||||
const shortcuts = await getShortcuts();
|
||||
|
||||
this.setState({
|
||||
shortcuts,
|
||||
});
|
||||
} catch (e) {
|
||||
alert("You're not running iOS 12!");
|
||||
}
|
||||
}
|
||||
|
||||
async clearBothShortcuts() {
|
||||
try {
|
||||
await clearShortcutsWithIdentifiers([
|
||||
'com.github.gustash.SiriShortcutsModuleExample.sayHello',
|
||||
'some.persistent.identifier',
|
||||
]);
|
||||
alert('Cleared Both Shortcuts');
|
||||
} catch (e) {
|
||||
alert("You're not running iOS 12!");
|
||||
}
|
||||
}
|
||||
|
||||
async clearShortcuts() {
|
||||
try {
|
||||
await clearAllShortcuts();
|
||||
alert('Deleted all the shortcuts');
|
||||
} catch (e) {
|
||||
alert("You're not running iOS 12!");
|
||||
}
|
||||
}
|
||||
|
||||
swapSiriButtonTheme() {
|
||||
const { addToSiriStyle } = this.state;
|
||||
|
||||
const styles = Object.keys(SiriButtonStyles).map(
|
||||
key => SiriButtonStyles[key],
|
||||
);
|
||||
const index = styles.findIndex(style => style === addToSiriStyle);
|
||||
if (index === styles.length - 1) this.setState({ addToSiriStyle: styles[0] });
|
||||
else this.setState({ addToSiriStyle: styles[index + 1] });
|
||||
}
|
||||
|
||||
render() {
|
||||
const { shortcutInfo, shortcutActivityType, addToSiriStyle, shortcuts } =
|
||||
this.state;
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<ScrollView
|
||||
style={styles.container}
|
||||
contentContainerStyle={styles.contentContainer}>
|
||||
<Text>Shortcut Activity Type: {shortcutActivityType || 'None'}</Text>
|
||||
<Text>
|
||||
Shortcut Info:{' '}
|
||||
{shortcutInfo ? JSON.stringify(shortcutInfo) : 'No shortcut data.'}
|
||||
</Text>
|
||||
<Button
|
||||
title="Create Shortcut 1"
|
||||
onPress={this.setupShortcut1.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Create Shortcut 2"
|
||||
onPress={this.setupShortcut2.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Clear Shortcut 1"
|
||||
onPress={this.clearShortcut1.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Clear Shortcut 2"
|
||||
onPress={this.clearShortcut2.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Clear Both Shortcuts"
|
||||
onPress={this.clearBothShortcuts.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Delete All Shortcuts"
|
||||
onPress={this.clearShortcuts.bind(this)}
|
||||
/>
|
||||
<Button
|
||||
title="Update list of shortcuts"
|
||||
onPress={this.updateShortcutList.bind(this)}
|
||||
/>
|
||||
<AddToSiriButton
|
||||
buttonStyle={addToSiriStyle}
|
||||
onPress={() => {
|
||||
presentShortcut(opts1, ({ status }) => {
|
||||
console.log(`I was ${status}`);
|
||||
});
|
||||
}}
|
||||
shortcut={opts1}
|
||||
/>
|
||||
<Button
|
||||
title="Swap Siri Button Theme"
|
||||
onPress={this.swapSiriButtonTheme.bind(this)}
|
||||
/>
|
||||
{shortcuts.length ? (
|
||||
shortcuts.map(({ identifier, phrase, options }, i) => (
|
||||
<View key={identifier}>
|
||||
<Text>Shortcut {i + 1}:</Text>
|
||||
<Text>Identifier - {identifier}</Text>
|
||||
<Text>Phrase - {phrase}</Text>
|
||||
<Text>Options - {JSON.stringify(options)}</Text>
|
||||
</View>
|
||||
))
|
||||
) : (
|
||||
<Text>No Shortcuts yet</Text>
|
||||
)}
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
contentContainer: {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,6 @@
|
||||
import React from 'react';
|
||||
import { View, Text } from 'react-native';
|
||||
|
||||
export default function App() {
|
||||
return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>No-op on this platform</Text></View>)
|
||||
}
|
||||
@@ -1,3 +1,10 @@
|
||||
### @config-plugins/ios-stickers [2.0.2](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-06-30)
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* **deps-dev:** bump memfs in /packages/ios-stickers ([#83](https://github.com/expo/config-plugins/issues/83)) ([764a047](https://github.com/expo/config-plugins/commit/764a04710bea6e66dbc6d0065812acb1591435fb))
|
||||
|
||||
### @config-plugins/ios-stickers [2.0.1](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-05-30)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@config-plugins/ios-stickers",
|
||||
"version": "2.0.1",
|
||||
"version": "2.0.2",
|
||||
"description": "Config plugin to auto configure iOS iMessage stickers",
|
||||
"main": "build/withStickerPack.js",
|
||||
"types": "build/withStickerPack.d.ts",
|
||||
@@ -34,6 +34,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"expo-module-scripts": "^2.0.0",
|
||||
"memfs": "^2.15.5"
|
||||
"memfs": "^3.4.4"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,19 @@
|
||||
## @config-plugins/react-native-callkeep [2.0.0](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-07-25)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add SDK 45 support (#79)
|
||||
|
||||
### Features
|
||||
|
||||
* add SDK 45 support ([#79](https://github.com/expo/config-plugins/issues/79)) ([96c72dd](https://github.com/expo/config-plugins/commit/96c72dda469ace2b9eafd38ba4d21f1bcd2e3cdf))
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* publish packages [no-ci] ([0c7b413](https://github.com/expo/config-plugins/commit/0c7b413a765e4b1ff92b9e3edc2b62077c41ce46))
|
||||
|
||||
### @config-plugins/react-native-callkeep [1.0.3](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-03-22)
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
## @config-plugins/react-native-dynamic-app-icon [2.0.0](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-06-14)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add SDK 45 support (#79)
|
||||
|
||||
### Features
|
||||
|
||||
* add SDK 45 support ([#79](https://github.com/expo/config-plugins/issues/79)) ([96c72dd](https://github.com/expo/config-plugins/commit/96c72dda469ace2b9eafd38ba4d21f1bcd2e3cdf))
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* publish packages [no-ci] ([0c7b413](https://github.com/expo/config-plugins/commit/0c7b413a765e4b1ff92b9e3edc2b62077c41ce46))
|
||||
|
||||
### @config-plugins/react-native-dynamic-app-icon [1.0.3](https://github.com/expo/config-plugins/compare/@config-plugins/[email protected]...@config-plugins/[email protected]) (2022-05-12)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
## @config-plugins/react-native-siri-shortcut 1.0.0 (2022-07-12)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **siri-shortcut:** Add config plugin ([#86](https://github.com/expo/config-plugins/issues/86)) ([226b2a6](https://github.com/expo/config-plugins/commit/226b2a6412ad3fe75c98952831fab5a63254d19f))
|
||||
|
||||
|
||||
### Other chores
|
||||
|
||||
* **react-native-siri-shortcut:** add tests ([#88](https://github.com/expo/config-plugins/issues/88)) ([994fadc](https://github.com/expo/config-plugins/commit/994fadc8ddf9ee858f2ccb7d544674f107f7f9ad))
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { ConfigPlugin } from "@expo/config-plugins";
|
||||
import { MergeResults } from "@expo/config-plugins/build/utils/generateCode";
|
||||
export declare function addSiriShortcutAppDelegateImport(src: string): MergeResults;
|
||||
export declare function addSiriShortcutAppDelegateInit(src: string): MergeResults;
|
||||
declare const _default: ConfigPlugin<void | string[]>;
|
||||
export default _default;
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.addSiriShortcutAppDelegateInit = exports.addSiriShortcutAppDelegateImport = void 0;
|
||||
const config_plugins_1 = require("@expo/config-plugins");
|
||||
const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
|
||||
/**
|
||||
* Apply react-native-siri-shortcut configuration for Expo SDK 44 projects.
|
||||
*/
|
||||
const withReactNativeSiriShortcut = (config, activityTypes) => {
|
||||
withSiriShortcutAppDelegate(config);
|
||||
withSiriEntitlements(config);
|
||||
const items = activityTypes || [];
|
||||
if (!Array.isArray(items) || !items.length) {
|
||||
return config;
|
||||
}
|
||||
return withReactNativeSiriShortcutInfoPlist(config, items);
|
||||
};
|
||||
const withReactNativeSiriShortcutInfoPlist = (config, activityTypes) => {
|
||||
return config_plugins_1.withInfoPlist(config, (config) => {
|
||||
config.modResults.NSUserActivityTypes = activityTypes;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
function addSiriShortcutAppDelegateImport(src) {
|
||||
return generateCode_1.mergeContents({
|
||||
tag: "react-native-siri-shortcut",
|
||||
src,
|
||||
newSrc: "#import <RNSiriShortcuts/RNSiriShortcuts.h>",
|
||||
anchor: /#import "AppDelegate\.h"/,
|
||||
offset: 1,
|
||||
comment: "//",
|
||||
});
|
||||
}
|
||||
exports.addSiriShortcutAppDelegateImport = addSiriShortcutAppDelegateImport;
|
||||
function addSiriShortcutAppDelegateInit(src) {
|
||||
return generateCode_1.mergeContents({
|
||||
tag: "react-native-siri-shortcut-delegate",
|
||||
src,
|
||||
newSrc: [
|
||||
" BOOL shortcutResult = [RNSSSiriShortcuts application:application continueUserActivity:userActivity restorationHandler:restorationHandler];",
|
||||
" if (shortcutResult) {",
|
||||
" return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || shortcutResult;",
|
||||
" }",
|
||||
].join("\n"),
|
||||
anchor: / return \[super application:application continueUserActivity:userActivity restorationHandler:restorationHandler\] \|\| result;/,
|
||||
offset: -1,
|
||||
comment: "//",
|
||||
});
|
||||
}
|
||||
exports.addSiriShortcutAppDelegateInit = addSiriShortcutAppDelegateInit;
|
||||
/** Append the siri entitlement on iOS */
|
||||
const withSiriEntitlements = (config) => {
|
||||
return config_plugins_1.withEntitlementsPlist(config, (config) => {
|
||||
config.modResults["com.apple.developer.siri"] = true;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
const withSiriShortcutAppDelegate = (config) => {
|
||||
return config_plugins_1.withAppDelegate(config, (config) => {
|
||||
if (["objc", "objcpp"].includes(config.modResults.language)) {
|
||||
try {
|
||||
config.modResults.contents = addSiriShortcutAppDelegateImport(config.modResults.contents).contents;
|
||||
config.modResults.contents = addSiriShortcutAppDelegateInit(config.modResults.contents).contents;
|
||||
}
|
||||
catch (error) {
|
||||
if (error.code === "ERR_NO_MATCH") {
|
||||
throw new Error(`Cannot add Siri Shortcut to the project's AppDelegate because it's malformed. Please report this with a copy of your project AppDelegate.`);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error("Cannot setup Siri Shortcut because the AppDelegate is not Objective C");
|
||||
}
|
||||
return config;
|
||||
});
|
||||
};
|
||||
const pkg = {
|
||||
// Prevent this plugin from being run more than once.
|
||||
// This pattern enables users to safely migrate off of this
|
||||
// out-of-tree `@config-plugins/react-native-siri-shortcut` to a future
|
||||
// upstream plugin in `react-native-siri-shortcut`
|
||||
name: "react-native-siri-shortcut",
|
||||
// Indicates that this plugin is dangerously linked to a module,
|
||||
// and might not work with the latest version of that module.
|
||||
version: "UNVERSIONED",
|
||||
};
|
||||
exports.default = config_plugins_1.createRunOncePlugin(withReactNativeSiriShortcut, pkg.name, pkg.version);
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require('expo-module-scripts/jest-preset-plugin');
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@config-plugins/react-native-siri-shortcut",
|
||||
"version": "0.0.0",
|
||||
"version": "1.0.0",
|
||||
"description": "Config plugin for react-native-siri-shortcut package",
|
||||
"main": "build/withReactNativeSiriShortcut.js",
|
||||
"types": "build/withReactNativeSiriShortcut.d.ts",
|
||||
@@ -35,5 +35,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"expo-module-scripts": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"upstreamPackage": "react-native-siri-shortcut"
|
||||
}
|
||||
+306
@@ -0,0 +1,306 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`addSiriShortcutAppDelegateImport adds import to Expo Modules AppDelegate 1`] = `
|
||||
"
|
||||
#import \\"AppDelegate.h\\"
|
||||
// @generated begin react-native-siri-shortcut - expo prebuild (DO NOT MODIFY) sync-34828decdfd158f5b96fe11a1e590a684e296e0e
|
||||
#import <RNSiriShortcuts/RNSiriShortcuts.h>
|
||||
// @generated end react-native-siri-shortcut
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import <React/RCTAppSetupUtils.h>
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
#import <React/CoreModulesPlugins.h>
|
||||
#import <React/RCTCxxBridgeDelegate.h>
|
||||
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||
#import <React/RCTSurfacePresenter.h>
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||
facebook::react::ContextContainer::Shared _contextContainer;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTAppSetupPrepareApp(application);
|
||||
|
||||
RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert(\\"ReactNativeConfig\\", _reactNativeConfig);
|
||||
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
|
||||
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
#endif
|
||||
|
||||
UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@\\"main\\" initialProperties:nil];
|
||||
|
||||
rootView.backgroundColor = [UIColor whiteColor];
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [self.reactDelegate createRootViewController];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
[super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
// If you'd like to export some custom RCTBridgeModules, add them here!
|
||||
return @[];
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@\\"index\\"];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@\\"main\\" withExtension:@\\"jsbundle\\"];
|
||||
#endif
|
||||
}
|
||||
|
||||
// Linking API
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
|
||||
}
|
||||
|
||||
// Universal Links
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
|
||||
BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
||||
{
|
||||
return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
|
||||
{
|
||||
return [super application:application didFailToRegisterForRemoteNotificationsWithError:error];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
|
||||
}
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
|
||||
#pragma mark - RCTCxxBridgeDelegate
|
||||
|
||||
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||
delegate:self
|
||||
jsInvoker:bridge.jsCallInvoker];
|
||||
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||
}
|
||||
|
||||
#pragma mark RCTTurboModuleManagerDelegate
|
||||
|
||||
- (Class)getModuleClassFromName:(const char *)name
|
||||
{
|
||||
return RCTCoreModulesClassProvider(name);
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
initParams:
|
||||
(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
|
||||
{
|
||||
return RCTAppSetupDefaultModuleFromClass(moduleClass);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`addSiriShortcutAppDelegateInit adds init to Expo Modules AppDelegate 1`] = `
|
||||
"
|
||||
#import \\"AppDelegate.h\\"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import <React/RCTAppSetupUtils.h>
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
#import <React/CoreModulesPlugins.h>
|
||||
#import <React/RCTCxxBridgeDelegate.h>
|
||||
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||
#import <React/RCTSurfacePresenter.h>
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||
facebook::react::ContextContainer::Shared _contextContainer;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTAppSetupPrepareApp(application);
|
||||
|
||||
RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert(\\"ReactNativeConfig\\", _reactNativeConfig);
|
||||
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
|
||||
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
#endif
|
||||
|
||||
UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@\\"main\\" initialProperties:nil];
|
||||
|
||||
rootView.backgroundColor = [UIColor whiteColor];
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [self.reactDelegate createRootViewController];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
[super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
// If you'd like to export some custom RCTBridgeModules, add them here!
|
||||
return @[];
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@\\"index\\"];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@\\"main\\" withExtension:@\\"jsbundle\\"];
|
||||
#endif
|
||||
}
|
||||
|
||||
// Linking API
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
|
||||
}
|
||||
|
||||
// Universal Links
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
|
||||
// @generated begin react-native-siri-shortcut-delegate - expo prebuild (DO NOT MODIFY) sync-291450a04ff243636b0bd0aef4a614f7218690b5
|
||||
BOOL shortcutResult = [RNSSSiriShortcuts application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
if (shortcutResult) {
|
||||
return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || shortcutResult;
|
||||
}
|
||||
// @generated end react-native-siri-shortcut-delegate
|
||||
BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
||||
{
|
||||
return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
|
||||
{
|
||||
return [super application:application didFailToRegisterForRemoteNotificationsWithError:error];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
|
||||
}
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
|
||||
#pragma mark - RCTCxxBridgeDelegate
|
||||
|
||||
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||
delegate:self
|
||||
jsInvoker:bridge.jsCallInvoker];
|
||||
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||
}
|
||||
|
||||
#pragma mark RCTTurboModuleManagerDelegate
|
||||
|
||||
- (Class)getModuleClassFromName:(const char *)name
|
||||
{
|
||||
return RCTCoreModulesClassProvider(name);
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
initParams:
|
||||
(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
|
||||
{
|
||||
return RCTAppSetupDefaultModuleFromClass(moduleClass);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
"
|
||||
`;
|
||||
@@ -0,0 +1,146 @@
|
||||
// SDK +45: https://github.com/expo/expo/blob/sdk-45/templates/expo-template-bare-minimum/ios/HelloWorld/AppDelegate.m
|
||||
export const ExpoModulesAppDelegate = `
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import <React/RCTAppSetupUtils.h>
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
#import <React/CoreModulesPlugins.h>
|
||||
#import <React/RCTCxxBridgeDelegate.h>
|
||||
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
|
||||
#import <React/RCTSurfacePresenter.h>
|
||||
#import <React/RCTSurfacePresenterBridgeAdapter.h>
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
|
||||
#import <react/config/ReactNativeConfig.h>
|
||||
|
||||
@interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
|
||||
RCTTurboModuleManager *_turboModuleManager;
|
||||
RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
|
||||
std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
|
||||
facebook::react::ContextContainer::Shared _contextContainer;
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
RCTAppSetupPrepareApp(application);
|
||||
|
||||
RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
|
||||
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
|
||||
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
|
||||
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
|
||||
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
|
||||
#endif
|
||||
|
||||
UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:nil];
|
||||
|
||||
rootView.backgroundColor = [UIColor whiteColor];
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
UIViewController *rootViewController = [self.reactDelegate createRootViewController];
|
||||
rootViewController.view = rootView;
|
||||
self.window.rootViewController = rootViewController;
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
[super application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
// If you'd like to export some custom RCTBridgeModules, add them here!
|
||||
return @[];
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
#endif
|
||||
}
|
||||
|
||||
// Linking API
|
||||
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
|
||||
}
|
||||
|
||||
// Universal Links
|
||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
|
||||
BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
|
||||
return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
|
||||
{
|
||||
return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
|
||||
{
|
||||
return [super application:application didFailToRegisterForRemoteNotificationsWithError:error];
|
||||
}
|
||||
|
||||
// Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
|
||||
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
|
||||
{
|
||||
return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
|
||||
}
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
|
||||
#pragma mark - RCTCxxBridgeDelegate
|
||||
|
||||
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
|
||||
delegate:self
|
||||
jsInvoker:bridge.jsCallInvoker];
|
||||
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
|
||||
}
|
||||
|
||||
#pragma mark RCTTurboModuleManagerDelegate
|
||||
|
||||
- (Class)getModuleClassFromName:(const char *)name
|
||||
{
|
||||
return RCTCoreModulesClassProvider(name);
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
||||
initParams:
|
||||
(const facebook::react::ObjCTurboModule::InitParams &)params
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
|
||||
{
|
||||
return RCTAppSetupDefaultModuleFromClass(moduleClass);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
`;
|
||||
@@ -0,0 +1,42 @@
|
||||
import {
|
||||
addSiriShortcutAppDelegateImport,
|
||||
addSiriShortcutAppDelegateInit,
|
||||
} from "../withReactNativeSiriShortcut";
|
||||
import { ExpoModulesAppDelegate } from "./fixtures/AppDelegate";
|
||||
|
||||
describe(addSiriShortcutAppDelegateImport, () => {
|
||||
it(`adds import to Expo Modules AppDelegate`, () => {
|
||||
const results = addSiriShortcutAppDelegateImport(ExpoModulesAppDelegate);
|
||||
// matches a static snapshot
|
||||
expect(results.contents).toMatchSnapshot();
|
||||
expect(results.contents).toMatch(/react-native-siri-shortcut/);
|
||||
expect(results.contents).toMatch(/RNSiriShortcuts\/RNSiriShortcuts\.h/);
|
||||
// did add new content
|
||||
expect(results.didMerge).toBe(true);
|
||||
// didn't remove old content
|
||||
expect(results.didClear).toBe(false);
|
||||
});
|
||||
|
||||
it(`fails to add to a malformed app delegate`, () => {
|
||||
expect(() => addSiriShortcutAppDelegateImport(`foobar`)).toThrow(/foobar/);
|
||||
});
|
||||
});
|
||||
describe(addSiriShortcutAppDelegateInit, () => {
|
||||
it(`adds init to Expo Modules AppDelegate`, () => {
|
||||
const results = addSiriShortcutAppDelegateInit(ExpoModulesAppDelegate);
|
||||
// matches a static snapshot
|
||||
expect(results.contents).toMatchSnapshot();
|
||||
expect(results.contents).toMatch(/react-native-siri-shortcut-delegate/);
|
||||
expect(results.contents).toMatch(
|
||||
/RNSSSiriShortcuts application:application/
|
||||
);
|
||||
// did add new content
|
||||
expect(results.didMerge).toBe(true);
|
||||
// didn't remove old content
|
||||
expect(results.didClear).toBe(false);
|
||||
});
|
||||
|
||||
it(`fails to add to a malformed app delegate`, () => {
|
||||
expect(() => addSiriShortcutAppDelegateInit(`foobar`)).toThrow(/foobar/);
|
||||
});
|
||||
});
|
||||
@@ -17,16 +17,23 @@ const withReactNativeSiriShortcut: ConfigPlugin<void | string[]> = (
|
||||
config,
|
||||
activityTypes
|
||||
) => {
|
||||
config = withSiriShortcutAppDelegate(config);
|
||||
withSiriShortcutAppDelegate(config);
|
||||
withSiriEntitlements(config);
|
||||
|
||||
const items = activityTypes || [];
|
||||
|
||||
if (!Array.isArray(items) || !items.length) {
|
||||
return config;
|
||||
}
|
||||
return withReactNativeSiriShortcutInfoPlist(config, items);
|
||||
};
|
||||
|
||||
const withReactNativeSiriShortcutInfoPlist: ConfigPlugin<string[]> = (
|
||||
config,
|
||||
activityTypes
|
||||
) => {
|
||||
return withInfoPlist(config, (config) => {
|
||||
config.modResults.NSUserActivityTypes = items;
|
||||
config.modResults.NSUserActivityTypes = activityTypes;
|
||||
return config;
|
||||
});
|
||||
};
|
||||
@@ -43,25 +50,23 @@ export function addSiriShortcutAppDelegateImport(src: string): MergeResults {
|
||||
}
|
||||
|
||||
export function addSiriShortcutAppDelegateInit(src: string): MergeResults {
|
||||
const newSrc = [];
|
||||
newSrc.push(
|
||||
" BOOL shortcutResult = [RNSSSiriShortcuts application:application continueUserActivity:userActivity restorationHandler:restorationHandler];",
|
||||
" if (shortcutResult) {",
|
||||
" return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || shortcutResult;",
|
||||
" }"
|
||||
);
|
||||
|
||||
console.log(src);
|
||||
return mergeContents({
|
||||
tag: "react-native-siri-shortcut-delegate",
|
||||
src,
|
||||
newSrc: newSrc.join("\n"),
|
||||
newSrc: [
|
||||
" BOOL shortcutResult = [RNSSSiriShortcuts application:application continueUserActivity:userActivity restorationHandler:restorationHandler];",
|
||||
" if (shortcutResult) {",
|
||||
" return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || shortcutResult;",
|
||||
" }",
|
||||
].join("\n"),
|
||||
anchor:
|
||||
/ return \[super application:application continueUserActivity:userActivity restorationHandler:restorationHandler\] \|\| result;/,
|
||||
offset: -1,
|
||||
comment: "//",
|
||||
});
|
||||
}
|
||||
|
||||
/** Append the siri entitlement on iOS */
|
||||
const withSiriEntitlements: ConfigPlugin = (config) => {
|
||||
return withEntitlementsPlist(config, (config) => {
|
||||
config.modResults["com.apple.developer.siri"] = true;
|
||||
@@ -70,7 +75,7 @@ const withSiriEntitlements: ConfigPlugin = (config) => {
|
||||
};
|
||||
|
||||
const withSiriShortcutAppDelegate: ConfigPlugin = (config) => {
|
||||
let cfg = withAppDelegate(config, (config) => {
|
||||
return withAppDelegate(config, (config) => {
|
||||
if (["objc", "objcpp"].includes(config.modResults.language)) {
|
||||
try {
|
||||
config.modResults.contents = addSiriShortcutAppDelegateImport(
|
||||
@@ -94,9 +99,6 @@ const withSiriShortcutAppDelegate: ConfigPlugin = (config) => {
|
||||
}
|
||||
return config;
|
||||
});
|
||||
cfg = withSiriEntitlements(cfg);
|
||||
|
||||
return cfg;
|
||||
};
|
||||
|
||||
const pkg = {
|
||||
|
||||
@@ -16941,6 +16941,11 @@ [email protected]:
|
||||
resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.2.4.tgz#4df42819759c4d3c74252c8678c2772cfa2271a6"
|
||||
integrity sha512-OOX+W2G4YYufvryonn6Kw6YnyT8ZThkxPHZBD04NLHaZmicUaaDVII/PZ3M5fD1o5N62+T+8K4bCS5Un2ggvkA==
|
||||
|
||||
react-native-siri-shortcut@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-native-siri-shortcut/-/react-native-siri-shortcut-3.1.0.tgz#920adf41eb6c72c93ef8571259c8d35358e50e71"
|
||||
integrity sha512-MM0f7HS3ADU2gUh0Q6n935uhdfA3KgjpN8hEEhf2RSf4azcRNh8zNMwZD08pGSrP9/JYj1kYndQ0oytpwPyk/A==
|
||||
|
||||
[email protected]:
|
||||
version "0.17.7"
|
||||
resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.17.7.tgz#038899dbc94467a0ca0be214b88a30e0c117b176"
|
||||
@@ -20118,10 +20123,8 @@ watchpack@^1.6.1:
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453"
|
||||
integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==
|
||||
dependencies:
|
||||
chokidar "^3.4.1"
|
||||
graceful-fs "^4.1.2"
|
||||
neo-async "^2.5.0"
|
||||
watchpack-chokidar2 "^2.0.1"
|
||||
optionalDependencies:
|
||||
chokidar "^3.4.1"
|
||||
watchpack-chokidar2 "^2.0.1"
|
||||
|
||||
Reference in new issue
Block a user