When debugging my app with the simulator, the routine didUpdateLocations is never involved. What I do:
In the simulator, I select Debug>location>Custom Location and the window with longitude and latitude pops up. When pressing ok, I would expect the didUpdateLocations to be called.
I use locMgr as a global variable in a ViewController-module:
locMgr = CLLocationManager()
and in the viewDidLoad-function includes the following sequence:
locMgr.delegate = self
if CLLocationManager.authorizationStatus() == .NotDetermined {
locMgr.requestWhenInUseAuthorization()
}
I have coded the didUpdateLocations-function as a method of my viewcontroller class. I also verified (debugger), that the requestWhenInUseAuthorization-routine is invoked during initialisation. So were is the problem, why is the didUpdateLocations protocol-routine not invoked?
dasdom solved the problem by suggesting: Why requestWhenInUseAuthorization doesn't prompt the user for access to the location?
Related
Hello all and thanks for viewing this question,
I have a program that users get access to via a login screen. Once the user's credentials have been validated on the login screen, the main program is called (from the login screen) and the login screen disappears. All good. However, if the session crashes (or I press CTRL-PAUSE), the main program is terminated and I end up at the initial login screen. I'd have assumed that after a session crash, Progress (11.4) should take me back to the OS (Windows Server 2012), but not back to the initial screen. I have tried placing QUIT in different areas of the program, but Progress still takes me back to the initial screen, while I need it to quit completely. Any thoughts would be greatly appreciated. Thanks!
It's the AVM's default behavior to rerun the startup procedure after a STOP condition has occurred that was not handled.
You can add an
ON STOP UNDO, RETURN "stopped" .
option to a DO, FOR or REPEAT block close where your "crash" happens. Then the calling procedure could check for the RETURN-VALUE of "stopped".
Assuming you are on a recent version (OpenEdge 12.x), you can also use CATCH Blocks for Progress.Lang.Stop:
CATCH stopcon AS Progress.Lang.Stop:
QUIT.
END CATCH.
I think that your use of the word "crashed" is very, very confusing. If your session actually "crashes" in the usual sense that _progres (or prowin if this is Windows) terminates, then you would not have any locked records remaining. You would also have a protrace file that would help you to identify where the issue occurs.
Incidentally, you could add error logging to the client startup to determine where the errors that QXtend cannot find are occurring:
_progres dbname -p startup.p -clientlog logname.log
You have not shared any code so I can only guess but, presumably, you are running your login program via the -p startup parameter.
Correct me if I am wrong but something along these lines:
_progres dbname -p startup.p
The startup program then runs whatever it runs to get you logged in and run the application. Maybe something like this:
/* startup.p
*/
message "(re)starting!".
pause.
run value( "login.p" ).
run value( "stuff.p" ).
message "all done".
pause.
quit.
And:
/* login.p
*/
message "hello, logging in!".
pause.
return.
Along with:
/* stuff.p
*/
message "hello, doing stuff!".
pause.
run value( "notthere.p" ).
message "hello, doing more stuff!".
pause.
return.
At some point an error occurs (you seem to want to call this a "crash"). I have arranged for a serious error to occur when stuff.p tries to "run notthere.p". So if you run my example you will see the behavior that you have described - your session "crashes", the startup procedure re-runs, and you get to the login screen again.
To change that and trap the error simply wrap a "DO ON STOP" around the RUN statements. Like this:
/* startup.p
*/
message "(re)starting!".
pause.
do on error undo, leave
on endkey undo, leave
on stop undo, leave
on quit undo, leave: /* "leave", exits this block when one of the named conditions arises */
run value( "login.p" ).
run value( "stuff.p" ).
/* we just leave because we finished normally */
end.
message "all done".
pause.
quit.
You mention QXtend so I am guessing that MFG/Pro is involved. If you cannot directly modify the MFG/Pro startup procedure (as I recall that would be "-p mfg.p") just adapt the code above to be a "shim" that runs mfg.p from within the "DO ON STOP..." block.
I believe I have found a way to quit the initial login screen when this appears as the result of a session crash, by using the the ETIME function. Thanks again, Mike for your response.
I am using this code to show the AudioRecorder on the Apple Watch (taken from https://www.raywenderlich.com/345-audio-recording-in-watchos-tutorial)
let outputURL = chatMasterController.newOutputURL()
let preset = WKAudioRecorderPreset.narrowBandSpeech
let options: [String : Any] =
[WKAudioRecorderControllerOptionsMaximumDurationKey: 30]
presentAudioRecorderController(
withOutputURL: outputURL,
preset: preset,
options: options) {
[weak self] (didSave: Bool, error: Error?) in
guard didSave else { return }
print("finished audio to \(chatID) at \(outputURL)")
print(outputURL)
}
The Recorder pops up however it doesn't seem to take any input. The wave forms don't rise while speaking and trying to play the recording afterwards leaves me with 0.2seconds of silence no matter how long the recording is.
I've tried another app that's making use of the microphone and this app did ask me for permission to record audio. I have feared having dismissed the permission before so I have reinstalled my app which however didn't change anything - no permission being asked, no input being generated.
Is there something I've missed e.g. importing a lib?
I've now figured it out. You don't just need the Privacy - Microphone Usage Description string in your Watch app's plist - you also need to set it in the iPhone's plist.
Only setting it on the Watch does nothing, only setting it on the iPhone doesn't let you allow it on the Watch directly. So you need it on both.
No idea why this isn't documented anywhere but it fits Apple's "we are going downhill" movement :)
Here is some watchOS code I have working on the Similator(Watch):
.....
let interval = 60.0
NSTimer.scheduledTimerWithTimeInterval(interval,
target: self,
selector: #selector(InterfaceController.timerDidEnd(_:)),
userInfo: nil, repeats: false)
.....
func timerDidEnd(timer:NSTimer) {
print("Time is over! Please wake up!")
}
From Xcode I run the app, the first part of the code above gets executed. Then I hit Command-Shift-H and the app goes in the background.
After one minute I see in the debugging console the message: Time is over! Please wake up!
All works as I expect. My question is:
What should I write inside the function timerDidEnd(), in order to have the app wake up from the background on the simulator, rather than just printing the current message in the debugger?
There's nothing you can write inside a timer action that will bring an app to the foreground. Only the user can resume an app.
If you think about it, it would confusing and disruptive for the user if an app could programmatically bring itself to the foreground whenever it wanted.
The only way to resume an app is by the user reacting to a notification. This is similar to what happens on the phone when the user taps notification actions from the home screen.
Hey there,
I'm a little confused with some Actionscript I'm working on. For my GUI, I have written four functions for times when computing is taking place. These are showMessage("Loading Text..."), disableButtons(), clearMessage(), and enableButtons(). They work great throughout the program. ShowMessage displays a loading message, disableButtons disables buttons so no one can click anything, clearMessage clears the loading message when job is done, and enableButtons turns them all back on.
For some reason, there is one button click handler which is giving me troubles and I'm not sure why. I've set it up just like others similar to it (which all work) but this one doesn't display the message or shut off my buttons. Here is my clickHandler...
private function Buffer_Route_clickHandler():void
{
showMessage("Loading RBE Options");
disableButtons();
if(Buffer_Route.selected && rbeAC.length == 0){
createRbeAC();
}
}
And here is the creatRbeAC function...
private function createRbeAC():void
{
rbeAC.removeAll();
hiddenRBELayers.removeAll();
var rbeIDs:Array = rbeConfigList.getKeySet();
for each (var rbeID:int in rbeIDs)
{
var rbeConfig:Hashtable = rbeConfigList.find(rbeID) as Hashtable;
var rbeData:Object =
{
restURL:rbeConfig.find("rbeRESTURL") as String,
layername:rbeConfig.find("rbeLayerName") as String,
icon: rbeConfig.find("rbeIcon") as String,
titlefield: rbeConfig.find("rbeTitleField") as String,
checked: rbeConfig.find("rbeChecked") as String,
count: "0" as String
};
if(rbeData.checked == "false")
{
hiddenRBELayers.addItem(rbeData.layername);// as String);
}
rbeAC.addItem(rbeData);
}
}
I wasn't getting any loading text, so I took out my clearMessage and enableButtons functions from the code to see if it was adding the message and disabling the buttons to begin with. I am still not getting anything though. Since clearMessage and enableButtons is no where to be found in this button click handler or creatRbeAC function, then I can not understand why the loading message and buttons aren't disabled, even when the computing is finished.
Some things to note. If I comment out the creatRbeAC function, the loading message shows and buttons do disable. Its almost as if those functions are being ignored when the creatRbeAC function is in the code.
Any help? I would greatly appreciate it. Hopefully I have provided enough information.
in my actual app, i have similiar problems.
In my Eventhandler (it doesn't matter, if there is a button handler or a mouse handler), I also wan't to disable the app and use some filter functions for my arrayCollection.
Unfortunately, this action seems to need too much ressources, especialy, when the app run in debug mode. I have to waint for the next screnn refresh. So i try to implement the "applyFilterMethod" in my eventhandler with
callLater(applyFilterMethod)
but it also wo't work.
Finally, the setTimeOut(applyFilterMethod,500)
solved my issue. So, try it with the timeout-method, if you have luck.
BR
Frank
I use the following code to get GeoLocation for my app
QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this);
if (source) {
source->setUpdateInterval(1000); // time in milliseconds
source->setPreferredPositioningMethods(QGeoPositionInfoSource::AllPositioningMethods);
connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
source->startUpdates();
source->requestUpdate(30000);
const QGeoPositionInfo &info =source->lastKnownPosition();
ui->label->setText(QString("Latitude - %1 Longitude - %2").arg(info.coordinate().latitude()).arg(info.coordinate().longitude()));
}
This code runs perfectly on the Simulator and gives me the coordinates provided by the simulator however this does not work when i try to run it on my N900. It returns Nan instead of the latitude and longitude coordinate. The current GPS signal on the phone is coarse accuracy. Also geolocation is working in the OVI Maps app on the phone. Any idea why the above code is unable to get the geolocation on the phone but works perfectly on the simulator ?
You should be setting the label from the slot for positionUpdated() as the signal is fired when an update has been received. Your call to requestUpdate() also triggers the positionUpdated() signal. If it does not get an update after your timeout setting, it will signal requestTimeout() which you might want to connect a slot to for informational purposes. It is likely that when you retrieve lastKnownPosition(), no position has been determined yet and the value returned is a null value. It's difficult to be sure just from the documentation but I think it implies that requestUpdate() will always return immediately, not after it has successfully received an update so you should call source->lastKnownPosition.isValid() to see if it contains a good position.
You should really be checking the position in the positionUpdated() slot or after that slot has been called at least once. It's likely the simulator has a postion available immediately and works in that case.
Does your positionUpdated() slot ever get called?