@exxili/capacitor-nfc 0.0.1

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 = 'CapacitorNfc'
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/Package.swift ADDED
@@ -0,0 +1,28 @@
1
+ // swift-tools-version: 5.9
2
+ import PackageDescription
3
+
4
+ let package = Package(
5
+ name: "CapacitorNfc",
6
+ platforms: [.iOS(.v13)],
7
+ products: [
8
+ .library(
9
+ name: "CapacitorNfc",
10
+ targets: ["NFCPlugin"])
11
+ ],
12
+ dependencies: [
13
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", branch: "main")
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,371 @@
1
+ # Capacitor NFC Plugin (@exxili/capacitor-nfc)
2
+
3
+ A Capacitor plugin for reading and writing NFC tags on iOS devices. This plugin allows you to:
4
+
5
+ - Read NDEF messages from NFC tags.
6
+ - Write NDEF messages to NFC tags.
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
10
+
11
+ ## Table of Contents
12
+
13
+ - [Installation](#installation)
14
+ - [iOS Setup](#ios-setup)
15
+ - Android Setup (in Development)
16
+ - [Usage](#usage)
17
+ - [Reading NFC Tags](#reading-nfc-tags)
18
+ - [Writing NFC Tags](#writing-nfc-tags)
19
+ - [API](#api)
20
+ - [Methods](#methods)
21
+ - [`startScan()`](#startscan)
22
+ - [`writeNDEF(options)`](#writendefoptions)
23
+ - [Listeners](#listeners)
24
+ - [`addListener('nfcTag', listener)`](#addlistenernfctag-listener)
25
+ - [`addListener('nfcError', listener)`](#addlistenernfcerror-listener)
26
+ - [`addListener('nfcWriteSuccess', listener)`](#addlistenernfcwritesuccess-listener)
27
+ - [Interfaces](#interfaces)
28
+ - [`NDEFWriteOptions`](#ndefwriteoptions)
29
+ - [`NDEFMessages`](#ndefmessages)
30
+ - [`NDEFMessage`](#ndefmessage)
31
+ - [`NDEFRecord`](#ndefrecord)
32
+ - [`NFCError`](#nfcerror)
33
+ - [Integration into a Capacitor App](#integration-into-a-capacitor-app)
34
+ - [Example](#example)
35
+ - [License](#license)
36
+
37
+ ## Installation
38
+
39
+ Install the plugin using npm:
40
+
41
+ ```bash
42
+ npm install @exxili/capacitor-nfc
43
+ npx cap sync
44
+ ```
45
+
46
+ ## iOS Setup
47
+
48
+ To use NFC functionality on iOS, you need to perform some additional setup steps.
49
+
50
+ ### 1. Enable NFC Capability
51
+
52
+ In Xcode:
53
+
54
+ 1. Open your project (`.xcworkspace` file) in Xcode.
55
+ 2. Select your project in the Project Navigator.
56
+ 3. Select your app target.
57
+ 4. Go to the **Signing & Capabilities** tab.
58
+ 5. Click the `+ Capability` button.
59
+ 6. Add **Near Field Communication Tag Reading**.
60
+
61
+ ### 2. Add Usage Description
62
+
63
+ Add the `NFCReaderUsageDescription` key to your `Info.plist` file to explain why your app needs access to NFC.
64
+
65
+ In your `Info.plist` file (usually located at `ios/App/App/Info.plist`), add:
66
+
67
+ ```xml
68
+ <key>NFCReaderUsageDescription</key>
69
+ <string>This app requires access to NFC to read and write NFC tags.</string>
70
+ ```
71
+
72
+ Replace the description with a message that explains why your app needs NFC access.
73
+
74
+ ## Usage
75
+
76
+ Import the plugin into your code:
77
+
78
+ ```typescript
79
+ import { NFC } from '@exxili/capacitor-nfc';
80
+ ```
81
+
82
+ ### Reading NFC Tags
83
+
84
+ To read NFC tags, you need to start a scanning session and listen for `nfcTag` events.
85
+
86
+ ```typescript
87
+ import { NFC, NDEFMessages, NFCError } from '@exxili/capacitor-nfc';
88
+
89
+ // Start NFC scanning
90
+ NFC.startScan().catch((error) => {
91
+ console.error('Error starting NFC scan:', error);
92
+ });
93
+
94
+ // Listen for NFC tag detection
95
+ const nfcTagListener = NFC.addListener('nfcTag', (data: NDEFMessages) => {
96
+ console.log('Received NFC tag:', data);
97
+ });
98
+
99
+ // Handle NFC errors
100
+ const nfcErrorListener = NFC.addListener('nfcError', (error: NFCError) => {
101
+ console.error('NFC Error:', error);
102
+ });
103
+ ```
104
+
105
+ ### Writing NFC Tags
106
+
107
+ To write NDEF messages to NFC tags, use the `writeNDEF` method and listen for `nfcWriteSuccess` events.
108
+
109
+ ```typescript
110
+ import { NFC, NDEFWriteOptions, NFCError } from '@exxili/capacitor-nfc';
111
+
112
+ const message: NDEFWriteOptions = {
113
+ records: [
114
+ {
115
+ type: 'T', // Text record type
116
+ payload: 'Hello, NFC!',
117
+ },
118
+ ],
119
+ };
120
+
121
+ // Write NDEF message to NFC tag
122
+ NFC.writeNDEF(message)
123
+ .then(() => {
124
+ console.log('Write initiated');
125
+ })
126
+ .catch((error) => {
127
+ console.error('Error writing to NFC tag:', error);
128
+ });
129
+
130
+ // Listen for write success
131
+ const nfcWriteSuccessListener = NFC.addListener('nfcWriteSuccess', () => {
132
+ console.log('NDEF message written successfully.');
133
+ });
134
+
135
+ // Handle NFC errors
136
+ const nfcErrorListener = NFC.addListener('nfcError', (error: NFCError) => {
137
+ console.error('NFC Error:', error);
138
+ });
139
+ ```
140
+
141
+ ## API
142
+
143
+ ### Methods
144
+
145
+ #### `startScan()`
146
+
147
+ Starts the NFC scanning session.
148
+
149
+ **Returns**: `Promise<void>`
150
+
151
+ ```typescript
152
+ NFC.startScan()
153
+ .then(() => {
154
+ // Scanning started
155
+ })
156
+ .catch((error) => {
157
+ console.error('Error starting NFC scan:', error);
158
+ });
159
+ ```
160
+
161
+ #### `writeNDEF(options: NDEFWriteOptions)`
162
+
163
+ Writes an NDEF message to an NFC tag.
164
+
165
+ **Parameters**:
166
+
167
+ - `options: NDEFWriteOptions` - The NDEF message to write.
168
+
169
+ **Returns**: `Promise<void>`
170
+
171
+ ```typescript
172
+ NFC.writeNDEF(options)
173
+ .then(() => {
174
+ // Write initiated
175
+ })
176
+ .catch((error) => {
177
+ console.error('Error writing NDEF message:', error);
178
+ });
179
+ ```
180
+
181
+ ### Listeners
182
+
183
+ #### `addListener('nfcTag', listener: (data: NDEFMessages) => void)`
184
+
185
+ Adds a listener for NFC tag detection events.
186
+
187
+ **Parameters**:
188
+
189
+ - `eventName: 'nfcTag'`
190
+ - `listener: (data: NDEFMessages) => void` - The function to call when an NFC tag is detected.
191
+
192
+ **Returns**: `PluginListenerHandle`
193
+
194
+ ```typescript
195
+ const nfcTagListener = NFC.addListener('nfcTag', (data: NDEFMessages) => {
196
+ console.log('Received NFC tag:', data);
197
+ });
198
+ ```
199
+
200
+ #### `addListener('nfcError', listener: (error: NFCError) => void)`
201
+
202
+ Adds a listener for NFC error events.
203
+
204
+ **Parameters**:
205
+
206
+ - `eventName: 'nfcError'`
207
+ - `listener: (error: NFCError) => void` - The function to call when an NFC error occurs.
208
+
209
+ **Returns**: `PluginListenerHandle`
210
+
211
+ ```typescript
212
+ const nfcErrorListener = NFC.addListener('nfcError', (error: NFCError) => {
213
+ console.error('NFC Error:', error);
214
+ });
215
+ ```
216
+
217
+ #### `addListener('nfcWriteSuccess', listener: () => void)`
218
+
219
+ Adds a listener for NFC write success events.
220
+
221
+ **Parameters**:
222
+
223
+ - `eventName: 'nfcWriteSuccess'`
224
+ - `listener: () => void` - The function to call when an NDEF message has been written successfully.
225
+
226
+ **Returns**: `PluginListenerHandle`
227
+
228
+ ```typescript
229
+ const nfcWriteSuccessListener = NFC.addListener('nfcWriteSuccess', () => {
230
+ console.log('NDEF message written successfully.');
231
+ });
232
+ ```
233
+
234
+ ### Interfaces
235
+
236
+ #### `NDEFWriteOptions`
237
+
238
+ Options for writing an NDEF message.
239
+
240
+ ```typescript
241
+ interface NDEFWriteOptions {
242
+ records: NDEFRecord[];
243
+ }
244
+ ```
245
+
246
+ #### `NDEFMessages`
247
+
248
+ Data received from an NFC tag.
249
+
250
+ ```typescript
251
+ interface NDEFMessages {
252
+ messages: NDEFMessage[];
253
+ }
254
+ ```
255
+
256
+ #### `NDEFMessage`
257
+
258
+ An NDEF message consisting of one or more records.
259
+
260
+ ```typescript
261
+ interface NDEFMessage {
262
+ records: NDEFRecord[];
263
+ }
264
+ ```
265
+
266
+ #### `NDEFRecord`
267
+
268
+ An NDEF record.
269
+
270
+ ```typescript
271
+ interface NDEFRecord {
272
+ /**
273
+ * The type of the record.
274
+ */
275
+ type: string;
276
+
277
+ /**
278
+ * The payload of the record.
279
+ */
280
+ payload: string;
281
+ }
282
+ ```
283
+
284
+ #### `NFCError`
285
+
286
+ An NFC error.
287
+
288
+ ```typescript
289
+ interface NFCError {
290
+ /**
291
+ * The error message.
292
+ */
293
+ error: string;
294
+ }
295
+ ```
296
+
297
+ ## Integration into a Capacitor App
298
+
299
+ To integrate this plugin into your Capacitor app:
300
+
301
+ 1. **Install the plugin:**
302
+
303
+ ```bash
304
+ npm install @exxili/capacitor-nfc
305
+ npx cap sync
306
+ ```
307
+
308
+ 2. **Import the plugin in your code:**
309
+
310
+ ```typescript
311
+ import { NFC } from '@exxili/capacitor-nfc';
312
+ ```
313
+
314
+ 3. **Use the plugin methods as described in the [Usage](#usage) section.**
315
+
316
+ ## Example
317
+
318
+ Here's a complete example of how to read and write NFC tags in your app:
319
+
320
+ ```typescript
321
+ import { NFC, NDEFMessages, NDEFWriteOptions, NFCError } from '@exxili/capacitor-nfc';
322
+
323
+ // Start NFC scanning
324
+ NFC.startScan().catch((error) => {
325
+ console.error('Error starting NFC scan:', error);
326
+ });
327
+
328
+ // Listen for NFC tag detection
329
+ const nfcTagListener = NFC.addListener('nfcTag', (data: NDEFMessages) => {
330
+ console.log('Received NFC tag:', data);
331
+ });
332
+
333
+ // Handle NFC errors
334
+ const nfcErrorListener = NFC.addListener('nfcError', (error: NFCError) => {
335
+ console.error('NFC Error:', error);
336
+ });
337
+
338
+ // Prepare an NDEF message to write
339
+ const message: NDEFWriteOptions = {
340
+ records: [
341
+ {
342
+ type: 'T', // Text record type
343
+ payload: 'Hello, NFC!',
344
+ },
345
+ ],
346
+ };
347
+
348
+ // Write NDEF message to NFC tag
349
+ NFC.writeNDEF(message)
350
+ .then(() => {
351
+ console.log('Write initiated');
352
+ })
353
+ .catch((error) => {
354
+ console.error('Error writing to NFC tag:', error);
355
+ });
356
+
357
+ // Listen for write success
358
+ const nfcWriteSuccessListener = NFC.addListener('nfcWriteSuccess', () => {
359
+ console.log('NDEF message written successfully.');
360
+ });
361
+ ```
362
+
363
+ ## License
364
+
365
+ [MIT License](LICENSE)
366
+
367
+ ---
368
+
369
+ **Support**: If you encounter any issues or have questions, feel free to open an issue.
370
+
371
+ ---
@@ -0,0 +1,58 @@
1
+ ext {
2
+ junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
4
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5'
5
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1'
6
+ }
7
+
8
+ buildscript {
9
+ repositories {
10
+ google()
11
+ mavenCentral()
12
+ }
13
+ dependencies {
14
+ classpath 'com.android.tools.build:gradle:8.2.1'
15
+ }
16
+ }
17
+
18
+ apply plugin: 'com.android.library'
19
+
20
+ android {
21
+ namespace "com.exxili.capacitornfc"
22
+ compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 34
23
+ defaultConfig {
24
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
25
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 34
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_17
41
+ targetCompatibility JavaVersion.VERSION_17
42
+ }
43
+ }
44
+
45
+ repositories {
46
+ google()
47
+ mavenCentral()
48
+ }
49
+
50
+
51
+ dependencies {
52
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
53
+ implementation project(':capacitor-android')
54
+ implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
55
+ testImplementation "junit:junit:$junitVersion"
56
+ androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
57
+ androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
58
+ }
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,11 @@
1
+ package com.exxili.capacitornfc;
2
+
3
+ import android.util.Log;
4
+
5
+ public class NFC {
6
+
7
+ public String echo(String value) {
8
+ Log.i("Echo", value);
9
+ return value;
10
+ }
11
+ }
@@ -0,0 +1,22 @@
1
+ package com.exxili.capacitornfc;
2
+
3
+ import com.getcapacitor.JSObject;
4
+ import com.getcapacitor.Plugin;
5
+ import com.getcapacitor.PluginCall;
6
+ import com.getcapacitor.PluginMethod;
7
+ import com.getcapacitor.annotation.CapacitorPlugin;
8
+
9
+ @CapacitorPlugin(name = "NFC")
10
+ public class NFCPlugin extends Plugin {
11
+
12
+ private NFC implementation = new NFC();
13
+
14
+ @PluginMethod
15
+ public void echo(PluginCall call) {
16
+ String value = call.getString("value");
17
+
18
+ JSObject ret = new JSObject();
19
+ ret.put("value", implementation.echo(value));
20
+ call.resolve(ret);
21
+ }
22
+ }
File without changes
@@ -0,0 +1,54 @@
1
+ import { PluginListenerHandle } from '@capacitor/core';
2
+ export interface NFCPlugin {
3
+ /**
4
+ * Starts the NFC scanning session.
5
+ */
6
+ startScan(): Promise<void>;
7
+ /**
8
+ * Writes an NDEF message to an NFC tag.
9
+ * @param options The NDEF message to write.
10
+ */
11
+ writeNDEF(options: NDEFWriteOptions): Promise<void>;
12
+ /**
13
+ * Adds a listener for NFC tag detection events.
14
+ * @param eventName The name of the event ('nfcTag').
15
+ * @param listenerFunc The function to call when an NFC tag is detected.
16
+ */
17
+ addListener(eventName: 'nfcTag', listenerFunc: (data: NDEFMessages) => void): Promise<PluginListenerHandle> & PluginListenerHandle;
18
+ /**
19
+ * Adds a listener for NFC error events.
20
+ * @param eventName The name of the event ('nfcError').
21
+ * @param listenerFunc The function to call when an NFC error occurs.
22
+ */
23
+ addListener(eventName: 'nfcError', listenerFunc: (error: NFCError) => void): Promise<PluginListenerHandle> & PluginListenerHandle;
24
+ /**
25
+ * Removes all listeners for the specified event.
26
+ * @param eventName The name of the event.
27
+ */
28
+ removeAllListeners(eventName: 'nfcTag' | 'nfcError'): Promise<void>;
29
+ }
30
+ export interface NDEFMessages {
31
+ messages: NDEFMessage[];
32
+ }
33
+ export interface NDEFMessage {
34
+ records: NDEFRecord[];
35
+ }
36
+ export interface NDEFRecord {
37
+ /**
38
+ * The type of the record.
39
+ */
40
+ type: string;
41
+ /**
42
+ * The payload of the record.
43
+ */
44
+ payload: string;
45
+ }
46
+ export interface NFCError {
47
+ /**
48
+ * The error message.
49
+ */
50
+ error: string;
51
+ }
52
+ export interface NDEFWriteOptions {
53
+ records: NDEFRecord[];
54
+ }
@@ -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 { PluginListenerHandle } from '@capacitor/core';\n\nexport interface NFCPlugin {\n /**\n * Starts the NFC scanning session.\n */\n startScan(): Promise<void>;\n\n /**\n * Writes an NDEF message to an NFC tag.\n * @param options The NDEF message to write.\n */\n writeNDEF(options: NDEFWriteOptions): Promise<void>;\n\n /**\n * Adds a listener for NFC tag detection events.\n * @param eventName The name of the event ('nfcTag').\n * @param listenerFunc The function to call when an NFC tag is detected.\n */\n addListener(\n eventName: 'nfcTag',\n listenerFunc: (data: NDEFMessages) => void,\n ): Promise<PluginListenerHandle> & PluginListenerHandle;\n\n /**\n * Adds a listener for NFC error events.\n * @param eventName The name of the event ('nfcError').\n * @param listenerFunc The function to call when an NFC error occurs.\n */\n addListener(\n eventName: 'nfcError',\n listenerFunc: (error: NFCError) => void,\n ): Promise<PluginListenerHandle> & PluginListenerHandle;\n\n /**\n * Removes all listeners for the specified event.\n * @param eventName The name of the event.\n */\n removeAllListeners(eventName: 'nfcTag' | 'nfcError'): Promise<void>;\n}\n\nexport interface NDEFMessages {\n messages: NDEFMessage[];\n}\n\nexport interface NDEFMessage {\n records: NDEFRecord[];\n}\n\nexport interface NDEFRecord {\n /**\n * The type of the record.\n */\n type: string;\n\n /**\n * The payload of the record.\n */\n payload: string;\n}\n\nexport interface NFCError {\n /**\n * The error message.\n */\n error: string;\n}\n\nexport interface NDEFWriteOptions {\n records: NDEFRecord[];\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import type { NFCPlugin } from './definitions';
2
+ declare const NFC: NFCPlugin;
3
+ export * from './definitions';
4
+ export { NFC };
@@ -0,0 +1,5 @@
1
+ import { registerPlugin } from '@capacitor/core';
2
+ const NFC = registerPlugin('NFC');
3
+ export * from './definitions';
4
+ export { NFC };
5
+ //# 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;AAGjD,MAAM,GAAG,GAAG,cAAc,CAAY,KAAK,CAAC,CAAC;AAE7C,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\nimport type { NFCPlugin } from './definitions';\n\nconst NFC = registerPlugin<NFCPlugin>('NFC');\n\nexport * from './definitions';\nexport { NFC };\n"]}
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var core = require('@capacitor/core');
6
+
7
+ const NFC = core.registerPlugin('NFC');
8
+
9
+ exports.NFC = NFC;
10
+ //# sourceMappingURL=plugin.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst NFC = registerPlugin('NFC');\nexport * from './definitions';\nexport { NFC };\n//# sourceMappingURL=index.js.map"],"names":["registerPlugin"],"mappings":";;;;;;AACK,MAAC,GAAG,GAAGA,mBAAc,CAAC,KAAK;;;;"}
package/dist/plugin.js ADDED
@@ -0,0 +1,13 @@
1
+ var capacitorNFC = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ const NFC = core.registerPlugin('NFC');
5
+
6
+ exports.NFC = NFC;
7
+
8
+ Object.defineProperty(exports, '__esModule', { value: true });
9
+
10
+ return exports;
11
+
12
+ })({}, capacitorExports);
13
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst NFC = registerPlugin('NFC');\nexport * from './definitions';\nexport { NFC };\n//# sourceMappingURL=index.js.map"],"names":["registerPlugin"],"mappings":";;;AACK,OAAC,GAAG,GAAGA,mBAAc,CAAC,KAAK;;;;;;;;;;;;"}
@@ -0,0 +1,93 @@
1
+ import Foundation
2
+ import Capacitor
3
+ import CoreNFC
4
+
5
+ @objc(NFCPlugin)
6
+ public class NFCPlugin: CAPPlugin, CAPBridgedPlugin {
7
+ public let identifier = "NFCPlugin"
8
+ public let jsName = "NFC"
9
+ public let pluginMethods: [CAPPluginMethod] = [
10
+ CAPPluginMethod(name: "startScan", returnType: CAPPluginReturnPromise),
11
+ CAPPluginMethod(name: "writeNDEF", returnType: CAPPluginReturnPromise)
12
+ ]
13
+
14
+ private let reader = NFCReader()
15
+ private let writer = NFCWriter()
16
+
17
+ @objc func startScan(_ call: CAPPluginCall) {
18
+ print("startScan called")
19
+ reader.onNDEFMessageReceived = { messages in
20
+ var ndefMessages = [[String: Any]]()
21
+ for message in messages {
22
+ var records = [[String: Any]]()
23
+ for record in message.records {
24
+ let recordType = String(data: record.type, encoding: .utf8) ?? ""
25
+ let payload = String(data: record.payload, encoding: .utf8) ?? ""
26
+ records.append([
27
+ "type": recordType,
28
+ "payload": payload
29
+ ])
30
+ }
31
+ ndefMessages.append([
32
+ "records": records
33
+ ])
34
+ }
35
+ self.notifyListeners("nfcTag", data: ["messages": ndefMessages])
36
+ }
37
+
38
+ reader.onError = { error in
39
+ if let nfcError = error as? NFCReaderError {
40
+ if nfcError.code != .readerSessionInvalidationErrorUserCanceled {
41
+ self.notifyListeners("nfcError", data: ["error": nfcError.localizedDescription])
42
+ }
43
+ }
44
+ }
45
+
46
+ reader.startScanning()
47
+ call.resolve()
48
+ }
49
+
50
+ @objc func writeNDEF(_ call: CAPPluginCall) {
51
+ print("writeNDEF called")
52
+
53
+ guard let recordsData = call.getArray("records") as? [[String: Any]] else {
54
+ call.reject("Records are required")
55
+ return
56
+ }
57
+
58
+ var ndefRecords = [NFCNDEFPayload]()
59
+ for recordData in recordsData {
60
+ guard let type = recordData["type"] as? String,
61
+ let payload = recordData["payload"] as? String,
62
+ let typeData = type.data(using: .utf8),
63
+ let payloadData = payload.data(using: .utf8) else {
64
+ continue
65
+ }
66
+
67
+ let ndefRecord = NFCNDEFPayload(
68
+ format: .nfcWellKnown,
69
+ type: typeData,
70
+ identifier: Data(),
71
+ payload: payloadData
72
+ )
73
+ ndefRecords.append(ndefRecord)
74
+ }
75
+
76
+ let ndefMessage = NFCNDEFMessage(records: ndefRecords)
77
+
78
+ writer.onWriteSuccess = {
79
+ self.notifyListeners("nfcWriteSuccess", data: ["success": true])
80
+ }
81
+
82
+ writer.onError = { error in
83
+ if let nfcError = error as? NFCReaderError {
84
+ if nfcError.code != .readerSessionInvalidationErrorUserCanceled {
85
+ self.notifyListeners("nfcError", data: ["error": nfcError.localizedDescription])
86
+ }
87
+ }
88
+ }
89
+
90
+ writer.startWriting(message: ndefMessage)
91
+ call.resolve()
92
+ }
93
+ }
@@ -0,0 +1,96 @@
1
+ import Foundation
2
+ import CoreNFC
3
+
4
+ @objc public class NFCReader: NSObject, NFCNDEFReaderSessionDelegate {
5
+ private var readerSession: NFCNDEFReaderSession?
6
+
7
+ public var onNDEFMessageReceived: (([NFCNDEFMessage]) -> Void)?
8
+ public var onError: ((Error) -> Void)?
9
+
10
+ @objc public func startScanning() {
11
+ print("NFCReader startScanning called")
12
+
13
+ guard NFCNDEFReaderSession.readingAvailable else {
14
+ print("NFC scanning not supported on this device")
15
+ return
16
+ }
17
+ readerSession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true)
18
+ readerSession?.alertMessage = "Hold your iPhone near the NFC tag."
19
+ readerSession?.begin()
20
+ }
21
+
22
+ // NFCNDEFReaderSessionDelegate methods for reading
23
+ public func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
24
+ print("NFC reader session error: \(error.localizedDescription)")
25
+ onError?(error)
26
+ }
27
+
28
+ public func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
29
+ onNDEFMessageReceived?(messages)
30
+ }
31
+
32
+ public func readerSessionDidBecomeActive(_ session: NFCNDEFReaderSession) {
33
+
34
+ }
35
+
36
+ // Handle detection of NDEF tags (need to connect and read the NDEF message)
37
+ public func readerSession(_ session: NFCNDEFReaderSession, didDetect tags: [NFCNDEFTag]) {
38
+ if tags.count > 1 {
39
+ // Restart polling in 500ms
40
+ let retryInterval = DispatchTimeInterval.milliseconds(500)
41
+ session.alertMessage = "More than one tag detected. Please remove extra tags and try again."
42
+ DispatchQueue.global().asyncAfter(deadline: .now() + retryInterval) {
43
+ session.restartPolling()
44
+ }
45
+ return
46
+ }
47
+
48
+ // Connect to the found tag and perform NDEF message reading
49
+ let tag = tags.first!
50
+ session.connect(to: tag) { (error: Error?) in
51
+ if let error = error {
52
+ session.alertMessage = "Unable to connect to tag."
53
+ session.invalidate()
54
+ self.onError?(error)
55
+ return
56
+ }
57
+
58
+ tag.queryNDEFStatus { (ndefStatus: NFCNDEFStatus, capacity: Int, error: Error?) in
59
+ if let error = error {
60
+ session.alertMessage = "Unable to query NDEF status of tag."
61
+ session.invalidate()
62
+ self.onError?(error)
63
+ return
64
+ }
65
+
66
+ if ndefStatus == .notSupported {
67
+ session.alertMessage = "Tag is not NDEF compliant."
68
+ session.invalidate()
69
+ return
70
+ }
71
+
72
+ tag.readNDEF { (message: NFCNDEFMessage?, error: Error?) in
73
+ var statusMessage: String
74
+ if let error = error {
75
+ statusMessage = "Failed to read NDEF from tag."
76
+ session.alertMessage = statusMessage
77
+ session.invalidate()
78
+ self.onError?(error)
79
+ return
80
+ }
81
+
82
+ if let message = message {
83
+ statusMessage = "Found 1 NDEF message."
84
+ session.alertMessage = statusMessage
85
+ session.invalidate()
86
+ self.onNDEFMessageReceived?([message])
87
+ } else {
88
+ statusMessage = "No NDEF message found."
89
+ session.alertMessage = statusMessage
90
+ session.invalidate()
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,96 @@
1
+ import Foundation
2
+ import CoreNFC
3
+
4
+ @objc public class NFCWriter: NSObject, NFCNDEFReaderSessionDelegate {
5
+ private var writerSession: NFCNDEFReaderSession?
6
+ private var messageToWrite: NFCNDEFMessage?
7
+
8
+ public var onWriteSuccess: (() -> Void)?
9
+ public var onError: ((Error) -> Void)?
10
+
11
+ @objc public func startWriting(message: NFCNDEFMessage) {
12
+ print("NFCWriter startWriting called")
13
+ self.messageToWrite = message
14
+
15
+ guard NFCNDEFReaderSession.readingAvailable else {
16
+ print("NFC writing not supported on this device")
17
+ return
18
+ }
19
+ writerSession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false)
20
+ writerSession?.alertMessage = "Hold your iPhone near the NFC tag to write."
21
+ writerSession?.begin()
22
+ }
23
+
24
+ public func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
25
+ }
26
+
27
+ // NFCNDEFReaderSessionDelegate methods for writing
28
+ public func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
29
+ print("NFC writer session error: \(error.localizedDescription)")
30
+ onError?(error)
31
+ }
32
+
33
+ public func readerSessionDidBecomeActive(_ session: NFCNDEFReaderSession) {
34
+
35
+ }
36
+
37
+ public func readerSession(_ session: NFCNDEFReaderSession, didDetect tags: [NFCNDEFTag]) {
38
+ if tags.count > 1 {
39
+ let retryInterval = DispatchTimeInterval.milliseconds(500)
40
+ session.alertMessage = "More than one tag detected. Please try again."
41
+ DispatchQueue.global().asyncAfter(deadline: .now() + retryInterval) {
42
+ session.restartPolling()
43
+ }
44
+ return
45
+ }
46
+
47
+ guard let tag = tags.first else { return }
48
+
49
+ session.connect(to: tag) { (error) in
50
+ if let error = error {
51
+ session.alertMessage = "Unable to connect to tag."
52
+ session.invalidate()
53
+ self.onError?(error)
54
+ return
55
+ }
56
+
57
+ tag.queryNDEFStatus { (ndefStatus, capacity, error) in
58
+ if let error = error {
59
+ session.alertMessage = "Unable to query the NDEF status of tag."
60
+ session.invalidate()
61
+ self.onError?(error)
62
+ return
63
+ }
64
+
65
+ switch ndefStatus {
66
+ case .notSupported:
67
+ session.alertMessage = "Tag is not NDEF compliant."
68
+ session.invalidate()
69
+ case .readOnly:
70
+ session.alertMessage = "Tag is read-only."
71
+ session.invalidate()
72
+ case .readWrite:
73
+ if let message = self.messageToWrite {
74
+ tag.writeNDEF(message) { (error) in
75
+ if let error = error {
76
+ session.alertMessage = "Failed to write NDEF message."
77
+ session.invalidate()
78
+ self.onError?(error)
79
+ return
80
+ }
81
+ session.alertMessage = "NDEF message written successfully."
82
+ session.invalidate()
83
+ self.onWriteSuccess?()
84
+ }
85
+ } else {
86
+ session.alertMessage = "No message to write."
87
+ session.invalidate()
88
+ }
89
+ @unknown default:
90
+ session.alertMessage = "Unknown NDEF tag status."
91
+ session.invalidate()
92
+ }
93
+ }
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,15 @@
1
+ import XCTest
2
+ @testable import NFCPlugin
3
+
4
+ class NFCTests: XCTestCase {
5
+ func testEcho() {
6
+ // This is an example of a functional test case for a plugin.
7
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
8
+
9
+ let implementation = NFC()
10
+ let value = "Hello, World!"
11
+ let result = implementation.echo(value)
12
+
13
+ XCTAssertEqual(value, result)
14
+ }
15
+ }
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@exxili/capacitor-nfc",
3
+ "version": "0.0.1",
4
+ "description": "A Capacitor plugin for reading and writing NFC NDEFtags.",
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
+ "CapacitorNfc.podspec"
17
+ ],
18
+ "author": "Exxili",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/Exxili/capacitor-nfc.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/Exxili/capacitor-nfc/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 CapacitorNfc -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 NFCPlugin --output-readme README.md --output-json dist/docs.json",
43
+ "build": "npm run clean && tsc && rollup -c rollup.config.js && rimraf *.tgz && npm pack",
44
+ "clean": "rimraf ./dist",
45
+ "watch": "tsc --watch",
46
+ "prepublishOnly": "npm run build"
47
+ },
48
+ "devDependencies": {
49
+ "@capacitor/android": "^6.0.0",
50
+ "@capacitor/core": "^6.0.0",
51
+ "@capacitor/docgen": "^0.2.2",
52
+ "@capacitor/ios": "^6.0.0",
53
+ "@ionic/eslint-config": "^0.4.0",
54
+ "@ionic/prettier-config": "^4.0.0",
55
+ "@ionic/swiftlint-config": "^1.1.2",
56
+ "eslint": "^8.57.0",
57
+ "prettier": "^3.3.3",
58
+ "prettier-plugin-java": "^2.6.4",
59
+ "rimraf": "^3.0.2",
60
+ "rollup": "^2.32.0",
61
+ "swiftlint": "^1.0.1",
62
+ "typescript": "~4.1.5"
63
+ },
64
+ "peerDependencies": {
65
+ "@capacitor/core": "^6.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
+ }