diff --git a/README.md b/README.md index 6555533..ba9fcd0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ npm downloads - A **config plugin** for Expo to check for the existence of installed apps on Android and iOS. > **Note:** This library supports **Expo SDK 51 and above**. @@ -22,6 +21,7 @@ A **config plugin** for Expo to check for the existence of installed apps on And - [Manual Configuration](#manual-configuration) - [API Documentation](#api-documentation) - [`checkInstalledApps`](#checkinstalledapps) + - [`checkInstalledAppsSync`](#checkinstalledappssync) - [Example Usage](#example-usage) - [Contributing](#contributing) - [Support the Project](#support-the-project) @@ -107,20 +107,36 @@ Add the URL schemes to your `Info.plist`: ### `checkInstalledApps` -Checks whether specific apps are installed on the user's device. +Checks asynchronously whether specific apps are installed on the user's device. #### Parameters -- **`packageNames`** (`Array`): +- **`packageNames`** (`Array`): An array of package names (for Android) or URL schemes (for iOS) to check. #### Returns -- **`Promise>`**: +- **`Promise>`**: Resolves to an object where keys are package names or URL schemes, and values are booleans: - `true`: App is installed. - `false`: App is not installed. +### `checkInstalledAppsSync` + +Checks synchronously whether specific apps are installed on the user's device. + +#### Parameters + +- **`packageNames`** (`Array`): + An array of package names (for Android) or URL schemes (for iOS) to check. + +#### Returns + +- **`Record`**: + Returns an object where keys are package names or URL schemes, and values are booleans: + - `true`: App is installed. + - `false`: App is not installed. + --- ## Example Usage @@ -167,5 +183,5 @@ Contributions are welcome! If you find this library helpful, consider supporting it: -[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-Support%20Me-orange?logo=buymeacoffee)](https://www.buymeacoffee.com/mantu.728) +[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-Support%20Me-orange?logo=buymeacoffee)](https://www.buymeacoffee.com/mantu.728) [![Donate via PayPal](https://img.shields.io/badge/Donate-PayPal-blue?logo=paypal)](https://paypal.me/Monty728) diff --git a/android/src/main/java/expo/modules/checkinstalledapps/ExpoCheckInstalledAppsModule.kt b/android/src/main/java/expo/modules/checkinstalledapps/ExpoCheckInstalledAppsModule.kt index 7f68240..8951424 100644 --- a/android/src/main/java/expo/modules/checkinstalledapps/ExpoCheckInstalledAppsModule.kt +++ b/android/src/main/java/expo/modules/checkinstalledapps/ExpoCheckInstalledAppsModule.kt @@ -32,24 +32,32 @@ class ExpoCheckInstalledAppsModule : Module() { // is by default dispatched on the different thread than the JavaScript runtime runs on. AsyncFunction("setValueAsync") { value: String -> // Send an event to JavaScript. - sendEvent("onChange", mapOf( - "value" to value - )) + sendEvent( + "onChange", mapOf( + "value" to value + ) + ) } // An asynchronous function that takes a list of package names and returns their installation status. AsyncFunction("checkAppsInstalled") { packageNames: Array, promise: Promise -> // Call the function to check installed apps and return the result - checkAppsInstalled(packageNames, promise) + val result = checkAppsInstalled(packageNames) + promise.resolve(result) } + // A synchronous function that takes a list of package names and returns their installation status. + Function("checkAppsInstalledSync") { packageNames: Array -> + // Call the function to check installed apps and return the result + checkAppsInstalled(packageNames) + } } private val context get() = requireNotNull(appContext.reactContext) // Function to check if multiple apps are installed and resolve the promise with the result - private fun checkAppsInstalled(packageNames: Array, promise: Promise) { + private fun checkAppsInstalled(packageNames: Array): MutableMap { val pm: PackageManager = context.packageManager val result = mutableMapOf() @@ -63,7 +71,6 @@ class ExpoCheckInstalledAppsModule : Module() { } } - // Resolve the promise with the map of package names and installation statuses - promise.resolve(result) + return result; } } diff --git a/example/App.tsx b/example/App.tsx index 267f227..90f6c53 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -1,9 +1,12 @@ import { Platform, StyleSheet, Text, View } from "react-native"; -import { checkInstalledApps, hello } from "expo-check-installed-apps"; +import { + checkInstalledApps, + hello, + checkInstalledAppsSync, +} from "expo-check-installed-apps"; import { useEffect, useState } from "react"; export default function App() { - const [result, setResult] = useState({}); const packageNames: string[] = Platform.select({ android: [ @@ -14,6 +17,8 @@ export default function App() { ios: ["fb://", "twitter://"], }) || []; + const [result, setResult] = useState(checkInstalledAppsSync(packageNames)); + useEffect(() => { const checkInstalled = async () => { const checkInstalledAppsResult = await checkInstalledApps(packageNames); diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 4ab7265..99d07ae 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -7,7 +7,7 @@ PODS: - ExpoModulesCore - ExpoAsset (10.0.10): - ExpoModulesCore - - ExpoCheckInstalledApps (0.2.1): + - ExpoCheckInstalledApps (0.2.9): - ExpoModulesCore - ExpoFileSystem (17.0.1): - ExpoModulesCore @@ -1407,7 +1407,7 @@ SPEC CHECKSUMS: EXConstants: 409690fbfd5afea964e5e9d6c4eb2c2b59222c59 Expo: 9b6666ef2fedcfc89c5b9be2aa1ce12b81f9e7f5 ExpoAsset: 323700f291684f110fb55f0d4022a3362ea9f875 - ExpoCheckInstalledApps: d1181123d716af565c50ce02e2633db3c91056f0 + ExpoCheckInstalledApps: 870cfbbe26fc1fffd561b92686d352271ad50018 ExpoFileSystem: 80bfe850b1f9922c16905822ecbf97acd711dc51 ExpoFont: 00756e6c796d8f7ee8d211e29c8b619e75cbf238 ExpoKeepAwake: 3b8815d9dd1d419ee474df004021c69fdd316d08 @@ -1468,4 +1468,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: b4fee261fb7f6e5b531dd61914c93496c7af3ed4 -COCOAPODS: 1.14.3 +COCOAPODS: 1.16.2 diff --git a/example/ios/expocheckinstalledappsexample.xcodeproj/project.pbxproj b/example/ios/expocheckinstalledappsexample.xcodeproj/project.pbxproj index 466541b..9c07024 100644 --- a/example/ios/expocheckinstalledappsexample.xcodeproj/project.pbxproj +++ b/example/ios/expocheckinstalledappsexample.xcodeproj/project.pbxproj @@ -174,6 +174,8 @@ TargetAttributes = { 13B07F861A680F5B00A75B9A = { LastSwiftMigration = 1250; + DevelopmentTeam = "8T93V936A6"; + ProvisioningStyle = Automatic; }; }; }; @@ -349,12 +351,15 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = expo.modules.checkinstalledapps.example; - PRODUCT_NAME = "expocheckinstalledappsexample"; + PRODUCT_NAME = expocheckinstalledappsexample; SWIFT_OBJC_BRIDGING_HEADER = "expocheckinstalledappsexample/expocheckinstalledappsexample-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; + DEVELOPMENT_TEAM = "8T93V936A6"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; }; name = Debug; }; @@ -377,11 +382,14 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; PRODUCT_BUNDLE_IDENTIFIER = expo.modules.checkinstalledapps.example; - PRODUCT_NAME = "expocheckinstalledappsexample"; + PRODUCT_NAME = expocheckinstalledappsexample; SWIFT_OBJC_BRIDGING_HEADER = "expocheckinstalledappsexample/expocheckinstalledappsexample-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; + DEVELOPMENT_TEAM = "8T93V936A6"; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; }; name = Release; }; diff --git a/ios/ExpoCheckInstalledAppsModule.swift b/ios/ExpoCheckInstalledAppsModule.swift index 6ff51f5..6442eb1 100644 --- a/ios/ExpoCheckInstalledAppsModule.swift +++ b/ios/ExpoCheckInstalledAppsModule.swift @@ -33,17 +33,26 @@ public class ExpoCheckInstalledAppsModule: Module { } AsyncFunction("checkAppsInstalled") { (packageNames: [String], promise: Promise) in - var result: [String: Bool] = [:] - - for packageName in packageNames { - if let url = URL(string: packageName), UIApplication.shared.canOpenURL(url) { - result[packageName] = true - } else { - result[packageName] = false - } - } - - promise.resolve(result) - } + var result = checkAppsInstalled(packageNames: packageNames) + promise.resolve(result) + } + + Function("checkAppsInstalledSync") { (packageNames: [String]) in + return checkAppsInstalled(packageNames: packageNames) + } + } + + func checkAppsInstalled(packageNames: [String]) -> [String: Bool] { + var result: [String: Bool] = [:] + + for packageName in packageNames { + if let url = URL(string: packageName), UIApplication.shared.canOpenURL(url) { + result[packageName] = true + } else { + result[packageName] = false + } + } + + return result } } diff --git a/src/index.ts b/src/index.ts index 7b8fe40..4438faf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,6 +13,12 @@ export async function checkInstalledApps( return ExpoCheckInstalledAppsModule.checkAppsInstalled(packageNames); } +export function checkInstalledAppsSync( + packageNames: Array +): Record { + return ExpoCheckInstalledAppsModule.checkAppsInstalledSync(packageNames); +} + export async function setValueAsync(value: string) { return await ExpoCheckInstalledAppsModule.setValueAsync(value); }