@iotize/device-com-nfc.cordova 3.8.0 → 3.8.2

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@iotize/device-com-nfc.cordova",
3
3
  "main": "bundles/iotize-device-com-nfc.cordova.umd.js",
4
- "version": "3.8.0",
4
+ "version": "3.8.2",
5
5
  "description": "Near Field Communication (NFC) Plugin. Read and write NDEF messages to NFC tags and share NDEF messages with peers.",
6
6
  "cordova": {
7
7
  "id": "@iotize/device-com-nfc.cordova",
package/plugin.xml CHANGED
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <plugin xmlns="http://www.phonegap.com/ns/plugins/1.0"
3
- xmlns:android="http://schemas.android.com/apk/res/android" id="@iotize/device-com-nfc.cordova" version="3.7.0">
3
+ xmlns:android="http://schemas.android.com/apk/res/android" id="@iotize/device-com-nfc.cordova" version="3.8.1">
4
4
 
5
5
  <name>@iotize/device-com-nfc.cordova</name>
6
6
 
@@ -131,104 +131,117 @@ public class NfcPlugin extends CordovaPlugin {
131
131
 
132
132
  @Override
133
133
  public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException {
134
+ try {
135
+ Log.d(TAG, "execute " + action);
134
136
 
135
- Log.d(TAG, "execute " + action);
136
-
137
- // showSettings can be called if NFC is disabled
138
- // might want to skip this if NO_NFC
139
- if (action.equalsIgnoreCase(SHOW_SETTINGS)) {
140
- showSettings(callbackContext);
141
- return true;
142
- }
137
+ // showSettings can be called if NFC is disabled
138
+ // might want to skip this if NO_NFC
139
+ if (action.equalsIgnoreCase(SHOW_SETTINGS)) {
140
+ showSettings(callbackContext);
141
+ return true;
142
+ }
143
143
 
144
- // the channel is set up when the plugin starts
145
- if (action.equalsIgnoreCase(CHANNEL)) {
146
- channelCallback = callbackContext;
147
- return true; // short circuit
148
- }
144
+ // the channel is set up when the plugin starts
145
+ if (action.equalsIgnoreCase(CHANNEL)) {
146
+ channelCallback = callbackContext;
147
+ return true; // short circuit
148
+ }
149
149
 
150
- if (!getNfcStatus().equals(STATUS_NFC_OK)) {
151
- callbackContext.error(getNfcStatus());
152
- return true; // short circuit
153
- }
150
+ if (!getNfcStatus().equals(STATUS_NFC_OK)) {
151
+ callbackContext.error(getNfcStatus());
152
+ return true; // short circuit
153
+ }
154
154
 
155
- createPendingIntent();
155
+ createPendingIntent();
156
156
 
157
- if (action.equalsIgnoreCase(READER_MODE)) {
158
- int flags = data.getInt(0);
159
- readerMode(flags, callbackContext);
157
+ if (action.equalsIgnoreCase(READER_MODE)) {
158
+ int flags = data.getInt(0);
159
+ readerMode(flags, callbackContext);
160
160
 
161
- } else if (action.equalsIgnoreCase(REGISTER_MIME_TYPE)) {
162
- registerMimeType(data, callbackContext);
163
- } else if (action.equalsIgnoreCase(REGISTER_NFC_TAP_DEVICE)) {
161
+ } else if (action.equalsIgnoreCase(REGISTER_MIME_TYPE)) {
162
+ registerMimeType(data, callbackContext);
163
+ } else if (action.equalsIgnoreCase(REGISTER_NFC_TAP_DEVICE)) {
164
164
  // JSONObject jsonStringOptions = data.getJSONObject(0);
165
- registerTapDevice(callbackContext);
166
- } else if (action.equalsIgnoreCase(REMOVE_MIME_TYPE)) {
167
- removeMimeType(data, callbackContext);
165
+ registerTapDevice(callbackContext);
166
+ } else if (action.equalsIgnoreCase(REMOVE_MIME_TYPE)) {
167
+ removeMimeType(data, callbackContext);
168
168
 
169
- } else if (action.equalsIgnoreCase(REGISTER_NDEF)) {
170
- registerNdef(callbackContext);
171
- } else if (action.equalsIgnoreCase(REMOVE_NDEF)) {
172
- removeNdef(callbackContext);
169
+ } else if (action.equalsIgnoreCase(REGISTER_NDEF)) {
170
+ registerNdef(callbackContext);
171
+ } else if (action.equalsIgnoreCase(REMOVE_NDEF)) {
172
+ removeNdef(callbackContext);
173
173
 
174
- } else if (action.equalsIgnoreCase(REGISTER_NDEF_FORMATABLE)) {
175
- registerNdefFormatable(callbackContext);
174
+ } else if (action.equalsIgnoreCase(REGISTER_NDEF_FORMATABLE)) {
175
+ registerNdefFormatable(callbackContext);
176
176
 
177
- } else if (action.equals(REGISTER_DEFAULT_TAG)) {
178
- registerDefaultTag(callbackContext);
177
+ } else if (action.equals(REGISTER_DEFAULT_TAG)) {
178
+ registerDefaultTag(callbackContext);
179
179
 
180
- } else if (action.equals(REMOVE_DEFAULT_TAG)) {
181
- removeDefaultTag(callbackContext);
180
+ } else if (action.equals(REMOVE_DEFAULT_TAG)) {
181
+ removeDefaultTag(callbackContext);
182
182
 
183
- } else if (action.equalsIgnoreCase(WRITE_TAG)) {
184
- writeTag(data, callbackContext);
183
+ } else if (action.equalsIgnoreCase(WRITE_TAG)) {
184
+ writeTag(data, callbackContext);
185
185
 
186
- } else if (action.equalsIgnoreCase(ERASE_TAG)) {
187
- eraseTag(callbackContext);
186
+ } else if (action.equalsIgnoreCase(ERASE_TAG)) {
187
+ eraseTag(callbackContext);
188
188
 
189
- } else if (action.equalsIgnoreCase(INIT)) {
190
- init(callbackContext);
189
+ } else if (action.equalsIgnoreCase(INIT)) {
190
+ init(callbackContext);
191
191
 
192
- } else if (action.equalsIgnoreCase(ENABLED)) {
193
- // status is checked before every call
194
- // if code made it here, NFC is enabled
195
- callbackContext.success(STATUS_NFC_OK);
192
+ } else if (action.equalsIgnoreCase(ENABLED)) {
193
+ // status is checked before every call
194
+ // if code made it here, NFC is enabled
195
+ callbackContext.success(STATUS_NFC_OK);
196
196
 
197
- } else if (action.equalsIgnoreCase(CONNECT_TAP)) {
198
- String tech = data.getString(0);
199
- int timeout = data.optInt(1, -1);
200
- connectTap(tech, timeout, callbackContext);
197
+ } else if (action.equalsIgnoreCase(CONNECT_TAP)) {
198
+ String tech = data.getString(0);
199
+ int timeout = data.optInt(1, -1);
200
+ connectTap(tech, timeout, callbackContext);
201
201
 
202
- } else if (action.equalsIgnoreCase(CONNECT_RAW)) {
203
- String tech = data.getString(0);
204
- int timeout = data.optInt(1, -1);
205
- connectRaw(tech, timeout, callbackContext);
202
+ } else if (action.equalsIgnoreCase(CONNECT_RAW)) {
203
+ String tech = data.getString(0);
204
+ int timeout = data.optInt(1, -1);
205
+ connectRaw(tech, timeout, callbackContext);
206
206
 
207
- } else if (action.equalsIgnoreCase(TRANSCEIVE)) {
208
- CordovaArgs args = new CordovaArgs(data); // execute is using the old signature with JSON data
207
+ } else if (action.equalsIgnoreCase(TRANSCEIVE)) {
208
+ CordovaArgs args = new CordovaArgs(data); // execute is using the old signature with JSON data
209
209
 
210
- byte[] command = args.getArrayBuffer(0);
211
- transceiveRaw(command, callbackContext);
210
+ byte[] command = args.getArrayBuffer(0);
211
+ transceiveRaw(command, callbackContext);
212
212
 
213
- } else if (action.equalsIgnoreCase(TRANSCEIVE_TAP)) {
214
- CordovaArgs args = new CordovaArgs(data); // execute is using the old signature with JSON data
213
+ } else if (action.equalsIgnoreCase(TRANSCEIVE_TAP)) {
214
+ CordovaArgs args = new CordovaArgs(data); // execute is using the old signature with JSON data
215
215
 
216
- byte[] command = args.getArrayBuffer(0);
217
- transceiveTap(command, callbackContext);
216
+ byte[] command = args.getArrayBuffer(0);
217
+ transceiveTap(command, callbackContext);
218
218
 
219
- } else if (action.equalsIgnoreCase(CLOSE)) {
220
- close(callbackContext);
219
+ } else if (action.equalsIgnoreCase(CLOSE)) {
220
+ close(callbackContext);
221
221
 
222
- } else if (action.equalsIgnoreCase(SET_TAP_DEVICE_DISCOVERY_ENABLED)) {
223
- CordovaArgs args = new CordovaArgs(data);
224
- this._isTapDeviceDiscoveryEnabled = args.getBoolean(0);
225
- } else {
226
- // invalid action
227
- callbackContext.error("Invalid NFC action \"" + action +"\"");
228
- return false;
222
+ } else if (action.equalsIgnoreCase(SET_TAP_DEVICE_DISCOVERY_ENABLED)) {
223
+ CordovaArgs args = new CordovaArgs(data);
224
+ this._isTapDeviceDiscoveryEnabled = args.getBoolean(0);
225
+ } else {
226
+ // invalid action
227
+ callbackContext.error("Invalid NFC action \"" + action + "\"");
228
+ return false;
229
+ }
230
+ return true;
231
+ }
232
+ catch (SecurityException err) {
233
+ if (err.getMessage().startsWith("Permission Denial")) {
234
+ callbackContext.error("NFC Tag lost!");
235
+ }
236
+ else {
237
+ callbackContext.error(err.getMessage());
238
+ }
239
+ return true;
240
+ }
241
+ catch (Throwable err) {
242
+ callbackContext.error(err.getMessage());
243
+ return true;
229
244
  }
230
-
231
- return true;
232
245
  }
233
246
 
234
247
  private String getNfcStatus() {
@@ -492,11 +505,9 @@ public class NfcPlugin extends CordovaPlugin {
492
505
  callbackContext.error("Tag doesn't support NDEF");
493
506
  }
494
507
  }
495
- } catch (FormatException e) {
496
- callbackContext.error(e.getMessage());
497
- } catch (TagLostException e) {
498
- callbackContext.error(e.getMessage());
499
- } catch (IOException e) {
508
+ } catch (SecurityException e) {
509
+ callbackContext.error("NFC Tag lost!");
510
+ } catch (Throwable e) {
500
511
  callbackContext.error(e.getMessage());
501
512
  }
502
513
  });
