Compare commits

...

6 Commits
master ... v1

Author SHA1 Message Date
Richie
92e82b34f9
Merge pull request #201 from poison/feature/typescript
🏷️ fixed typings (synced with the code)
2019-10-07 16:29:02 +08:00
Nicolas Van Eenaeme
d960a3d708 🏷️ fixed typings (synced with the code) 2019-10-02 23:02:23 +02:00
Richie
6b4f682623 1.2.6 2019-09-21 22:03:30 +08:00
Richie
4c82d1be69 fix utf8 bug in ndef-text / ndef-util 2019-09-21 22:02:59 +08:00
Richie
2a7b04c531 v1.2.5 2019-09-10 21:35:58 +08:00
Richie
67173c0893 v1: remove iOS 13 related codes to avoid xcode 10 build issues 2019-09-10 21:32:13 +08:00
8 changed files with 169 additions and 472 deletions

View File

@ -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
// -------------------------------------

View File

@ -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
View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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": {