Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc

# VSCode
.vscode

# macOS files
.DS_Store
Expand Down
44 changes: 42 additions & 2 deletions BREAKING.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,46 @@
## Versions

- [Capacitor 8 Update](#capacitor-8-update)
- [Version 4.x.x](#version-4xx)

---

## Capacitor 8 Update

### ⚠️ Breaking Change: Error Handling Strategy

**Starting from Capacitor 8, this plugin no longer rejects promises from native code.**

This is a consequence of changes in Capacitor’s native plugin APIs (specifically regarding Swift Package Manager on iOS), which removed or restricted direct promise rejection in iOS plugins.

**What changed:**
All plugin methods now always **resolve** and report errors via the returned object, following this pattern:

```javascript
// Old behavior (v4/v5/v6/v7)
try {
await NativeSettings.open(...);
} catch (error) {
console.error(error);
}

// New behavior (v8)
const result = await NativeSettings.open(...);
if (!result.success) {
console.error(result.error);
}

```

**Key Note:**

* Starting from **v8**, plugin methods **never reject promises**.
* Errors are returned in the resolved object as `{ success: false, error: "message" }`.

See: [Updating Plugins to Capacitor 8](https://capacitorjs.com/docs/updating/plugins/8-0)

---

## Version 4.x.x

### Capacitor 4
Expand All @@ -10,6 +49,7 @@ This plugin now supports Capacitor 4 only. Please run `npx cap sync` after updat

If you want to use this plugin with Capacitor 3, please install version `0.2.1`:

```
```bash
npm i capacitor-native-settings@0.2.1
```

```
2 changes: 1 addition & 1 deletion CapacitorNativeSettings.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Pod::Spec.new do |s|
s.author = package['author']
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
s.ios.deployment_target = '14.0'
s.ios.deployment_target = '15.0'
s.dependency 'Capacitor'
s.swift_version = '5.1'
end
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import PackageDescription

let package = Package(
name: "CapacitorNativeSettings",
platforms: [.iOS(.v14)],
platforms: [.iOS(.v15)],
products: [
.library(
name: "CapacitorNativeSettings",
targets: ["NativeSettingsPlugin"])
],
dependencies: [
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0")
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
],
targets: [
.target(
Expand Down
128 changes: 78 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ Capacitor plugin to open native settings screens for Android and iOS.

## Plugin versions

| Capacitor version | Plugin version |
| ---------- | ----------------------------------------- |
| v7 | >= v7.0.1 |
| v6 | >= v6.0.0 |
| v5 | >= v5.0.0 |
| v4 | >= v4.0.0 |
| v3 | <= v2.0.1 |
| Capacitor version | Plugin version |
| ----------------- | -------------- |
| v8 | >= v8.0.0 |
| v7 | >= v7.0.1 |
| v6 | >= v6.0.0 |
| v5 | >= v5.0.0 |
| v4 | >= v4.0.0 |
| v3 | <= v2.0.1 |

## Install

Expand All @@ -21,31 +22,47 @@ npx cap sync

## Example

```JS
```js
import { NativeSettings, AndroidSettings, IOSSettings } from 'capacitor-native-settings';

/**
* Note that the only supported option by Apple is "App".
* Using other options might break in future iOS versions
* or have your app rejected from the App Store.
* ⚠️ iOS limitation
*
* Apple officially supports opening only the app-specific settings screen.
* Other options rely on undocumented URL schemes and may stop working
* or cause App Store rejection.
*/
NativeSettings.open({
optionAndroid: AndroidSettings.ApplicationDetails,
optionIOS: IOSSettings.App
})
const result = await NativeSettings.open({
optionAndroid: AndroidSettings.ApplicationDetails,
optionIOS: IOSSettings.App,
});

if (!result.success) {
console.error(result.error);
}

NativeSettings.openAndroid({
const androidResult = await NativeSettings.openAndroid({
option: AndroidSettings.ApplicationDetails,
});

if (!androidResult.success) {
console.error(androidResult.error);
}

/**
* Note that the only supported option by Apple is "App".
* Using other options might break in future iOS versions
* or have your app rejected from the App Store.
* ⚠️ iOS limitation
*
* Apple officially supports opening only the app-specific settings screen.
* Other options rely on undocumented URL schemes and may stop working
* or cause App Store rejection.
*/
NativeSettings.openIOS({
const iosResult = await NativeSettings.openIOS({
option: IOSSettings.App,
});

if (!iosResult.success) {
console.error(iosResult.error);
}
```

## API
Expand All @@ -63,71 +80,78 @@ NativeSettings.openIOS({
<docgen-api>
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->

Capacitor NativeSettings plugin interface.

Provides access to native Android and iOS system settings screens.

### open(...)

```typescript
open(option: PlatformOptions) => Promise<{ status: boolean; }>
open(options: PlatformOptions) => Promise<NativeSettingsResult>
```

Opens the specified options on android & ios.
Note that the only supported option by Apple is "App". Using other options
might break in future iOS versions or have your app rejected in the App Store.
Opens the specified settings option on the current platform.

| Param | Type | Description |
| ------------ | ----------------------------------------------------------- | ---------------------------------------------- |
| **`option`** | <code><a href="#platformoptions">PlatformOptions</a></code> | <a href="#platformoptions">PlatformOptions</a> |
| Param | Type | Description |
| ------------- | ----------------------------------------------------------- | ----------------------------------- |
| **`options`** | <code><a href="#platformoptions">PlatformOptions</a></code> | Platform-specific settings options. |

**Returns:** <code>Promise&lt;{ status: boolean; }&gt;</code>
**Returns:** <code>Promise&lt;<a href="#nativesettingsresult">NativeSettingsResult</a>&gt;</code>

--------------------


### openAndroid(...)

```typescript
openAndroid(option: AndroidOptions) => Promise<{ status: boolean; }>
openAndroid(options: AndroidOptions) => Promise<NativeSettingsResult>
```

Opens the specified option in android.
Only use this if you have made sure the user is on android.
This can be done by checking the platform before hand.
Opens the specified Android settings screen.

| Param | Type | Description |
| ------------ | --------------------------------------------------------- | -------------------------------------------- |
| **`option`** | <code><a href="#androidoptions">AndroidOptions</a></code> | <a href="#androidoptions">AndroidOptions</a> |
| Param | Type | Description |
| ------------- | --------------------------------------------------------- | ------------------------- |
| **`options`** | <code><a href="#androidoptions">AndroidOptions</a></code> | Android settings options. |

**Returns:** <code>Promise&lt;{ status: boolean; }&gt;</code>
**Returns:** <code>Promise&lt;<a href="#nativesettingsresult">NativeSettingsResult</a>&gt;</code>

--------------------


### openIOS(...)

```typescript
openIOS(option: IOSOptions) => Promise<{ status: boolean; }>
openIOS(options: IOSOptions) => Promise<NativeSettingsResult>
```

Opens the specified option on iOS.
Only use this if you have made sure the user is on iOS.
This can be done by checking the platform before hand.

Note that the only supported option by Apple is "App". Using other options
might break in future iOS versions or have your app rejected in the App Store.
Opens the specified iOS settings screen.

| Param | Type | Description |
| ------------ | ------------------------------------------------- | ------------------------------------ |
| **`option`** | <code><a href="#iosoptions">IOSOptions</a></code> | <a href="#iosoptions">IOSOptions</a> |
| Param | Type | Description |
| ------------- | ------------------------------------------------- | --------------------- |
| **`options`** | <code><a href="#iosoptions">IOSOptions</a></code> | iOS settings options. |

**Returns:** <code>Promise&lt;{ status: boolean; }&gt;</code>
**Returns:** <code>Promise&lt;<a href="#nativesettingsresult">NativeSettingsResult</a>&gt;</code>

--------------------


### Interfaces


#### NativeSettingsResult

Result returned by native settings operations.

| Prop | Type | Description |
| ------------- | -------------------- | ----------------------------------------------- |
| **`success`** | <code>boolean</code> | Indicates whether the operation succeeded. |
| **`error`** | <code>string</code> | Optional error message if the operation failed. |


#### PlatformOptions

Platform-specific options.

| Prop | Type |
| ------------------- | ----------------------------------------------------------- |
| **`optionAndroid`** | <code><a href="#androidsettings">AndroidSettings</a></code> |
Expand All @@ -136,13 +160,17 @@ might break in future iOS versions or have your app rejected in the App Store.

#### AndroidOptions

Android-only options.

| Prop | Type |
| ------------ | ----------------------------------------------------------- |
| **`option`** | <code><a href="#androidsettings">AndroidSettings</a></code> |


#### IOSOptions

iOS-only options.

| Prop | Type |
| ------------ | --------------------------------------------------- |
| **`option`** | <code><a href="#iossettings">IOSSettings</a></code> |
Expand Down Expand Up @@ -196,8 +224,8 @@ might break in future iOS versions or have your app rejected in the App Store.
| **`TextToSpeech`** | <code>'text_to_speech'</code> | Show settings for configuring Text-to-Speech (TTS) output |
| **`Usage`** | <code>'usage'</code> | Show settings to control access to usage information |
| **`UserDictionary`** | <code>'user_dictionary'</code> | Show settings to manage the user input dictionary |
| **`VoiceInput`** | <code>'voice_input'</code> | Show settings to configure input methods, in particular allowing the user to enable input methods |
| **`VPN`** | <code>'vpn'</code> | Show settings to allow configuration of VPN |
| **`VoiceInput`** | <code>'voice_input'</code> | Show settings to configure input methods, in particular allowing the user to enable input methods |
| **`VPN`** | <code>'vpn'</code> | Show settings to allow configuration of VPN |
| **`Wifi`** | <code>'wifi'</code> | Show settings to allow configuration of Wi-Fi |
| **`WifiIp`** | <code>'wifi_ip'</code> | Show settings to allow configuration of a static IP address for Wi-Fi |
| **`Wireless`** | <code>'wireless'</code> | Show settings to allow configuration of wireless controls such as Wi-Fi, Bluetooth and Mobile networks |
Expand Down Expand Up @@ -235,7 +263,7 @@ might break in future iOS versions or have your app rejected in the App Store.
| **`SoftwareUpdate`** | <code>'softwareUpdate'</code> | Software update screen. |
| **`Store`** | <code>'store'</code> | Store settings. |
| **`Tracking`** | <code>'tracking'</code> | Tracking settings. |
| **`VPN`** | <code>'vpn'</code> | VPN settings. |
| **`VPN`** | <code>'vpn'</code> | VPN settings. |
| **`Wallpaper`** | <code>'wallpaper'</code> | Wallpaper settings. |
| **`WiFi`** | <code>'wifi'</code> | WiFi settings. |
| **`Tethering`** | <code>'tethering'</code> | Tethering settings (used to create a hotspot with mobile data). |
Expand Down
7 changes: 6 additions & 1 deletion android/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
/build
# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties
34 changes: 18 additions & 16 deletions android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,44 +1,47 @@
ext {
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
}

buildscript {
repositories {
google()
mavenCentral()
maven {
url = "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:8.7.2'
classpath 'com.android.tools.build:gradle:8.13.0'
}
}

apply plugin: 'com.android.library'

android {
namespace "nl.raphael.settings"
compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
namespace = "nl.raphael.settings"
compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion as Integer : 36
defaultConfig {
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
minSdkVersion = project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion as Integer : 24
targetSdkVersion = project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion as Integer : 36
versionCode = 1
versionName = '1.0.0'
testInstrumentationRunner = 'androidx.test.runner.AndroidJUnitRunner'
}
buildTypes {
release {
minifyEnabled false
minifyEnabled = false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
abortOnError = false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
}

Expand All @@ -47,7 +50,6 @@ repositories {
mavenCentral()
}


dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':capacitor-android')
Expand Down
Binary file modified android/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
Loading