@@ -1054,7 +1065,7 @@ public class NfcPlugin extends CordovaPlugin {
1054
1065
  }
1055
1066
  callbackContext.success();
1056
1067
 
1057
- } catch (Exception ex) {
1068
+ } catch (Throwable ex) {
1058
1069
  Log.e(TAG, "Error closing nfc connection", ex);
1059
1070
  callbackContext.error("Error closing nfc connection " + ex.getLocalizedMessage());
1060
1071
  }
@@ -1142,7 +1153,7 @@ public class NfcPlugin extends CordovaPlugin {
1142
1153
  }
1143
1154
  byte[] response = nfcProtocol.send(data);
1144
1155
  callbackContext.success(Helper.ByteArrayToHexString(response));
1145
- } catch (Exception e) {
1156
+ } catch (Throwable e) {
1146
1157
  Log.e(TAG, e.getMessage(), e);
1147
1158
  callbackContext.error(e.getMessage());
1148
1159
  }
@@ -66,6 +66,9 @@ class NFCTagReader : NSObject, NFCTagReaderSessionDelegate {
66
66
  initSessionCompletion = nil //do not keep session completion
67
67
  }
68
68
  printNFC( "tagReaderSessionDidBecomeActive" )
69
+ if (self.comSession == nil) {
70
+ self.comSession = session
71
+ }
69
72
  }
