@capgo/capacitor-nfc 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 = 'CapgoCapacitorNfc'
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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Capgo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/Package.swift ADDED
@@ -0,0 +1,28 @@
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "CapgoCapacitorNfc",
6
+ platforms: [.iOS(.v14)],
7
+ products: [
8
+ .library(
9
+ name: "CapgoCapacitorNfc",
10
+ targets: ["NfcPlugin"])
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: "NfcPlugin",
18
+ dependencies: [
19
+ .product(name: "Capacitor", package: "capacitor-swift-pm"),
20
+ .product(name: "Cordova", package: "capacitor-swift-pm")
21
+ ],
22
+ path: "ios/Sources/NfcPlugin"),
23
+ .testTarget(
24
+ name: "NfcPluginTests",
25
+ dependencies: ["NfcPlugin"],
26
+ path: "ios/Tests/NfcPluginTests")
27
+ ]
28
+ )
package/README.md ADDED
@@ -0,0 +1,385 @@
1
+ # @capgo/capacitor-nfc
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
+
9
+ Native NFC tag detection, reading, and writing for Capacitor apps on iOS and Android.
10
+
11
+ Modern Capacitor port of the battle-tested [phonegap-nfc](https://github.com/chariotsolutions/phonegap-nfc) plugin, aligned with Capgo conventions and tooling.
12
+
13
+ ## Documentation
14
+
15
+ The most complete documentation will live on the Capgo docs portal. Until then, explore the TypeScript definitions (`src/definitions.ts`) and run the included example app for a tour of the API.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install @capgo/capacitor-nfc
21
+ npx cap sync
22
+ ```
23
+
24
+ Remember to add the required platform configuration:
25
+
26
+ - **Android:** ensure your `AndroidManifest.xml` declares the `android.permission.NFC` permission.
27
+ - **iOS:** add `NFCReaderUsageDescription` to your app `Info.plist` to explain why NFC access is needed.
28
+
29
+ ## Usage
30
+
31
+ ```ts
32
+ import { CapacitorNfc } from '@capgo/capacitor-nfc';
33
+
34
+ await CapacitorNfc.startScanning({
35
+ invalidateAfterFirstRead: false, // keep the session open so we can write later
36
+ alertMessage: 'Hold a tag near the top of your device.',
37
+ });
38
+
39
+ const listener = await CapacitorNfc.addListener('nfcEvent', (event) => {
40
+ console.info('Tag type:', event.type);
41
+ console.info('First record:', event.tag?.ndefMessage?.[0]);
42
+ });
43
+
44
+ // Later, write a simple text record back to the tag
45
+ const encoder = new TextEncoder();
46
+ const langBytes = Array.from(encoder.encode('en'));
47
+ const textBytes = Array.from(encoder.encode('Hello Capgo'));
48
+ const payload = [langBytes.length & 0x3f, ...langBytes, ...textBytes];
49
+
50
+ await CapacitorNfc.write({
51
+ allowFormat: true,
52
+ records: [
53
+ {
54
+ tnf: 0x01,
55
+ type: [0x54], // 'T'
56
+ id: [],
57
+ payload,
58
+ },
59
+ ],
60
+ });
61
+
62
+ await listener.remove();
63
+ await CapacitorNfc.stopScanning();
64
+ ```
65
+
66
+ ## API
67
+
68
+ <docgen-index>
69
+
70
+ * [`startScanning(...)`](#startscanning)
71
+ * [`stopScanning()`](#stopscanning)
72
+ * [`write(...)`](#write)
73
+ * [`erase()`](#erase)
74
+ * [`makeReadOnly()`](#makereadonly)
75
+ * [`share(...)`](#share)
76
+ * [`unshare()`](#unshare)
77
+ * [`getStatus()`](#getstatus)
78
+ * [`showSettings()`](#showsettings)
79
+ * [`getPluginVersion()`](#getpluginversion)
80
+ * [`addListener('nfcEvent', ...)`](#addlistenernfcevent-)
81
+ * [`addListener('tagDiscovered' | 'ndefDiscovered' | 'ndefMimeDiscovered' | 'ndefFormatableDiscovered', ...)`](#addlistenertagdiscovered--ndefdiscovered--ndefmimediscovered--ndefformatablediscovered-)
82
+ * [`addListener('nfcStateChange', ...)`](#addlistenernfcstatechange-)
83
+ * [Interfaces](#interfaces)
84
+ * [Type Aliases](#type-aliases)
85
+
86
+ </docgen-index>
87
+
88
+ <docgen-api>
89
+ <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
90
+
91
+ Public API surface for the Capacitor NFC plugin.
92
+
93
+ The interface intentionally mirrors the behaviour of the reference PhoneGap
94
+ implementation to ease migration while embracing idiomatic Capacitor APIs.
95
+
96
+ ### startScanning(...)
97
+
98
+ ```typescript
99
+ startScanning(options?: StartScanningOptions | undefined) => Promise<void>
100
+ ```
101
+
102
+ Starts listening for NFC tags.
103
+
104
+ | Param | Type |
105
+ | ------------- | --------------------------------------------------------------------- |
106
+ | **`options`** | <code><a href="#startscanningoptions">StartScanningOptions</a></code> |
107
+
108
+ --------------------
109
+
110
+
111
+ ### stopScanning()
112
+
113
+ ```typescript
114
+ stopScanning() => Promise<void>
115
+ ```
116
+
117
+ Stops the ongoing NFC scanning session.
118
+
119
+ --------------------
120
+
121
+
122
+ ### write(...)
123
+
124
+ ```typescript
125
+ write(options: WriteTagOptions) => Promise<void>
126
+ ```
127
+
128
+ Writes the provided NDEF records to the last discovered tag.
129
+
130
+ | Param | Type |
131
+ | ------------- | ----------------------------------------------------------- |
132
+ | **`options`** | <code><a href="#writetagoptions">WriteTagOptions</a></code> |
133
+
134
+ --------------------
135
+
136
+
137
+ ### erase()
138
+
139
+ ```typescript
140
+ erase() => Promise<void>
141
+ ```
142
+
143
+ Attempts to erase the last discovered tag by writing an empty NDEF message.
144
+
145
+ --------------------
146
+
147
+
148
+ ### makeReadOnly()
149
+
150
+ ```typescript
151
+ makeReadOnly() => Promise<void>
152
+ ```
153
+
154
+ Attempts to make the last discovered tag read-only.
155
+
156
+ --------------------
157
+
158
+
159
+ ### share(...)
160
+
161
+ ```typescript
162
+ share(options: ShareTagOptions) => Promise<void>
163
+ ```
164
+
165
+ Shares an NDEF message with another device via peer-to-peer (Android only).
166
+
167
+ | Param | Type |
168
+ | ------------- | ----------------------------------------------------------- |
169
+ | **`options`** | <code><a href="#sharetagoptions">ShareTagOptions</a></code> |
170
+
171
+ --------------------
172
+
173
+
174
+ ### unshare()
175
+
176
+ ```typescript
177
+ unshare() => Promise<void>
178
+ ```
179
+
180
+ Stops sharing previously provided NDEF message (Android only).
181
+
182
+ --------------------
183
+
184
+
185
+ ### getStatus()
186
+
187
+ ```typescript
188
+ getStatus() => Promise<{ status: NfcStatus; }>
189
+ ```
190
+
191
+ Returns the current NFC adapter status.
192
+
193
+ **Returns:** <code>Promise&lt;{ status: <a href="#nfcstatus">NfcStatus</a>; }&gt;</code>
194
+
195
+ --------------------
196
+
197
+
198
+ ### showSettings()
199
+
200
+ ```typescript
201
+ showSettings() => Promise<void>
202
+ ```
203
+
204
+ Opens the system settings page where the user can enable NFC.
205
+
206
+ --------------------
207
+
208
+
209
+ ### getPluginVersion()
210
+
211
+ ```typescript
212
+ getPluginVersion() => Promise<{ version: string; }>
213
+ ```
214
+
215
+ Returns the version string baked into the native plugin.
216
+
217
+ **Returns:** <code>Promise&lt;{ version: string; }&gt;</code>
218
+
219
+ --------------------
220
+
221
+
222
+ ### addListener('nfcEvent', ...)
223
+
224
+ ```typescript
225
+ addListener(eventName: 'nfcEvent', listenerFunc: (event: NfcEvent) => void) => Promise<PluginListenerHandle>
226
+ ```
227
+
228
+ | Param | Type |
229
+ | ------------------ | ----------------------------------------------------------------- |
230
+ | **`eventName`** | <code>'nfcEvent'</code> |
231
+ | **`listenerFunc`** | <code>(event: <a href="#nfcevent">NfcEvent</a>) =&gt; void</code> |
232
+
233
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
234
+
235
+ --------------------
236
+
237
+
238
+ ### addListener('tagDiscovered' | 'ndefDiscovered' | 'ndefMimeDiscovered' | 'ndefFormatableDiscovered', ...)
239
+
240
+ ```typescript
241
+ addListener(eventName: 'tagDiscovered' | 'ndefDiscovered' | 'ndefMimeDiscovered' | 'ndefFormatableDiscovered', listenerFunc: (event: NfcEvent) => void) => Promise<PluginListenerHandle>
242
+ ```
243
+
244
+ | Param | Type |
245
+ | ------------------ | ------------------------------------------------------------------------------------------------------ |
246
+ | **`eventName`** | <code>'tagDiscovered' \| 'ndefDiscovered' \| 'ndefMimeDiscovered' \| 'ndefFormatableDiscovered'</code> |
247
+ | **`listenerFunc`** | <code>(event: <a href="#nfcevent">NfcEvent</a>) =&gt; void</code> |
248
+
249
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
250
+
251
+ --------------------
252
+
253
+
254
+ ### addListener('nfcStateChange', ...)
255
+
256
+ ```typescript
257
+ addListener(eventName: 'nfcStateChange', listenerFunc: (event: NfcStateChangeEvent) => void) => Promise<PluginListenerHandle>
258
+ ```
259
+
260
+ | Param | Type |
261
+ | ------------------ | --------------------------------------------------------------------------------------- |
262
+ | **`eventName`** | <code>'nfcStateChange'</code> |
263
+ | **`listenerFunc`** | <code>(event: <a href="#nfcstatechangeevent">NfcStateChangeEvent</a>) =&gt; void</code> |
264
+
265
+ **Returns:** <code>Promise&lt;<a href="#pluginlistenerhandle">PluginListenerHandle</a>&gt;</code>
266
+
267
+ --------------------
268
+
269
+
270
+ ### Interfaces
271
+
272
+
273
+ #### StartScanningOptions
274
+
275
+ Options controlling the behaviour of {@link CapacitorNfcPlugin.startScanning}.
276
+
277
+ | Prop | Type | Description |
278
+ | ------------------------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
279
+ | **`invalidateAfterFirstRead`** | <code>boolean</code> | iOS-only: closes the NFC session automatically after the first successful tag read. Defaults to `true`. |
280
+ | **`alertMessage`** | <code>string</code> | iOS-only: custom message displayed in the NFC system sheet while scanning. |
281
+ | **`androidReaderModeFlags`** | <code>number</code> | Android-only: raw flags passed to `NfcAdapter.enableReaderMode`. Defaults to enabling all tag types with skipping NDEF checks. |
282
+
283
+
284
+ #### WriteTagOptions
285
+
286
+ Options used when writing an NDEF message on the current tag.
287
+
288
+ | Prop | Type | Description |
289
+ | ----------------- | ------------------------- | ---------------------------------------------------------------------------------------------------- |
290
+ | **`records`** | <code>NdefRecord[]</code> | Array of records that compose the NDEF message to be written. |
291
+ | **`allowFormat`** | <code>boolean</code> | When `true`, the plugin attempts to format NDEF-formattable tags before writing. Defaults to `true`. |
292
+
293
+
294
+ #### NdefRecord
295
+
296
+ JSON structure representing a single NDEF record.
297
+
298
+ Mirrors the data format returned by the legacy Cordova implementation and
299
+ uses integer arrays instead of strings to preserve the original payload
300
+ bytes.
301
+
302
+ | Prop | Type | Description |
303
+ | ------------- | --------------------- | ------------------------------------------------------- |
304
+ | **`tnf`** | <code>number</code> | Type Name Format identifier. |
305
+ | **`type`** | <code>number[]</code> | Type field expressed as an array of byte values. |
306
+ | **`id`** | <code>number[]</code> | Record identifier expressed as an array of byte values. |
307
+ | **`payload`** | <code>number[]</code> | Raw payload expressed as an array of byte values. |
308
+
309
+
310
+ #### ShareTagOptions
311
+
312
+ Options used when sharing an NDEF message with another device using Android Beam / P2P mode.
313
+
314
+ | Prop | Type |
315
+ | ------------- | ------------------------- |
316
+ | **`records`** | <code>NdefRecord[]</code> |
317
+
318
+
319
+ #### PluginListenerHandle
320
+
321
+ | Prop | Type |
322
+ | ------------ | ----------------------------------------- |
323
+ | **`remove`** | <code>() =&gt; Promise&lt;void&gt;</code> |
324
+
325
+
326
+ #### NfcEvent
327
+
328
+ Generic NFC discovery event dispatched by the plugin.
329
+
330
+ | Prop | Type |
331
+ | ---------- | ----------------------------------------------------- |
332
+ | **`type`** | <code><a href="#nfceventtype">NfcEventType</a></code> |
333
+ | **`tag`** | <code><a href="#nfctag">NfcTag</a></code> |
334
+
335
+
336
+ #### NfcTag
337
+
338
+ Representation of the full tag information returned by the native layers.
339
+
340
+ | Prop | Type | Description |
341
+ | --------------------- | --------------------------------- | --------------------------------------------------------------------- |
342
+ | **`id`** | <code>number[]</code> | Raw identifier bytes for the tag. |
343
+ | **`techTypes`** | <code>string[]</code> | List of Android tech strings (e.g. `android.nfc.tech.Ndef`). |
344
+ | **`type`** | <code>string \| null</code> | Human readable tag type when available (e.g. `NFC Forum Type 2`). |
345
+ | **`maxSize`** | <code>number \| null</code> | Maximum writable size in bytes for tags that expose NDEF information. |
346
+ | **`isWritable`** | <code>boolean \| null</code> | Indicates whether the tag can be written to. |
347
+ | **`canMakeReadOnly`** | <code>boolean \| null</code> | Indicates whether the tag can be permanently locked. |
348
+ | **`ndefMessage`** | <code>NdefRecord[] \| null</code> | Array of NDEF records discovered on the tag. |
349
+
350
+
351
+ #### NfcStateChangeEvent
352
+
353
+ Event emitted whenever the NFC adapter availability changes.
354
+
355
+ | Prop | Type |
356
+ | ------------- | ----------------------------------------------- |
357
+ | **`status`** | <code><a href="#nfcstatus">NfcStatus</a></code> |
358
+ | **`enabled`** | <code>boolean</code> |
359
+
360
+
361
+ ### Type Aliases
362
+
363
+
364
+ #### NfcStatus
365
+
366
+ Possible NFC adapter states returned by {@link CapacitorNfcPlugin.getStatus}.
367
+
368
+ Matches the constants provided by the original PhoneGap NFC plugin for
369
+ compatibility with existing applications.
370
+
371
+ <code>'NFC_OK' | 'NO_NFC' | 'NFC_DISABLED' | 'NDEF_PUSH_DISABLED'</code>
372
+
373
+
374
+ #### NfcEventType
375
+
376
+ Event type describing the kind of NFC discovery that happened.
377
+
378
+ - `tag`: A generic NFC tag (no NDEF payload).
379
+ - `ndef`: A tag exposing an NDEF payload.
380
+ - `ndef-mime`: An NDEF tag that matched one of the MIME type filters.
381
+ - `ndef-formatable`: A tag that can be formatted to NDEF.
382
+
383
+ <code>'tag' | 'ndef' | 'ndef-mime' | 'ndef-formatable'</code>
384
+
385
+ </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.nfc"
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,9 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
3
+
4
+ <uses-permission android:name="android.permission.NFC" />
5
+ <uses-feature
6
+ android:name="android.hardware.nfc"
7
+ android:required="false" />
8
+
9
+ </manifest>