Mapbox integration

Hi,

Is there any way to integrate Mapbox (mapbox.com) IOS SDK and Android SDK into Fuse?

Regards

Hi!

Yes, but no unfortunatly. It can be integrated, but you need the new features for native UI coming (I hope) in the next major release. Then the code would look something like this:

extern(iOS) class iOSMapBox : Fuse.Controls.Native.iOS.View
{
    public iOSMapBox() : base(Create()) { }
    static ObjC.Object Create()
    @{
        // ObjC code
        // return the MapBox UIView object
    @}
}

public class MapBox : Fuse.Controls.Panel
{
    protected override IView CreateNativeView()
    {
        if defined(iOS)
            return new iOSMapBox();

        else return base.CreateNativeView();
    }
}

Then you can use <MapBox /> in UX :slight_smile:

Hi, any news on the new features being integrated to support Mapbox? thx

Subscribe

Resolved

Anyone tried this and would it be possible to integrate it now? Also, before I make an attempt. Would this allow me to overlay the map view with UX or does it suffer from the same problem of NativeViewHost that always sits on top?

Hi!

This has been possible for a while now. Since the MapBox API exposes a native view on Android and iOS you need to use a <NativeViewHost /> to host it in UX.

You are correct in that native views inside a NativeViewHost are always ontop of GL, but there are various ways to deal with this. Most UX features works inside NativeViewHost, so you could write all of the UX, include the MapBox in a NativeViewHost. The other way to deal with this is to put a <GraphicsView /> on top of your MapBox, this will allow you to us GL ontop of native.

I’m trying to integrate MapBox into FuseTools.

So I’ve followed this tutorial https://github.com/YugoCode/SwiftFuse and was able to call Swift code via ObjC.

Next I’ve created new method which should return MapBox view 200x200 for now. I’ve used code suggested above as a reference.

Here is what I got

extern(iOS) class iOSMapBox : Fuse.Controls.Native.iOS.View
    {
        public iOSMapBox() : base(Create()) { }
        static ObjC.Object Create()
        @{
            Text *test = [[Test alloc] init];
            return [test getMapBox];
        @}
    }

    public class MapBox : Fuse.Controls.Panel
    {
        protected override IView CreateNativeView()
        {
            if defined(iOS)
                return new iOSMapBox();

            else return base.CreateNativeView();
        }
    }

Here is my Swift File: where helloFromSwift method works just fine

import UIKit
import Mapbox

@objc class Test: NSObject {
    func helloFromSwift() {
        print("Hello from Swift :)")
    }
    
    func getMapBox() -> MGLMapView {
        let url = URL(string: "mapbox://styles/mapbox/streets-v10")
        let frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        let mapView = MGLMapView(frame: frame, styleURL: url)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        mapView.setCenter(CLLocationCoordinate2D(latitude: 59.31, longitude: 18.06), zoomLevel: 9, animated: false)
        return mapView
    }
}

Here is my repository with all source code: https://github.com/poul-kg/SwiftFuse

The problem is when I’m trying to rebuild FusePreview I’m getting this kind of errors:

fuse preview -t=iOS
Fuse 1.1.0 (build 13808)
Configuring
MainView.ux(20): E8001: Data type not found: MapBox
/Users/pavel/Fuse/SwiftFuse/MainView.ux(20,1): Error E8001: Data type not found: MapBox
MainView.ux(20): E8001: Could not resolve type 'MapBox'
/Users/pavel/Fuse/SwiftFuse/MainView.ux(20,1): Error E8001: Could not resolve type 'MapBox'

Build completed in 2.69 seconds
    2 errors
fuse: Failed to compile project

The problem is that your MapBox class is inside your SwiftHello class, so the UX compiler can’t find it by the name <MapBox />. Move it out as a public class in the root namespace, for example

Thank you Anders

now I can build and run local preview without errors.
I’m trying to return MapBox object from my Test class.
I’ve tested this Test class and it’s working, it can print log messages and return int values.
So I’ve added another method to that Test class which should return MapBox UIView object
but I’m getting ObjC compiler error that it can not find my Test class. What should I do/read next?

Updated Repo: https://github.com/poul-kg/SwiftFuse

Error Message

Hi poul,

‘Unknown type name’ sounds like a missing include. You may want to look into ForeignInclude which is mentioned in the ‘java’ & ‘objc’ sections below here https://www.fusetools.com/docs/native-interop/foreign-code#external-source-files

Unfortunately I wasn’t able to make it working with Swift/Objc etc.

So I decided to make it in ObjC only, to eliminate issues which can relate to Swift to ObjC bridging.
Also I decided to try to use MapKit map for now, and if it works then I can move to MapBox.
But I have same errors as before. I can not figure out what I’m missing.

FuseMapKit.unoproj

{
  "RootNamespace":"",
  "Packages": [
    "Fuse",
    "FuseJS"
  ],
  "Includes": [
    "*"
  ],
  "iOS": {
    "PList": {
        "NSLocationAlwaysUsageDescription": "Shows your location on the map and helps improve OpenStreetMap."
    }
  }
}

MainView.ux

<App>
    <StackPanel>
        <Button Text="Hello Fuse" />
        <NativeViewHost>
            <MapKitMap />
        </NativeViewHost>
    </StackPanel>
</App>

MapKitMap.uno

using Uno;
using Uno.Collections;
using Fuse;
using Fuse.Scripting;
using Fuse.Controls;
using Fuse.Controls.Native;
using Uno.Compiler.ExportTargetInterop;
using Uno.UX;

[Require("Source.Include", "MapKit/MapKit.h")]
extern(iOS) class iOSMapKitMap : Fuse.Controls.Native.iOS.View
{
    public iOSMapKitMap() : base(Create()) { }
    static ObjC.Object Create()
    @{
        UIView *mvc = [[UIView alloc] init];
        MKMapView* mv = [[MKMapView alloc] init];
        mv.frame = mvc.bounds;
        mv.translatesAutoresizingMaskIntoConstraints = YES;
        mv.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        [mvc addSubView:mv];
        return mvc;
    @}
}

public class MapKitMap : Fuse.Controls.Panel
{
    protected override IView CreateNativeView()
    {
        if defined(iOS)
            return new iOSMapKitMap();

        else return base.CreateNativeView();
    }
}

Error messages