Air - How to use a native extension in Flash CS5.5? - air

I would like to use a native extension (ANE) in Flash CS5.5. I saved the ANE as a SWC and added it to my project, but this error keeps on coming up:
Error message:
1172: Definition qnx.events:InvokeEvent could not be found.
ActionScript:
import qnx.events.InvokeEvent;
import qnx.invoke.*;
//NOTE: THIS MUST BE THE FIRST THING SET IN YOUR APPLICATION CONSTRUCTOR
InvokeManager.invokeManager.addEventListener(InvokeEvent.INVOKE, onInvoke );
function onInvoke( event:InvokeEvent ):void
{
if( InvokeManager.invokeManager.startupMode == InvokeStartupMode.INVOKE )
{
//invoked as an application/target.
var mydata:InvokeRequest = InvokeManager.invokeManager.startupRequest;
}
else if( InvokeManager.invokeManager.startupMode == InvokeStartupMode.VIEWER )
{
//invoked as a viewer
var myotherdata:InvokeViewerRequest = InvokeManager.invokeManager.startupViewerRequest;
}
else
{
//launched by the pressing on the icon on the home screen.
}
}
Is there anything missing in the code?
I never used an ANE/SWC before, so any help is welcome.
I uploaded the files. Would be great if someone could take a look at them:
Download: http://www.sendspace.com/file/gjqp1w
Thanks.

How are you packaging the application? This error generally means the extension is not being packaged correctly with the application.
I believe from CS5.5 you still have to use the adt command line to specify the location of the ANE file when packaging, so if you're just exporting from CS5.5 you'll get this error.
Something like the following:
adt -package
-target ipa-ad-hoc
-storetype pkcs12 -keystore ../AppleDistribution.p12
-provisioning-profile AppleDistribution.mobileprofile
myApp.ipa
myApp-app.xml
myApp.swf icons Default.png
-extdir extensionsDir
Additionally you have to make sure you add the extensions id to you application descriptor:
<extensions>
<extensionID>com.extension.id</extensionID>
</extensions>

Related

React-native packager configuration - How to include .zip file in bundle?

My problem:
I have a zip file that contains a firmware update for my company's device
I want to be able to access it using react-native-fs with the code below
.
export function readAssetFile(name) {
if(Platform.OS === 'ios') {
return RNFS.readFile(`${RNFS.MainBundlePath}/assets/data/${name}`);
} else {
return RNFS.readFileAssets(`raw/${name}`, 'base64');
}
}
My project structure looks like:
ProjectDir
android
data
image1.png
image2.png
firmwarefile.zip
ios
The android branch works, because I added a build step in my .gradle to copy firmwarefile.zip into ProjectDir/android/app/src/main/assets/raw. So I can call readAssetFile('firmwarefile.zip'), and it returns the data.
On iOS, all the image files (Image1.png, Image2.png) are included in MyProject.app/assets/data/ without me having to do anything, but the zip file that sits beside them is not.
Looking into the actual packager code (from the metro project), it seems (based on metro/src/defaults.js) that zip files aren't included by default by the packager, but the packager can be configured to include other file types. But I can't find any documentation for how I'd go about doing that configuring.
Sorry for what feels like a really simple question, but I've been trying to get this zip included in my bundle for ~4 hours now. I'm resorting to manually putting in console.logs and error-throws to trace things inside metro to try and find where I should be sending in my config.
Versions:
React-native: 0.55.3
Metro: 0.30.2
This is a hack, but it gets it done:
Convert your zip binary to a base64 string
Stick it in a .js file, a la module.exports = "<your base64 data goes here>"
In your file that needs the zip file, use import myZipFileAsBase64 from './hacky-base64-file.js';
Here's a quick script to make your base64 files:
var fs = require('fs');
function prepareZip(file, outJs) {
const b64 = fs.readFileSync(file, 'base64');
fs.writeFileSync(outJs, `module.exports = ${JSON.stringify(b64)};`);
}
prepareZip('./data/myFirmware.zip', './hacky-base64-file.js');

Flow saying "Required module not found" for <Image> sources

