what make getCurrentPosition fail? - w3c-geolocation

I made a simple website with javascript on it that calls to:
navigator.geolocation.getCurrentPosition(show_map, show_map_error);
I have put the website on the internet. I tried to open the website from different PCs (no GPS gadget) on different locations. One from my home, one from a friends office.
But the script does not always get a position.
What would be a problem?
Thank you.

The method is not guaranteed to return a position, especially if there is no GPS attached.
You could try getting a cached position instead. See the following from the API specification
// Request a position. We only accept cached positions, no matter what
// their age is. If the user agent does not have a cached position at
// all, it will immediately invoke the error callback.
navigator.geolocation.getCurrentPosition(successCallback,
errorCallback,
{maximumAge:Infinity, timeout:0});
function successCallback(position) {
// By setting the 'maximumAge' to Infinity, the position
// object is guaranteed to be a cached one.
// By using a 'timeout' of 0 milliseconds, if there is
// no cached position available at all, the user agent
// will immediately invoke the error callback with code
// TIMEOUT and will not initiate a new position
// acquisition process.
if (position.timestamp < freshness_threshold &&
position.coords.accuracy < accuracy_threshold) {
// The position is relatively fresh and accurate.
} else {
// The position is quite old and/or inaccurate.
}
}
function errorCallback(error) {
switch(error.code) {
case error.TIMEOUT:
// Quick fallback when no cached position exists at all.
doFallback();
// Acquire a new position object.
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
break;
case ... // treat the other error cases.
};
}
function doFallback() {
// No cached position available at all.
// Fallback to a default position.
}

Related

Use CMSensorRecorder to continuously collect Accelerometer data in Apple Watch

I want to use CMSensorRecorder to continuously collect the Accelerometer data, also if user didn't open my app on watch\phone.
What I want to do is - "whenever possible" (i.e. watch is awake and I can execute code), do the following:
call recordAccelerometerForDuration to tell watch to keep collecting data for as long as possible
call accelerometerDataFromDate to get data collected so far (or from last time I got the data)
My question is - how to implement the "whenever possible", i.e. how can I cause my watch application to wake up and execute these apis whenever the watch itself wakes up ?
CMSensorRecorder- to recored data continuously use ExtentionDelegate to triger CMSensorRecorder to invoke start recording and reading data.
func applicationDidBecomeActive() {
print("Active")
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
AccelorometerDataReader.sharedReader.sessionEndDate = Date()
AccelorometerDataReader.sharedReader.getRecordedData()
}
func applicationWillResignActive() {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, etc.
print("inactive")
AccelorometerDataReader.sharedReader.startReadingAccelorometerData()
AccelorometerDataReader.sharedReader.sessionStartDate = Date()
}
//AccelorometerReaderCode
func startReadingAccelorometerData()
{
if CMSensorRecorder.isAccelerometerRecordingAvailable()
{
if CMSensorRecorder.isAuthorizedForRecording()
{
print("Authorized.......")
DispatchQueue.global(qos: .background).async
{
self.recorder?.recordAccelerometer(forDuration: 3 * 60) // Record for 3 minutes
}
}
else
{
print("not authorized")
}
}
else
{
print("NOt available for recording")
}
}
func getRecordedData()
{
DispatchQueue.global(qos: .background).async
{
if self.sessionStartDate < self.sessionEndDate
{
if let list = self.recorder?.accelerometerData(from: self.sessionStartDate, to:self.sessionEndDate)
{
for record in list
{
let data = record as! CMRecordedAccelerometerData
print("x: \(data.acceleration.x) y: \(data.acceleration.y) z: \(data.acceleration.z) time :\(data.startDate.getFormattedDate())")
}
}
}
}
}
}
It doesn't seem you can. I have tried the following but none of these really work.
Register for backgroundApplicationRefresh (watchOS 3) and make sure the app is saved to the Dock. Dock apps can rely on getting one call an hour to update themselves.
On completion of the period query for the accelerometer data and archive the result to file and then transfer the file to the iOS companion app. The file transfer will occur in the background independent of the watch kit app assuming you get enough CPU time to write the accelerometer data to file.
Try using ProcessInfo API to keep the process running.
To date the only success I have had is in running an async thread to extract the data and keeping the watch kit app active by tapping on the screen each time the screen blanks.
Hope this helps and please post any better solution you find.

When to call DiscardView on RTV/DSV?

