user5956451
user5956451

Reputation:

How to use PositionService in Gluon Mobile on iOS?

I want to use the PositionService of Gluon Mobile on iOS. I have written a small sample app that runs on desktop, providing (as intended) fake location changes, and on Android. On the iOS simulator, however, the listener is not called. Here is the relevant part of the code:

public class BasicView extends View {

        private static final Logger LOGGER = Logger.getLogger(BasicView.class.getName());

        final Label label;

        public BasicView(String name) {
            super(name);
            label = new Label();
            VBox controls = new VBox(15.0, label);
            controls.setAlignment(Pos.CENTER);
            setCenter(controls);
            // get current position
            Platform p = PlatformFactory.getPlatform();
            PositionService ps = p.getPositionService();
            outputPos(ps.getPosition());
            ps.positionProperty().addListener((obs, oldPos, newPos) -> {
                LOGGER.log(Level.INFO, "\nobs: {0}\noldPos: {1}\nnewPos: {2}",
                        new Object[]{obs, oldPos, newPos});
                outputPos(newPos);
            });
        }

        private void outputPos(Position p) {
            if (p != null) {
                label.setText(String.format("We are currently here: %f %f",
                        p.getLatitude(),
                        p.getLongitude()));
            }
        }

        @Override
        protected void updateAppBar(AppBar appBar) {
            appBar.setNavIcon(MaterialDesignIcon.MENU.button(e -> System.out.println("Menu")));
            appBar.setTitleText("Basic View");
            appBar.getActionItems().add(MaterialDesignIcon.SEARCH.button(e -> System.out.println("Search")));
        }

    }

I have added libCharm.a, but as far as I can tell it should not be needed here.

I also found hints on updating the info.plist as follows, but with or without it the listener is not called.

    <key>UIRequiredDeviceCapabilities</key>
    <array>
            <string>armv7</string>
            <string>location-services</string>
    </array>
    ...
    <key>NSLocationWhenInUseUsageDescription</key>
            <string>Location is required to find out where you are</string>
    <key>NSLocationAlwaysUsageDescription</key>
            <string>Location is required to find out where you are</string>

The only output regarding location I see is this:

Aug 27, 2016 1:37:31 PM com.gluonhq.charm.down.ios.IOSPositionService <init>
INFO: Location Manager configured with desiredAccuracy 10.00 and distanceFilter 100.00

Aug 27, 2016 1:37:31 PM com.gluonhq.charm.down.ios.IOSPositionService <init>
INFO: Telling LocationManager to start updating location.

I guess I am missing something here... As always, any help is greatly appreciated.

EDIT: Sorry, forgot build.gradle:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.0.8'
    }
}

apply plugin: 'org.javafxports.jfxmobile'

repositories {
    jcenter()
    maven {
        url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
    }
}

mainClassName = 'com.thomaskuenneth.gluon.positionservicedemo.PositionServiceDemo'

dependencies {
    compile 'com.gluonhq:charm:3.0.0'

    androidRuntime 'com.gluonhq:charm-android:3.0.0'
    iosRuntime 'com.gluonhq:charm-ios:3.0.0'
    desktopRuntime 'com.gluonhq:charm-desktop:3.0.0'
}

jfxmobile {
    android {
        manifest = 'src/android/AndroidManifest.xml'
        compileSdkVersion = 23
    }
    ios {
        infoPList = file('src/ios/Default-Info.plist')
        forceLinkClasses = [
                'com.gluonhq.**.*',
                'io.datafx.**.*',
                'javax.annotations.**.*',
                'javax.inject.**.*',
                'javax.json.**.*',
                'org.glassfish.json.**.*'
        ]
    }
}

Upvotes: 8

Views: 496

Answers (1)

user5956451
user5956451

Reputation:

I followed the advice of José Pereda and upgraded to Gluon Mobile 4. After the following steps I saw position changes in the iPad Simulator. So, I suggest anyone having the same difficulties as I mentioned in my question, try upgrading. That solved my issue.

Update build.gradle as follows:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'org.javafxports:jfxmobile-plugin:1.1.1'
    }
}

apply plugin: 'org.javafxports.jfxmobile'

repositories {
    jcenter()
    maven {
        url 'http://nexus.gluonhq.com/nexus/content/repositories/releases'
    }
}

mainClassName = 'com.thomaskuenneth.gluon.positionservicedemo.PositionServiceDemo'

dependencies {
    compile 'com.gluonhq:charm:4.0.1'
}

jfxmobile {
    downConfig {
        version '3.0.0'
        plugins 'display', 'lifecycle', 'statusbar', 'storage', 'position'
    }
    android {
        manifest = 'src/android/AndroidManifest.xml'
        androidSdk = "/Users/thomas/Library/Android/sdk"
        compileSdkVersion = 24
    }
    ios {
        infoPList = file('src/ios/Default-Info.plist')
        forceLinkClasses = [
                'com.gluonhq.**.*',
                'io.datafx.**.*',
                'javax.annotations.**.*',
                'javax.inject.**.*',
                'javax.json.**.*',
                'org.glassfish.json.**.*'
        ]
    }
}

As Charm Down API has changed slightly, modify the code that accesses the position services as follows:

package com.thomaskuenneth.gluon.positionservicedemo;

import com.gluonhq.charm.down.Services;
import com.gluonhq.charm.down.plugins.Position;
import com.gluonhq.charm.down.plugins.PositionService;
import com.gluonhq.charm.glisten.control.AppBar;
import com.gluonhq.charm.glisten.mvc.View;
import com.gluonhq.charm.glisten.visual.MaterialDesignIcon;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.geometry.Pos;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;

public class BasicView extends View {

    private static final Logger LOGGER = Logger.getLogger(BasicView.class.getName());

    final Label label;

    public BasicView(String name) {
        super(name);
        label = new Label();
        VBox controls = new VBox(15.0, label);
        controls.setAlignment(Pos.CENTER);
        setCenter(controls);
        Services.get(PositionService.class).ifPresent(serivce -> {
            serivce.positionProperty().addListener((obs, oldPos, newPos) -> {
                LOGGER.log(Level.INFO, "\nobs: {0}\noldPos: {1}\nnewPos: {2}",
                        new Object[]{obs, oldPos, newPos});
                outputPos(newPos);
            });
        });
    }

    private void outputPos(Position p) {
        if (p != null) {
            label.setText(String.format("We are currently here: %f %f",
                    p.getLatitude(),
                    p.getLongitude()));
        }
    }

    @Override
    protected void updateAppBar(AppBar appBar) {
        appBar.setNavIcon(MaterialDesignIcon.MENU.button(e -> System.out.println("Menu")));
        appBar.setTitleText("Basic View");
        appBar.getActionItems().add(MaterialDesignIcon.SEARCH.button(e -> System.out.println("Search")));
    }

}

In earlier versions it seemed necessary to have the file ibCharm.a in src/ios/jniLibs. With Gluon 4 I kept seeing errors upon linking until I removed the file. I assume that due to the refactoring of Charm Down that lib is no longer needed in this directory.

Also, please note that you need to edit Default-Info.plist as now mentioned in the Charm Down documentation about the PositionService. I already described this in my question. As of today, the docu does not mention to consider adding

<string>location-services</string>

to

<key>UIRequiredDeviceCapabilities</key>
<array>
    ...

but I think this might be a good idea if your app NEEDS the position service and will not run otherwise. Maybe an iOS expert could comment on this, please.

Upvotes: 1

Related Questions