We have an existing React Native project (version 0.22.2) and I'm trying to set up the Flow type checker (version 0.23) on certain files. However, Flow is giving a lot of errors for the require()s calls we're using for <Image> sources. For example, we have this code in one of our components in Header.js:
<Image source={require('./images/nav.png')} style={styles.navIcon} />
Which React Native handles fine and it works. However, Flow seems to be trying to treat the require() as a regular module require and not finding it, and giving errors like this:
Header.js:30
30: <Image source={require('./images/nav.png')} style={styles.navIcon} />
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ./images/nav.png. Required module not found
How can I tell Flow to stop giving these errors? I've tried adding .*/images/.* to the [ignore] section of my .flowconfig, but that doesn't change anything.
You can use the module.name_mapper.extension option in .flowconfig. For example,
[options]
module.name_mapper.extension= 'png' -> '<PROJECT_ROOT>/ImageSourceStub.js.flow'
which will map any module name ending in .png to an ImageSourceStub module, as if instead of writing require('./foo.png') you had written require('./path/to/root/ImageSourceStub').
In ImageSourceStub.js.flow you can do
const stub = {
uri: 'stub.png'
};
export default stub; // or module.exports = stub;
so that Flow knows that require('*.png') returns a {uri: string}.
See also the Advanced Configuration docs.
I don't have a real answer besides to say that flow in React Native seems really dodgy today and it would not surprise me if flow just simply doesn't support this usage at all, but I'd love to be totally surprised!
Personally, as a work-around, I'd just add a higher level component and ignore the flow errors in that file.
// Picture.js
// (No #flow tag at top of file)
const Picture = ({ source }) => (
<Image source={require(source)} />
)
Then use <Picture source="my/path/pic.jpg" /> instead.
Had same issue, for JPG files, solved with this .flowconfig
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
module.name_mapper='^[./a-zA-Z0-9$_-]+\.png$' -> 'RelativeImageStub'
module.name_mapper='^[./a-zA-Z0-9$_-]+\.jpg$' -> 'RelativeImageStub'

How to offer files for download?

I have a problem. In my sencha touch application I have list items like .pdf, .png, ... If user taps on one of them file should be download on his mobile device.
How can I do this? I have no idea :-)
Thanks for help.
You can use phonegap file api to download files, If you are using sencha touch 2.3 or above just follow the bellow steps.
Install phonegap in sencha project by executing following command at the project root and this command creates phonegap folder inside project root.
sencha phonegap init
You need to install two phonegap plugins to work with file api by executing two following commands inside phonegap folder.
$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-file.git
$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-file-transfer.git
Now you can start working file api in sencha touch and you can follow below code i used for one of my project.
If you want to download file, first you need to read device file system and then using file system you can download files.
getFileSystem : function(){
var me =this;
Ext.Viewport.mask({
xtype: 'loadmask',
message: 'Downloading files..'
});
var extfs = Ext.create("Ext.device.filesystem.Cordova");
extfs.requestFileSystem({
type: window.PERSISTENT,
size: 1024 * 1024,
success: function(fSys) {
window.fileSys = fSys;
Ext.Viewport.unmask();
me.fileDownload("myfolder/filename.png","http://someurl");
},
failure: function(error){
alert(error);
Ext.Viewport.unmask();
}
});
}
I am passing fileLocation(location you want to store file inside phone) & url in above function.
fileDownload: function(fileLocation,Url){
Ext.Viewport.mask({
xtype: 'loadmask',
message: 'Downloading files..'
});
var me = this;
var fSys = window.fileSys
if(fSys){
var file = Ext.create('Ext.device.filesystem.FileEntry',
fSys.fs.root.toURL() + fileLocation, fSys);
file.download({
source: Url,
success: function(entry){
Ext.Msg.alert('SUCCESS', 'Image successfully downloaded');
Ext.Viewport.unmask();
},
failure: function(error){
Ext.Msg.alert('ERROR', 'Download failed');
Ext.Viewport.unmask();
}
});
}
}
Now can see image at internalMemorycard/myfolder/filename.png
Sencha docs
Ext.device.filesystem.Cordova
Ext.device.filesystem.FileEntry
If you are using sencha touch 2.2 or below only change is instead of using sencha class you need to directly use phonegap api.
For reading file system & File download follow phonegap documentation.
Sencha basically operates over HTML, CSS & JS. Rather than doing this using Sencha just implement it similar to how you would do it in HTML then integrate into your application.
Eg: Homework
Try this
document.location= url;
Try the following code it may help you.
var newWindow = window.open('filepath', '_self'); //were filepath is the path of file with extension.

