public static object Log(Context c, object[] args)
{
foreach (var arg in args) debug_log arg;
return null;
}
[Foreign(Language.Java)]
public static extern(Android) void ALog(string message)
@{
android.util.Log.d("ForeignCodeExample", message);
@}
If I do this (on a real Android device):
MyModule.Log('Hello from JS!")
I get “Hello from JS!” in the log as expected.
However, if I do:
MyModule.ALog('Hello from JS!")
I just get:
Source line: Nfc.ALog("Hello from JavaScript!");
( 1606): JS stack trace: TypeError: MyModule.ALog is not a function
( 1606): at Object._tempMethod (Pages/SplashPage.js:6:5)
( 1606): in Fuse.Reactive.JavaScript.DiagnosticSubject<Pages/SplashPage.js:6>
To me it seems the problem then is that you haven’t exposed the function to JS. Similarly how you have the AddMember for Log, you should add one for ALog:
Well that’s because there isn’t, if you’re running it on local preview. Foreign code is very well aware of the platform it is being run on, so you need to take care about defining what a method does in every case.
Here’s a complete, working example that you can use like so:
<App>
<JavaScript>
var Nfc = require("Nfc");
Nfc.ALog("ohai");
</JavaScript>
</App>
And the Uno code, with helpful comments:
using Fuse;
using Fuse.Scripting;
using Uno.UX;
using Uno.Compiler.ExportTargetInterop;
[UXGlobalModule]
public class Nfc : NativeModule
{
static readonly Nfc _instance;
public Nfc()
{
if (_instance != null) return;
_instance = this;
Resource.SetGlobalKey(_instance, "Nfc");
AddMember(new NativeFunction("ALog", (NativeCallback)ALog));
}
// this is the "proxy" method that dispatches calls to whatever the platform-specific implementation is
// native functions exposed to JS need to return an object, so we define the return type like such, and return null in this case
public static object ALog(Context c, object[] args)
{
ALogImpl(args[0].ToString());
return null;
}
// this is called from the "proxy" method when the app is not running on mobile targets (local preview, for one)
public static extern(!Mobile) void ALogImpl(string message)
{
debug_log message;
}
// this is called from the "proxy" method when the app is running on Android
[Foreign(Language.Java)]
public static extern(Android) void ALogImpl(string message)
@{
android.util.Log.d("ForeignCodeExample", message);
@}
// this is called from the "proxy" method when the app is running on iOS
[Foreign(Language.ObjC)]
public static extern(iOS) void ALogImpl(string message)
@{
NSLog(@"%@", message);
@}
}
Take a look at this library to see how more complex (but still relatively simple) platform-aware things can be implemented.