From 245c1c4f6330554382db6c346692001fb2fb53a1 Mon Sep 17 00:00:00 2001 From: Richie Date: Mon, 5 Jul 2021 07:51:13 +0800 Subject: [PATCH] feat: add support for iOS background tag reading --- index.d.ts | 1 + ios/NfcManager.h | 14 ++++++++++ ios/NfcManager.m | 64 ++++++++++++++++++++++++++++++++------------ src/NfcManagerIOS.js | 3 +++ 4 files changed, 65 insertions(+), 17 deletions(-) diff --git a/index.d.ts b/index.d.ts index 1372634..7e14375 100644 --- a/index.d.ts +++ b/index.d.ts @@ -203,6 +203,7 @@ declare module 'react-native-nfc-manager' { /** * iOS only */ + getBackgroundNdef: () => Promise; setAlertMessageIOS: (alertMessage: string) => Promise; invalidateSessionIOS: () => Promise; invalidateSessionWithErrorIOS: (errorMessage: string) => Promise; diff --git a/ios/NfcManager.h b/ios/NfcManager.h index 477ea1a..9905b90 100644 --- a/ios/NfcManager.h +++ b/ios/NfcManager.h @@ -9,10 +9,24 @@ #endif #import +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 12000) /* __IPHONE_12_0 */ +#import +#endif + @interface NfcManager : RCTEventEmitter { } @property (strong, nonatomic) NFCNDEFReaderSession *session; @property (strong, nonatomic) NFCTagReaderSession *tagSession; + ++ (BOOL)application:(nonnull UIApplication *)application + continueUserActivity:(nonnull NSUserActivity *)userActivity + restorationHandler: + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 12000) /* __IPHONE_12_0 */ + (nonnull void (^)(NSArray> *_Nullable))restorationHandler; + #else + (nonnull void (^)(NSArray *_Nullable))restorationHandler; + #endif + @end diff --git a/ios/NfcManager.m b/ios/NfcManager.m index 850ae8e..5c7c036 100755 --- a/ios/NfcManager.m +++ b/ios/NfcManager.m @@ -39,6 +39,27 @@ @implementation NfcManager { @synthesize tagSession; @synthesize bridge = _bridge; +NSArray * bgNdefRecords = nil; + ++ (BOOL)application:(UIApplication *)application +continueUserActivity:(NSUserActivity *)userActivity + restorationHandler: + #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 12000) /* __IPHONE_12_0 */ + (nonnull void (^)(NSArray> *_Nullable))restorationHandler { + #else + (nonnull void (^)(NSArray *_Nullable))restorationHandler { + #endif + if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) { + if (@available(iOS 12.0, *)) { + NFCNDEFMessage * ndefMessage = userActivity.ndefMessagePayload; + if (ndefMessage != nil) { + bgNdefRecords = [NfcManager convertNdefMessage: ndefMessage]; + } + } + } + return YES; +} + - (instancetype)init { if (self = [super init]) { @@ -86,7 +107,7 @@ - (NSData *)arrayToData: (NSArray *) array return payload; } -- (NSArray *)dataToArray:(NSData *)data ++ (NSArray *)dataToArray:(NSData *)data { const unsigned char *dataBuffer = data ? (const unsigned char *)[data bytes] : NULL; @@ -102,7 +123,7 @@ - (NSArray *)dataToArray:(NSData *)data return array; } -- (NSDictionary*)convertNdefRecord:(NFCNDEFPayload *) record ++ (NSDictionary*)convertNdefRecord:(NFCNDEFPayload *) record { return @{ @"id": [self dataToArray:[record identifier]], @@ -112,7 +133,7 @@ - (NSDictionary*)convertNdefRecord:(NFCNDEFPayload *) record }; } -- (NSArray*)convertNdefMessage:(NFCNDEFMessage *)message ++ (NSArray*)convertNdefMessage:(NFCNDEFMessage *)message { NSArray * records = [message records]; NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity: [records count]]; @@ -143,13 +164,13 @@ - (NSDictionary*)getRNTag:(id)tag { id iso7816Tag = [tag asNFCISO7816Tag]; [tagInfo setObject:getHexString(iso7816Tag.identifier) forKey:@"id"]; [tagInfo setObject:iso7816Tag.initialSelectedAID forKey:@"initialSelectedAID"]; - [tagInfo setObject:[self dataToArray:iso7816Tag.historicalBytes] forKey:@"historicalBytes"]; - [tagInfo setObject:[self dataToArray:iso7816Tag.applicationData] forKey:@"applicationData"]; + [tagInfo setObject:[NfcManager dataToArray:iso7816Tag.historicalBytes] forKey:@"historicalBytes"]; + [tagInfo setObject:[NfcManager dataToArray:iso7816Tag.applicationData] forKey:@"applicationData"]; } else if (tag.type == NFCTagTypeISO15693) { id iso15693Tag = [tag asNFCISO15693Tag]; [tagInfo setObject:getHexString(iso15693Tag.identifier) forKey:@"id"]; [tagInfo setObject:[NSNumber numberWithUnsignedInteger:iso15693Tag.icManufacturerCode] forKey:@"icManufacturerCode"]; - [tagInfo setObject:[self dataToArray:iso15693Tag.icSerialNumber] forKey:@"icSerialNumber"]; + [tagInfo setObject:[NfcManager dataToArray:iso15693Tag.icSerialNumber] forKey:@"icSerialNumber"]; } else if (tag.type == NFCTagTypeFeliCa) { id felicaTag = [tag asNFCFeliCaTag]; [tagInfo setObject:getHexString(felicaTag.currentIDm) forKey:@"idm"]; @@ -183,7 +204,7 @@ - (void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray 0) { // parse the first message for now [self sendEventWithName:@"NfcManagerDiscoverTag" - body:@{@"ndefMessage": [self convertNdefMessage:messages[0]]}]; + body:@{@"ndefMessage": [NfcManager convertNdefMessage:messages[0]]}]; } else { [self sendEventWithName:@"NfcManagerDiscoverTag" body:@{@"ndefMessage": @[]}]; @@ -252,6 +273,15 @@ + (BOOL)requiresMainQueueSetup { return YES; } + +RCT_EXPORT_METHOD(getBackgroundNdef: (nonnull RCTResponseSenderBlock)callback) +{ + if (bgNdefRecords != nil) { + callback(@[[NSNull null], bgNdefRecords]); + } else { + callback(@[[NSNull null], [NSNull null]]); + } +} RCT_EXPORT_METHOD(isSupported: (NSString *)tech callback:(nonnull RCTResponseSenderBlock)callback) { @@ -395,7 +425,7 @@ + (BOOL)requiresMainQueueSetup if (ndefTag) { [ndefTag readNDEFWithCompletionHandler:^(NFCNDEFMessage *ndefMessage, NSError *error) { if (!error) { - [rnTag setObject:[self convertNdefMessage:ndefMessage] forKey:@"ndefMessage"]; + [rnTag setObject:[NfcManager convertNdefMessage:ndefMessage] forKey:@"ndefMessage"]; } callback(@[[NSNull null], rnTag]); }]; @@ -424,7 +454,7 @@ + (BOOL)requiresMainQueueSetup if (error) { callback(@[getErrorMessage(error), [NSNull null]]); } else { - callback(@[[NSNull null], @{@"ndefMessage": [self convertNdefMessage:ndefMessage]}]); + callback(@[[NSNull null], @{@"ndefMessage": [NfcManager convertNdefMessage:ndefMessage]}]); } }]; return; @@ -548,7 +578,7 @@ + (BOOL)requiresMainQueueSetup if (error) { callback(@[getErrorMessage(error), [NSNull null]]); } else { - callback(@[[NSNull null], [self dataToArray:response]]); + callback(@[[NSNull null], [NfcManager dataToArray:response]]); } }]; return; @@ -579,7 +609,7 @@ + (BOOL)requiresMainQueueSetup if (error) { callback(@[getErrorMessage(error), [NSNull null]]); } else { - callback(@[[NSNull null], [self dataToArray:response]]); + callback(@[[NSNull null], [NfcManager dataToArray:response]]); } }]; return; @@ -609,7 +639,7 @@ + (BOOL)requiresMainQueueSetup if (error) { callback(@[getErrorMessage(error), [NSNull null]]); } else { - callback(@[[NSNull null], [self dataToArray:response], [NSNumber numberWithInt:sw1], [NSNumber numberWithInt:sw2]]); + callback(@[[NSNull null], [NfcManager dataToArray:response], [NSNumber numberWithInt:sw1], [NSNumber numberWithInt:sw2]]); } }]; return; @@ -650,7 +680,7 @@ + (BOOL)requiresMainQueueSetup if (error) { callback(@[getErrorMessage(error), [NSNull null]]); } else { - callback(@[[NSNull null], [self dataToArray:response], [NSNumber numberWithInt:sw1], [NSNumber numberWithInt:sw2]]); + callback(@[[NSNull null], [NfcManager dataToArray:response], [NSNumber numberWithInt:sw1], [NSNumber numberWithInt:sw2]]); } }]; return; @@ -766,7 +796,7 @@ + (BOOL)requiresMainQueueSetup return; } - callback(@[[NSNull null], [self dataToArray:resp]]); + callback(@[[NSNull null], [NfcManager dataToArray:resp]]); }]; } else { callback(@[@"Not support in this device", [NSNull null]]); @@ -802,7 +832,7 @@ + (BOOL)requiresMainQueueSetup } NSMutableArray *blocks = [NSMutableArray arrayWithCapacity:[dataBlocks count]]; [dataBlocks enumerateObjectsUsingBlock:^(NSData *blockData, NSUInteger idx, BOOL *stop) { - [blocks addObject:[self dataToArray:blockData]]; + [blocks addObject:[NfcManager dataToArray:blockData]]; }]; callback(@[[NSNull null], blocks]); }]; @@ -1116,7 +1146,7 @@ + (BOOL)requiresMainQueueSetup return; } - callback(@[[NSNull null], [self dataToArray:resp]]); + callback(@[[NSNull null], [NfcManager dataToArray:resp]]); }]; } else { callback(@[@"Not support in this device", [NSNull null]]); @@ -1148,7 +1178,7 @@ + (BOOL)requiresMainQueueSetup return; } - callback(@[[NSNull null], [self dataToArray:resp]]); + callback(@[[NSNull null], [NfcManager dataToArray:resp]]); }]; } else { callback(@[@"Not support in this device", [NSNull null]]); diff --git a/src/NfcManagerIOS.js b/src/NfcManagerIOS.js index e22512e..3694f34 100644 --- a/src/NfcManagerIOS.js +++ b/src/NfcManagerIOS.js @@ -57,6 +57,9 @@ class NfcManagerIOS extends NfcManagerBase { // ------------------------------------- // public only for iOS // ------------------------------------- + getBackgroundNdef = () => + handleNativeException(callNative('getBackgroundNdef')); + setAlertMessage = (alertMessage) => handleNativeException(callNative('setAlertMessage', [alertMessage]));