@exxili/capacitor-nfc 0.0.2 → 0.0.9

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 = 'ExxiliCapacitorNfc'
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 = '13.0'
15
+ s.dependency 'Capacitor'
16
+ s.swift_version = '5.1'
17
+ end
package/README.md CHANGED
@@ -1,31 +1,33 @@
1
1
  # Capacitor NFC Plugin (@exxili/capacitor-nfc)
2
2
 
3
- A Capacitor plugin for reading and writing NFC tags on iOS devices. This plugin allows you to:
3
+ A Capacitor plugin for reading and writing NFC tags on iOS and Android devices. This plugin allows you to:
4
4
 
5
5
  - Read NDEF messages from NFC tags.
6
6
  - Write NDEF messages to NFC tags.
7
7
 
8
- **Note**: NFC functionality is only available on compatible iOS devices running iOS 13.0 or later. Android NFC functionality is still
9
- in development
8
+ **Note**: NFC functionality is only available on compatible iOS devices running iOS 13.0 or later.
10
9
 
11
10
  ## Table of Contents
12
11
 
13
12
  - [Installation](#installation)
14
13
  - [iOS Setup](#ios-setup)
15
- - Android Setup (in Development)
14
+ - [Android Setup](#android-setup)
16
15
  - [Usage](#usage)
17
16
  - [Reading NFC Tags](#reading-nfc-tags)
18
17
  - [Writing NFC Tags](#writing-nfc-tags)
19
18
  - [API](#api)
20
19
  - [Methods](#methods)
20
+ - [`isSupported()`](#issupported)
21
21
  - [`startScan()`](#startscan)
22
- - [`writeNDEF(options)`](#writendefoptions)
22
+ - [`writeNDEF(options)`](#writendefoptions-ndefwriteoptionst-extends-string--number--uint8array--string)
23
+ - [`cancelWriteAndroid`](#cancelwriteandroid)
23
24
  - [Listeners](#listeners)
24
- - [`addListener('nfcTag', listener)`](#addlistenernfctag-listener)
25
- - [`addListener('nfcError', listener)`](#addlistenernfcerror-listener)
26
- - [`addListener('nfcWriteSuccess', listener)`](#addlistenernfcwritesuccess-listener)
25
+ - [`onRead(listener)`](#onreadlistener-data-ndefmessagestransformable--void)
26
+ - [`onError('listener)`](#onerrorlistener-error-nfcerror--void)
27
+ - [`onWrite(listener)`](#onwritelistener---void)
27
28
  - [Interfaces](#interfaces)
28
29
  - [`NDEFWriteOptions`](#ndefwriteoptions)
30
+ - [`NDEFWriteOptions`](#ndefmessagestransformable)
29
31
  - [`NDEFMessages`](#ndefmessages)
30
32
  - [`NDEFMessage`](#ndefmessage)
31
33
  - [`NDEFRecord`](#ndefrecord)
@@ -71,6 +73,15 @@ In your `Info.plist` file (usually located at `ios/App/App/Info.plist`), add:
71
73
 
72
74
  Replace the description with a message that explains why your app needs NFC access.
73
75
 
76
+ ## Android Setup
77
+
78
+ Add the following to your `AndroidManifest.xml` file:
79
+
80
+ ```xml
81
+ <uses-permission android:name="android.permission.NFC" />
82
+ <uses-feature android:name="android.hardware.nfc" android:required="true" />
83
+ ```
84
+
74
85
  ## Usage
75
86
 
76
87
  Import the plugin into your code:
@@ -81,10 +92,10 @@ import { NFC } from '@exxili/capacitor-nfc';
81
92
 
82
93
  ### Reading NFC Tags
83
94
 
84
- To read NFC tags, you need to start a scanning session and listen for `nfcTag` events.
95
+ To read NFC tags, you need to listen for `nfcTag` events. On iOS, you must also start the NFC scanning session using `startScan()`.
85
96
 
86
97
  ```typescript
87
- import { NFC, NDEFMessages, NFCError } from '@exxili/capacitor-nfc';
98
+ import {NFC, NDEFMessagesTransformable, NFCError} from '@exxili/capacitor-nfc';
88
99
 
89
100
  // Start NFC scanning
90
101
  NFC.startScan().catch((error) => {
@@ -92,19 +103,19 @@ NFC.startScan().catch((error) => {
92
103
  });
93
104
 
94
105
  // Listen for NFC tag detection
95
- const nfcTagListener = NFC.addListener('nfcTag', (data: NDEFMessages) => {
96
- console.log('Received NFC tag:', data);
106
+ NFC.onRead((data: NDEFMessagesTransformable) => {
107
+ console.log('Received NFC tag:', data.string());
97
108
  });
98
109
 
99
110
  // Handle NFC errors
100
- const nfcErrorListener = NFC.addListener('nfcError', (error: NFCError) => {
111
+ NFC.onError('nfcError', (error: NFCError) => {
101
112
  console.error('NFC Error:', error);
102
113
  });
103
114
  ```
104
115
 
105
116
  ### Writing NFC Tags
106
117
 
107
- To write NDEF messages to NFC tags, use the `writeNDEF` method and listen for `nfcWriteSuccess` events.
118
+ To write NDEF messages to NFC tags, use the `writeNDEF` method and listen for `onWrite` events.
108
119
 
109
120
  ```typescript
110
121
  import { NFC, NDEFWriteOptions, NFCError } from '@exxili/capacitor-nfc';
@@ -128,12 +139,12 @@ NFC.writeNDEF(message)
128
139
  });
129
140
 
130
141
  // Listen for write success
131
- const nfcWriteSuccessListener = NFC.addListener('nfcWriteSuccess', () => {
142
+ NFC.onWrite(() => {
132
143
  console.log('NDEF message written successfully.');
133
144
  });
134
145
 
135
146
  // Handle NFC errors
136
- const nfcErrorListener = NFC.addListener('nfcError', (error: NFCError) => {
147
+ NFC.onError((error: NFCError) => {
137
148
  console.error('NFC Error:', error);
138
149
  });
139
150
  ```
@@ -142,9 +153,15 @@ const nfcErrorListener = NFC.addListener('nfcError', (error: NFCError) => {
142
153
 
143
154
  ### Methods
144
155
 
156
+ #### `isSupported()`
157
+
158
+ Returns if NFC is supported on the scanning device.
159
+
160
+ **Returns**: `Promise<{ supported: boolean }>`
161
+
145
162
  #### `startScan()`
146
163
 
147
- Starts the NFC scanning session.
164
+ Starts the NFC scanning session on ***iOS only***. Android devices are always in reading mode, so setting up the `nfcTag` listener is sufficient to handle tag reads on Android.
148
165
 
149
166
  **Returns**: `Promise<void>`
150
167
 
@@ -158,13 +175,17 @@ NFC.startScan()
158
175
  });
159
176
  ```
160
177
 
161
- #### `writeNDEF(options: NDEFWriteOptions)`
178
+ #### `writeNDEF(options: NDEFWriteOptions<T extends string | number[] | Uint8Array = string)`
162
179
 
163
180
  Writes an NDEF message to an NFC tag.
164
181
 
182
+ Payload may be provided as a string, `Uint8Array`, or an array of numbers. The plugin will automatically convert the payload to a byte array for storage on the NFC tag.
183
+
184
+ Android use: since Android has no default UI for reading and writing NFC tags, it is recommended that you add a UI indicator to your application when calling `writeNDEF` and remove it in the `nfcWriteSuccess` listener callback and the `nfcError` listener callback. This will prevent accidental writes to tags that your users intended to read from.
185
+
165
186
  **Parameters**:
166
187
 
167
- - `options: NDEFWriteOptions` - The NDEF message to write.
188
+ - `options: NDEFWriteOptions<T extends string | number[] | Uint8Array = string>` - The NDEF message to write.
168
189
 
169
190
  **Returns**: `Promise<void>`
170
191
 
@@ -178,55 +199,61 @@ NFC.writeNDEF(options)
178
199
  });
179
200
  ```
180
201
 
202
+ #### `cancelWriteAndroid()`
203
+
204
+ Cancels an Android NFC write operation. Android does not have a native UI for NFC tag writing, so this method allows developers to hook up a custom UI to cancel an in-progress scan.
205
+
181
206
  ### Listeners
182
207
 
183
- #### `addListener('nfcTag', listener: (data: NDEFMessages) => void)`
208
+ #### `onRead(listener: (data: NDEFMessagesTransformable) => void)`
209
+
210
+ Adds a listener for NFC tag detection events. Returns type `NDEFMessagesTransformable`, which returns the following methods to provide the payload:
184
211
 
185
- Adds a listener for NFC tag detection events.
212
+ * `string()`: Returns `NDEFMessages<string>`, where all payloads are strings.
213
+ * `base64()`: Returns `NDEFMessages<string>`, where all payloads are the base64-encoded payloads read from the NFC tag.
214
+ * `uint8Array()`: Returns `NDEFMessages<Uint8Array>`, where all payloads are the `Uint8Array` bytes from the NFC tag.
215
+ * `numberArray()`: Returns `NDEFMessages<number[]>`, where all payloads bytes from the NFC tag represented as a `number[]`.
186
216
 
187
217
  **Parameters**:
188
218
 
189
- - `eventName: 'nfcTag'`
190
- - `listener: (data: NDEFMessages) => void` - The function to call when an NFC tag is detected.
219
+ - `listener: (data: NDEFMessagesTransformable) => void` - The function to call when an NFC tag is detected.
191
220
 
192
- **Returns**: `PluginListenerHandle`
221
+ **Returns**: `void`
193
222
 
194
223
  ```typescript
195
- const nfcTagListener = NFC.addListener('nfcTag', (data: NDEFMessages) => {
224
+ NFC.onRead((data: NDEFMessages) => {
196
225
  console.log('Received NFC tag:', data);
197
226
  });
198
227
  ```
199
228
 
200
- #### `addListener('nfcError', listener: (error: NFCError) => void)`
229
+ #### `onError(listener: (error: NFCError) => void)`
201
230
 
202
231
  Adds a listener for NFC error events.
203
232
 
204
233
  **Parameters**:
205
234
 
206
- - `eventName: 'nfcError'`
207
235
  - `listener: (error: NFCError) => void` - The function to call when an NFC error occurs.
208
236
 
209
237
  **Returns**: `PluginListenerHandle`
210
238
 
211
239
  ```typescript
212
- const nfcErrorListener = NFC.addListener('nfcError', (error: NFCError) => {
240
+ NFC.onError((error: NFCError) => {
213
241
  console.error('NFC Error:', error);
214
242
  });
215
243
  ```
216
244
 
217
- #### `addListener('nfcWriteSuccess', listener: () => void)`
245
+ #### `onWrite(listener: () => void)`
218
246
 
219
247
  Adds a listener for NFC write success events.
220
248
 
221
249
  **Parameters**:
222
250
 
223
- - `eventName: 'nfcWriteSuccess'`
224
251
  - `listener: () => void` - The function to call when an NDEF message has been written successfully.
225
252
 
226
253
  **Returns**: `PluginListenerHandle`
227
254
 
228
255
  ```typescript
229
- const nfcWriteSuccessListener = NFC.addListener('nfcWriteSuccess', () => {
256
+ NFC.onWrite('nfcWriteSuccess', () => {
230
257
  console.log('NDEF message written successfully.');
231
258
  });
232
259
  ```
@@ -238,8 +265,26 @@ const nfcWriteSuccessListener = NFC.addListener('nfcWriteSuccess', () => {
238
265
  Options for writing an NDEF message.
239
266
 
240
267
  ```typescript
241
- interface NDEFWriteOptions {
242
- records: NDEFRecord[];
268
+ interface NDEFWriteOptions<T extends string | number[] | Uint8Array = string> {
269
+ records: NDEFRecord<T>[];
270
+ }
271
+ ```
272
+
273
+ #### `NDEFMessagesTransformable`
274
+
275
+ Returned by `onRead` and includes the following methods to provide the payload:
276
+
277
+ * `string()`: Returns `NDEFMessages<string>`, where all payloads are strings.
278
+ * `base64()`: Returns `NDEFMessages<string>`, where all payloads are the base64-encoded payloads read from the NFC tag.
279
+ * `uint8Array()`: Returns `NDEFMessages<Uint8Array>`, where all payloads are the `Uint8Array` bytes from the NFC tag.
280
+ * `numberArray()`: Returns `NDEFMessages<number[]>`, where all payloads bytes from the NFC tag represented as a `number[]`.
281
+
282
+ ```typescript
283
+ interface NDEFMessagesTransformable {
284
+ base64: ()=> NDEFMessages;
285
+ uint8Array: ()=> NDEFMessages<Uint8Array>;
286
+ string: ()=> NDEFMessages;
287
+ numberArray: ()=> NDEFMessages<number[]>;
243
288
  }
244
289
  ```
245
290
 
@@ -265,10 +310,10 @@ interface NDEFMessage {
265
310
 
266
311
  #### `NDEFRecord`
267
312
 
268
- An NDEF record.
313
+ An NDEF record. `payload` is, by default, an array of bytes representing the data; this is how an `NDEFRecord` is read from an NFC tag. You can choose to provide an `NDEFRecord` as a string a `Uint8Array` also.
269
314
 
270
315
  ```typescript
271
- interface NDEFRecord {
316
+ interface NDEFRecord<T = number[]> {
272
317
  /**
273
318
  * The type of the record.
274
319
  */
@@ -277,9 +322,9 @@ interface NDEFRecord {
277
322
  /**
278
323
  * The payload of the record.
279
324
  */
280
- payload: string;
325
+ payload: T;
281
326
  }
282
- ```
327
+ ````
283
328
 
284
329
  #### `NFCError`
285
330
 
@@ -320,18 +365,26 @@ Here's a complete example of how to read and write NFC tags in your app:
320
365
  ```typescript
321
366
  import { NFC, NDEFMessages, NDEFWriteOptions, NFCError } from '@exxili/capacitor-nfc';
322
367
 
323
- // Start NFC scanning
368
+ // Check if NFC is supported
369
+ const { supported } = await NFC.isSupported();
370
+
371
+ // Start NFC scanning -- iOS only
324
372
  NFC.startScan().catch((error) => {
325
373
  console.error('Error starting NFC scan:', error);
326
374
  });
327
375
 
328
376
  // Listen for NFC tag detection
329
- const nfcTagListener = NFC.addListener('nfcTag', (data: NDEFMessages) => {
330
- console.log('Received NFC tag:', data);
377
+ NFC.onRead((data: NDEFMessages) => {
378
+ const stringMessages: NDEFMessage<string> = data.string();
379
+ const uint8ArrayMessages: NDEFMessage<Uint8Array> = data.uint8Array();
380
+
381
+ // Print all Uint8Array payloads
382
+ console.log('Received NFC tag:', stringMessages.messages?.at(0)?.records?.at(0).payload); // prints string[]
383
+ console.log('Received NFC tag:', uint8ArrayPayloads.messages?.at(0)?.records?.at(0).payload); // prints Uint8Array[]
331
384
  });
332
385
 
333
386
  // Handle NFC errors
334
- const nfcErrorListener = NFC.addListener('nfcError', (error: NFCError) => {
387
+ NFC.onError((error: NFCError) => {
335
388
  console.error('NFC Error:', error);
336
389
  });
337
390
 
@@ -355,14 +408,14 @@ NFC.writeNDEF(message)
355
408
  });
356
409
 
357
410
  // Listen for write success
358
- const nfcWriteSuccessListener = NFC.addListener('nfcWriteSuccess', () => {
411
+ NFC.onWrite('nfcWriteSuccess', () => {
359
412
  console.log('NDEF message written successfully.');
360
413
  });
361
414
  ```
362
415
 
363
416
  ## License
364
417
 
365
- [MIT License](LICENSE)
418
+ [MIT License](https://opensource.org/license/mit)
366
419
 
367
420
  ---
368
421
 
@@ -6,22 +6,27 @@ ext {
6
6
  }
7
7
 
8
8
  buildscript {
9
+ ext {
10
+ kotlin_version = '2.1.21'
11
+ }
9
12
  repositories {
10
13
  google()
11
14
  mavenCentral()
12
15
  }
13
16
  dependencies {
14
- classpath 'com.android.tools.build:gradle:8.2.1'
17
+ classpath 'com.android.tools.build:gradle:8.2.2'
18
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
15
19
  }
16
20
  }
17
21
 
18
22
  apply plugin: 'com.android.library'
23
+ apply plugin: 'org.jetbrains.kotlin.android'
19
24
 
20
25
  android {
21
26
  namespace "com.exxili.capacitornfc"
22
27
  compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34
23
28
  defaultConfig {
24
- minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
29
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 33
25
30
  targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 34
26
31
  versionCode 1
27
32
  versionName "1.0"
@@ -40,6 +45,9 @@ android {
40
45
  sourceCompatibility JavaVersion.VERSION_17
41
46
  targetCompatibility JavaVersion.VERSION_17
42
47
  }
48
+ kotlinOptions {
49
+ jvmTarget = '17'
50
+ }
43
51
  }
44
52
 
45
53
  repositories {
@@ -52,6 +60,7 @@ dependencies {
52
60
  implementation fileTree(dir: 'libs', include: ['*.jar'])
53
61
  implementation project(':capacitor-android')
54
62
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
63
+ implementation 'androidx.core:core-ktx:1.16.0'
55
64
  testImplementation "junit:junit:$junitVersion"
56
65
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
57
66
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
@@ -0,0 +1,11 @@
1
+ package com.exxili.capacitornfc
2
+
3
+ import android.os.Bundle
4
+ import com.getcapacitor.BridgeActivity
5
+
6
+ class MainActivity : BridgeActivity() {
7
+ public override fun onCreate(savedInstanceState: Bundle?) {
8
+ super.onCreate(savedInstanceState)
9
+ registerPlugin(NFCPlugin::class.java)
10
+ }
11
+ }