Worklight showIOS7StatusBar

I am running the Worklight IDE Version 6.0.0.20130926-1933. I have tried disabling the ios7 top status bar as per the Worklight technote found here:
http://www-01.ibm.com/support/docview.wss?uid=swg27039574
I have set in the initOptions.js file
var wlInitOptions = {
// # Should application automatically attempt to connect to Worklight Server on application start up
// # The default value is true, we are overriding it to false here.
connectOnStartup : true,
showIOS7StatusBar : false,
However, when I load my app I still see the statusBar displayed on my iOS7 devices. Is there some other change I need to make to my code? Note: I don't have access to xCode and I am using a company tool to build the ipa file. Thanks!
JT
You can also change it in the {AppName}-Info.plist in your IOS native directory
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarHidden</key>
<true/>
Did you do a build of the application in Worklight and in Xcode and you still see it?
Anyway, you can add to your CSS file:
#wl_ios7bar {
display:none;
}
and you will not see it anymore.
What you can do is in the main.css or equivalent file of the iPhone environment specifically, override the application css with the code like:
.ios7
{
margin-top: 17px !important;
}
And in the main.js or equivalent file of the iPhone environment,
override the js file with the code like:
function wlEnvInit(){
wlCommonInit(); // Environment initialization code goes here
if (parseFloat(window.device.version) >= 7.0) {
$("body").addClass("ios7");
}
}
You can also check the reference link

Adobe AIR ANE default platform can't find method name

I have an Adobe AIR ANE that builds and runs fine on iOS. I want to run this app in the AIR simulator, but with an actionscript version of the native ANE.
Reading the docs, it seems like a default profile would be perfect for this.
I added the default profile to the extension.xml file. I added a AS implementation of the native interface to every project in my workspace. I have made methods static/not static, etc. I have tried everything but I keep getting this error:
ArgumentError: Error #3500: The extension context does not have a method with the name
I am at a complete loss. Here are the relevant files:
extension.xml
<extension xmlns="http://ns.adobe.com/air/extension/3.1">
<id>com.novel.analytics.ext.ApsalarNativeInterface</id>
<versionNumber>0.0.0</versionNumber>
<platforms>
<platform name="iPhone-ARM">
<applicationDeployment>
<nativeLibrary>libApsalarNativeInterface.a</nativeLibrary>
<initializer>ExtInitializer</initializer>
<finalizer>ExtFinalizer</finalizer>
</applicationDeployment>
</platform>
<platform name="default">
<applicationDeployment/>
</platform>
</platforms>
</extension>
My AS implementation:
package com.novel.analytics.ext
{
public class ApsalarNativeInterface
{
public function ApsalarNativeInterface()
{
}
private static function initExtension():void
{
}
public function initApsalar(apiKey:String, secret:String):void
{
}
}
}
my native interface:
package com.novel.analytics
{
import flash.external.ExtensionContext;
public class ApsalarInterface
{
private static const EXTENSION_ID : String = "com.novel.analytics.ext.ApsalarNativeInterface";
private var context : ExtensionContext;
public function ApsalarInterface()
{
this.context = ExtensionContext.createExtensionContext(EXTENSION_ID, null);
}
public function initApsalar(apiKey:String, secret:String):void
{
context.call("initApsalar", apiKey, secret);
}
}
}
Here is my adt command line (library.swf is the lib that contains the two above files:
/Applications/Adobe\ Flash\ Builder\ 4.6/sdks/4.6.0/bin/adt -package -target ane ../../$PRODUCT_NAME.ane extension.xml -swc NativeInterface.swc -platform iPhone-ARM -C . library.swf -platform default -C . library.swf
Like I said, I am at a complete loss on this one.
Sorry for the much delayed response, but I think you'd benefit from checking out this wonderful tutorial:
http://www.digitalprimates.net/author/nweber/2012/04/10/building-a-native-extension-part-3/
Based on your code snippets above, it looks like you're trying to define your pure-ActionScript implementation in a different package, with a different classname. Seems you actually want to use the same package+class+method names and just store it in a different library (so it's bundled as its own SWF). Then you tell ADT how to bundle things.