Meteor MongoDb findOne $near not always working - ios

I really don't get it. I have the following code in a Meteor (v1.3.3, MongoDb v2.6.7) app running on my iPhone, and it does not always work. Sometimes it does, and other times it doesn't:
Places = new Mongo.Collection("places");
if(Meteor.isServer) {
Places._ensureIndex({'loc':'2dsphere', name: 1});
}
if(Meteor.isClient) {
var maxDistance = 50;
...
latLng = Geolocation.latLng();
if (! latLng)
{
console.warn('Could not get location!');
return;
}
console.log('location: ' + latLng.lat + ' (' + typeof latLng.lat + '), ' + latLng.lng + ' (' + typeof latLng.lng + ')');
var placeNearby = Places.findOne({
loc: {
$near: {
$geometry: {
type: "Point",
coordinates: [latLng.lng, latLng.lat]
},
$maxDistance: maxDistance //meters
}
}
});
...
}
After I fetch placeNearby, I do a console.log('placeNearby', placeNearby). There are times when it does find a place and some other times it does not.
I am running this on my iPhone 5s (iOS 9) though Xcode:
meteor run ios-device --mobile-server http://10.0.1.10:3000
I am always at the same place when I test this. I thought it might be because of GPS coordinates imprecision, so I increased maxDistance to 50000, but it did not change anything. The funny thing is that my console.log does not output undefined for placeNearby. It seems to be outputting an empty string.
However, if I enter the following query in MongoDb terminal, it retrieves some results:
db.places.find({
loc: {
$near: {
$geometry: {
type: "Point",
coordinates: [-73.56737205923496, 45.50178023952462]
},
$maxDistance: 50 //meters
}
}
})

It was a stupid error. I had forgotten that I had turned off wifi on the iPhone, so it was not able to communicate with the local server. This being said, I would not have thought that a connection with the server was necessary. I thought all the data was being copied to the minimongo database on the client side, and that the app could run independently.
I am wondering now if there is a way to publish a Meteor app that can run locally on the device all by itself. I read a bit about GroudDB, but was not able to find any documentation about geometry queries using $near with GroundDB.

Related

Ionic - Some functionnalities are not working while compiling on IOS

