I'm creating a HarmonyOS Wearable app using the JS Framework and I want to use the vibrator. The watch definitely has a vibrator because I can feel it when I use the scroll weel in the settings app.
So I requested the system_grant ohos.permission.VIBRATE permission in the config.json file as described here
"module": {
...
"reqPermissions": [
{
"name": "ohos.permission.VIBRATE",
"reason": "Make vibrates"
}
]
...
}
Then it should be simple to use the imported vibrator like this
import vibrator from '#system.vibrator';
export default {
// ...
onShow() {
console.log("VIBRATOR");
vibrator.vibrate({
mode : "long",
success: () => console.debug("Vibrator Success"),
fail : (data, code) => console.log("Vibrator handle fail, data = ${data}, code = ${code}"),
complete : () => console.debug("Vibrator Complete")
});
}
// ...
}
I do get the VIBRATOR log in HiLog but non of the other logs in the vibrator callbacks nor does the device vibrate.
Does anyone know what I'm doing wrong?
EDIT:
I noticed a bunch of error logs after the VIBRATOR log. I cant figure out what they mean so I'm posting them here.
D 03B00/JSApp: app Log: VIBRATOR
E 03900/Ace: [<private> (<private>)] ace Log: [JS Framework] Failed to invoke the event handler of "viewappear" on div (_root):
E 03900/Ace: TypeError: value has no property
E 03900/Ace: [<private> (<private>)] Qjs FireAsyncEvent FAILED !! jsCall: <private>
E 03900/Ace: [<private> (<private>)] [DUMP] <private>
E 03900/Ace: [<private> (<private>)] <private>
The JS API document is written based on the wearables. The standard usage of smart devices is as follows:
vibrator.vibrate({
mode: "short"
});
or
vibrator.vibrate();
Related
Following the apple documentation and Branch's documentation here, I have set up a working universal link in my Nativescript Angular (iOS) app. But, how do I parse the link when the app opens?
For example, when someone opens the app from the link, I want to have my app read the link so it can go to the correct page of the app.
There is some helpful code in this answer, but I keep getting errors with it. This could be bc the code is written in vanilla JS and I am not translating it into Angular correctly. The use of "_extends" and "routeUrL" both cause errors for me.
And the Nativescript url-handler plugin does not seem to work without further code.
So, after setting up the universal link, and installing the nativescript url-handler plugin, I have entered the following in app.module.ts:
const Application = require("tns-core-modules/application");
import { handleOpenURL, AppURL } from 'nativescript-urlhandler';
declare var NSUserActivityTypeBrowsingWeb
if (Application.ios) {
const MyDelegate = (function (_super) {
_extends(MyDelegate, _super);
function MyDelegate() {
_super.apply(this, arguments);
}
MyDelegate.prototype.applicationContinueUserActivityRestorationHandler = function (application, userActivity) {
if (userActivity.activityType === NSUserActivityTypeBrowsingWeb) {
this.routeUrl(userActivity.webpageURL);
}
return true;
};
MyDelegate.ObjCProtocols = [UIApplicationDelegate];
return MyDelegate;
})(UIResponder);
Application.ios.delegate = MyDelegate;
}
...
export class AppModule {
ngOnInit(){
handleOpenURL((appURL: AppURL) => {
console.log('Got the following appURL = ' + appURL);
});
}
}
The trouble seems to be mostly with "_extends" and "_super.apply". For example, I get this error:
'NativeScript encountered a fatal error: TypeError: undefined is not an object (evaluating '_extends')
EDIT: Note that the nativescript-urlhandler plugin is no longer being updated. Does anyone know how to parse universal links with Nativescript?
I have figured out a method to get this working:
The general idea is to use the iOS App Delegate method: applicationContinueUserActivityRestorationHandler.
The syntax in the Nativescript documentation on app delegates did not work for me. You can view that documentation here.
This appears to work:
--once you have a universal link set up, following documentation like here, and now you want your app to read ("handle") the details of the link that was tapped to open the app:
EDIT: This code sample puts everything in one spot in app.module.ts. However, most of the time its better to move things out of app.module and into separate services. There is sample code for doing that in the discussion here. So the below has working code, but keep in mind it is better to put this code in a separate service.
app.module.ts
declare var UIResponder, UIApplicationDelegate
if (app.ios) {
app.ios.delegate = UIResponder.extend({
applicationContinueUserActivityRestorationHandler: function(application, userActivity) {
if (userActivity.activityType === NSUserActivityTypeBrowsingWeb) {
let tappedUniversalLink = userActivity.webpageURL
console.log('the universal link url was = ' + tappedUniversalLink)
}
return true;
}
},
{
name: "CustomAppDelegate",
protocols: [UIApplicationDelegate]
});
}
NOTE: to get the NSUserActivity/Application Delegate stuff to work with typescript, I also needed to download the tns-platforms-declarations plugin, and configure the app. So:
$ npm i tns-platforms-declarations
and
references.d.ts
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
The above code works for me to be able to read the details of the tapped universal link when the link opens the app.
From there, you can determine what you want to do with that information. For example, if you want to navigate to a specific page of your app depending on the details of the universal link, then I have found this to work:
app.module.ts
import { ios, resumeEvent, on as applicationOn, run as applicationRun, ApplicationEventData } from "tns-core-modules/application";
import { Router } from "#angular/router";
let univeralLinkUrl = ''
let hasLinkBeenTapped = false
if (app.ios) {
//code from above, to get value of the universal link
applicationContinueUserActivityRestorationHandler: function(application, userActivity) {
if (userActivity.activityType === NSUserActivityTypeBrowsingWeb) {
hasLinkBeenTapped = true
universalLinkUrl = userActivity.webpageURL
}
return true;
},
{
name: "CustomAppDelegate",
protocols: [UIApplicationDelegate]
});
}
#ngModule({...})
export class AppModule {
constructor(private router: Router) {
applicationOn(resumeEvent, (args) => {
if (hasLinkBeenTapped === true){
hasLinkBeenTapped = false //set back to false bc if you don't app will save setting of true, and always assume from here out that the universal link has been tapped whenever the app opens
let pageToOpen = //parse universalLinkUrl to get the details of the page you want to go to
this.router.navigate(["pageToOpen"])
} else {
universalLinkUrl = '' //set back to blank
console.log('app is resuming, but universal Link has not been tapped')
}
})
}
}
You can use the nativescript-plugin-universal-links plugin to do just that.
It has support for dealing with an existing app delegate so if you do have another plugin that implements an app delegate, both of them will work.
Here's the usage example from the docs:
import { Component, OnInit } from "#angular/core";
import { registerUniversalLinkCallback } from "nativescript-plugin-universal-links";
#Component({
selector: "my-app",
template: "<page-router-outlet></page-router-outlet>"
})
export class AppComponent {
constructor() {}
ngOnInit() {
registerUniversalLinkCallback(ul => {
// use the router to navigate to the screen
});
}
}
And the callback will receive a ul (universal link) param that looks like this
{
"href": "https://www.example.com/blog?title=welcome",
"origin": "https://www.example.com",
"pathname": "/blog",
"query": {
"title": "welcome"
}
}
Disclaimer: I'm the author of the plugin.
I disabled all plugins on the server except point-of-view.
fastify.register(require('point-of-view'), {
engine: {
nunjucks: require('nunjucks')
},
templates: 'server/views',
includeViewExtension: true
})
The handler is calling the view function.
reply.view('/v1/main', {
nonce: nanoid(1),
token: nanoid(1)
})
The complete error message is:
{"level":50,"time":1547208496144,"msg":"client error","pid":16013,"hostname":"jer-ryzentwo","err":{"type":"Error","message":"Parse Error","stack":"Error: Parse Error","bytesParsed":0,"code":"HPE_INVALID_METHOD","rawPacket":{"type":"Buffer","data":[22,3,1,2,0,1,0,1,105,3,3,167,247,206,59,236,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}},"v":1}
{"level":50,"time":1547208496145,"msg":"client error","pid":16013,"hostname":"jer-ryzentwo","err":{"type":"Error","message":"Parse Error","stack":"Error: Parse Error","bytesParsed":0,"code":"HPE_INVALID_METHOD","rawPacket":{"type":"Buffer","data":[10,0,1,0,2,2,20]}},"v":1}
I cannot pinpoint the source of this issue.
Any idea what and why a HPE_INVALID_METHOD error is being generated?
When subscribing to appsync using amplify using API.graphql(graphqlOperation(subscription)); the subscription works for a while, but the I get socket closed error.
CONSOLE LOG [native code]: {
"[INFO] 24:12.893 MqttOverWSProvider": {
"errorCode": 8,
"errorMessage": "AMQJS0008I Socket closed.",
"uri": "wss://<uri>
The same subscription works in the appsync console without any issue and I get events as long as the subscription is running, but stops after around 2 mins on device.
code involved
let cs = await this.subscriptionService.appSubscriptions();
this.sbscriptions = this.cs.subscribe({
next: data => {
console.dir(data);
},
error: error => console.dir(JSON.stringify(error)),
close: () => console.log("closed")
});
This part of code throws no error, and the error shown above is only visible when setting LOG_LEVEL = DEBUG
NOTE : The subscription does work for a while before this error shows up, and in that time I can see all the events that I trigger from console.
I am writing an ionic 2 application, and want to cache images.
After long searching on the web I found these references:
https://gist.github.com/ozexpert/d95677e1fe044e6173ef59840c9c484e
https://github.com/chrisben/imgcache.js/blob/master/js/imgcache.js
I implemented the given solution, but i see that the ImgCache module does not behave as expected - the ImgCache.isCached callback is never called.
Any idea or other good solution for caching images in ionic 2?
======== UPDATE ==========
Here is the directive code I use:
import { Directive, ElementRef, Input } from '#angular/core';
import ImgCache from 'imgcache.js';
#Directive({
selector: '[image-cache]'
})
export class ImageCacheDirective {
constructor (
private el: ElementRef
) {
// init
}
ngOnInit() {
// This message is shown in console
console.log('ImageCacheDirective *** ngOnInit: ', this.el.nativeElement.src);
this.el.nativeElement.crossOrigin = "Anonymous"; // CORS enabling
ImgCache.isCached(this.el.nativeElement.src, (path: string, success: any) => {
// These message are never printed
console.log('path - '+ path);
console.log('success - '+ success);
if (success) {
// already cached
console.log('already cached so using cached');
ImgCache.useCachedFile(this.el.nativeElement);
} else {
// not there, need to cache the image
console.log('not there, need to cache the image - ' + this.el.nativeElement.src);
ImgCache.cacheFile(this.el.nativeElement.src, () => {
console.log('cached file');
// ImgCache.useCachedFile(el.nativeElement);
});
}
});
}
}
In app.nodule.es I do:
import { ImageCacheDirective } from '../components/image-cache-directive/image-cache-directive';
and then in home.html:
<img src="http://localhost/ionic-test/img/timeimg.php" image-cache>
It's late but probably this is the solution:
1. Install cordova FileTransfer:
ionic plugin add cordova-plugin-file-transfer --save
2. Init ImgCache when the deviceready event of cordova fires. In src/app/app.component.ts add these methods (or integrate them with your initializeApp() method - this method comes up with a default project start):
initImgCache() {
// activated debug mode
ImgCache.options.debug = true;
ImgCache.options.chromeQuota = 100 * 1024 * 1024; // 100 MB
ImgCache.init(() => { },
() => { console.log('ImgCache init: error! Check the log for errors'); });
}
initializeApp() {
this.platform.ready().then(() => {
this.initImgCache();
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
StatusBar.styleDefault();
Splashscreen.hide();
});
}
Another option is to use a dedicated cache manager for ionic. instead of implementing everything on your own.
Here are 2 options :
1. A generic cache implementation :https://github.com/Nodonisko/ionic-cache
2. This one is better for images: https://github.com/BenBBear/ionic-cache-src
EDIT:
This is not a "link only" answer.. it tells the user to use a ready made implementations instead of trying to implement from scratch.
Version 2.0.0
I'm trying to use the parse object as per the docs: https://trigger.io/modules/parse/current/docs/index.html
forge.parse.push.subscribe(...)
The error I am getting: Uncaught TypeError: Cannot read property 'push' of undefined which. So the parse property is not set. I have heard that this is a problem where the config is not set correctly, but setting parse up via the toolkit doesn't seem to have any effect and the parse property is still not set.
My config:
{
...
"modules": {
...
"parse": {
"version": "2.0",
"config": {
"clientKey": "xxx",
"applicationId": "xxx"
}
}
...
}
...
}
Forge signature:
{
button: Object
config: Object
document: Object
enableDebug: function (){h.debug=true;h.priv.call("internal.showDebugWarning", },null,null);h.priv.call("internal.hideDebugWarning",{},null,null)}
event: Object
file: Object
geolocation: Object
internal: Object
is: Object
logging: Object
message: Object
notification: Object
prefs: Object
reload: Object
request: Object
tabs: Object
tools: Object
__proto__: Object
}
It looks like you're trying to use Parse on a non-mobile target (probably web). Parse push notifications are only available on Android and iOS.
Try below.
forge.partners.parse.push.subscribe("offers",
function () {
forge.logging.info("subscribed to offers push notifications!");
},
function (err) {
forge.logging.error("error subscribing to offers notifications: "+
JSON.stringify(err));
});