When the push notification is pushed from server side, the default Urban Airship message center is displayed on the app using
UAirship.defaultMessageCenter().display()
and tapping on the messages displays the message details. The content of message details page is an HTML payload which is part of the push notification triggered by server side. I need to call a swift function when a button on the WebView is tapped. Since we don't have access to the WKWebView presented in the view controller which is provided by UA, I am not able to call any swift function from javascript. Please suggest.
Consider using Urban Airship's actions framework which can be used to trigger native code from a message center webview.
First, define your custom UAAction.
let swiftAction = UAAction(block: { (args: UAActionArguments, handler: UAActionCompletionHandler) -> Void in
print("Action is performing with: \(args)")
handler(UAActionResult.empty())
})
Then register the action after takeOff.
UAirship.shared().actionRegistry.registerAction(swiftAction, name:"swift_action")
You can then modify your HTML content to run the action from your message. Use the runAction method on the UAirship object which is inserted in the message center webview.
UAirship.runAction("swift_action", "arguments", function() {return true})
Additional resources:
Urban Airship Javascript Interface
Custom Actions
Related
Please help me to find the way how to navigate back on webviewclient using back button on android.
I am using Xamarin hybrid app using Razor views,
I am using loadDataWithBaseURL method to find each method and move on that page, like following:
if (method == "SignIn")///sign-in.html
{
var template = new SignIn();
var page = template.GenerateString();
webView.LoadDataWithBaseURL("file:///android_asset/", page, "text/html", "UTF-8", null);
}
The above code I am using in ShouldOverrideUrlLoading(WebView webView, string Url)
the URL is passed as "hybrid:SignIn?"
Now back navigation is not working either on using OnBackPressed() method, or using OnKeyDown()
I also tried, WebBackForwardList, I can see in debug mode te current items in it , but no any url to go back on.
The url is always "about:blank"
and page is showing blank on GoBack() method.
When downloading a file, I'm not getting an on.progress callback so am not able to display a progress bar. Works fine for file uploading.
What am I doing wrong?
Thanks,
Pete
BoxFile *boxFile = (BoxFile *)boxObject;
[boxFile previewWithCallbacks:^(id<BoxOperationCallbacks> on)
{
on.progress(^(NSNumber *ratio)
{
// update progress bar
});
on.after(^(BoxCallbackResponse response)
{
if (response == BoxCallbackResponseSuccessful)
{
We have the same problem but we manage to get the answer for this, although we did not try to implement it yet.
"Currently, the expected method to get progress on file downloads is
to register your object as an observer of the download queue ([Box
registerObserverForDownloadQueue:self];) and then to extend the
BoxObserver protocol and implement any of these callback methods that
you are interested in:
- (void)downloadDidBeginForItem:(BoxID *)itemID;
- (void)downloadDidProgressForItem:(BoxID *)itemID bytesDownloaded:(NSUInteger)bytes;
- (void)downloadDidCompleteForItem:(BoxID *)itemID withResponse:(BoxCallbackResponse)response;
- (void)downloadDidCompleteForAllItems;
Please remember to remove your object from the observers before you
expect your object to be deallocated because observers are currently
retained."
This question is no moot since Box have a completely new iOS SDK (v2.0), which does have the proper progress callbacks.
In CakePHP 2.x, i use this path to show results to visitors
example.com/my/showResults
*getSomeResults* function makes some Twitter API requests which lasts generally 5-25 seconds.
I need to put a "loading div" into my view.
But i couldn't decide the structure.
The examples i found by google shows, when user clicks a button, an AJAX request is made and results are shown in that div.
But in my case, when the page is loaded that request will be done asynchronously, when results are available, they will be shown in another div.
Regarding to my file structure below, where should i put AJAX request?
Should i remove lines in showResults method and run another action when AJAX request will succeed?
I would be happy if you can recommend a structure for, show results when AJAX request is succeed in CakePHP 2 way. Thank you
// appcontroller.php
class AppController extends Controller {
function getSomeResults() {
// make some http requests to twitter API
}
}
// mycontroller.php
class MyController extends AppController {
public function showResults() {
$data=$this->getSomeResults();
$this->set('data', $data);
$this->render('myelement');
}
}
// myelement.ctp
<div id="before">
Please wait loading..
</div>
<div id="results" style="display: none">
<?php echo $data ?>
</div>
// myscript.js
$(document).ready(function() {
$("#results").hide();
setTimeout('$("#results").show();',8000);
}
It looks to me, like you are grabbing the web service and then handing off the data through cakephp. Meaning it does not look like you are using ajax at all.
Since you appear to be using jquery already I would recommend that you connect to twitter using jquery's ajax method [http://api.jquery.com/jQuery.ajax/]. So not only would you remove showResults(), but you would also remove getSomeResults(). If you needed this info to be refreshed you could set this ajax call into a function and call it on a regular interval.
Unless you had the div for loading at the top of the page, you could use jquery to change the results div from now loading to the data.
Just my 2 cents.
I am trying to create an ad for a website. When someone clicks on the ad, it is supposed to redirect them to a website, and register the click with google analytics.
I have done this with the following script:
import flash.external.ExternalInterface;
movieClip_3.addEventListener(MouseEvent.CLICK, onClick);
function onClick(event:MouseEvent):void {
trace("hi");
ExternalInterface.call("console.log", "test");
//ExternalInterface.call("_gaq._trackPageview", "/vpv/annoncer/[firmanavn.dk]");
navigateToURL(new URLRequest("http://www.google.com"), "_blank");
}
When i run this using preview->flash and i click on the surface, (where there is a big red square called movieClip_3) It opens the webpage. However when i try to publish as html, the big red square shows, but nothing happens on click. Not even console.log. I have tried setting allowscriptaccess = always but that does not change anything.
Can you guys help me? Any help is appreciated.
Security problems?
Developers should validate all URLs before passing them to this
function.
For local content running in a browser, calls to the navigateToURL()
method that specify a "javascript:" pseudo-protocol (via a URLRequest
object passed as the first parameter) are only permitted if the SWF
file and the containing web page (if there is one) are in the
local-trusted security sandbox. Some browsers do not support using the
javascript protocol with the navigateToURL() method. Instead, consider
using the call() method of the ExternalInterface API to invoke
JavaScript methods within the enclosing HTML page.
source: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/package.html#navigateToURL()
EDIT:
Since javascript is not permitted out of the sandbox, you can try with ExternalInterface:
ExternalInterface.call("javascript_functionname", "mypage.html");
In the parameters for publishing:
'allowScriptAccess', 'always',
You can only test this on your server not locally.
I'd suggest double checking the security settings (right click on flash container->Global Settings-> Advanced -> Trusted Location Settings). Also make sure your html file contains the javascript function you're trying to execute and look for blocked pop-up notifications in the browser. Maybe you just don't allow pop-ups to run.
In Google Chrome's extension developer section, it says
The HTML pages inside an extension
have complete access to each other's
DOMs, and they can invoke functions on
each other. ... The popup's contents
are a web page defined by an HTML file
(popup.html). The popup doesn't need
to duplicate code that's in the
background page (background.html)
because the popup can invoke functions
on the background page
I've loaded and tested jQuery, and can access DOM elements in background.html with jQuery, but I cannot figure out how to get access to DOM elements in popup.html from background.html.
can you discuss why you would want to do that? A background page is a page that lives forever for the life time of your extension. While the popup page only lives when you click on the popup.
In my opinion, it should be refactored the other way around, your popup should request something from the background page. You just do this in the popup to access the background page:
chrome.extension.getBackgroundPage()
But if you insist, you can use simple communication with extension pages with sendRequest() and onRequest. Perhaps you can use chrome.extension.getViews
I understand why you want to do this as I have run into the problem myself.
The easiest thing I could think of was using Google's method of a callback - the sendRequest and onRequest methods work as well, but I find them to be clunky and less straightforward.
Popup.js
chrome.extension.getBackgroundPage().doMethod(function(params)
{
// Work with modified params
// Use local variables
});
Background.html
function doMethod(callback)
{
if(callback)
{
// Create/modify params if needed
var params;
// Invoke the callback
callback(params);
}
}
As other answers mention, you can call background.js functions from popup.js like so:
var _background = chrome.extension.getBackgroundPage();
_background.backgroundJsFunction();
But to access popup.js or popup.html from background.js, you're supposed to use the messages architecture like so:
// in background.js
chrome.runtime.sendMessage( { property: value } );
// in popup.js
chrome.runtime.onMessage.addListener(handleBackgroundMessages);
function handleBackgroundMessages(message)
{
if (message.property === value)
// do stuff
}
However, it seems that you can synchronously access popup.js from background.js, just like you can synchronously access the other way around. chrome.extension.getViews can get you the popup window object, and you can use that to call functions, access variables, and access the DOM.
var _popup = chrome.extension.getViews( { type: 'popup' } )[0];
_popup.popupJsFunction();
_popup.document.getElementById('element');
_popup.document.title = 'poop'
Note that getViews() will return [] if the popup is not open, so you have to handle that.
I'm not sure why no one else mentioned this. Perhaps there's some pitfalls or bad practices to this that I've overlooked? But in my limited testing in my own extension, it seems to work.