Context:
Hello, I am working on a Ionic application (made in Typescript). In this application, I control a wifi camera via HTTP Request to the IP (http://192.72.1.1/myCommand to be precise).
Main actions I do with the camera:
Start recording
Stop recording
Get videos list
Download a video
When I use the Ionic DevApp:
With the Ionic DevApp, everything works perfectly, I can do all mains actions without a problem.
When I compile the application on IOS:
I compile with the command ionic cordova build ios --prod, then I archive with Xcode and send it to the AppStore to test it with Test Flight.
I got no errors while compiling / archive the application. But when I try it on my iPhone, I can start / stop recording, but can't download the video.
Problem:
Some commands are not working, but I don't know if it is getting the list or downloading the video, I have no logs. I don't understand why some commands are working but others no.
IOS is blocking download requests? How to solve my problem?
Notes:
I already tried all basic things like delete the IOS platform, recompile, uninstall, ...
I tried different Ionic HTTP plugins, same problem with all of them.
Some code:
Start / Stop the camera: (it is the same command to start / stop).
startCamera(){
var url = "http://192.72.1.1/changeRecordStatus";
var result = this.http.get(url);
result.subscribe(data => {
console.log("Works");
},
err => {
console.log("Error" + err);
}
);
}
Getting the name of the last video:
getLastVideo(){
var url = "http://192.72.1.1/listVideos";
this.http.get(url, {}, {})
.then(data => {
var xml = data.data
var xmlDOM = new DOMParser().parseFromString(xml, 'text/xml');
var temp = this.xmlToJson(xmlDOM); // function that convert XML to JSON
var resultArray = Object.keys(temp).map(function(i){
let ite = temp[i];
return ite;
});
resultArray = resultArray[0]['file'].reverse();
this.lastVideo = resultArray[0]['name']; // lastVideo is a global variable
},
(error) =>{
console.log("Error while getting the name of the last video" + error);
});
}
Downloading the file from the camera:
downloadFileFromCamera() {
this.getLastVideo();
var basename_file = this.lastVideo;
var url = "http://192.72.1.1" + basename_file;
this.fileTransfer.download(encodeURI(url), this.file.dataDirectory + '/videos/' + basename_file, true).then((entry) => {
this.video[this.counterVideos] = entry; // video is a global array
this.counterVideos +=1;
}, (error) => {
console.log("Error while downloading the last video" + error);
});
}
If someone knows how to solve my problem, I would be so grateful! Thanks in advance.

Potential causes of Ionic function not working in Ionic View, but working on web

I am building a food delivery app using Ionic. And I am having problems getting the app to work on mobile for the address creation step. After creating an account the user must create a delivery address, at which point the app figures out what delivery location to use.
Address creation works in Chrome (ionic serve) and in iOS simulator (ionic run ios -l -c -s).
However, once I've uploaded the app to my Ionic View iOS app for testing, it gets stuck at the Address creation step.
But at the address creation step, the Ionic loading wheel starts but it doesn't go away and there is no state transition to the menu.
Here is the implementation in the controller.
Address.create($scope.newAddress, $scope.user)
.then(function(response) { // never gets a response back in Ionic View
console.log("address created");
user.save(null,
{ success: function(user) {
// success callback
}, error: function(error) {
// throw error
}
});
}, function(error) {
// throw error
});
The Address.create() method I have implemented is fairly lengthy:
...
.factory('Address', ['$http', '$q', 'PARSE_HEADERS'
function ($http, $q, PARSE_HEADERS) {
return {
create: function(data, userID) {
var deferred = $q.defer();
var zipArray = ['1111','22222','33333'];
var inZone = false;
var restaurantCoords = {
latitude: 11.11111, longitude: 22.22222
};
for (var i=0, bLen=zipBrooklyn.length; i<bLen; i++) {
if(data.zipCode==zipArray[i]) {
inZone = true;
}
}
if (inZone == true ) { // valid zip
function onSuccess(coords) {
var limit = 3041.66;
var meters = getDistance(coords, restaurantCoords);
if (meters < limit) {
$http.post('https://api.parse.com/1/classes/Address', data, {
headers: PARSE_HEADERS
})
.success(function(addressData) {
deferred.resolve(addressData);
})
.error(function(error, addressData) {
deferred.reject(error);
});
}
function onError() {
deferred.reject("Unable to Geocode the coordinates");
}
// GET COORDS
navigator.geocoder.geocodeString(onSuccess, onError, data.address1 + ',' + data.zipCode);
}
}
return deferred.promise;
}]);
I've stripped out all of the code that I believe was working.
So a valid answer for this question could take multiple forms:
I'd accept an answer giving a decent way to debug apps IN Ionic View.
Or, if someone could provide an answer as to why it might be working in the browser and in iOS Simulator, but not iOS itself, that would be appreciated even more.
Ionic view doesn't support all the plugins yet. please take a look at this link for the list of supported plugins.
Device is always better (First Option). If you have a ios device and apple developer account. You can create and configure the required certificate with the device id and run the app using 'ionic run ios'. Second option is iOS simulator. You can use the simulator for your whole app, though few tasks would need a device.
Even if you use the simulator for the whole development, it is always advisable to test in the device before launcing the app.

Get working Ionic + ngCordova + background geolocation

Goal of the app: get geolocation on each move and log location either when app is in foreground and background.
I've tried so many code and combination but I can't manage to have it working (2 days from now...).
The classic geolocation (getCurrentPosition) is working fine but when we close the app the background geolocation is launched but nothing happen... Function "callbackFn" is never fired.
I'm testing on IOS with xcode > Capabilities Audio & location activated for background activity. I also made working the jQuery sample example given in plugin so I saw it working but never with ionic/angularjs.
Here is the current controller handling the background:
.controller('TestCtrl', function($scope, $timeout, $cordovaBackgroundGeolocation, $ionicPlatform, $window)
{
$scope.lat_geo = "loading lat...";
$scope.long_geo = "loading long...";
//-- Geolocal launch
var options = {
enableHighAccuracy : false,
desiredAccuracy: 0,
stationaryRadius: 1,
distanceFilter: 5,
notificationTitle: 'Background tracking', // <-- android only, customize the title of the notification
notificationText: 'ENABLED', // <-- android only, customize the text of the notification
activityType: 'AutomotiveNavigation',
debug: true, // <-- enable this hear sounds for background-geolocation life-cycle.
stopOnTerminate: false // <-- enable this to clear background location settings when the app terminates
};
$ionicPlatform.ready(function()
{
console.log("[IONIC PLATFORM IS NOW READY]");
//-- First launch a basic geolocalisation to get user acceptance of geosharing ;)
navigator.geolocation.getCurrentPosition(function(location) {
console.log('[GEOLOCAL JS1] Location from Phonegap');
},
function (error){
console.log('[GEOLOCAL JS1] error with GPS: error.code: ' + error.code + ' Message: ' + error.message);
},options);
//-- test adaptation depuis l'app jquery
var callbackFn = function(location) {
console.log('[BackgroundGeoLocation] Update callback: ' + location.latitude + ',' + location.longitude);
};
var failureFn = function(error) {
console.log('[BackgroundGeoLocation] Error: '+error);
};
$cordovaBackgroundGeolocation.configure(callbackFn, failureFn, options);
// Turn ON the background-geolocation system. The user will be tracked whenever they suspend the app.
$cordovaBackgroundGeolocation.start();
//-- Just a timeout to retreive long / lat
$timeout(function()
{
navigator.geolocation.getCurrentPosition(function(location)
{
console.log('[GEOLOCAL JS3] Location from Phonegap');
startPos = location;
$scope.$apply(function () {
$scope.lat_geo = startPos.coords.latitude;
$scope.long_geo = startPos.coords.longitude;
});
console.log("[GEOLOCAL BASIC] OK this time :)");
},
function (error){
console.log('[GEOLOCAL JS3] error with GPS: error.code: ' + error.code + ' Message: ' + error.message);
},options);
}, 3000);
});
//-- End Geolocal
})
I've put all my code (a complete ionic app starter) on github: https://github.com/Jeff86/ionic_ngcordova_backgroundgeo_test/tree/master
I read this article http://ngcordova.com/docs/plugins/backgroundGeolocation/
I see that you should put your code into
document.addEventListener("deviceready", function () { ... });
Do you find any solution?
You definitely don't want to use the std Cordova-geolocation plugin in the bg, it'll kill the battery in no time.
I'm the author of the underlying background-geolocation plugin for Ionic. I've created a New Ionic-based SampleApp.
https://github.com/transistorsoft/cordova-background-geolocation-SampleApp

iOS / Phonegap : using FileTransfer response

first, sorry if my english is bad.
Then, here is my issue:
I try to make an app for iOS with PhoneGap 2.8.1 . Evrything is going well on Android, now I just want to move my code on Xcode to compile on iPad or iPhone.
The probleme I have is with FileTransfer, when I upload an image. The transfer itself has no problem, as it finishes with a response code 200, so it's a success.
Then, my serve is supposed to return back an XML file, handled by the javascript code. The server works fine, because I have absolutly no problem with Android devices.
So, I made a lot of tests, and it appears that the app has a problem with the success callback or the FileTransfer.upload(). When I just put a simple console.log('success') in this callback function, it's fine. But when I try to use the FileUploadResult object, nothing happens.
And the weirdest thing is, that when I press the main button of the iPad or iPhone, in order to close my app, I see all my logs displayed in the debug window, such as console.log("Code = " + r.responseCode);, like in the PhoneGap example. And here, I can finally see that I actually receive the server response, but it's like something blocks it until I close the app.
Here is that part of the code :
function onPhotoDataSuccess(imageURI) {
console.log("---> Image: "+imageURI);
// File Transfer
var options = new FileUploadOptions();
options.fileKey="file";
options.chunkedMode = false;
options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
options.mimeType="image/jpeg";
var ft = new FileTransfer();
ft.upload(imageURI, encodeURI(window.localStorage.getItem("wsURL")), win, fail, options);
// Transfer succeeded
function win(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
// Handle the XML response
}
else {
alert("No response. Please retry");
}
}
// Transfer failed
function fail(error) {
alert("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
}
}
Thanks for your help

How do I detect what iOS device my function tests are running on?

I currently have a number of function tests written in javascript using Apple's UIAutomation API. The tests are written for iPhone, but the application also supports the iPad.
To extend my tests to run on an iPad I need to make some adjustments in the code, but first I need to find out what device is running the tests.
How do I detect what device/simulator is running the tests? when I'm running the javascript tests from the Automation tool.
UIATarget.localTarget().model() holds the information about which device the tests are running on.
I have discovered Alex Vollmer's tuneup_js library. It allows for device independent code to some extent as least.
e.g.)
test("my test", function(target, app) {
assertWindow({
"navigationBar~iphone": {
leftButton: { name: "Back" },
rightButton: { name: "Done" }
},
"navigationBar~ipad": {
leftButton: null,
rightButton: { name: "Cancel" }
},
});
});
edit
Found the following in tuneup_js:
/**
* A convenience method for detecting that you're running on an iPad
*/
isDeviceiPad: function() {
return this.model().match(/^iPad/) !== null;
},
/**
* A convenience method for detecting that you're running on an
* iPhone or iPod touch
*/
isDeviceiPhone: function() {
return this.model().match(/^iPhone/) !== null;
}
With these I'll be able to write device specific code.
Follow the documentation provided here, you will get all the information:
https://developer.apple.com/library/ios/#documentation/ToolsLanguages/Reference/UIATargetClassReference/UIATargetClass/UIATargetClass.html
//Here is the script I am using to get the device name, os version, bundle id, target etc..
#import "tuneupjs/Utilities.js"
var target = UIATarget.localTarget();
var app_bundle_id = target.frontMostApp().bundleID();
UIALogger.logDebug("App Bundle Id : " + app_bundle_id);
if(app_bundle_id.strContains("ShazamDev"))
UIALogger.logDebug("Running UIA Scripts for ShazamDev");
var device_name = target.name();
UIALogger.logDebug("Phone Name : " + target.name());
var device_model = target.model();
UIALogger.logDebug("Device Model: " + device_model);
//UIALogger.logDebug("System Name: " + target.systemName());
var ios_version = target.systemVersion();
UIALogger.logDebug("IOS Version: " + ios_version);
Here is the code for StrContains method in my Utilities file
String.prototype.strContains = function(value, ignorecase) {
if (ignorecase) {
return (this.toLowerCase().indexOf(value.toString().toLowerCase()) != -1);
}
else {
return this.indexOf(value) != -1;
}
};

Resources