Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92e82b34f9 | ||
|
|
d960a3d708 | ||
|
|
6b4f682623 | ||
|
|
4c82d1be69 | ||
|
|
2a7b04c531 | ||
|
|
67173c0893 |
@ -191,68 +191,6 @@ class NfcManager {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
registerTagEventEx(listener, alertMessage = '', options = {}) {
|
||||
if (Platform.OS === 'android') {
|
||||
return Promise.reject('not implemented');
|
||||
}
|
||||
|
||||
// Support legacy `invalidateAfterFirstRead` boolean
|
||||
if (options === true || options === false) {
|
||||
options = {
|
||||
invalidateAfterFirstRead: options,
|
||||
};
|
||||
}
|
||||
|
||||
options = {
|
||||
...DEFAULT_REGISTER_TAG_EVENT_OPTIONS,
|
||||
...options,
|
||||
};
|
||||
|
||||
if (!this._subscription) {
|
||||
return new Promise((resolve, reject) => {
|
||||
NativeNfcManager.registerTagEventEx(
|
||||
alertMessage,
|
||||
options,
|
||||
(err, result) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
this._clientTagDiscoveryListener = listener;
|
||||
this._subscription = NfcManagerEmitter.addListener(
|
||||
Events.DiscoverTag,
|
||||
this._handleDiscoverTag,
|
||||
);
|
||||
resolve(result);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
unregisterTagEventEx() {
|
||||
if (Platform.OS === 'android') {
|
||||
return Promise.reject('not implemented');
|
||||
}
|
||||
|
||||
if (this._subscription) {
|
||||
this._clientTagDiscoveryListener = null;
|
||||
this._subscription.remove();
|
||||
this._subscription = null;
|
||||
return new Promise((resolve, reject) => {
|
||||
NativeNfcManager.unregisterTagEventEx((err, result) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(result)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
_handleDiscoverTag = tag => {
|
||||
if (this._clientTagDiscoveryListener) {
|
||||
this._clientTagDiscoveryListener(tag);
|
||||
@ -342,22 +280,6 @@ class NfcManager {
|
||||
})
|
||||
}
|
||||
|
||||
requestTechnologies(techs) {
|
||||
if (Platform.OS === 'ios') {
|
||||
return Promise.reject('not implemented');
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
NativeNfcManager.requestTechnologies(techs, (err, result) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
cancelTechnologyRequest() {
|
||||
return new Promise((resolve, reject) => {
|
||||
NativeNfcManager.cancelTechnologyRequest((err, result) => {
|
||||
@ -465,7 +387,6 @@ class NfcManager {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
// NfcTech.MifareClassic API
|
||||
// -------------------------------------
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
Button,
|
||||
Platform,
|
||||
TouchableOpacity,
|
||||
Linking,
|
||||
TextInput,
|
||||
ScrollView,
|
||||
} from 'react-native';
|
||||
import NfcManager, {Ndef} from '../NfcManager';
|
||||
|
||||
class AppIOS13 extends React.Component {
|
||||
componentDidMount() {
|
||||
NfcManager.start();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this._cleanUp();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={{padding: 20}}>
|
||||
<Text>NFC Demo on iOS13</Text>
|
||||
<TouchableOpacity
|
||||
style={{padding: 10, width: 200, margin: 20, borderWidth: 1, borderColor: 'black'}}
|
||||
onPress={this._testMifare}
|
||||
>
|
||||
<Text>Test Mifare</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={{padding: 10, width: 200, margin: 20, borderWidth: 1, borderColor: 'black'}}
|
||||
onPress={this._cleanUp}
|
||||
>
|
||||
<Text>Cancel Test</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
_cleanUp = () => {
|
||||
NfcManager.cancelTechnologyRequest().catch(() => 0);
|
||||
NfcManager.unregisterTagEventEx().catch(() => 0);
|
||||
}
|
||||
|
||||
_testMifare = async () => {
|
||||
try {
|
||||
await NfcManager.registerTagEventEx()
|
||||
let resp = await NfcManager.requestTechnology('mifare');
|
||||
console.warn(resp);
|
||||
let tag = await NfcManager.getTag();
|
||||
console.warn(tag);
|
||||
this._cleanUp();
|
||||
} catch (ex) {
|
||||
this._cleanUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default AppIOS13;
|
||||
193
index.d.ts
vendored
193
index.d.ts
vendored
@ -6,10 +6,10 @@ import { EmitterSubscription } from "react-native";
|
||||
|
||||
declare module 'react-native-nfc-manager' {
|
||||
export interface NdefRecord {
|
||||
id?: number[];
|
||||
id: string;
|
||||
tnf: number;
|
||||
type: number[];
|
||||
payload: any[];
|
||||
payload: number[];
|
||||
}
|
||||
|
||||
export interface ParseUriResult {
|
||||
@ -21,108 +21,159 @@ declare module 'react-native-nfc-manager' {
|
||||
}
|
||||
|
||||
export interface TagEvent {
|
||||
ndefMessage: NdefRecord[];
|
||||
id?: string;
|
||||
techTypes?: string[];
|
||||
}
|
||||
|
||||
export interface NdefEvent extends TagEvent {
|
||||
type: 'NFC Forum Type 1' | 'NFC Forum Type 2' | 'NFC Forum Type 3' | 'NFC Forum Type 4' | string;
|
||||
maxSize: number;
|
||||
type: string;
|
||||
techTypes: string[];
|
||||
id: number[];
|
||||
isWritable: boolean;
|
||||
ndefMessage: NdefRecord[] | null;
|
||||
canMakeReadOnly: boolean | null;
|
||||
}
|
||||
|
||||
export interface NdefSimpleEvent {
|
||||
type: 'NDEF';
|
||||
ndefMessage: NdefRecord[] | null;
|
||||
}
|
||||
|
||||
interface RegisterTagEventOpts {
|
||||
invalidateAfterFirstRead?: boolean;
|
||||
isReaderModeEnabled?: boolean;
|
||||
readerModeFlags?: number;
|
||||
}
|
||||
invalidateAfterFirstRead?: boolean;
|
||||
isReaderModeEnabled?: boolean;
|
||||
readerModeFlags?: number;
|
||||
}
|
||||
|
||||
interface NdefWriteOpts {
|
||||
format?: boolean
|
||||
formatReadOnly?: boolean
|
||||
format?: boolean;
|
||||
formatReadOnly?: boolean;
|
||||
}
|
||||
|
||||
interface EventStateChange {
|
||||
state: string
|
||||
state: 'unknown' | 'off' | 'turning_off' | 'on' | 'turning_on';
|
||||
}
|
||||
|
||||
interface NfcManager {
|
||||
start(options?: StartOptions): Promise<void>;
|
||||
|
||||
start(options?: StartOptions): Promise<any>;
|
||||
stop(): Promise<void>;
|
||||
|
||||
stop(): void;
|
||||
|
||||
isSupported(): Promise<boolean>;
|
||||
isSupported(tech?: string): Promise<boolean>;
|
||||
|
||||
/** [ANDROID ONLY] */
|
||||
isEnabled(): Promise<boolean>;
|
||||
|
||||
/** [ANDROID ONLY] */
|
||||
goToNfcSetting(): Promise<any>;
|
||||
goToNfcSetting(): Promise<void>;
|
||||
|
||||
/** [ANDROID ONLY] */
|
||||
getLaunchTagEvent(): Promise<TagEvent | null>;
|
||||
getLaunchTagEvent(): Promise<TagEvent | NdefEvent | null>;
|
||||
|
||||
/**
|
||||
* Start to listen to ANY NFC Tags
|
||||
* @param listener The callback function when a tag is found.
|
||||
* @param alertMessage [iOS ONLY] Message displayed when NFC Scanning popup appears.
|
||||
* @param invalidateAfterFirstRead [iOS ONLY] When set to true, will auto-dismiss the NFC Scanning popup after scanning.
|
||||
*/
|
||||
registerTagEvent(
|
||||
listener: (tag: TagEvent) => void,
|
||||
alertMessage?: string,
|
||||
options?: RegisterTagEventOpts,
|
||||
): Promise<any>;
|
||||
/**
|
||||
* Start to listen to ANY NFC Tags
|
||||
* @param listener The callback function when a tag is found.
|
||||
* @param alertMessage [iOS ONLY] Message displayed when NFC Scanning popup appears.
|
||||
* @param options [iOS ONLY] When set to true, will auto-dismiss the NFC Scanning popup after scanning.
|
||||
*/
|
||||
registerTagEvent(
|
||||
listener: (tag: TagEvent | NdefEvent) => void,
|
||||
alertMessage?: string,
|
||||
options?: RegisterTagEventOpts | boolean,
|
||||
): Promise<void>;
|
||||
|
||||
unregisterTagEvent(): Promise<any>;
|
||||
/* android only */
|
||||
cancelNdefWrite(): Promise<any>;
|
||||
requestNdefWrite(bytes: number[], opts?: NdefWriteOpts): Promise<any>;
|
||||
unregisterTagEvent(): Promise<void>;
|
||||
|
||||
/** [ANDROID ONLY] */
|
||||
onStateChanged(listener: (event: EventStateChange) => void): Promise<EmitterSubscription>;
|
||||
|
||||
mifareClassicSectorToBlock: (sector: number) => ArrayLike<number>
|
||||
mifareClassicReadBlock: (block: ArrayLike<number>) => ArrayLike<number>
|
||||
mifareClassicWriteBlock: (block: ArrayLike<number>, simpliArr: any[]) => void
|
||||
cancelTechnologyRequest: () => Promise<EmitterSubscription>
|
||||
closeTechnology: () => void
|
||||
requestTechnology: (data: any) => void
|
||||
getTag: () => void
|
||||
mifareClassicGetSectorCount: () => number
|
||||
mifareClassicAuthenticateA: (sector: number, keys: number[]) => void
|
||||
setNdefPushMessage(bytes: number[]): Promise<void>;
|
||||
requestNdefWrite(bytes: number[], opts?: NdefWriteOpts): Promise<void>;
|
||||
cancelNdefWrite(): Promise<void>;
|
||||
requestTechnology(tech: string): Promise<void>;
|
||||
cancelTechnologyRequest(): Promise<void>;
|
||||
closeTechnology(): Promise<void>;
|
||||
getTag(): Promise<TagEvent | null>;
|
||||
writeNdefMessage(bytes: number[]): Promise<void>;
|
||||
getNdefMessage(): Promise<NdefEvent | NdefSimpleEvent | null>;
|
||||
getCachedNdefMessage(): Promise<NdefEvent | NdefSimpleEvent | null>;
|
||||
makeReadOnly(): Promise<boolean>;
|
||||
mifareClassicAuthenticateA(sector: number, key: number[]): Promise<boolean>;
|
||||
mifareClassicAuthenticateB(sector: number, key: number[]): Promise<boolean>;
|
||||
mifareClassicGetBlockCountInSector(sector: number): Promise<number>;
|
||||
mifareClassicGetSectorCount(): Promise<number>;
|
||||
mifareClassicSectorToBlock(sector: number): Promise<number>;
|
||||
mifareClassicReadBlock(block: number): Promise<number[]>;
|
||||
mifareClassicReadSector(sector: number): Promise<number[]>;
|
||||
mifareClassicWriteBlock(block: number, data: number[]): Promise<boolean>;
|
||||
mifareUltralightReadPages(pageOffset: number): Promise<number[]>;
|
||||
mifareUltralightWritePage(pageOffset: number, data: number[]): Promise<void>;
|
||||
setTimeout(timeout: number): Promise<void>;
|
||||
connect(techs: string[]): Promise<void>;
|
||||
close(): Promise<void>;
|
||||
transceive(bytes: number[]): Promise<number[]>;
|
||||
getMaxTransceiveLength(): Promise<number>;
|
||||
}
|
||||
|
||||
const nfcManager: NfcManager;
|
||||
|
||||
export namespace ByteParser {
|
||||
function byteToHexString(bytes: number[]): string;
|
||||
function byteToString(bytes: number[]): string;
|
||||
}
|
||||
|
||||
export namespace NdefParser {
|
||||
function parseUri(ndef: NdefRecord): ParseUriResult;
|
||||
function parseUri(ndef: NdefRecord): ParseUriResult | null;
|
||||
function parseText(ndef: NdefRecord): string | null;
|
||||
}
|
||||
|
||||
type ISOLangCode = "en" | string;
|
||||
type ISOLangCode = 'en' | string;
|
||||
type URI = string;
|
||||
|
||||
export enum NfcAdapter {
|
||||
FLAG_READER_NFC_A= 0x1,
|
||||
FLAG_READER_NFC_B= 0x2,
|
||||
FLAG_READER_NFC_F= 0x4,
|
||||
FLAG_READER_NFC_V= 0x8,
|
||||
FLAG_READER_NFC_BARCODE= 0x10,
|
||||
FLAG_READER_SKIP_NDEF_CHECK= 0x80,
|
||||
FLAG_READER_NO_PLATFORM_SOUNDS= 0x100,
|
||||
FLAG_READER_NFC_A = 0x1,
|
||||
FLAG_READER_NFC_B = 0x2,
|
||||
FLAG_READER_NFC_F = 0x4,
|
||||
FLAG_READER_NFC_V = 0x8,
|
||||
FLAG_READER_NFC_BARCODE = 0x10,
|
||||
FLAG_READER_SKIP_NDEF_CHECK = 0x80,
|
||||
FLAG_READER_NO_PLATFORM_SOUNDS = 0x100,
|
||||
}
|
||||
|
||||
export const NfcEvents: {
|
||||
DiscoverTag: 'NfcManagerDiscoverTag';
|
||||
SessionClosed: 'NfcManagerSessionClosed';
|
||||
StateChanged: 'NfcManagerStateChanged';
|
||||
};
|
||||
|
||||
export const NfcTech: {
|
||||
Ndef: 'Ndef';
|
||||
NfcA: 'NfcA';
|
||||
NfcB: 'NfcB';
|
||||
NfcF: 'NfcF';
|
||||
NfcV: 'NfcV';
|
||||
IsoDep: 'IsoDep';
|
||||
MifareClassic: 'MifareClassic';
|
||||
MifareUltralight: 'MifareUltralight';
|
||||
MifareIOS: 'mifare';
|
||||
};
|
||||
|
||||
export const Ndef: {
|
||||
TNF_EMPTY: 0x0,
|
||||
TNF_WELL_KNOWN: 0x01,
|
||||
TNF_MIME_MEDIA: 0x02,
|
||||
TNF_ABSOLUTE_URI: 0x03,
|
||||
TNF_EXTERNAL_TYPE: 0x04,
|
||||
TNF_UNKNOWN: 0x05,
|
||||
TNF_UNCHANGED: 0x06,
|
||||
TNF_RESERVED: 0x07,
|
||||
|
||||
RTD_TEXT: "T", // [0x54]
|
||||
RTD_URI: "U", // [0x55]
|
||||
RTD_SMART_POSTER: "Sp", // [0x53, 0x70]
|
||||
RTD_ALTERNATIVE_CARRIER: "ac", //[0x61, 0x63]
|
||||
RTD_HANDOVER_CARRIER: "Hc", // [0x48, 0x63]
|
||||
RTD_HANDOVER_REQUEST: "Hr", // [0x48, 0x72]
|
||||
RTD_HANDOVER_SELECT: "Hs", // [0x48, 0x73]
|
||||
|
||||
TNF_EMPTY: 0x0;
|
||||
TNF_WELL_KNOWN: 0x01;
|
||||
TNF_MIME_MEDIA: 0x02;
|
||||
TNF_ABSOLUTE_URI: 0x03;
|
||||
TNF_EXTERNAL_TYPE: 0x04;
|
||||
TNF_UNKNOWN: 0x05;
|
||||
TNF_UNCHANGED: 0x06;
|
||||
TNF_RESERVED: 0x07;
|
||||
|
||||
RTD_TEXT: 'T'; // [0x54]
|
||||
RTD_URI: 'U'; // [0x55]
|
||||
RTD_SMART_POSTER: 'Sp'; // [0x53, 0x70]
|
||||
RTD_ALTERNATIVE_CARRIER: 'ac'; // [0x61, 0x63]
|
||||
RTD_HANDOVER_CARRIER: 'Hc'; // [0x48, 0x63]
|
||||
RTD_HANDOVER_REQUEST: 'Hr'; // [0x48, 0x72]
|
||||
RTD_HANDOVER_SELECT: 'Hs'; // [0x48, 0x73]
|
||||
|
||||
text: {
|
||||
encodePayload: (text: string, lang?: ISOLangCode, encoding?: any) => NdefRecord;
|
||||
decodePayload: (data: Uint8Array) => string;
|
||||
@ -144,7 +195,7 @@ declare module 'react-native-nfc-manager' {
|
||||
decodeMessage(bytes: any[] | Buffer): NdefRecord[];
|
||||
textRecord(text: string, lang?: ISOLangCode, encoding?: any): NdefRecord;
|
||||
uriRecord(uri: URI, id?: any): NdefRecord;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default nfcManager;
|
||||
|
||||
@ -9,10 +9,9 @@
|
||||
#endif
|
||||
#import <CoreNFC/CoreNFC.h>
|
||||
|
||||
@interface NfcManager : RCTEventEmitter <RCTBridgeModule, NFCNDEFReaderSessionDelegate, NFCTagReaderSessionDelegate> {
|
||||
@interface NfcManager : RCTEventEmitter <RCTBridgeModule, NFCNDEFReaderSessionDelegate> {
|
||||
|
||||
}
|
||||
|
||||
@property (strong, nonatomic) NFCNDEFReaderSession *session;
|
||||
@property (strong, nonatomic) NFCTagReaderSession *sessionEx;
|
||||
@end
|
||||
|
||||
176
ios/NfcManager.m
176
ios/NfcManager.m
@ -37,15 +37,11 @@ NSString* getErrorMessage(NSError *error) {
|
||||
}
|
||||
|
||||
@implementation NfcManager {
|
||||
NSDictionary *nfcTechTypes;
|
||||
NSString *techRequestType;
|
||||
RCTResponseSenderBlock techRequestCallback;
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
@synthesize session;
|
||||
@synthesize sessionEx;
|
||||
@synthesize bridge = _bridge;
|
||||
|
||||
- (instancetype)init
|
||||
@ -54,17 +50,6 @@ RCT_EXPORT_MODULE()
|
||||
NSLog(@"NfcManager created");
|
||||
}
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
nfcTechTypes = @{
|
||||
[NSNumber numberWithInt: NFCTagTypeMiFare]: @"mifare",
|
||||
[NSNumber numberWithInt: NFCTagTypeFeliCa]: @"felica",
|
||||
[NSNumber numberWithInt: NFCTagTypeISO7816Compatible]: @"iso7816",
|
||||
[NSNumber numberWithInt: NFCTagTypeISO15693]: @"iso15693",
|
||||
};
|
||||
} else {
|
||||
nfcTechTypes = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -114,37 +99,6 @@ RCT_EXPORT_MODULE()
|
||||
return resultArray;
|
||||
}
|
||||
|
||||
- (NSString*)getRNTechName:(id<NFCTag>)tag {
|
||||
NSString * tech = [nfcTechTypes objectForKey:[NSNumber numberWithInt:(int)tag.type]];
|
||||
if (tech == nil) {
|
||||
tech = @"unknown";
|
||||
}
|
||||
return tech;
|
||||
}
|
||||
|
||||
- (NSDictionary*)getRNTag:(id<NFCTag>)tag {
|
||||
NSMutableDictionary *tagInfo = @{}.mutableCopy;
|
||||
NSString* tech = [self getRNTechName:tag];
|
||||
[tagInfo setObject:tech forKey:@"tech"];
|
||||
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if (tag.type == NFCTagTypeMiFare) {
|
||||
id<NFCMiFareTag> mifareTag = [tag asNFCMiFareTag];
|
||||
[tagInfo setObject:getHexString(mifareTag.identifier) forKey:@"id"];
|
||||
} else if (tag.type == NFCTagTypeISO7816Compatible) {
|
||||
id<NFCISO7816Tag> iso7816Tag = [tag asNFCISO7816Tag];
|
||||
[tagInfo setObject:getHexString(iso7816Tag.identifier) forKey:@"id"];
|
||||
} else if (tag.type == NFCTagTypeISO15693) {
|
||||
id<NFCISO15693Tag> iso15693Tag = [tag asNFCISO15693Tag];
|
||||
[tagInfo setObject:getHexString(iso15693Tag.identifier) forKey:@"id"];
|
||||
} else if (tag.type == NFCTagTypeFeliCa) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
return tagInfo;
|
||||
}
|
||||
|
||||
- (void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray<NFCNDEFMessage *> *)messages
|
||||
{
|
||||
NSLog(@"didDetectNDEFs");
|
||||
@ -166,61 +120,6 @@ RCT_EXPORT_MODULE()
|
||||
body:@{}];
|
||||
}
|
||||
|
||||
- (void)readerSession:(NFCNDEFReaderSession *)session didDetectTags:(NSArray<__kindof id<NFCNDEFTag>> *)tags {
|
||||
NSLog(@"didDetectNdefTag");
|
||||
[self sendEventWithName:@"NfcManagerDidDetectNdefTags"
|
||||
body:@{}];
|
||||
}
|
||||
|
||||
- (void)tagReaderSession:(NFCTagReaderSession *)session didDetectTags:(NSArray<__kindof id<NFCTag>> *)tags
|
||||
{
|
||||
NSLog(@"NFCTag didDetectTags");
|
||||
if (@available(iOS 13.0, *)) {
|
||||
[self sendEventWithName:@"NfcManagerDidDetectTags"
|
||||
body:@{}];
|
||||
|
||||
if (techRequestCallback != nil) {
|
||||
id<NFCTag> tagFound = nil;
|
||||
for (id<NFCTag> tag in tags) {
|
||||
NSString * tagType = [self getRNTechName:tag];
|
||||
if ([tagType isEqualToString:techRequestType]) {
|
||||
tagFound = tag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tagFound == nil) {
|
||||
techRequestCallback(@[@"No tech matches", [NSNull null]]);
|
||||
return;
|
||||
}
|
||||
|
||||
[sessionEx connectToTag:tagFound completionHandler:^(NSError *error) {
|
||||
if (error != nil) {
|
||||
self->techRequestCallback(@[getErrorMessage(error), [NSNull null]]);
|
||||
return;
|
||||
}
|
||||
|
||||
self->techRequestCallback(@[[NSNull null], self->techRequestType]);
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)tagReaderSession:(NFCTagReaderSession *)session didInvalidateWithError:(NSError *)error
|
||||
{
|
||||
NSLog(@"NFCTag didInvalidateWithError");
|
||||
sessionEx = nil;
|
||||
techRequestType = nil;
|
||||
techRequestCallback = nil;
|
||||
[self sendEventWithName:@"NfcManagerSessionClosed"
|
||||
body:@{}];
|
||||
}
|
||||
|
||||
- (void)tagReaderSessionDidBecomeActive:(NFCTagReaderSession *)session
|
||||
{
|
||||
NSLog(@"NFCTag didBecomeActive");
|
||||
}
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup
|
||||
{
|
||||
return YES;
|
||||
@ -250,28 +149,6 @@ RCT_EXPORT_METHOD(start: (nonnull RCTResponseSenderBlock)callback)
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(requestTechnology: (NSString *)tech callback:(nonnull RCTResponseSenderBlock)callback)
|
||||
{
|
||||
if (sessionEx == nil) {
|
||||
callback(@[@"you need to call registerTagEvent first", [NSNull null]]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (techRequestCallback == nil) {
|
||||
techRequestType = tech;
|
||||
techRequestCallback = callback;
|
||||
} else {
|
||||
callback(@[@"duplicate tech request, please call cancelTechnologyRequest to cancel previous one", [NSNull null]]);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(cancelTechnologyRequest:(nonnull RCTResponseSenderBlock)callback)
|
||||
{
|
||||
techRequestType = nil;
|
||||
techRequestCallback = nil;
|
||||
callback(@[]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(registerTagEvent: (NSString *)alertMessage options:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
||||
{
|
||||
if (@available(iOS 11.0, *)) {
|
||||
@ -295,8 +172,6 @@ RCT_EXPORT_METHOD(unregisterTagEvent: (nonnull RCTResponseSenderBlock)callback)
|
||||
if (session != nil) {
|
||||
[session invalidateSession];
|
||||
session = nil;
|
||||
techRequestType = nil;
|
||||
techRequestCallback = nil;
|
||||
callback(@[]);
|
||||
} else {
|
||||
callback(@[@"Not even registered", [NSNull null]]);
|
||||
@ -306,56 +181,5 @@ RCT_EXPORT_METHOD(unregisterTagEvent: (nonnull RCTResponseSenderBlock)callback)
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(registerTagEventEx: (NSString *)alertMessage options:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
||||
{
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if (sessionEx == nil) {
|
||||
sessionEx = [[NFCTagReaderSession alloc] initWithPollingOption:NFCPollingISO14443 delegate:self queue:dispatch_get_main_queue()];
|
||||
sessionEx.alertMessage = alertMessage;
|
||||
[sessionEx beginSession];
|
||||
callback(@[]);
|
||||
} else {
|
||||
callback(@[@"Duplicated registration", [NSNull null]]);
|
||||
}
|
||||
} else {
|
||||
callback(@[@"Not support in this device", [NSNull null]]);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(unregisterTagEventEx: (nonnull RCTResponseSenderBlock)callback)
|
||||
{
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if (sessionEx != nil) {
|
||||
[sessionEx invalidateSession];
|
||||
sessionEx = nil;
|
||||
techRequestType = nil;
|
||||
techRequestCallback = nil;
|
||||
callback(@[]);
|
||||
} else {
|
||||
callback(@[@"Not even registered", [NSNull null]]);
|
||||
}
|
||||
} else {
|
||||
callback(@[@"Not support in this device", [NSNull null]]);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getTag: (nonnull RCTResponseSenderBlock)callback)
|
||||
{
|
||||
if (@available(iOS 13.0, *)) {
|
||||
if (sessionEx != nil) {
|
||||
if (sessionEx.connectedTag) {
|
||||
NSDictionary* rnTag = [self getRNTag:sessionEx.connectedTag];
|
||||
callback(@[[NSNull null], rnTag]);
|
||||
return;
|
||||
}
|
||||
callback(@[@"Not connected", [NSNull null]]);
|
||||
} else {
|
||||
callback(@[@"Not even registered", [NSNull null]]);
|
||||
}
|
||||
} else {
|
||||
callback(@[@"Not support in this device", [NSNull null]]);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@ -7,39 +7,11 @@ function decode(data) {
|
||||
var languageCodeLength = (data[0] & 0x3F), // 6 LSBs
|
||||
languageCode = data.slice(1, 1 + languageCodeLength),
|
||||
utf16 = (data[0] & 0x80) !== 0; // assuming UTF-16BE
|
||||
|
||||
if (utf16) {
|
||||
return util.bytesToString(data.slice(languageCodeLength + 1));
|
||||
}
|
||||
|
||||
var utf8 = "";
|
||||
var i, len, c;
|
||||
var char2, char3;
|
||||
|
||||
len = data.length;
|
||||
i = 0;
|
||||
while(i < len) {
|
||||
c = data[i++];
|
||||
switch(c >> 4)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
|
||||
utf8 += String.fromCharCode(c);
|
||||
break;
|
||||
case 12: case 13:
|
||||
char2 = data[i++];
|
||||
utf8 += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
|
||||
break;
|
||||
case 14:
|
||||
char2 = data[i++];
|
||||
char3 = data[i++];
|
||||
utf8 += String.fromCharCode(((c & 0x0F) << 12) |
|
||||
((char2 & 0x3F) << 6) |
|
||||
((char3 & 0x3F) << 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TODO need to deal with UTF in the future
|
||||
// console.log("lang " + languageCode + (utf16 ? " utf16" : " utf8"));
|
||||
|
||||
return utf8;
|
||||
return util.bytesToString(data.slice(languageCodeLength + 1));
|
||||
}
|
||||
|
||||
// encode text payload
|
||||
|
||||
@ -2,31 +2,29 @@
|
||||
// Copyright 2013 Don Coleman
|
||||
//
|
||||
|
||||
// Thanks to
|
||||
// https://weblog.rogueamoeba.com/2017/02/27/javascript-correctly-converting-a-byte-array-to-a-utf-8-string/
|
||||
// https://gist.github.com/joni/3760795
|
||||
function _utf8ArrayToStr(data) {
|
||||
const extraByteMap = [1, 1, 1, 1, 2, 2, 3, 0];
|
||||
var count = data.length;
|
||||
var str = "";
|
||||
var str = '',
|
||||
i;
|
||||
|
||||
for (var index = 0; index < count;) {
|
||||
var ch = data[index++];
|
||||
if (ch & 0x80) {
|
||||
var extra = extraByteMap[(ch >> 3) & 0x07];
|
||||
if (!(ch & 0x40) || !extra || ((index + extra) > count))
|
||||
return null;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
var value = data[i];
|
||||
|
||||
ch = ch & (0x3F >> extra);
|
||||
for (; extra > 0; extra -= 1) {
|
||||
var chx = data[index++];
|
||||
if ((chx & 0xC0) != 0x80)
|
||||
return null;
|
||||
if (value < 0x80) {
|
||||
str += String.fromCharCode(value);
|
||||
} else if (value > 0xBF && value < 0xE0) {
|
||||
str += String.fromCharCode((value & 0x1F) << 6 | data[i + 1] & 0x3F);
|
||||
i += 1;
|
||||
} else if (value > 0xDF && value < 0xF0) {
|
||||
str += String.fromCharCode((value & 0x0F) << 12 | (data[i + 1] & 0x3F) << 6 | data[i + 2] & 0x3F);
|
||||
i += 2;
|
||||
} else {
|
||||
// surrogate pair
|
||||
var charCode = ((value & 0x07) << 18 | (data[i + 1] & 0x3F) << 12 | (data[i + 2] & 0x3F) << 6 | data[i + 3] & 0x3F) - 0x010000;
|
||||
|
||||
ch = (ch << 6) | (chx & 0x3F);
|
||||
}
|
||||
str += String.fromCharCode(charCode >> 10 | 0xD800, charCode & 0x03FF | 0xDC00);
|
||||
i += 3;
|
||||
}
|
||||
|
||||
str += String.fromCharCode(ch);
|
||||
}
|
||||
|
||||
return str;
|
||||
@ -34,35 +32,31 @@ function _utf8ArrayToStr(data) {
|
||||
|
||||
// https://stackoverflow.com/questions/18729405/how-to-convert-utf8-string-to-byte-array
|
||||
function _toUTF8Array(str) {
|
||||
var utf8 = [];
|
||||
for (var i=0; i < str.length; i++) {
|
||||
var charcode = str.charCodeAt(i);
|
||||
if (charcode < 0x80) utf8.push(charcode);
|
||||
else if (charcode < 0x800) {
|
||||
utf8.push(0xc0 | (charcode >> 6),
|
||||
0x80 | (charcode & 0x3f));
|
||||
}
|
||||
else if (charcode < 0xd800 || charcode >= 0xe000) {
|
||||
utf8.push(0xe0 | (charcode >> 12),
|
||||
0x80 | ((charcode>>6) & 0x3f),
|
||||
0x80 | (charcode & 0x3f));
|
||||
}
|
||||
// surrogate pair
|
||||
else {
|
||||
i++;
|
||||
// UTF-16 encodes 0x10000-0x10FFFF by
|
||||
// subtracting 0x10000 and splitting the
|
||||
// 20 bits of 0x0-0xFFFFF into two halves
|
||||
charcode = 0x10000 + (((charcode & 0x3ff)<<10)
|
||||
| (str.charCodeAt(i) & 0x3ff));
|
||||
utf8.push(0xf0 | (charcode >>18),
|
||||
0x80 | ((charcode>>12) & 0x3f),
|
||||
0x80 | ((charcode>>6) & 0x3f),
|
||||
0x80 | (charcode & 0x3f));
|
||||
}
|
||||
var out = [], p = 0;
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
var c = str.charCodeAt(i);
|
||||
if (c < 128) {
|
||||
out[p++] = c;
|
||||
} else if (c < 2048) {
|
||||
out[p++] = (c >> 6) | 192;
|
||||
out[p++] = (c & 63) | 128;
|
||||
} else if (
|
||||
((c & 0xFC00) == 0xD800) && (i + 1) < str.length &&
|
||||
((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {
|
||||
// Surrogate Pair
|
||||
c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);
|
||||
out[p++] = (c >> 18) | 240;
|
||||
out[p++] = ((c >> 12) & 63) | 128;
|
||||
out[p++] = ((c >> 6) & 63) | 128;
|
||||
out[p++] = (c & 63) | 128;
|
||||
} else {
|
||||
out[p++] = (c >> 12) | 224;
|
||||
out[p++] = ((c >> 6) & 63) | 128;
|
||||
out[p++] = (c & 63) | 128;
|
||||
}
|
||||
return utf8;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
function stringToBytes(string) {
|
||||
return _toUTF8Array(string);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-nfc-manager",
|
||||
"version": "1.2.4",
|
||||
"version": "1.2.6",
|
||||
"description": "A NFC module for react native.",
|
||||
"main": "NfcManager",
|
||||
"repository": {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user