Is it a safe strategy to call DiscardView immediately before clearing the associated view? It seems that misusing this API could lead to bad things, so some explanation on how to effectively use this would be much appreciated.
DiscardView is an optimization for tiled hardware renderering, so it's not strictly required.
In the standard Windows 8 Store, Windows phone 8, and universal Windows apps template, it's called right after Present
void DX::DeviceResources::Present()
{
// The first argument instructs DXGI to block until VSync, putting the application
// to sleep until the next VSync. This ensures we don't waste any cycles rendering
// frames that will never be displayed to the screen.
HRESULT hr = m_swapChain->Present(1, 0);
// Discard the contents of the render target.
// This is a valid operation only when the existing contents will be entirely
// overwritten. If dirty or scroll rects are used, this call should be removed.
m_d3dContext->DiscardView(m_d3dRenderTargetView.Get());
// Discard the contents of the depth stencil.
m_d3dContext->DiscardView(m_d3dDepthStencilView.Get());
// If the device was removed either by a disconnection or a driver upgrade, we
// must recreate all device resources.
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
HandleDeviceLost();
}
else
{
DX::ThrowIfFailed(hr);
}
}

How would you write fetching a collection the "Reactive Cocoa" way?

The client I'm building is using Reactive Cocoa with Octokit and so far it has been going very well. However now I'm at a point where I want to fetch a collection of repositories and am having trouble wrapping my head around doing this the "RAC way"
// fire this when an authenticated client is set
[[RACAbleWithStart([GHDataStore sharedStore], client)
filter:^BOOL (OCTClient *client) {
return client != nil && client.authenticated;
}]
subscribeNext:^(OCTClient *client) {
[[[client fetchUserRepositories] deliverOn:RACScheduler.mainThreadScheduler]
subscribeNext:^(OCTRepository *fetchedRepo) {
NSLog(#" Received new repo: %#",fetchedRepo.name);
}
error:^(NSError *error) {
NSLog(#"Error fetching repos: %#",error.localizedDescription);
}];
} completed:^{
NSLog(#"Completed fetching repos");
}];
I originally assumed that -subscribeNext: would pass an NSArray, but now understand that it sends the message every "next" object returned, which in this case is an OCTRepository.
Now I could do something like this:
NSMutableArray *repos = [NSMutableArray array];
// most of that code above
subscribeNext:^(OCTRepository *fetchedRepo) {
[repos addObject:fetchedRepo];
}
// the rest of the code above
Sure, this works, but it doesn't seem to follow the functional principles that RAC enables. I'm really trying to stick to conventions here. Any light on capabilities of RAC/Octokit are greatly appreciated!
It largely depends on what you want to do with the repositories afterward. It seems like you want to do something once you have all the repositories, so I'll set up an example that does that.
// Watch for the client to change
RAC(self.repositories) = [[[[[RACAbleWithStart([GHDataStore sharedStore], client)
// Ignore clients that aren't authenticated
filter:^ BOOL (OCTClient *client) {
return client != nil && client.authenticated;
}]
// For each client, execute the block. Returns a signal that sends a signal
// to fetch the user repositories whenever a new client comes in. A signal of
// of signals is often used to do some work in response to some other work.
// Often times, you'd want to use `-flattenMap:`, but we're using `-map:` with
// `-switchToLatest` so the resultant signal will only send repositories for
// the most recent client.
map:^(OCTClient *client) {
// -collect will send a single value--an NSArray with all of the values
// that were send on the original signal.
return [[client fetchUserRepositories] collect];
}]
// Switch to the latest signal that was returned from the map block.
switchToLatest]
// Execute a block when an error occurs, but don't alter the values sent on
// the original signal.
doError:^(NSError *error) {
NSLog(#"Error fetching repos: %#",error.localizedDescription);
}]
deliverOn:RACScheduler.mainThreadScheduler];
Now self.repositories will change (and fire a KVO notification) whenever the repositories are updated from the client.
A couple things to note about this:
It's best to avoid subscribeNext: whenever possible. Using it steps outside of the functional paradigm (as do doNext: and doError:, but they're also helpful tools at times). In general, you want to think about how you can transform the signal into something that does what you want.
If you want to chain one or more pieces of work together, you often want to use flattenMap:. More generally, you want to start thinking about signals of signals--signals that send other signals that represent the other work.
You often want to wait as long as possible to move work back to the main thread.
When thinking through a problem, it's sometimes valuable to start by writing out each individual signal to think about a) what you have, b) what you want, and c) how to get from one to the other.
EDIT: Updated to address #JustinSpahrSummers' comment below.
There is a -collect operator that should do exactly what you're looking for.
// Collect all receiver's `next`s into a NSArray. nil values will be converted
// to NSNull.
//
// This corresponds to the `ToArray` method in Rx.
//
// Returns a signal which sends a single NSArray when the receiver completes
// successfully.
- (RACSignal *)collect;

DADiskEject causing problems with error code 12 (kDAReturnUnsupported)

I try to eject external USB drives and Disk Images after being unmounted in the following callback function:
void __unmountCallback(DADiskRef disk, DADissenterRef dissenter, void *context )
{
...
if (!dissenter)
{
DADiskEject(disk,
kDADiskEjectOptionDefault,
__ejectCallback,
NULL);
}
}
Unfortunately I get an error in __ejectCallback...
void __ejectCallback(DADiskRef disk, DADissenterRef dissenter, void * context)
{
if(dissenter)
{
DAReturn status = DADissenterGetStatus(dissenter);
if(unix_err(status))
{
int code = err_get_code(status);
...
}
}
}
The error code is 12 meaning kDAReturnUnsupported. I don't really know what is going wrong. Can anyone please comment on this? Does this mean disk images can not be ejected???
Many thanks in advance!!
The documentation is pretty unclear on this. Therefore, it's a good idea to look into the actual source code of the DARequest class to find out what causes the kDAReturnUnsupported response.
It reveals the following conditions that return a kDAReturnUnsupported response:
Does your DADisk instance represent the entire volume or not?
if ( DADiskGetDescription(disk, kDADiskDescriptionMediaWholeKey) == NULL )
{
status = kDAReturnUnsupported;
}
if ( DADiskGetDescription(disk, kDADiskDescriptionMediaWholeKey) == kCFBooleanFalse )
{
status = kDAReturnUnsupported;
}
Looking into the IO Kit documentation (for which DiscArbitation.framework is a wrapper for), we find that kDADiskDescriptionMediaWholeKey describes whether the media is whole or not (that is, it represents the whole disk or a partition on it), so check that you're ejecting the entire disc and not a partition. Remember, you can unmount a partition, but you can't eject it. (that wouldn't make sense)
Is the disc mountable?
Another condition in DARequest.c is whether the volume is mountable or not, so make sure it is:
if (DADiskGetDescription(disk, kDADiskDescriptionVolumeMountableKey) == kCFBooleanFalse )
{
status = kDAReturnUnsupported;
}
Is the DADisk instance's name valid?
A third check validates the volume's name. Some system provided (internal) volumes don't have a name and can't be ejected. The check is very simple and simply looks for any name, so this shouldn't be a big deal.
if (DARequestGetArgument2(request) == NULL)
{
status = kDAReturnUnsupported;
}
Go through these three checks and see if they apply to you. This way you're bound to find out what's wrong.

Dojo: Is there an event after drag & drop finished

I've got two dojo.dnd.Sources with items. Whenever an item is dropped I need to persist the new order of the items in the Sources using an xhr.
Is there an dojo event or topic that is fired after an dnd operation has (successfully) finished? What would be the best way to use it?
Probably I don't understand the problem in all details but I don't see why you need to process events or topics. The best way to record changes is to intercept updating methods on relevant sources. Specifically you need to intercept insertNodes() for drops or any other additions.
Simple example (pseudo-code):
var source1, source2;
// ...
// initialize sources
// populate sources
// ...
function getAllItems(source){
var items = source.getAllNodes().map(function(node){
return source.getItem(node.id);
});
return items;
}
function dumpSource(source){
var items = getAllItems(source);
// XHR items here to your server
}
function recordChange(){
// now we know that some change has occured
// it could be a drop or some programmatic updates
// we don't really care
dumpSource(source1);
dumpSource(source2);
}
dojo.connect(source1, "insertNodes", recordChanges);
dojo.connect(source2, "insertNodes", recordChanges);
// now any drop or other change will trigger recordChanges()
// after the change has occurred.
You can try to be smart about that and send some diff information instead of a whole list, but it is up to you to generate it — you have everything you need for that.
You can use dojo.subscribe to do something when a drop is finished like so:
dojo.subscribe("/dnd/drop", function(source, nodes, copy, target) {
// do your magic here
});
There's examples of using subscribe on the dojotoolkit tests site. More info about dojo publish and subscribe too.
Alternately, you could connect to the onDndDrop method.
var source = new dojo.dnd.Source( ... );
dojo.connect( source, "onDndDrop", function( source, nodes, copy, target ) {
// make magic happen here
});
connect methods are called at the end so the items will be there at that point.
I'm keeping this note for dojo Tree folks just like me who would run in to this problem. Solutions given here was not quite worked well in my situation. I was using a dijit.tree.dndSource with Dojo tree and subscribing to "/dnd/drop" allows me to capture the event even though at that point my underlying data store hadn't been updated with latest changes. So I tried waiting as Wienczny explains, that doesn't solve the problem completely as I can't rely on a timeout to do the waiting job. Time taken for store update could be vary, i.e. shorter or very long depends on how complex your data structure is. I found the solution with overriding the onDndDrop method of the dndController. Simply you can specify the onDndDrop : on your tree initialization. One thing I found odd though you can not hitch this method, you will get weird behavior during dnd.
Tree
this._tree = new MapConfigTree({
checkAcceptance: this.dndAccept,
onDndDrop: this.onDndDrop,
betweenThreshold:5,
method
onDndDrop : function(source, nodes, copy, target){
if(source.dropPosition === 'Over' && (target.targetAnchor.item.type[0] == 'Test layer')) {
this.inherited(arguments);
// do your bit here
} else {
this.onDndCancel();
}
}