70
73
 
71
74
  func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
@@ -82,7 +85,7 @@ class NFCTagReader : NSObject, NFCTagReaderSessionDelegate {
82
85
  }
83
86
 
84
87
  func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
85
- printNFC( "tagReaderSession:didDectectTag" )
88
+ printNFC( "tagReaderSession:didDetectTag" )
86
89
  guard let session = self.comSession else {
87
90
  return;
88
91
  }
@@ -103,7 +106,7 @@ class NFCTagReader : NSObject, NFCTagReaderSessionDelegate {
103
106
 
104
107
  self.tag = tag
105
108
 
106
- if let onDiscover = self.onDiscoverCompletion {
109
+ if self.onDiscoverCompletion != nil {
107
110
 
108
111
  Task {
109
112
  self.onDiscoverCompletion?(await self.createJSON(tag: tag), nil)
@@ -193,6 +196,12 @@ class NFCTagReader : NSObject, NFCTagReaderSessionDelegate {
193
196
  return
194
197
  case .failure(let error):
195
198
  printNFC("TRANSCEIVE RAW ERROR \(error.localizedDescription), TRY \(nbTry)")
199
+ if (error is NFCReaderError) {
200
+ if (!iso7816Tag.isAvailable) {
201
+ completed(nil, error)
202
+ return
203
+ }
204
+ }
196
205
  if (nbTry >= 0) {
197
206
  usleep(NFCTagReader.DELAY)
198
207
  return self.transceiveRaw(request: request, completed: completed, nbTry: nbTry - 1)
@@ -496,5 +505,32 @@ extension NFCTagReader {
496
505
  try? await self.comSession?.connect(to: tag)
497
506
  return await tag.toJSON(isTapDiscoveryEnabled: self.plugin.isTapDiscoveryEnabled())
498
507
  }
508
+
509
+ func writeNDEF(message: NFCNDEFMessage, completed: @escaping (Error?)->()) {
510
+ guard let ndefTag = self.tag else {
511
+ completed(NFCReaderError(NFCReaderError.readerTransceiveErrorTagNotConnected))
512
+ return
513
+ }
514
+ var tag: NFCNDEFTag? = nil
515
+ switch(ndefTag) {
516
+ case .iso15693(let iso15693Tag):
517
+ tag = iso15693Tag
518
+ default:
519
+ completed(NFCReaderError(NFCReaderError.readerTransceiveErrorTagNotConnected))
520
+ return
521
+
522
+ }
523
+ if (tag != nil) {
524
+ tag?.writeNDEF(message, completionHandler: {
525
+ (error:Error?) in
526
+ if (error != nil) {
527
+ completed(error)
528
+ } else {
529
+ completed(nil)
530
+ }
531
+ })
532
+
533
+ }
534
+ }
499
535
  }
500
536
 
@@ -152,7 +152,7 @@ import CoreNFC
152
152
  DispatchQueue.main.async {
153
153
  printNFC("sending ...")
154
154
  if self.nfcController == nil {
155
- self.sendError(command: command, result: "no session available")
155
+ self.sendError(command: command, result: "not connected")
156
156
  return
157
157
  }
158
158
 
@@ -176,7 +176,7 @@ import CoreNFC
176
176
  DispatchQueue.main.async {
177
177
  if error != nil {
178
178
  self.lastError = error
179
- self.sendError(command: command, result: error!.localizedDescription)
179
+ self.sendError(command: command, result: "Tag was lost")//error!.localizedDescription)
180
180
  } else {
181
181
  printNFC("responded \(response!.hexEncodedString())")
182
182
  self.sendSuccess(command: command, result: response!.hexEncodedString())
@@ -412,6 +412,8 @@ import CoreNFC
412
412
  alertMessage = alertMessageFromCommand
413
413
  }
414
414
 
415
+ printNFC("Begin session for tech \(tech) with message: \(alertMessage)")
416
+
415
417
  DispatchQueue.main.async {
416
418
  printNFC("Begin session NFC \(String(describing: pollingOption))")
417
419
  if self.nfcController == nil {
@@ -523,5 +525,59 @@ import CoreNFC
523
525
  func registerChannel() {
524
526
  isListeningNDEF = true // Flag for the AppDelegate
525
527
  }
528
+
529
+ @objc(writeTag:)
530
+ func writeTag(command: CDVInvokedUrlCommand) {
531
+ printNFC("writeTag")
532
+
533
+ guard #available(iOS 13.0, *) else {
534
+ sendError(command: command, result: "write is only available on iOS 13+")
535
+ return
536
+ }
537
+ guard let messagesJSON = command.argument(at: 0) as? [NSDictionary] else {
538
+ sendError(command: command, result: "No message to write")
539
+ return
540
+ }
541
+
542
+ guard let tagReader = self.nfcController as? NFCTagReader else {
543
+ self.sendError(command: command, result: "no session available")
544
+ return
545
+ }
546
+ guard ((tagReader.comSession?.isReady) != nil) else {
547
+ self.sendError(command: command, result: "no session available")
548
+ return
549
+ }
550
+
551
+ printNFC("write NDEF messages with \(messagesJSON.count) records")
552
+
553
+ //convert message array to NFCNDEFMessage
554
+ var records: [NFCNDEFPayload] = []
555
+ for record in messagesJSON {
556
+ let tnf: UInt8 = record["tnf"] as? UInt8 ?? 0
557
+ if let type = record["type"] as? [UInt8] {
558
+ if let id = record["id"] as? [UInt8] {
559
+ if let payload = record["payload"] as? [UInt8] {
560
+ records.append(
561
+ NFCNDEFPayload(format: .init(rawValue: tnf) ?? .unknown, type: Data(type), identifier: Data(id), payload: Data(payload))
562
+ )
563
+ }
564
+ }
565
+
566
+ }
567
+ }
568
+
569
+ DispatchQueue.main.async {
570
+
571
+ tagReader.writeNDEF(message: .init(records: records), completed: {
572
+ (error:Error?) in
573
+ if (error != nil) {
574
+ self.sendError(command: command, result: error!.localizedDescription)
575
+ return
576
+ }
577
+ self.sendSuccess(command: command)
578
+ })
579
+
580
+ }
581
+ }
526
582
 
527
583
  }