I forked the plugin nativescript-nfc and implemented the NFC write feature for iOS, it works well when using NativeScript 6. But if I upgrade the plugin to 7 or 8, the writing doesn't work, NFCNDEFTag.prototype.queryNDEFStatusWithCompletionHandler is always undefined.
The implementation of writing NFC is shown below.
readerSessionDidDetectTags(
session: NFCNDEFReaderSession,
tags: NSArray<NFCNDEFTag> | NFCNDEFTag[]
): void {
const tag = tags[0];
session.connectToTagCompletionHandler(tag, (error: NSError) => {
console.log("connectToTagCompletionHandler");
if (error) {
console.log(error);
session.invalidateSessionWithErrorMessage("Error connecting to tag.");
this.errorCallback(error);
return;
}
const ndefTag: NFCNDEFTag = new interop.Reference<NFCNDEFTag>(
interop.types.id,
tag
).value;
try {
NFCNDEFTag.prototype.queryNDEFStatusWithCompletionHandler.call(
ndefTag,
(status: NFCNDEFStatus, number: number, error: NSError) => {
console.log("queryNDEFStatusWithCompletionHandler");
if (status == NFCNDEFStatus.NotSupported) {
var errMessage = "Tag is not NDEF compliant.";
session.invalidateSessionWithErrorMessage(errMessage);
} else if (status === NFCNDEFStatus.ReadOnly) {
var errMessage = "Tag is read only.";
session.invalidateSessionWithErrorMessage(errMessage);
} else if (status === NFCNDEFStatus.ReadWrite) {
const ndefMessage = this._owner.get().message;
NFCNDEFTag.prototype.writeNDEFCompletionHandler.call(
ndefTag,
ndefMessage,
(error: NSError) => {
if (error) {
console.log(error);
session.invalidateSessionWithErrorMessage("Write failed.");
this.errorCallback(error);
} else {
if (
ndefMessage.records[0].typeNameFormat ==
NFCTypeNameFormat.Empty
) {
session.alertMessage = "Erased data from NFC tag.";
} else {
if (this.options.writeHint) {
session.alertMessage = this.options.writeHint;
}
this.resultCallback(NfcHelper.ndefToJson(ndefMessage));
}
session.invalidateSession();
}
}
);
}
}
);
} catch (e) {
session.alertMessage = "error";
}
});
}
I'm not sure if I implement it in the correct way for NativeScript 7 or 8, but at least it works on 6, I actually don't believe it's a bug in the NativeScript across both 7 and 8. We used to live with 6 for a long time just for using this plugin, but really need to upgrade to 7 or 8 for the sake of other features.
Any help, suggestion or comment would be highly appreciated!
Below is the repo and branches for different NativeScript versions.
Repo: https://github.com/nordsense/nativescript-nfc
Branch feature/upgrade-nativescript: This is NativeScript 8, only read works
Branch nordsense: This is NativeScript 6 and both read and write work
You can use the demo project to test, set ndef listener is for read and write Text is for write
I managed to get it working on NS 8. Referring to the below code snippet, if NFCNDEFTag.prototype is accessed before line 2, like the code in line 1 or by using console.dir(NFCNDEFTag.prototype), line 3 will dump the correct data that belongs to the correct protocol NFCNDEFTag, the remaining code also works well ; if commenting out line 1, line 3 will dump incorrect data which belongs to some other protocols/objects like NSKeyValueCoding and UIAccessibilityAction. I still don't know why this happens, feel like a NativeScript issue, I filed an issue here https://github.com/NativeScript/NativeScript/issues/9609
I rebuilt the plugin and published the package here https://github.com/cloudhx/nativescript-plugins
readerSessionDidDetectTags(session: NFCNDEFReaderSession, tags: NSArray<NFCNDEFTag> | NFCNDEFTag[]): void {
const prototype = NFCNDEFTag.prototype; // Line 1
const tag = (<NSArray<NFCNDEFTag>>tags).firstObject; // Line 2
console.dir(NFCNDEFTag.prototype); // Line 3
session.connectToTagCompletionHandler(tag, (error: NSError) => {
console.log('connectToTagCompletionHandler');
if (error) {
console.log(error);
session.invalidateSessionWithErrorMessage('Unable to connect to tag.');
this.errorCallback(error);
return;
}
const ndefTag: NFCNDEFTag = new interop.Reference<NFCNDEFTag>(interop.types.id, tag).value;
try {
NFCNDEFTag.prototype.queryNDEFStatusWithCompletionHandler.call(ndefTag, (status: NFCNDEFStatus, number: number, error: NSError) => {
console.log('queryNDEFStatusWithCompletionHandler');
// Code omitted for brevity
Related
I have a project built on ionic 4.2.1. The project is developed for ios and uses audio playing. First I tried #ionic-native/media lib for tracking statuses (I actually need only two of them - 'started' and 'stoped'), and tested in browser it all worked good, but on ios there is a big problem.
At first time I play audio there are no callback at all.
The second one - just after I clicked the button two callback are fired at the same time - start and stop.
After that, the second case is repeated all the next times. Audio is playing properly all the time though.
I tried to use cordova-plugin-media itself, without #ionic-native/media, but the problem is in cordova plugin and nothing changed.
Tested on ios 11.x and 12.1
ionic 4.2.1
cordova-plugin-media ^5.0.1
#ionic-native/media ^4.17.0
with pure cordova-media-plugin
this.platform.ready().then(() => {
let file = new (<any>window).Media(path,
() => {
console.log("playAudio():Audio Success")
},
(err) => {
console.log("playAudio():Audio Error: " + err)
},
(status) => {
this.addConsole('status=' + status)
if (status === 1) {
this.isAudioActive = true
this.addConsole('played')
}
if (status === 4) {
this.addConsole('stoped')
this.isAudioActive = false
}
}
)
this.file = file
this.file.play()
})
with #ionic-native/media
let file: MediaObject = this.media.create(path);
this.file = file
this.addConsole('play')
this.file.play()
this.file.onStatusUpdate.subscribe(
(status) => {
this.addConsole('status=' + status)
if (status === 1) {
this.isAudioActive = true
this.addConsole('played')
}
if (status === 4) {
this.addConsole('stoped')
this.isAudioActive = false
}
}
)
Hope since cordova-plugin-media callback methods anything has changed
Any help will be appreciated
I am trying to use react-native-fbsdk in my react-native app. It was working fine untill yesterday. But, today it gives a weird error stating RCTJSONStringify() encountered the following error: Invalid type in JSON write (NSURL).
RN v0.42.0
Here is my code:
_fbAuth(error, result) {
if (error) {
console.log("error");
alert("login has error: " + result.error);
} else if (result.isCancelled) {
console.log("login cancelled");
alert("login is cancelled.");
} else {
AccessToken.getCurrentAccessToken().then((data) => {
console.log("login success");
console.log(data.accessToken.toString());
let accessToken = data.accessToken;
alert(data.accessToken.toString());
const responseInfoCallback = (error, result) => {
if (error) {
console.log(error);
} else {
console.log(result);
}
}
const infoRequest = new GraphRequest(
'/me',
{
accessToken: accessToken,
parameters: {
fields: {
string: 'email,name,first_name,middle_name,last_name'
}
}
},
responseInfoCallback
);
// Start the graph request.
new GraphRequestManager().addRequest(infoRequest).start();
});
}
}
render() {
console.log("in new render");
return (
<View style={styles.container}>
<LoginButton
publishPermissions={["publish_actions"]}
onLoginFinished={this._fbAuth}
onLogoutFinished={() => alert("logout.")}/>
</View>
);
}
The error information printed in debugger:
I get the above error while calling the graphAPI in the function responseInfoCallback. Any ideas what is happening ?
Update 1:
This error happens only when remote debugger is turned on!! Else it is not happening. But without remote debugger, I cannot proceed with developing the app. Are there any other methods to see log statements of react-native app other than remote debugger ?
Update 2:
The RCTJSONStringify() error happens only behind proxy. And also https fetch calls does not work under proxy. I tested in an open network, it works fine. I guess, it is to add some proxy information to RN app. I think it is related to APP transport security
If you turn the debugger off, you can see the proper error in the XCode console. Access it from Xcode menu View/Debug Area/Activate console, if it's not enabled automatically.
I just migrate my Xamarin iOS app to Xamarin Unified using the Migration Tool. The code below was working fine and the app didn’t have any error or warning before the migration. After the migration I got the following errors Error-1 PresentViewController doesn’t accept the MediaPickerController object as a parameter. Error-2 mediaPickerController doesn’t have the method DismissViewController
protected void TakePicture()
{
MediaPickerController mediaPickerController = mediaPicker.GetTakePhotoUI(new StoreCameraMediaOptions
{
Name = this.PictureName + ".jpg",
DefaultCamera = CameraDevice.Rear
});
if (!mediaPicker.IsCameraAvailable)
{
ShowUnsupported();
}
//Error-1
PresentViewController(mediaPickerController, true, null);
try
{
mediaPickerController.GetResultAsync().ContinueWith(t =>
{
BTProgressHUD.Show("Processing");
// Dismiss the UI yourself
//Error-2
mediaPickerController.DismissViewController(true, () =>
{
if (t.IsCanceled || t.IsFaulted)
{
BTProgressHUD.Dismiss();
return;
}
MediaFile file = t.Result;
FinishedPickingMedia(file);
BTProgressHUD.Dismiss();
});
}, TaskScheduler.FromCurrentSynchronizationContext());
}
catch (Exception ex)
{
Insights.Report(ex, ReportSeverity.Error);
}
}
You need to update your Xamarin component that contains MediaPickerController to the latest version compatible with Xamarin.iOS unified code!
The latest version of Xamarin.Mobile is 0.7.6. Double check with your project if your are using an older one.
I'm getting a 409 on PUT, POST and DELETE actions.
I have successfully created a database and have PUT one document successfully ONCE. I have tried local and "normal" documents. I haven't spend any focus on revisions but think it has to do with this. I only want to save and update this one JSON string in my app - thats it.
It's like I have created this one document to stay forever :-)
Will sample code help? I'm really only using Angular's $http.
On a side note: I need a save mechanism in phonegap that is html5 cache-clear resistent.
You need to check if your document exists first before you update it. that's why it worked the first time and not the second.
config.db.get( "myDocumentID", function(error, doc) {
if (error) {
if (error.status == 404) {
//document does not exist insert it
config.db.put( "myDocumentID", myDocument, function(error,ok) {
if(error) { alert( "error" + JSON.stringify( error ) } else {
alert("success");
}
} )
} else {
alert( "error:" + JSON.stringify( error ) )
}
} else {
//update your document
doc.my_new_key = "value";
config.db.put( "myDocumentID", doc, function(error, ok) {
if( error ) { alert( "error:" + JSON.stringify( error ) ) } else {
alert("success");
}
} );
}
} )
I get an exception when i try to upgrade my indexedDB database with a higher version then the browser currently has,
but the funny part abort is that, it gets upgraded. Is this by design or have i done something wrong.
I got very inspired from the dart sample Todo, so my code ended up looking like this.
void open_db(String DB_name, int Version, String Store_Name){
var request = window.indexedDB.open(DB_name, Version);
request.on.success.add((e) => _onDbOpened(request.result));
request.on.error.add((e) => print("Error opening db"));
request.on.upgradeNeeded.add((e) => _onUpgradeNeeded(request.transaction, Store_Name));
}
void _onDbOpened(IDBDatabase db){
_db = db;
print("DB opened");
}
void _onUpgradeNeeded(IDBTransaction changeVersionTransaction, String Store_Name){
changeVersionTransaction.on.error.add((e) => print("Error upgrading db"));
changeVersionTransaction.on.complete.add((e) => print("Success upgrading db"));
changeVersionTransaction.db.createObjectStore(Store_Name);
}
When I run this with version=4 and the browser only have version=3, then it jumps to _onUpgradeNeeded as expected, but I get an IDBDatabaseException with message: "ConstraintError: DOM IDBDatabase Exception 4".
So where is it I go wrong?
Thanks for your question!
You may need to check if the store exists first.
if (db.objectStoreNames.indexOf(storeName) == -1) {
db.createObjectStore(storeName);
}
Here is some code to update your IndexedDB database, using Dart. Note, this compensates for the two ways to upgrade (an old way that Chrome used, and the new way that Firefox and newer versions of Chrome use)
_openDb(afterOpen()) {
var request = window.indexedDB.open(DB_NAME, VERSION);
if (request is IDBOpenDBRequest) {
// New upgrade protocol. FireFox 15, Chrome 24, hopefully IE10.
request.on.success.add(expectAsync1((e) {
db = e.target.result;
afterOpen();
}));
request.on.upgradeNeeded.add((e) {
guardAsync(() {
_createObjectStore(e.target.result);
});
});
request.on.error.add(fail('open'));
} else {
// Legacy setVersion upgrade protocol. Chrome < 23.
request.on.success.add(expectAsync1((e) {
db = e.target.result;
if (db.version != '$VERSION') {
var setRequest = db.setVersion('$VERSION');
setRequest.on.success.add(
expectAsync1((e) {
_createObjectStore(db);
var transaction = e.target.result;
transaction.on.complete.add(
expectAsync1((e) => afterOpen()));
transaction.on.error.add(fail('Upgrade'));
}));
setRequest.on.error.add(fail('setVersion error'));
} else {
afterOpen();
}
}));
request.on.error.add(fail('open'));
}
}
_createObjectStore(db) {
try {
// Nuke object store if it already exists.
db.deleteObjectStore(STORE_NAME);
}
on IDBDatabaseException catch(e) { } // Chrome
on DOMException catch(e) { } // Firefox
db.createObjectStore(STORE_NAME);
}
Note, this code is from this test: http://code.google.com/p/dart/source/browse/trunk/dart/tests/html/indexeddb_3_test.dart