Skip to content

Commit

Permalink
feat: add support for iOS background tag reading
Browse files Browse the repository at this point in the history
  • Loading branch information
whitedogg13 committed Jul 4, 2021
1 parent 588df7b commit 245c1c4
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 17 deletions.
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ declare module 'react-native-nfc-manager' {
/**
* iOS only
*/
getBackgroundNdef: () => Promise<NdefRecord[] | null>;
setAlertMessageIOS: (alertMessage: string) => Promise<void>;
invalidateSessionIOS: () => Promise<void>;
invalidateSessionWithErrorIOS: (errorMessage: string) => Promise<void>;
Expand Down
14 changes: 14 additions & 0 deletions ios/NfcManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,24 @@
#endif
#import <CoreNFC/CoreNFC.h>

#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 12000) /* __IPHONE_12_0 */
#import <UIKit/UIUserActivity.h>
#endif

@interface NfcManager : RCTEventEmitter <RCTBridgeModule, NFCNDEFReaderSessionDelegate, NFCTagReaderSessionDelegate> {

}

@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<id<UIUserActivityRestoring>> *_Nullable))restorationHandler;
#else
(nonnull void (^)(NSArray *_Nullable))restorationHandler;
#endif

@end
64 changes: 47 additions & 17 deletions ios/NfcManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -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<id<UIUserActivityRestoring>> *_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]) {
Expand Down Expand Up @@ -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;

Expand All @@ -102,7 +123,7 @@ - (NSArray *)dataToArray:(NSData *)data
return array;
}

- (NSDictionary*)convertNdefRecord:(NFCNDEFPayload *) record
+ (NSDictionary*)convertNdefRecord:(NFCNDEFPayload *) record
{
return @{
@"id": [self dataToArray:[record identifier]],
Expand All @@ -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]];
Expand Down Expand Up @@ -143,13 +164,13 @@ - (NSDictionary*)getRNTag:(id<NFCTag>)tag {
id<NFCISO7816Tag> 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<NFCISO15693Tag> 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<NFCFeliCaTag> felicaTag = [tag asNFCFeliCaTag];
[tagInfo setObject:getHexString(felicaTag.currentIDm) forKey:@"idm"];
Expand Down Expand Up @@ -183,7 +204,7 @@ - (void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray<NF
if ([messages count] > 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": @[]}];
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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]);
}];
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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]]);
Expand Down Expand Up @@ -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]);
}];
Expand Down Expand Up @@ -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]]);
Expand Down Expand Up @@ -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]]);
Expand Down
3 changes: 3 additions & 0 deletions src/NfcManagerIOS.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ class NfcManagerIOS extends NfcManagerBase {
// -------------------------------------
// public only for iOS
// -------------------------------------
getBackgroundNdef = () =>
handleNativeException(callNative('getBackgroundNdef'));

setAlertMessage = (alertMessage) =>
handleNativeException(callNative('setAlertMessage', [alertMessage]));

Expand Down

0 comments on commit 245c1c4

Please sign in to comment.