@capgo/capacitor-sim 7.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ require 'json'
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = 'CapgoCapacitorSim'
7
+ s.version = package['version']
8
+ s.summary = package['description']
9
+ s.license = package['license']
10
+ s.homepage = package['repository']['url']
11
+ s.author = package['author']
12
+ s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
+ s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
+ s.ios.deployment_target = '14.0'
15
+ s.dependency 'Capacitor'
16
+ s.swift_version = '5.1'
17
+ end
package/Package.swift ADDED
@@ -0,0 +1,28 @@
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "CapgoCapacitorSim",
6
+ platforms: [.iOS(.v14)],
7
+ products: [
8
+ .library(
9
+ name: "CapgoCapacitorSim",
10
+ targets: ["SimPlugin"])
11
+ ],
12
+ dependencies: [
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0")
14
+ ],
15
+ targets: [
16
+ .target(
17
+ name: "SimPlugin",
18
+ dependencies: [
19
+ .product(name: "Capacitor", package: "capacitor-swift-pm"),
20
+ .product(name: "Cordova", package: "capacitor-swift-pm")
21
+ ],
22
+ path: "ios/Sources/SimPlugin"),
23
+ .testTarget(
24
+ name: "SimPluginTests",
25
+ dependencies: ["SimPlugin"],
26
+ path: "ios/Tests/SimPluginTests")
27
+ ]
28
+ )
package/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # @capgo/capacitor-sim
2
+ <a href="https://capgo.app/"><img src='https://raw.githubusercontent.com/Cap-go/capgo/main/assets/capgo_banner.png' alt='Capgo - Instant updates for capacitor'/></a>
3
+
4
+ <div align="center">
5
+ <h2><a href="https://capgo.app/?ref=plugin"> ➡️ Get Instant updates for your App with Capgo</a></h2>
6
+ <h2><a href="https://capgo.app/consulting/?ref=plugin"> Missing a feature? We’ll build the plugin for you 💪</a></h2>
7
+ </div>
8
+ Capacitor plugin to get information from device's sim cards
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ npm install @capgo/capacitor-sim
14
+ npx cap sync
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```ts
20
+ import { Sim } from '@capgo/capacitor-sim';
21
+
22
+ const loadSimCards = async () => {
23
+ const { simCards } = await Sim.getSimCards();
24
+
25
+ return simCards;
26
+ };
27
+ ```
28
+
29
+ The returned `simCards` array contains carrier information for each detected SIM. On Android the list also exposes the `subscriptionId` and `simSlotIndex` values so you can correlate entries across platform APIs.
30
+
31
+ ### iOS 16.4+ limitations
32
+
33
+ Starting with iOS 16.4 Apple restricts access to several carrier fields returned by CoreTelephony. On devices running iOS 16.4 or newer the plugin may return placeholder values such as `65535`, `--`, or empty strings for `carrierName`, `isoCountryCode`, `mobileCountryCode`, and `mobileNetworkCode`. This behaviour is handled at the OS level and is tracked upstream in [jonz94/capacitor-sim#8](https://github.com/jonz94/capacitor-sim/issues/8); there is currently no known workaround besides relying on Android data or older iOS versions.
34
+
35
+ ## API
36
+
37
+ <docgen-index>
38
+
39
+ * [`getSimCards()`](#getsimcards)
40
+ * [`checkPermissions()`](#checkpermissions)
41
+ * [`requestPermissions()`](#requestpermissions)
42
+ * [Interfaces](#interfaces)
43
+ * [Type Aliases](#type-aliases)
44
+
45
+ </docgen-index>
46
+
47
+ <docgen-api>
48
+ <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
49
+
50
+ ### getSimCards()
51
+
52
+ ```typescript
53
+ getSimCards() => Promise<GetSimCardsResult>
54
+ ```
55
+
56
+ Get information from the device's SIM cards.
57
+
58
+ **Returns:** <code>Promise&lt;<a href="#getsimcardsresult">GetSimCardsResult</a>&gt;</code>
59
+
60
+ **Since:** 1.0.0
61
+
62
+ --------------------
63
+
64
+
65
+ ### checkPermissions()
66
+
67
+ ```typescript
68
+ checkPermissions() => Promise<PermissionStatus>
69
+ ```
70
+
71
+ Check permission to access SIM card information.
72
+
73
+ On iOS and Web the status is always granted or denied respectively without prompting.
74
+
75
+ **Returns:** <code>Promise&lt;<a href="#permissionstatus">PermissionStatus</a>&gt;</code>
76
+
77
+ **Since:** 1.0.0
78
+
79
+ --------------------
80
+
81
+
82
+ ### requestPermissions()
83
+
84
+ ```typescript
85
+ requestPermissions() => Promise<PermissionStatus>
86
+ ```
87
+
88
+ Request permission to access SIM card information.
89
+
90
+ On iOS the status is always granted. On Web the status remains denied.
91
+
92
+ **Returns:** <code>Promise&lt;<a href="#permissionstatus">PermissionStatus</a>&gt;</code>
93
+
94
+ **Since:** 1.0.0
95
+
96
+ --------------------
97
+
98
+
99
+ ### Interfaces
100
+
101
+
102
+ #### GetSimCardsResult
103
+
104
+ Result returned by {@link SimPlugin.getSimCards}.
105
+
106
+ | Prop | Type |
107
+ | -------------- | ---------------------- |
108
+ | **`simCards`** | <code>SimCard[]</code> |
109
+
110
+
111
+ #### SimCard
112
+
113
+ A SIM card description.
114
+
115
+ | Prop | Type | Description | Since |
116
+ | ----------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
117
+ | **`number`** | <code>string</code> | Android only: Phone number for this SIM slot, when available. | 1.0.0 |
118
+ | **`subscriptionId`** | <code>string</code> | Android only: Unique subscription identifier. | 1.1.0 |
119
+ | **`simSlotIndex`** | <code>number</code> | Android only: Physical SIM slot index for this subscription. | 1.1.0 |
120
+ | **`allowsVOIP`** | <code>boolean</code> | iOS only: Indicates whether the carrier supports VoIP. | 1.0.0 |
121
+ | **`carrierName`** | <code>string</code> | Display name of the cellular service provider. On iOS 16.4+ the system may return placeholder values such as `--`. See https://github.com/jonz94/capacitor-sim/issues/8 for details. | 1.0.0 |
122
+ | **`isoCountryCode`** | <code>string</code> | ISO 3166-1 alpha-2 country code of the service provider. On iOS 16.4+ the system may return an empty string or `--`. See https://github.com/jonz94/capacitor-sim/issues/8 for details. | 1.0.0 |
123
+ | **`mobileCountryCode`** | <code>string</code> | Mobile Country Code (MCC) of the service provider. On iOS 16.4+ the system may return placeholder values such as `65535`. See https://github.com/jonz94/capacitor-sim/issues/8 for details. | 1.0.0 |
124
+ | **`mobileNetworkCode`** | <code>string</code> | Mobile Network Code (MNC) of the service provider. On iOS 16.4+ the system may return placeholder values such as `65535`. See https://github.com/jonz94/capacitor-sim/issues/8 for details. | 1.0.0 |
125
+
126
+
127
+ #### PermissionStatus
128
+
129
+ Result of a permission check or request.
130
+
131
+ | Prop | Type |
132
+ | ----------------- | ----------------------------------------------------------- |
133
+ | **`readSimCard`** | <code><a href="#permissionstate">PermissionState</a></code> |
134
+
135
+
136
+ ### Type Aliases
137
+
138
+
139
+ #### PermissionState
140
+
141
+ <code>'prompt' | 'prompt-with-rationale' | 'granted' | 'denied'</code>
142
+
143
+ </docgen-api>
@@ -0,0 +1,57 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
6
+ }
7
+
8
+ buildscript {
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+ dependencies {
14
+ classpath 'com.android.tools.build:gradle:8.7.2'
15
+ }
16
+ }
17
+
18
+ apply plugin: 'com.android.library'
19
+
20
+ android {
21
+ namespace "app.capgo.plugin.sim"
22
+ compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
23
+ defaultConfig {
24
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
25
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
26
+ versionCode 1
27
+ versionName "1.0"
28
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
29
+ }
30
+ buildTypes {
31
+ release {
32
+ minifyEnabled false
33
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
34
+ }
35
+ }
36
+ lintOptions {
37
+ abortOnError false
38
+ }
39
+ compileOptions {
40
+ sourceCompatibility JavaVersion.VERSION_21
41
+ targetCompatibility JavaVersion.VERSION_21
42
+ }
43
+ }
44
+
45
+ repositories {
46
+ google()
47
+ mavenCentral()
48
+ }
49
+
50
+ dependencies {
51
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
52
+ implementation project(':capacitor-android')
53
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
54
+ testImplementation "junit:junit:$junitVersion"
55
+ androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
56
+ androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
57
+ }
@@ -0,0 +1,4 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
3
+ <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
4
+ </manifest>
@@ -0,0 +1,124 @@
1
+ package app.capgo.plugin.sim;
2
+
3
+ import android.Manifest;
4
+ import android.annotation.SuppressLint;
5
+ import android.content.Context;
6
+ import android.os.Build;
7
+ import android.telephony.SubscriptionInfo;
8
+ import android.telephony.SubscriptionManager;
9
+ import com.getcapacitor.JSArray;
10
+ import com.getcapacitor.JSObject;
11
+ import com.getcapacitor.Logger;
12
+ import com.getcapacitor.PermissionState;
13
+ import com.getcapacitor.Plugin;
14
+ import com.getcapacitor.PluginCall;
15
+ import com.getcapacitor.PluginMethod;
16
+ import com.getcapacitor.annotation.CapacitorPlugin;
17
+ import com.getcapacitor.annotation.Permission;
18
+ import com.getcapacitor.annotation.PermissionCallback;
19
+ import java.util.List;
20
+
21
+ @SuppressLint("InlinedApi")
22
+ @CapacitorPlugin(
23
+ name = "Sim",
24
+ permissions = {
25
+ @Permission(strings = { Manifest.permission.READ_PHONE_STATE }, alias = SimPlugin.READ_PHONE_STATE),
26
+ @Permission(strings = { Manifest.permission.READ_PHONE_NUMBERS }, alias = SimPlugin.READ_PHONE_NUMBERS)
27
+ }
28
+ )
29
+ public class SimPlugin extends Plugin {
30
+
31
+ static final String READ_PHONE_STATE = "readPhoneState";
32
+ static final String READ_PHONE_NUMBERS = "readPhoneNumbers";
33
+ private static final String PERMISSION_DENIED_ERROR = "Unable to get information from SIM cards, user denied permission request.";
34
+
35
+ @PluginMethod
36
+ public void getSimCards(PluginCall call) {
37
+ if (!isPermissionGranted()) {
38
+ requestPhonePermissions(call);
39
+ return;
40
+ }
41
+
42
+ SubscriptionManager subscriptionManager = (SubscriptionManager) getContext().getSystemService(
43
+ Context.TELEPHONY_SUBSCRIPTION_SERVICE
44
+ );
45
+
46
+ JSArray carrierInfoCollection = subscriptionManager != null ? collectSubscriptionInfo(subscriptionManager) : new JSArray();
47
+
48
+ JSObject result = new JSObject();
49
+ result.put("simCards", carrierInfoCollection);
50
+
51
+ call.resolve(result);
52
+ }
53
+
54
+ @PermissionCallback
55
+ private void permissionCallback(PluginCall call) {
56
+ if (!isPermissionGranted()) {
57
+ Logger.debug(getLogTag(), "User denied SIM read permissions request.");
58
+ call.reject(PERMISSION_DENIED_ERROR);
59
+ return;
60
+ }
61
+
62
+ if ("getSimCards".equals(call.getMethodName())) {
63
+ getSimCards(call);
64
+ }
65
+ }
66
+
67
+ private void requestPhonePermissions(PluginCall call) {
68
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
69
+ requestPermissionForAliases(new String[] { READ_PHONE_NUMBERS, READ_PHONE_STATE }, call, "permissionCallback");
70
+ } else {
71
+ requestPermissionForAlias(READ_PHONE_STATE, call, "permissionCallback");
72
+ }
73
+ }
74
+
75
+ private boolean isPermissionGranted() {
76
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
77
+ return (
78
+ getPermissionState(READ_PHONE_NUMBERS) == PermissionState.GRANTED &&
79
+ getPermissionState(READ_PHONE_STATE) == PermissionState.GRANTED
80
+ );
81
+ }
82
+
83
+ return getPermissionState(READ_PHONE_STATE) == PermissionState.GRANTED;
84
+ }
85
+
86
+ @SuppressLint("MissingPermission")
87
+ private JSArray collectSubscriptionInfo(SubscriptionManager subscriptionManager) {
88
+ JSArray results = new JSArray();
89
+ List<SubscriptionInfo> subscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();
90
+
91
+ if (subscriptionInfoList == null) {
92
+ return results;
93
+ }
94
+
95
+ for (SubscriptionInfo subscriptionInfo : subscriptionInfoList) {
96
+ JSObject carrierInfo = new JSObject();
97
+
98
+ String number = null;
99
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
100
+ number = subscriptionManager.getPhoneNumber(subscriptionInfo.getSubscriptionId());
101
+ } else {
102
+ number = subscriptionInfo.getNumber();
103
+ }
104
+
105
+ carrierInfo.put("number", number);
106
+ carrierInfo.put("subscriptionId", Integer.toString(subscriptionInfo.getSubscriptionId()));
107
+ carrierInfo.put("simSlotIndex", subscriptionInfo.getSimSlotIndex());
108
+ carrierInfo.put("carrierName", subscriptionInfo.getCarrierName());
109
+ carrierInfo.put("isoCountryCode", subscriptionInfo.getCountryIso());
110
+
111
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
112
+ carrierInfo.put("mobileCountryCode", subscriptionInfo.getMccString());
113
+ carrierInfo.put("mobileNetworkCode", subscriptionInfo.getMncString());
114
+ } else {
115
+ carrierInfo.put("mobileCountryCode", Integer.toString(subscriptionInfo.getMcc()));
116
+ carrierInfo.put("mobileNetworkCode", Integer.toString(subscriptionInfo.getMnc()));
117
+ }
118
+
119
+ results.put(carrierInfo);
120
+ }
121
+
122
+ return results;
123
+ }
124
+ }
File without changes
package/dist/docs.json ADDED
@@ -0,0 +1,247 @@
1
+ {
2
+ "api": {
3
+ "name": "SimPlugin",
4
+ "slug": "simplugin",
5
+ "docs": "",
6
+ "tags": [],
7
+ "methods": [
8
+ {
9
+ "name": "getSimCards",
10
+ "signature": "() => Promise<GetSimCardsResult>",
11
+ "parameters": [],
12
+ "returns": "Promise<GetSimCardsResult>",
13
+ "tags": [
14
+ {
15
+ "name": "since",
16
+ "text": "1.0.0"
17
+ }
18
+ ],
19
+ "docs": "Get information from the device's SIM cards.",
20
+ "complexTypes": [
21
+ "GetSimCardsResult"
22
+ ],
23
+ "slug": "getsimcards"
24
+ },
25
+ {
26
+ "name": "checkPermissions",
27
+ "signature": "() => Promise<PermissionStatus>",
28
+ "parameters": [],
29
+ "returns": "Promise<PermissionStatus>",
30
+ "tags": [
31
+ {
32
+ "name": "since",
33
+ "text": "1.0.0"
34
+ }
35
+ ],
36
+ "docs": "Check permission to access SIM card information.\n\nOn iOS and Web the status is always granted or denied respectively without prompting.",
37
+ "complexTypes": [
38
+ "PermissionStatus"
39
+ ],
40
+ "slug": "checkpermissions"
41
+ },
42
+ {
43
+ "name": "requestPermissions",
44
+ "signature": "() => Promise<PermissionStatus>",
45
+ "parameters": [],
46
+ "returns": "Promise<PermissionStatus>",
47
+ "tags": [
48
+ {
49
+ "name": "since",
50
+ "text": "1.0.0"
51
+ }
52
+ ],
53
+ "docs": "Request permission to access SIM card information.\n\nOn iOS the status is always granted. On Web the status remains denied.",
54
+ "complexTypes": [
55
+ "PermissionStatus"
56
+ ],
57
+ "slug": "requestpermissions"
58
+ }
59
+ ],
60
+ "properties": []
61
+ },
62
+ "interfaces": [
63
+ {
64
+ "name": "GetSimCardsResult",
65
+ "slug": "getsimcardsresult",
66
+ "docs": "Result returned by {@link SimPlugin.getSimCards}.",
67
+ "tags": [
68
+ {
69
+ "text": "1.0.0",
70
+ "name": "since"
71
+ }
72
+ ],
73
+ "methods": [],
74
+ "properties": [
75
+ {
76
+ "name": "simCards",
77
+ "tags": [],
78
+ "docs": "",
79
+ "complexTypes": [
80
+ "SimCard"
81
+ ],
82
+ "type": "SimCard[]"
83
+ }
84
+ ]
85
+ },
86
+ {
87
+ "name": "SimCard",
88
+ "slug": "simcard",
89
+ "docs": "A SIM card description.",
90
+ "tags": [
91
+ {
92
+ "text": "1.0.0",
93
+ "name": "since"
94
+ }
95
+ ],
96
+ "methods": [],
97
+ "properties": [
98
+ {
99
+ "name": "number",
100
+ "tags": [
101
+ {
102
+ "text": "1.0.0",
103
+ "name": "since"
104
+ }
105
+ ],
106
+ "docs": "Android only: Phone number for this SIM slot, when available.",
107
+ "complexTypes": [],
108
+ "type": "string | undefined"
109
+ },
110
+ {
111
+ "name": "subscriptionId",
112
+ "tags": [
113
+ {
114
+ "text": "1.1.0",
115
+ "name": "since"
116
+ }
117
+ ],
118
+ "docs": "Android only: Unique subscription identifier.",
119
+ "complexTypes": [],
120
+ "type": "string | undefined"
121
+ },
122
+ {
123
+ "name": "simSlotIndex",
124
+ "tags": [
125
+ {
126
+ "text": "1.1.0",
127
+ "name": "since"
128
+ }
129
+ ],
130
+ "docs": "Android only: Physical SIM slot index for this subscription.",
131
+ "complexTypes": [],
132
+ "type": "number | undefined"
133
+ },
134
+ {
135
+ "name": "allowsVOIP",
136
+ "tags": [
137
+ {
138
+ "text": "1.0.0",
139
+ "name": "since"
140
+ }
141
+ ],
142
+ "docs": "iOS only: Indicates whether the carrier supports VoIP.",
143
+ "complexTypes": [],
144
+ "type": "boolean | undefined"
145
+ },
146
+ {
147
+ "name": "carrierName",
148
+ "tags": [
149
+ {
150
+ "text": "1.0.0",
151
+ "name": "since"
152
+ }
153
+ ],
154
+ "docs": "Display name of the cellular service provider.\n\nOn iOS 16.4+ the system may return placeholder values such as `--`.\nSee https://github.com/jonz94/capacitor-sim/issues/8 for details.",
155
+ "complexTypes": [],
156
+ "type": "string"
157
+ },
158
+ {
159
+ "name": "isoCountryCode",
160
+ "tags": [
161
+ {
162
+ "text": "1.0.0",
163
+ "name": "since"
164
+ }
165
+ ],
166
+ "docs": "ISO 3166-1 alpha-2 country code of the service provider.\n\nOn iOS 16.4+ the system may return an empty string or `--`.\nSee https://github.com/jonz94/capacitor-sim/issues/8 for details.",
167
+ "complexTypes": [],
168
+ "type": "string"
169
+ },
170
+ {
171
+ "name": "mobileCountryCode",
172
+ "tags": [
173
+ {
174
+ "text": "1.0.0",
175
+ "name": "since"
176
+ }
177
+ ],
178
+ "docs": "Mobile Country Code (MCC) of the service provider.\n\nOn iOS 16.4+ the system may return placeholder values such as `65535`.\nSee https://github.com/jonz94/capacitor-sim/issues/8 for details.",
179
+ "complexTypes": [],
180
+ "type": "string"
181
+ },
182
+ {
183
+ "name": "mobileNetworkCode",
184
+ "tags": [
185
+ {
186
+ "text": "1.0.0",
187
+ "name": "since"
188
+ }
189
+ ],
190
+ "docs": "Mobile Network Code (MNC) of the service provider.\n\nOn iOS 16.4+ the system may return placeholder values such as `65535`.\nSee https://github.com/jonz94/capacitor-sim/issues/8 for details.",
191
+ "complexTypes": [],
192
+ "type": "string"
193
+ }
194
+ ]
195
+ },
196
+ {
197
+ "name": "PermissionStatus",
198
+ "slug": "permissionstatus",
199
+ "docs": "Result of a permission check or request.",
200
+ "tags": [
201
+ {
202
+ "text": "1.0.0",
203
+ "name": "since"
204
+ }
205
+ ],
206
+ "methods": [],
207
+ "properties": [
208
+ {
209
+ "name": "readSimCard",
210
+ "tags": [],
211
+ "docs": "",
212
+ "complexTypes": [
213
+ "PermissionState"
214
+ ],
215
+ "type": "PermissionState"
216
+ }
217
+ ]
218
+ }
219
+ ],
220
+ "enums": [],
221
+ "typeAliases": [
222
+ {
223
+ "name": "PermissionState",
224
+ "slug": "permissionstate",
225
+ "docs": "",
226
+ "types": [
227
+ {
228
+ "text": "'prompt'",
229
+ "complexTypes": []
230
+ },
231
+ {
232
+ "text": "'prompt-with-rationale'",
233
+ "complexTypes": []
234
+ },
235
+ {
236
+ "text": "'granted'",
237
+ "complexTypes": []
238
+ },
239
+ {
240
+ "text": "'denied'",
241
+ "complexTypes": []
242
+ }
243
+ ]
244
+ }
245
+ ],
246
+ "pluginConfigs": []
247
+ }
@@ -0,0 +1,108 @@
1
+ import type { PermissionState } from '@capacitor/core';
2
+ /**
3
+ * Result of a permission check or request.
4
+ *
5
+ * @since 1.0.0
6
+ */
7
+ export interface PermissionStatus {
8
+ readSimCard: PermissionState;
9
+ }
10
+ export interface SimPlugin {
11
+ /**
12
+ * Get information from the device's SIM cards.
13
+ *
14
+ * @since 1.0.0
15
+ */
16
+ getSimCards(): Promise<GetSimCardsResult>;
17
+ /**
18
+ * Check permission to access SIM card information.
19
+ *
20
+ * On iOS and Web the status is always granted or denied respectively without prompting.
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ checkPermissions(): Promise<PermissionStatus>;
25
+ /**
26
+ * Request permission to access SIM card information.
27
+ *
28
+ * On iOS the status is always granted. On Web the status remains denied.
29
+ *
30
+ * @since 1.0.0
31
+ */
32
+ requestPermissions(): Promise<PermissionStatus>;
33
+ }
34
+ /**
35
+ * Result returned by {@link SimPlugin.getSimCards}.
36
+ *
37
+ * @since 1.0.0
38
+ */
39
+ export interface GetSimCardsResult {
40
+ simCards: SimCard[];
41
+ }
42
+ /**
43
+ * A SIM card description.
44
+ *
45
+ * @since 1.0.0
46
+ */
47
+ export interface SimCard {
48
+ /**
49
+ * Android only: Phone number for this SIM slot, when available.
50
+ *
51
+ * @since 1.0.0
52
+ */
53
+ number?: string;
54
+ /**
55
+ * Android only: Unique subscription identifier.
56
+ *
57
+ * @since 1.1.0
58
+ */
59
+ subscriptionId?: string;
60
+ /**
61
+ * Android only: Physical SIM slot index for this subscription.
62
+ *
63
+ * @since 1.1.0
64
+ */
65
+ simSlotIndex?: number;
66
+ /**
67
+ * iOS only: Indicates whether the carrier supports VoIP.
68
+ *
69
+ * @since 1.0.0
70
+ */
71
+ allowsVOIP?: boolean;
72
+ /**
73
+ * Display name of the cellular service provider.
74
+ *
75
+ * On iOS 16.4+ the system may return placeholder values such as `--`.
76
+ * See https://github.com/jonz94/capacitor-sim/issues/8 for details.
77
+ *
78
+ * @since 1.0.0
79
+ */
80
+ carrierName: string;
81
+ /**
82
+ * ISO 3166-1 alpha-2 country code of the service provider.
83
+ *
84
+ * On iOS 16.4+ the system may return an empty string or `--`.
85
+ * See https://github.com/jonz94/capacitor-sim/issues/8 for details.
86
+ *
87
+ * @since 1.0.0
88
+ */
89
+ isoCountryCode: string;
90
+ /**
91
+ * Mobile Country Code (MCC) of the service provider.
92
+ *
93
+ * On iOS 16.4+ the system may return placeholder values such as `65535`.
94
+ * See https://github.com/jonz94/capacitor-sim/issues/8 for details.
95
+ *
96
+ * @since 1.0.0
97
+ */
98
+ mobileCountryCode: string;
99
+ /**
100
+ * Mobile Network Code (MNC) of the service provider.
101
+ *
102
+ * On iOS 16.4+ the system may return placeholder values such as `65535`.
103
+ * See https://github.com/jonz94/capacitor-sim/issues/8 for details.
104
+ *
105
+ * @since 1.0.0
106
+ */
107
+ mobileNetworkCode: string;
108
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PermissionState } from '@capacitor/core';\n\n/**\n * Result of a permission check or request.\n *\n * @since 1.0.0\n */\nexport interface PermissionStatus {\n readSimCard: PermissionState;\n}\n\nexport interface SimPlugin {\n /**\n * Get information from the device's SIM cards.\n *\n * @since 1.0.0\n */\n getSimCards(): Promise<GetSimCardsResult>;\n\n /**\n * Check permission to access SIM card information.\n *\n * On iOS and Web the status is always granted or denied respectively without prompting.\n *\n * @since 1.0.0\n */\n checkPermissions(): Promise<PermissionStatus>;\n\n /**\n * Request permission to access SIM card information.\n *\n * On iOS the status is always granted. On Web the status remains denied.\n *\n * @since 1.0.0\n */\n requestPermissions(): Promise<PermissionStatus>;\n}\n\n/**\n * Result returned by {@link SimPlugin.getSimCards}.\n *\n * @since 1.0.0\n */\nexport interface GetSimCardsResult {\n simCards: SimCard[];\n}\n\n/**\n * A SIM card description.\n *\n * @since 1.0.0\n */\nexport interface SimCard {\n /**\n * Android only: Phone number for this SIM slot, when available.\n *\n * @since 1.0.0\n */\n number?: string;\n\n /**\n * Android only: Unique subscription identifier.\n *\n * @since 1.1.0\n */\n subscriptionId?: string;\n\n /**\n * Android only: Physical SIM slot index for this subscription.\n *\n * @since 1.1.0\n */\n simSlotIndex?: number;\n\n /**\n * iOS only: Indicates whether the carrier supports VoIP.\n *\n * @since 1.0.0\n */\n allowsVOIP?: boolean;\n\n /**\n * Display name of the cellular service provider.\n *\n * On iOS 16.4+ the system may return placeholder values such as `--`.\n * See https://github.com/jonz94/capacitor-sim/issues/8 for details.\n *\n * @since 1.0.0\n */\n carrierName: string;\n\n /**\n * ISO 3166-1 alpha-2 country code of the service provider.\n *\n * On iOS 16.4+ the system may return an empty string or `--`.\n * See https://github.com/jonz94/capacitor-sim/issues/8 for details.\n *\n * @since 1.0.0\n */\n isoCountryCode: string;\n\n /**\n * Mobile Country Code (MCC) of the service provider.\n *\n * On iOS 16.4+ the system may return placeholder values such as `65535`.\n * See https://github.com/jonz94/capacitor-sim/issues/8 for details.\n *\n * @since 1.0.0\n */\n mobileCountryCode: string;\n\n /**\n * Mobile Network Code (MNC) of the service provider.\n *\n * On iOS 16.4+ the system may return placeholder values such as `65535`.\n * See https://github.com/jonz94/capacitor-sim/issues/8 for details.\n *\n * @since 1.0.0\n */\n mobileNetworkCode: string;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { SimPlugin } from './definitions';
2
+ declare const Sim: SimPlugin;
3
+ export * from './definitions';
4
+ export { Sim };
@@ -0,0 +1,7 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const Sim = registerPlugin('Sim', {
3
+ web: () => import('./web').then((m) => new m.SimWeb()),
4
+ });
5
+ export * from './definitions';
6
+ export { Sim };
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,GAAG,GAAG,cAAc,CAAY,KAAK,EAAE;IAC3C,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;CACvD,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { SimPlugin } from './definitions';\n\nconst Sim = registerPlugin<SimPlugin>('Sim', {\n web: () => import('./web').then((m) => new m.SimWeb()),\n});\n\nexport * from './definitions';\nexport { Sim };\n"]}
@@ -0,0 +1,7 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import type { GetSimCardsResult, PermissionStatus, SimPlugin } from './definitions';
3
+ export declare class SimWeb extends WebPlugin implements SimPlugin {
4
+ getSimCards(): Promise<GetSimCardsResult>;
5
+ checkPermissions(): Promise<PermissionStatus>;
6
+ requestPermissions(): Promise<PermissionStatus>;
7
+ }
@@ -0,0 +1,13 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ export class SimWeb extends WebPlugin {
3
+ async getSimCards() {
4
+ throw this.unimplemented('Sim.getSimCards is not implemented on web.');
5
+ }
6
+ async checkPermissions() {
7
+ return { readSimCard: 'denied' };
8
+ }
9
+ async requestPermissions() {
10
+ return this.checkPermissions();
11
+ }
12
+ }
13
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,OAAO,MAAO,SAAQ,SAAS;IACnC,KAAK,CAAC,WAAW;QACf,MAAM,IAAI,CAAC,aAAa,CAAC,4CAA4C,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC;IACjC,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type { GetSimCardsResult, PermissionStatus, SimPlugin } from './definitions';\n\nexport class SimWeb extends WebPlugin implements SimPlugin {\n async getSimCards(): Promise<GetSimCardsResult> {\n throw this.unimplemented('Sim.getSimCards is not implemented on web.');\n }\n\n async checkPermissions(): Promise<PermissionStatus> {\n return { readSimCard: 'denied' };\n }\n\n async requestPermissions(): Promise<PermissionStatus> {\n return this.checkPermissions();\n }\n}\n"]}
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ var core = require('@capacitor/core');
4
+
5
+ const Sim = core.registerPlugin('Sim', {
6
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.SimWeb()),
7
+ });
8
+
9
+ class SimWeb extends core.WebPlugin {
10
+ async getSimCards() {
11
+ throw this.unimplemented('Sim.getSimCards is not implemented on web.');
12
+ }
13
+ async checkPermissions() {
14
+ return { readSimCard: 'denied' };
15
+ }
16
+ async requestPermissions() {
17
+ return this.checkPermissions();
18
+ }
19
+ }
20
+
21
+ var web = /*#__PURE__*/Object.freeze({
22
+ __proto__: null,
23
+ SimWeb: SimWeb
24
+ });
25
+
26
+ exports.Sim = Sim;
27
+ //# sourceMappingURL=plugin.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Sim = registerPlugin('Sim', {\n web: () => import('./web').then((m) => new m.SimWeb()),\n});\nexport * from './definitions';\nexport { Sim };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class SimWeb extends WebPlugin {\n async getSimCards() {\n throw this.unimplemented('Sim.getSimCards is not implemented on web.');\n }\n async checkPermissions() {\n return { readSimCard: 'denied' };\n }\n async requestPermissions() {\n return this.checkPermissions();\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;AACK,MAAC,GAAG,GAAGA,mBAAc,CAAC,KAAK,EAAE;AAClC,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;AAC1D,CAAC;;ACFM,MAAM,MAAM,SAASC,cAAS,CAAC;AACtC,IAAI,MAAM,WAAW,GAAG;AACxB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,4CAA4C,CAAC;AAC9E,IAAI;AACJ,IAAI,MAAM,gBAAgB,GAAG;AAC7B,QAAQ,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE;AACxC,IAAI;AACJ,IAAI,MAAM,kBAAkB,GAAG;AAC/B,QAAQ,OAAO,IAAI,CAAC,gBAAgB,EAAE;AACtC,IAAI;AACJ;;;;;;;;;"}
package/dist/plugin.js ADDED
@@ -0,0 +1,30 @@
1
+ var capacitorSim = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ const Sim = core.registerPlugin('Sim', {
5
+ web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.SimWeb()),
6
+ });
7
+
8
+ class SimWeb extends core.WebPlugin {
9
+ async getSimCards() {
10
+ throw this.unimplemented('Sim.getSimCards is not implemented on web.');
11
+ }
12
+ async checkPermissions() {
13
+ return { readSimCard: 'denied' };
14
+ }
15
+ async requestPermissions() {
16
+ return this.checkPermissions();
17
+ }
18
+ }
19
+
20
+ var web = /*#__PURE__*/Object.freeze({
21
+ __proto__: null,
22
+ SimWeb: SimWeb
23
+ });
24
+
25
+ exports.Sim = Sim;
26
+
27
+ return exports;
28
+
29
+ })({}, capacitorExports);
30
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Sim = registerPlugin('Sim', {\n web: () => import('./web').then((m) => new m.SimWeb()),\n});\nexport * from './definitions';\nexport { Sim };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class SimWeb extends WebPlugin {\n async getSimCards() {\n throw this.unimplemented('Sim.getSimCards is not implemented on web.');\n }\n async checkPermissions() {\n return { readSimCard: 'denied' };\n }\n async requestPermissions() {\n return this.checkPermissions();\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,GAAG,GAAGA,mBAAc,CAAC,KAAK,EAAE;IAClC,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;IAC1D,CAAC;;ICFM,MAAM,MAAM,SAASC,cAAS,CAAC;IACtC,IAAI,MAAM,WAAW,GAAG;IACxB,QAAQ,MAAM,IAAI,CAAC,aAAa,CAAC,4CAA4C,CAAC;IAC9E,IAAI;IACJ,IAAI,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE;IACxC,IAAI;IACJ,IAAI,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,OAAO,IAAI,CAAC,gBAAgB,EAAE;IACtC,IAAI;IACJ;;;;;;;;;;;;;;;"}
@@ -0,0 +1,53 @@
1
+ import Capacitor
2
+ import CoreTelephony
3
+ import Foundation
4
+
5
+ @objc(SimPlugin)
6
+ public class SimPlugin: CAPPlugin, CAPBridgedPlugin {
7
+ public let identifier = "SimPlugin"
8
+ public let jsName = "Sim"
9
+ public let pluginMethods: [CAPPluginMethod] = [
10
+ CAPPluginMethod(name: "getSimCards", returnType: CAPPluginReturnPromise),
11
+ CAPPluginMethod(name: "checkPermissions", returnType: CAPPluginReturnPromise),
12
+ CAPPluginMethod(name: "requestPermissions", returnType: CAPPluginReturnPromise)
13
+ ]
14
+
15
+ @objc func getSimCards(_ call: CAPPluginCall) {
16
+ let telephonyInfo = CTTelephonyNetworkInfo()
17
+ var result: [[String: Any]] = []
18
+
19
+ if let carriers = telephonyInfo.serviceSubscriberCellularProviders?.values, !carriers.isEmpty {
20
+ for carrier in carriers {
21
+ result.append(buildCarrierPayload(from: carrier))
22
+ }
23
+ } else if let carrier = telephonyInfo.subscriberCellularProvider {
24
+ result.append(buildCarrierPayload(from: carrier))
25
+ }
26
+
27
+ call.resolve([
28
+ "simCards": result
29
+ ])
30
+ }
31
+
32
+ @objc override public func checkPermissions(_ call: CAPPluginCall) {
33
+ call.resolve([
34
+ "readSimCard": "granted"
35
+ ])
36
+ }
37
+
38
+ @objc override public func requestPermissions(_ call: CAPPluginCall) {
39
+ call.resolve([
40
+ "readSimCard": "granted"
41
+ ])
42
+ }
43
+
44
+ private func buildCarrierPayload(from carrier: CTCarrier) -> [String: Any] {
45
+ return [
46
+ "allowsVOIP": carrier.allowsVOIP,
47
+ "carrierName": carrier.carrierName ?? "",
48
+ "isoCountryCode": carrier.isoCountryCode ?? "",
49
+ "mobileCountryCode": carrier.mobileCountryCode ?? "",
50
+ "mobileNetworkCode": carrier.mobileNetworkCode ?? ""
51
+ ]
52
+ }
53
+ }
@@ -0,0 +1,8 @@
1
+ import XCTest
2
+
3
+ final class SimPluginTests: XCTestCase {
4
+ func testDummyPasses() {
5
+ // Placeholder test to keep the test target alive.
6
+ XCTAssertTrue(true)
7
+ }
8
+ }
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@capgo/capacitor-sim",
3
+ "version": "7.0.0",
4
+ "description": "Capacitor plugin to get information from device's sim cards",
5
+ "main": "dist/plugin.cjs.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/esm/index.d.ts",
8
+ "unpkg": "dist/plugin.js",
9
+ "files": [
10
+ "android/src/main/",
11
+ "android/build.gradle",
12
+ "dist/",
13
+ "ios/Sources",
14
+ "ios/Tests",
15
+ "Package.swift",
16
+ "CapgoCapacitorSim.podspec"
17
+ ],
18
+ "author": "Martin Donadieu <martin@capgo.app>",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/Cap-go/capacitor-sim.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/Cap-go/capacitor-sim/issues"
26
+ },
27
+ "keywords": [
28
+ "capacitor",
29
+ "plugin",
30
+ "native"
31
+ ],
32
+ "scripts": {
33
+ "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
34
+ "verify:ios": "xcodebuild -scheme CapgoCapacitorSim -destination generic/platform=iOS",
35
+ "verify:android": "cd android && ./gradlew clean build test && cd ..",
36
+ "verify:web": "npm run build",
37
+ "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
38
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
39
+ "eslint": "eslint . --ext ts",
40
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
41
+ "swiftlint": "node-swiftlint",
42
+ "docgen": "docgen --api SimPlugin --output-readme README.md --output-json dist/docs.json",
43
+ "build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
44
+ "clean": "rimraf ./dist",
45
+ "watch": "tsc --watch",
46
+ "prepublishOnly": "npm run build"
47
+ },
48
+ "devDependencies": {
49
+ "@capacitor/android": "^7.0.0",
50
+ "@capacitor/core": "^7.0.0",
51
+ "@capacitor/docgen": "^0.3.0",
52
+ "@capacitor/ios": "^7.0.0",
53
+ "@ionic/eslint-config": "^0.4.0",
54
+ "@ionic/prettier-config": "^4.0.0",
55
+ "@ionic/swiftlint-config": "^2.0.0",
56
+ "eslint": "^8.57.0",
57
+ "prettier": "^3.4.2",
58
+ "prettier-plugin-java": "^2.6.6",
59
+ "rimraf": "^6.0.1",
60
+ "rollup": "^4.30.1",
61
+ "swiftlint": "^2.0.0",
62
+ "typescript": "~4.1.5"
63
+ },
64
+ "peerDependencies": {
65
+ "@capacitor/core": ">=7.0.0"
66
+ },
67
+ "prettier": "@ionic/prettier-config",
68
+ "swiftlint": "@ionic/swiftlint-config",
69
+ "eslintConfig": {
70
+ "extends": "@ionic/eslint-config/recommended"
71
+ },
72
+ "capacitor": {
73
+ "ios": {
74
+ "src": "ios"
75
+ },
76
+ "android": {
77
+ "src": "android"
78
+ }
79
+ }
80
+ }