Integrating Chartboost SDK

Hey all!

For our new project we need to work with some ad networks, Chartboost especially. While waiting for updates on foreign code from the Fuse team I decided to try integrating Chartboost SDK. It took almost an hour to get it to work including reading the complete documentation and skimming through the code samples. I am a complete noob to Fuse, so I’m sharing this with you so can let me know if I’m doing something really absurd :slight_smile:

I started with a native Javascript module which makes foreign calls to Chartboost iOS SDK.

using Fuse;
using Fuse.Scripting;
using Fuse.Reactive;
using Uno.Compiler.ExportTargetInterop;

public class ChartboostModule : NativeModule
{
    public ChartboostModule()
    {
        AddMember(new NativeFunction("Log", (NativeCallback)Log));
        AddMember(new NativeFunction("Register", (NativeCallback)Register));
        AddMember(new NativeFunction("ShowInterstitial", (NativeCallback)ShowInterstitial));
    }

    static object Log(Context c, object[] args)
    {
        foreach (var arg in args) {
            string msg = (string)arg;
            Log_iOS(msg);
        }
        return null;
    }

    static object Register(Context c, object[] args)
    {
        Log_iOS("Registering Chartboost...");
        Register_iOS();
        return null;
    }

    static object ShowInterstitial(Context c, object[] args)
    {
        Log_iOS("Showing interstitial");
        ShowInterstitial_iOS();
        return null;
    }

    [Foreign(Language.ObjC)]
    public static extern(iOS) void Log_iOS(string message)
    @{
        NSLog(@"%@", message);
    @}

    [Foreign(Language.ObjC)]
    public static extern(iOS) void Register_iOS()
    @{
        uAppDelegate delegate = (uAppDelegate )[[UIApplication sharedApplication] delegate];        [Chartboost startWithAppId:@"4f21c409cd1cb2fb7000001b" appSignature:@"92e2de2fd7070327bdeb54c15a5295309c6fcd2d" delegate:[[UIApplication sharedApplication] delegate]];    @}

    [Foreign(Language.ObjC)]
    public static extern(iOS) void ShowInterstitial_iOS()
    @{
        [Chartboost showInterstitial:CBLocationHomeScreen];    @}
}

Here’s the ux calling the module:

<App Theme="Basic" Background="#eeeeeeff">
    <ChartboostModule ux:Global="ChartboostModule" />
    <JavaScript>
        var Log = require("ChartboostModule").Log;
        var Register = require("ChartboostModule").Register;
        var ShowInterstitial = require("ChartboostModule").ShowInterstitial;
        Log("App started.");
        Register();

        module.exports = {
            showAdClick: function(args) {
                Log("Show ads!");
                ShowInterstitial();
            }
        }
    </JavaScript>

    <Button Text="Show Ad" Height="45" Alignment="Bottom" Margin="20,80" Clicked="{showAdClick}" /></App>

Also you need to add Fuse.Scripting to .unoproj.

Build the project for iOS and open the project in XCode.

Add the StoreKit and Chartboost frameworks to the project. At this point if you compile the project you’ll get reference errors because of the missing imports in the auto-generated module file, _root.ChartboostModule.m, named after our native JS module.

I added the following imports:

#import <Chartboost/Chartboost.h>
#import <Chartboost/CBAnalytics.h>
#import <Chartboost/CBInPlay.h>
#include <Uno-iOS/AppDelegate.h>
#import <StoreKit/StoreKit.h>

Question: I couldn’t find a way to include these imports statements in Fuse documentation, maybe I missed it. If there’s a way, please let me know.

_

I imported Uno-iOS/AppDelegate.h because in the native JS module I’m accessing the uAppDelegate to pass it to Chartboost initializer as a delegate:

_

uAppDelegate delegate = (uAppDelegate *)[[UIApplication sharedApplication] delegate]; [Chartboost startWithAppId:@"4f21c409cd1cb2fb7000001b" appSignature:@"92e2de2fd7070327bdeb54c15a5295309c6fcd2d" delegate:(id<ChartboostDelegate>)delegate];

Another question : I also couldn’t find a way to intercept application didFinishLaunchingWithOptions. If there’s any please let me know :slight_smile:

Now if your run the app from XCode and click the Show Ad button, everything will (hopefully) work fine.

Fuse is great!

Hello! Very awesome. I’m glad you’re enjoying Fuse so far!

There are some attributes that will help you with imports and frameworks:

The following will add an import to the source file that is generated from MyClass:

[Require("Source.Import", "SomeHeader.h")]
class MyClass ...

The following will add an include:

[Require("Source.Include", "SomeHeader.h")]

To automatically include frameworks in the generated Xcode project, you can use:

[Require("Xcode.FrameworkDirectory", "@('relativeFrameworkDir':Path)")]
[Require("Xcode.Framework", "@('relativeFrameworkDir/someFramework.framework':Path)")]

Use Xcode.EmbeddedFramework for frameworks that should be embedded in the app.

These attributes can also be put on methods.

Hook yourself up to Uno.Platform2.Application.EnteringForeground which corresponds to didFinishLaunchingWithOptions on iOS:

Uno.Platform2.Application.EnteringForeground += MyEnteringForeground;
...

void MyEnteringForeground(Uno.Platform2.ApplicationState state)
{
    ...
}

Hey Olle!

After having a second look at the documentation, I don’t know how I missed those attributes :slight_smile:

The manuel process in the XCode will be eliminated with the help of these attributes.

Thank you very much for the help!

Hello again,

I’m looking for a way to the the same for Android. I assume the process will largely be identical but I couldn’t even find a way to include 3rd party Java libraries in the project. Any help is greatly appreciated.

Thanks!

BUMP

Hey again!

We have recently published an example that uses a third-party SDK on both iOS and Android here. In particular, you can include a jar file using uxl like we do here.

We’re also working on supporting Gradle and aars, so you can expect this to become more streamlined in the future.

Hi, It’s so cool that we can use third party’s sdk in Fuse.

Here I have another question: I’m trying to use a third party’s sdk(like this: http://www.agora.io), which it will use a view controller to put it’s video inside it. Are there any suggestion on this? Can I setup a panel in my mainview.ux file and use it as a view controller in my [Foreign Code] section?

Thanks!

Hi

Where you able to implement the Fuse Wrapper for the Chartboost’s watch-to-get-reward ads?

regards,
Mateusz

Just a quick clarification didFinishLaunchingWithOptions is not equivalent to EnteringForeground, that was a mistake from our side.

If you want an event that is called once as the app starts use: Fuse.Platform.Lifecycle.Started

If you want an event that is called every time the app moves from background to foreground use: Fuse.Platform.EnteringForeground

I’d advise against using the Uno.Platform2.Application events as we are making big changes to the lower levels of Uno right now and I don’t want you to get bitten by those :slight_smile: Instead use Fuse.Platform.Lifecycle

Fuse.Platform.Lifecycle.Started += OnStarted;     

static void OnStarted(Fuse.Platform.ApplicationState newState)
{
   debug_log "And here we are!";
}

To be honest though, if you are writing Uno you are probably making a module for JS right? In that case you will have a class like this:

[UXGlobalModule]
public sealed class Foo : NativeModule
{
    public Foo()
    {
        ..stuff..
    }
}

You can just put your initialization code in the constructor. We will then make sure the constructor is called as the app starts and you don’t have to worry about hooking/unhooking to uno events.

I hope this helps :slight_smile: