Skip to content

Commit

Permalink
Added Expo config plugin (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
sakshya73 authored Mar 7, 2022
1 parent 3eef7b8 commit 8ab386e
Show file tree
Hide file tree
Showing 7 changed files with 632 additions and 46 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
*.xcuserstate

\.DS_Store

plugin/build
107 changes: 63 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ A React Native module for iOS that provides Spotlight search functionality. This

## Current Features

* Adding items.
* Updating items.
* Deleting items.
* Register a callback to handle when a search item is tapped.
* Support for images
- Adding items.
- Updating items.
- Deleting items.
- Register a callback to handle when a search item is tapped.
- Support for images

![Spotlight Search Demo](http://i.imgur.com/tbI3yAs.gif)

Expand All @@ -22,10 +22,30 @@ Or with NPM:

### iOS

#### Expo

<h2 align="center">Prebuild Plugin</h2>

> This package cannot be used in the "Expo Go" app because [it requires custom native code](https://docs.expo.io/workflow/customizing/).
After installing this npm package, add the [config plugin](https://docs.expo.io/guides/config-plugins/) to the [`plugins`](https://docs.expo.io/versions/latest/config/app/#plugins) array of your `app.json` or `app.config.js`:

```json
{
"expo": {
"plugins": ["react-native-spotlight-search"]
}
}
```

Next, rebuild your app as described in the ["Adding custom native code"](https://docs.expo.io/workflow/customizing/) guide.

#### RN >= 0.60

Auto linking or Manually below

#### RN < 0.60

`react-native link react-native-spotlight-search` or Manually below

Simply add `RCTSpotlightSearch.xcodeproj` to **Libraries** and add `libRCTSpotlightSearch.a` to **Link Binary With Libraries** under **Build Phases**. [More info and screenshots about how to do this is available in the React Native documentation](http://facebook.github.io/react-native/docs/linking-libraries-ios.html#content).
Expand Down Expand Up @@ -56,7 +76,7 @@ Like this:
First up, import the module:
```js
import SpotlightSearch from 'react-native-spotlight-search';
import SpotlightSearch from "react-native-spotlight-search";
```

### Indexing Items
Expand All @@ -65,45 +85,45 @@ You can either add an array of items:

```js
SpotlightSearch.indexItems([
{
title: 'Strawberry',
contentDescription: 'A sweet and juicy fruit.',
uniqueIdentifier: '1',
domain: 'fruit',
thumbnailName: 'strawberry',
},
{
title: 'Kiwi',
contentDescription: 'Not a type of bird.',
uniqueIdentifier: '2',
domain: 'fruit',
thumbnailName: 'kiwi',
},
{
title: "Strawberry",
contentDescription: "A sweet and juicy fruit.",
uniqueIdentifier: "1",
domain: "fruit",
thumbnailName: "strawberry",
},
{
title: "Kiwi",
contentDescription: "Not a type of bird.",
uniqueIdentifier: "2",
domain: "fruit",
thumbnailName: "kiwi",
},
]);
```

Or individual items:

```js
SpotlightSearch.indexItem({
title: 'Strawberry',
contentDescription: 'A sweet and juicy fruit.',
uniqueIdentifier: '1',
thumbnailName: 'strawberry',
title: "Strawberry",
contentDescription: "A sweet and juicy fruit.",
uniqueIdentifier: "1",
thumbnailName: "strawberry",
});
```

#### Search Item Properties

| Property | Description | Type | Required |
|---|----|---|---|
|**`title`**|The title of the search item.|`string`|Yes|
|**`contentDescription`**|A description which appears below the title in the search results.|`string`|No|
|**`uniqueIdentifier`**|A unique and stable identifier. Used to refer to the item. |`string`|Yes|
|**`domain`**|A string for grouping related items together in a way that makes sense. Not displayed to the user. |`string`|Yes|
|**`thumbnailName`**|A local file name/key to a thumbnail image. See [A Note About Thumbnails](#a-note-about-thumbnails).|`string`|No|
|**`thumbnailData`**|A base64 string representation of a thumbnail image. See [A Note About Thumbnails](#a-note-about-thumbnails).|`string`|No|
|**`keywords`**|An array of keywords which can be used to help inform the search index. Not visible to the user.|`[string]`|No|
| Property | Description | Type | Required |
| ------------------------ | ------------------------------------------------------------------------------------------------------------- | ---------- | -------- |
| **`title`** | The title of the search item. | `string` | Yes |
| **`contentDescription`** | A description which appears below the title in the search results. | `string` | No |
| **`uniqueIdentifier`** | A unique and stable identifier. Used to refer to the item. | `string` | Yes |
| **`domain`** | A string for grouping related items together in a way that makes sense. Not displayed to the user. | `string` | Yes |
| **`thumbnailName`** | A local file name/key to a thumbnail image. See [A Note About Thumbnails](#a-note-about-thumbnails). | `string` | No |
| **`thumbnailData`** | A base64 string representation of a thumbnail image. See [A Note About Thumbnails](#a-note-about-thumbnails). | `string` | No |
| **`keywords`** | An array of keywords which can be used to help inform the search index. Not visible to the user. | `[string]` | No |

### Updating Items

Expand Down Expand Up @@ -136,10 +156,10 @@ All API index and delete methods are asynchronous and return promises. You can c
```js
SpotlightSearch.deleteAllItems().then(() => {
SpotlightSearch.indexItem({
title: 'Strawberry',
contentDescription: 'A sweet and juicy fruit.',
uniqueIdentifier: '1',
thumbnailName: 'strawberry',
title: "Strawberry",
contentDescription: "A sweet and juicy fruit.",
uniqueIdentifier: "1",
thumbnailName: "strawberry",
});
});
```
Expand All @@ -160,23 +180,22 @@ Optionally, if you want to capture the search item that was tapped to open the a
SpotlightSearch.getInitialSearchItem().then((uniqueIdentifier) => {
alert(`You tapped on ${uniqueIdentifier} and opened the app!`);
});

```

The parameter will be the ```uniqueIdentifier``` that the item was indexed with. You can use this to lookup the item and display information about it, e.g. by navigating to a relevant page in your app.
The parameter will be the `uniqueIdentifier` that the item was indexed with. You can use this to lookup the item and display information about it, e.g. by navigating to a relevant page in your app.

## A Note About Thumbnails

Currently, in order to use an image path it must exist locally on the device in the project assets folder. This is a limitation of iOS rather than of this library.

To use images that are not in your assets folder (local or remote files), read them as
base64 and include the string value using the ```thumbnailData``` property.
base64 and include the string value using the `thumbnailData` property.

## To-do

* Support additional built in types (location etc).
* Public links.
* Initial release.
* New iOS 10 features.
- Support additional built in types (location etc).
- Public links.
- Initial release.
- New iOS 10 features.

PRs welcome ❤️
1 change: 1 addition & 0 deletions app.plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("./plugin/build/withSpotlight");
12 changes: 10 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@
"index.js",
"index.d.ts",
"ios/*",
"react-native-spotlight-search.podspec"
"react-native-spotlight-search.podspec",
"plugin/*"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"postinstall": "yarn build:plugin",
"build:plugin": "tsc --build plugin"
},
"repository": {
"type": "git",
Expand All @@ -32,5 +35,10 @@
"homepage": "https://github.com/jdmunro/react-native-spotlight-search#readme",
"peerDependencies": {
"react-native": "*"
},
"dependencies": {
"@expo/config-plugins": "^4.0.6",
"@types/node": "^16.11.5",
"typescript": "^4.4.4"
}
}
50 changes: 50 additions & 0 deletions plugin/src/withSpotlight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
ConfigPlugin,
createRunOncePlugin,
WarningAggregator,
withAppDelegate,
} from "@expo/config-plugins";

const pkg = require("react-native-spotlight-search/package.json");

const SPOTLIGHT_IMPORT = `#import "RCTSpotlightSearch.h"
`;
const SPOTLIGHT_ACTIVITY = `- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {`;

const SPOTLIGHT_ACTIVITY_ADD = `- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
[RCTSpotlightSearch handleContinueUserActivity:userActivity];
return YES;`;

const modifyAppDelegate = (appDelegate: string) => {
if (!appDelegate.includes(SPOTLIGHT_IMPORT)) {
appDelegate = SPOTLIGHT_IMPORT + appDelegate;
}
const updatedAppDelegate = appDelegate.replace(
SPOTLIGHT_ACTIVITY,
SPOTLIGHT_ACTIVITY_ADD
);
return updatedAppDelegate;
};

const withSpotlightAppDelegate = (config: any) => {
return withAppDelegate(config, (config) => {
if (config.modResults.language === "objc") {
config.modResults.contents = modifyAppDelegate(
config.modResults.contents
);
} else {
WarningAggregator.addWarningIOS(
"withSpotlightAppDelegate",
"Swift AppDelegate files are not supported yet."
);
}
return config;
});
};

const withSpotlight: ConfigPlugin<void> = (config) => {
config = withSpotlightAppDelegate(config);
return config;
};

export default createRunOncePlugin(withSpotlight, pkg.name, pkg.version);
15 changes: 15 additions & 0 deletions plugin/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"outDir": "build",
"rootDir": "src",
"declaration": true,
"lib": ["es2018"],
"module": "commonjs",
"target": "es2018",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["./src"]
}
Loading

0 comments on commit 8ab386e

Please sign in to comment.