diff --git a/README.md b/README.md index 4df50fb7..1ac3792f 100644 --- a/README.md +++ b/README.md @@ -452,7 +452,6 @@ Function `nfc.share` writes an NdefMessage via peer-to-peer. This should appear ### Supported Platforms -- Android - Windows - BlackBerry 7 - BlackBerry 10 @@ -481,7 +480,6 @@ Function `nfc.unshare` stops sharing data via peer-to-peer. ### Supported Platforms -- Android - Windows - BlackBerry 7 - BlackBerry 10 @@ -1264,6 +1262,46 @@ Or to scan only Plain Text tags use See the [BlackBerry documentation](http://developer.blackberry.com/native/documentation/cascades/device_comm/nfc/receiving_content.html) for more info. +# Launching your iOS Application when Scanning a Tag + +On iOS, your application can be launched when an NFC tag is read, if the tag contains an NDEF message with a Universal Link (URL). This is optional and requires configuration on your application entitlements. The Universal Link needs to point to an actual HTTPS server that contains an `apple-app-site-association` that links the URL with your app. + +In a nutshell, you need to: + +1. Setup an associated domain relationship between your app and the Universal Link URL of your choosing. See: https://developer.apple.com/documentation/xcode/supporting-associated-domains + +2. Add an associated domain entitlement to your app in XCode. See: https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_associated-domains + * If you are developing in a multi-platform environment, you can do this by adding the following to your `config.xml`: + +```xml + + + + applinks:myapp.com + + + + + applinks:myapp.com + + + +``` + +3. On your app, during or after the Cordova `deviceready` event, call the `parseLaunchIntent` plugin function, for example: + +```javascript +document.addEventListener("deviceready", onDeviceReady, false); + +function onDeviceReady() { + nfc.parseLaunchIntent(function(tag) { + console.log('Application was launched with tag: ' + JSON.stringify(tag)); + }); +} +``` + + * You may want to do the same on the `onresume` event to support the case where your app was already running in the background. + # Launching your Android Application when Scanning a Tag On Android, intents can be used to launch your application when a NFC tag is read. This is optional and configured in AndroidManifest.xml. @@ -1280,6 +1318,44 @@ We have found it necessary to add `android:noHistory="true"` to the activity ele See the Android documentation for more information about [filtering for NFC intents](http://developer.android.com/guide/topics/connectivity/nfc/nfc.html#ndef-disc). +## Accessing Tag information during application launch + +If your application is launched because an NFC tag was read, the intent passed to your main activity will be the `LAUNCH` intent, rather than one of the NFC tag intents (e.g. `NDEF_DISCOVERED`). In order to capture the NFC tag intent that was used to launch your application, you need to associate the NFC tag intent filter with an activity other than Cordova's `MainActivity`. + +You can do this following these steps: + +1. Add a section to your `AndroidManifest.xml` file with the appropriate NFC `intent-filter` that points to the activity `com.chariotsolutions.nfc.plugin.NfcActivity`. + * If you are developing in a multi-platform environment, you can do this by adding the following to your `config.xml`: + +```xml + + + + + + + + + + + + +``` + +2. On your app, during or after the Cordova `deviceready` event, call the `parseLaunchIntent` function, for example: + +```javascript +document.addEventListener("deviceready", onDeviceReady, false); + +function onDeviceReady() { + nfc.parseLaunchIntent(function(tag) { + console.log('Application was launched with tag: ' + JSON.stringify(tag)); + }); +} +``` + + * You may want to do the same on the `onresume` event to support the case where your app was already running in the background. + Testing ======= diff --git a/plugin.xml b/plugin.xml index d2dddbe4..d89d1af4 100644 --- a/plugin.xml +++ b/plugin.xml @@ -26,6 +26,8 @@ + NDEF - TAG + TAG NDEF - TAG + TAG diff --git a/src/android/src/com/chariotsolutions/nfc/plugin/NfcActivity.java b/src/android/src/com/chariotsolutions/nfc/plugin/NfcActivity.java new file mode 100644 index 00000000..6b16c66a --- /dev/null +++ b/src/android/src/com/chariotsolutions/nfc/plugin/NfcActivity.java @@ -0,0 +1,48 @@ +package com.chariotsolutions.nfc.plugin; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +public class NfcActivity extends Activity +{ + private static Intent launchIntent = null; + private static boolean initialized = false; + + public static final String TAG = "NfcActivity"; + + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + Log.i(TAG, "onCreate: " + getIntent().getAction()); + launchIntent = getIntent(); + + if (!initialized) { + // This looks like a cold start (Cordova has not launched) so send a launch intent + final Intent launchIntent = getPackageManager().getLaunchIntentForPackage(getPackageName()); + if (launchIntent != null) { + launchIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(launchIntent); + } else { + Log.w(TAG, "onCreate: no launch intent defined!"); + } + } + + finish(); + } + + public static void onPluginInitialize() { + Log.i(TAG, "onPluginInitialize"); + initialized = true; + } + + public static Intent getLaunchIntent() { + final Intent result = launchIntent; + launchIntent = null; + Log.i(TAG, "getLaunchIntent: " + result); + return result; + } +} diff --git a/src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java b/src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java index e8256d83..7abe95bc 100644 --- a/src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java +++ b/src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java @@ -31,11 +31,12 @@ import android.nfc.tech.Ndef; import android.nfc.tech.NdefFormatable; import android.nfc.tech.TagTechnology; +import android.os.Build; import android.os.Bundle; import android.os.Parcelable; import android.util.Log; -public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCompleteCallback { +public class NfcPlugin extends CordovaPlugin { private static final String REGISTER_MIME_TYPE = "registerMimeType"; private static final String REMOVE_MIME_TYPE = "removeMimeType"; private static final String REGISTER_NDEF = "registerNdef"; @@ -46,13 +47,10 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom private static final String WRITE_TAG = "writeTag"; private static final String MAKE_READ_ONLY = "makeReadOnly"; private static final String ERASE_TAG = "eraseTag"; - private static final String SHARE_TAG = "shareTag"; - private static final String UNSHARE_TAG = "unshareTag"; - private static final String HANDOVER = "handover"; // Android Beam - private static final String STOP_HANDOVER = "stopHandover"; private static final String ENABLED = "enabled"; private static final String INIT = "init"; private static final String SHOW_SETTINGS = "showSettings"; + private static final String PARSE_LAUNCH_INTENT = "parseLaunchIntent"; private static final String NDEF = "ndef"; private static final String NDEF_MIME = "ndef-mime"; @@ -80,15 +78,12 @@ public class NfcPlugin extends CordovaPlugin implements NfcAdapter.OnNdefPushCom private final List intentFilters = new ArrayList<>(); private final ArrayList techLists = new ArrayList<>(); - private NdefMessage p2pMessage = null; private PendingIntent pendingIntent = null; private Intent savedIntent = null; private CallbackContext readerModeCallback; private CallbackContext channelCallback; - private CallbackContext shareTagCallback; - private CallbackContext handoverCallback; @Override public boolean execute(String action, JSONArray data, CallbackContext callbackContext) throws JSONException { @@ -155,21 +150,12 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo } else if (action.equalsIgnoreCase(ERASE_TAG)) { eraseTag(callbackContext); - } else if (action.equalsIgnoreCase(SHARE_TAG)) { - shareTag(data, callbackContext); - - } else if (action.equalsIgnoreCase(UNSHARE_TAG)) { - unshareTag(callbackContext); - - } else if (action.equalsIgnoreCase(HANDOVER)) { - handover(data, callbackContext); - - } else if (action.equalsIgnoreCase(STOP_HANDOVER)) { - stopHandover(callbackContext); - } else if (action.equalsIgnoreCase(INIT)) { init(callbackContext); + } else if (action.equalsIgnoreCase(PARSE_LAUNCH_INTENT)) { + parseLaunchIntent(callbackContext); + } else if (action.equalsIgnoreCase(ENABLED)) { // status is checked before every call // if code made it here, NFC is enabled @@ -197,6 +183,12 @@ public boolean execute(String action, JSONArray data, CallbackContext callbackCo return true; } + @Override + protected void pluginInitialize() { + super.pluginInitialize(); + NfcActivity.onPluginInitialize(); + } + private String getNfcStatus() { NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); if (nfcAdapter == null) { @@ -246,6 +238,7 @@ public void onTagDiscovered(Tag tag) { Intent tagIntent = new Intent(); tagIntent.putExtra(NfcAdapter.EXTRA_TAG, tag); + savedIntent = tagIntent; setIntent(tagIntent); PluginResult result = new PluginResult(PluginResult.Status.OK, json); @@ -289,13 +282,6 @@ private void removeNdef(CallbackContext callbackContext) { callbackContext.success(); } - private void unshareTag(CallbackContext callbackContext) { - p2pMessage = null; - stopNdefPush(); - shareTagCallback = null; - callbackContext.success(); - } - private void init(CallbackContext callbackContext) { Log.d(TAG, "Enabling plugin " + getIntent()); @@ -306,6 +292,59 @@ private void init(CallbackContext callbackContext) { callbackContext.success(); } + private void parseLaunchIntent(final CallbackContext callbackContext) { + final Intent intent = NfcActivity.getLaunchIntent(); + if (intent != null) { + Log.d(TAG, "parseLaunchIntent " + intent); + String action = intent.getAction(); + Log.d(TAG, "action " + action); + final String data = intent.getDataString(); + Log.d(TAG, "data " + data); + + try { + Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); + Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES)); + + if (action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) { + Ndef ndef = Ndef.get(tag); + callbackContext.success(buildNdefJSON(ndef, messages)); + } else if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED)) { + Ndef ndef = null; + for (String tagTech : tag.getTechList()) { + Log.d(TAG, tagTech); + if (tagTech.equals(Ndef.class.getName())) { // + ndef = Ndef.get(tag); + } + } + if (ndef != null) { + callbackContext.success(buildNdefJSON(ndef, messages)); + } else { + callbackContext.success(Util.tagToJSON(tag)); + } + } else if (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) { + callbackContext.success(Util.tagToJSON(tag)); + } else { + if (data != null) { + callbackContext.success(data); + } else { + callbackContext.error("NO_INTENT"); + } + } + } catch (Exception exception) { + Log.e(TAG, "failed to parse tag from launch intent", exception); + if (data != null) { + // Fallback to returning the URL obtained from the intent + callbackContext.success(data); + } else { + callbackContext.error("NO_INTENT"); + } + } + } else { + Log.d(TAG, "parseLaunchIntent: NO_INTENT"); + callbackContext.error("NO_INTENT"); + } + } + private void removeMimeType(JSONArray data, CallbackContext callbackContext) throws JSONException { String mimeType = data.getString(0); removeIntentFilter(mimeType); @@ -438,35 +477,6 @@ private void makeReadOnly(final CallbackContext callbackContext) { }); } - private void shareTag(JSONArray data, CallbackContext callbackContext) throws JSONException { - NdefRecord[] records = Util.jsonToNdefRecords(data.getString(0)); - this.p2pMessage = new NdefMessage(records); - - startNdefPush(callbackContext); - } - - // setBeamPushUris - // Every Uri you provide must have either scheme 'file' or scheme 'content'. - // Note that this takes priority over setNdefPush - // - // See http://developer.android.com/reference/android/nfc/NfcAdapter.html#setBeamPushUris(android.net.Uri[],%20android.app.Activity) - private void handover(JSONArray data, CallbackContext callbackContext) throws JSONException { - - Uri[] uri = new Uri[data.length()]; - - for (int i = 0; i < data.length(); i++) { - uri[i] = Uri.parse(data.getString(i)); - } - - startNdefBeam(callbackContext, uri); - } - - private void stopHandover(CallbackContext callbackContext) { - stopNdefBeam(); - handoverCallback = null; - callbackContext.success(); - } - private void showSettings(CallbackContext callbackContext) { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { Intent intent = new Intent(android.provider.Settings.ACTION_NFC_SETTINGS); @@ -483,7 +493,13 @@ private void createPendingIntent() { Activity activity = getActivity(); Intent intent = new Intent(activity, activity.getClass()); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); - pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); + pendingIntent = PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_MUTABLE); + } else { + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); + pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0); + } } } @@ -545,10 +561,6 @@ private void startNfc() { if (intentFilters.length > 0 || techLists.length > 0) { nfcAdapter.enableForegroundDispatch(getActivity(), getPendingIntent(), intentFilters, techLists); } - - if (p2pMessage != null) { - nfcAdapter.setNdefPushMessage(p2pMessage, getActivity()); - } } catch (IllegalStateException e) { // issue 110 - user exits app with home button while nfc is initializing Log.w(TAG, "Illegal State Exception starting NFC. Assuming application is terminating."); @@ -575,77 +587,6 @@ private void stopNfc() { }); } - private void startNdefBeam(final CallbackContext callbackContext, final Uri[] uris) { - getActivity().runOnUiThread(() -> { - - NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); - - if (nfcAdapter == null) { - callbackContext.error(STATUS_NO_NFC); - } else if (!nfcAdapter.isNdefPushEnabled()) { - callbackContext.error(STATUS_NDEF_PUSH_DISABLED); - } else { - nfcAdapter.setOnNdefPushCompleteCallback(NfcPlugin.this, getActivity()); - try { - nfcAdapter.setBeamPushUris(uris, getActivity()); - - PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT); - result.setKeepCallback(true); - handoverCallback = callbackContext; - callbackContext.sendPluginResult(result); - - } catch (IllegalArgumentException e) { - callbackContext.error(e.getMessage()); - } - } - }); - } - - private void startNdefPush(final CallbackContext callbackContext) { - getActivity().runOnUiThread(() -> { - - NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); - - if (nfcAdapter == null) { - callbackContext.error(STATUS_NO_NFC); - } else if (!nfcAdapter.isNdefPushEnabled()) { - callbackContext.error(STATUS_NDEF_PUSH_DISABLED); - } else { - nfcAdapter.setNdefPushMessage(p2pMessage, getActivity()); - nfcAdapter.setOnNdefPushCompleteCallback(NfcPlugin.this, getActivity()); - - PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT); - result.setKeepCallback(true); - shareTagCallback = callbackContext; - callbackContext.sendPluginResult(result); - } - }); - } - - private void stopNdefPush() { - getActivity().runOnUiThread(() -> { - - NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); - - if (nfcAdapter != null) { - nfcAdapter.setNdefPushMessage(null, getActivity()); - } - - }); - } - - private void stopNdefBeam() { - getActivity().runOnUiThread(() -> { - - NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(getActivity()); - - if (nfcAdapter != null) { - nfcAdapter.setBeamPushUris(null, getActivity()); - } - - }); - } - private void addToTechList(String[] techs) { techLists.add(techs); } @@ -835,22 +776,6 @@ private void setIntent(Intent intent) { getActivity().setIntent(intent); } - @Override - public void onNdefPushComplete(NfcEvent event) { - - // handover (beam) take precedence over share tag (ndef push) - if (handoverCallback != null) { - PluginResult result = new PluginResult(PluginResult.Status.OK, "Beamed Message to Peer"); - result.setKeepCallback(true); - handoverCallback.sendPluginResult(result); - } else if (shareTagCallback != null) { - PluginResult result = new PluginResult(PluginResult.Status.OK, "Shared Message with Peer"); - result.setKeepCallback(true); - shareTagCallback.sendPluginResult(result); - } - - } - /** * Enable I/O operations to the tag from this TagTechnology object. * * diff --git a/src/ios/NfcPlugin.h b/src/ios/NfcPlugin.h index 46391af1..ce2f1dfa 100644 --- a/src/ios/NfcPlugin.h +++ b/src/ios/NfcPlugin.h @@ -11,16 +11,26 @@ #import #import +#import "AppDelegate.h" + @interface NfcPlugin : CDVPlugin { } // iOS Specific API +// Cordova lifecycle events +- (void) onPause; +- (void) onResume; + // deprecated use scanNdef or scanTag - (void)beginSession:(CDVInvokedUrlCommand *)command; // deprecated use stopScan - (void)invalidateSession:(CDVInvokedUrlCommand *)command; +// Handle launch data +- (void)parseLaunchIntent:(CDVInvokedUrlCommand *)command; +- (void)messageReceived:(NFCNDEFMessage *)message; + // Added iOS 13 - (void)scanNdef:(CDVInvokedUrlCommand *)command; - (void)scanTag:(CDVInvokedUrlCommand *)command; @@ -37,4 +47,8 @@ @end +@interface AppDelegate (PhonegapNfc) + - (BOOL)application:(UIApplication *)application swizzledContinueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *))restorationHandler ; +@end + #endif diff --git a/src/ios/NfcPlugin.m b/src/ios/NfcPlugin.m index 9b40f251..80df838f 100644 --- a/src/ios/NfcPlugin.m +++ b/src/ios/NfcPlugin.m @@ -5,6 +5,47 @@ // (c) 2107-2020 Don Coleman #import "NfcPlugin.h" +#import + +static void * UserActivityPropertyKey = &UserActivityPropertyKey; +static NFCNDEFMessage * LaunchMessage = nil; +static NfcPlugin* Listener = nil; + +@implementation AppDelegate (PhonegapNfc) + ++ (void)load { + Method original = class_getInstanceMethod(self, @selector(application:continueUserActivity:restorationHandler:)); + Method swizzled = class_getInstanceMethod(self, @selector(application:swizzledContinueUserActivity:restorationHandler:)); + method_exchangeImplementations(original, swizzled); +} + +- (BOOL)application:(UIApplication *)application +swizzledContinueUserActivity:(NSUserActivity *)userActivity + restorationHandler:(void (^)(NSArray *))restorationHandler { + if (@available(iOS 12, *)) { + if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) + { + NFCNDEFMessage *messagePayload = userActivity.ndefMessagePayload; + if (messagePayload.records.count > 0 && messagePayload.records[0].typeNameFormat != NFCTypeNameFormatEmpty) + { + NSLog(@"nfcDelegate - received NDEF message"); + if (Listener != nil) + { + [Listener messageReceived:messagePayload]; + } + else + { + LaunchMessage = messagePayload; + } + return YES; + } + } + } + + return [self application:application swizzledContinueUserActivity:userActivity restorationHandler:restorationHandler]; +} + +@end @interface NfcPlugin() { NSString* sessionCallbackId; @@ -20,6 +61,7 @@ @interface NfcPlugin() { @property (nonatomic, assign) BOOL keepSessionOpen; @property (strong, nonatomic) NFCReaderSession *nfcSession API_AVAILABLE(ios(11.0)); @property (strong, nonatomic) NFCNDEFMessage *messageToWrite API_AVAILABLE(ios(11.0)); +@property BOOL hasListener; @end @implementation NfcPlugin @@ -47,6 +89,54 @@ - (void)channel:(CDVInvokedUrlCommand *)command { channelCallbackId = [command.callbackId copy]; } +- (void)onPause { + Listener = nil; +} + +- (void)onResume { + if (self.hasListener) { + Listener = self; + } +} + +- (void)parseLaunchIntent:(CDVInvokedUrlCommand *)command { + NSLog(@"parseLaunchIntent"); + + NFCNDEFMessage* ndefMessage = LaunchMessage; + LaunchMessage = nil; + + CDVPluginResult* pluginResult; + + if (ndefMessage == nil) + { + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"NO_INTENT"]; + } + else + { + NSDictionary* parsedMessage = [self buildTagDictionary:ndefMessage metaData:nil]; + pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:parsedMessage]; + } + + [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; +} + +- (void)messageReceived:(NFCNDEFMessage *)ndefMessage { + NSLog(@"messageReceived"); + + NSMutableDictionary *nfcEvent = [NSMutableDictionary new]; + nfcEvent[@"type"] = @"ndef"; + nfcEvent[@"tag"] = [self buildTagDictionary:ndefMessage metaData:nil]; + + if (channelCallbackId) { + NSLog(@"Sending NFC data via channelCallbackId so an NDEF event fires)"); + + CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:nfcEvent]; + [pluginResult setKeepCallback:[NSNumber numberWithBool:YES]]; + [self.commandDelegate sendPluginResult:pluginResult callbackId:channelCallbackId]; + } +} + + - (void)beginSession:(CDVInvokedUrlCommand*)command { NSLog(@"beginSession"); NSLog(@"WARNING: beginSession is deprecated. Use scanNdef or scanTag."); @@ -125,13 +215,13 @@ - (void)writeTag:(CDVInvokedUrlCommand*)command API_AVAILABLE(ios(13.0)){ if (self.shouldUseTagReaderSession) { NSLog(@"Using NFCTagReaderSession"); - self.nfcSession = [[NFCTagReaderSession new] + self.nfcSession = [[NFCTagReaderSession alloc] initWithPollingOption:(NFCPollingISO14443 | NFCPollingISO15693) delegate:self queue:dispatch_get_main_queue()]; } else { NSLog(@"Using NFCTagReaderSession"); - self.nfcSession = [[NFCNDEFReaderSession new]initWithDelegate:self queue:nil invalidateAfterFirstRead:FALSE]; + self.nfcSession = [[NFCNDEFReaderSession alloc]initWithDelegate:self queue:nil invalidateAfterFirstRead:FALSE]; } } @@ -172,6 +262,8 @@ - (void)invalidateSession:(CDVInvokedUrlCommand*)command { // Nothing happens here, the event listener is registered in JavaScript - (void)registerNdef:(CDVInvokedUrlCommand *)command { NSLog(@"registerNdef"); + self.hasListener = TRUE; + Listener = self; CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @@ -179,6 +271,8 @@ - (void)registerNdef:(CDVInvokedUrlCommand *)command { // Nothing happens here, the event listener is removed in JavaScript - (void)removeNdef:(CDVInvokedUrlCommand *)command { NSLog(@"removeNdef"); + self.hasListener = FALSE; + Listener = nil; CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId]; } @@ -306,12 +400,12 @@ - (void)startScanSession:(CDVInvokedUrlCommand*)command { if (self.shouldUseTagReaderSession) { NSLog(@"Using NFCTagReaderSession"); - self.nfcSession = [[NFCTagReaderSession new] + self.nfcSession = [[NFCTagReaderSession alloc] initWithPollingOption:(NFCPollingISO14443 | NFCPollingISO15693) delegate:self queue:dispatch_get_main_queue()]; } else { NSLog(@"Using NFCNDEFReaderSession"); - self.nfcSession = [[NFCNDEFReaderSession new]initWithDelegate:self queue:nil invalidateAfterFirstRead:TRUE]; + self.nfcSession = [[NFCNDEFReaderSession alloc]initWithDelegate:self queue:nil invalidateAfterFirstRead:TRUE]; } sessionCallbackId = [command.callbackId copy]; self.nfcSession.alertMessage = @"Hold near NFC tag to scan."; @@ -319,7 +413,7 @@ - (void)startScanSession:(CDVInvokedUrlCommand*)command { } else if (@available(iOS 11.0, *)) { NSLog(@"iOS < 13, using NFCNDEFReaderSession"); - self.nfcSession = [[NFCNDEFReaderSession new]initWithDelegate:self queue:nil invalidateAfterFirstRead:TRUE]; + self.nfcSession = [[NFCNDEFReaderSession alloc]initWithDelegate:self queue:nil invalidateAfterFirstRead:TRUE]; sessionCallbackId = [command.callbackId copy]; self.nfcSession.alertMessage = @"Hold near NFC tag to scan."; [self.nfcSession beginSession]; diff --git a/www/phonegap-nfc.js b/www/phonegap-nfc.js index 7349bb7a..811ed110 100644 --- a/www/phonegap-nfc.js +++ b/www/phonegap-nfc.js @@ -500,6 +500,10 @@ var nfc = { cordova.exec(win, fail, "NfcPlugin", "showSettings", []); }, + parseLaunchIntent: function (win, fail) { + cordova.exec(win, fail, "NfcPlugin", "parseLaunchIntent", []); + }, + // iOS only - scan for NFC NDEF tag using NFCNDEFReaderSession scanNdef: function (options) { return new Promise(function(resolve, reject) {