Cannot stop Updates with stopUpdatingLocation and stopRelativeAltitudeUpdates - xcode

I am building a paragliding app for watchOS, that can display and log values like altitude, speed, glide ratio and so on.
So far I built the UI, integrated some settings and I am receiving pressure sensor data and gps location.
To save battery life I included a "stop button" that triggers the locationManager.stopUpdatingLocation and CMAltimeter.stopRelativeAltitudeUpdates functions. But in the console I can see still location and altitude updates coming in.
I uploaded the code to https://github.com/LukeCrouch/iAlti/tree/main/iAlti%20WatchKit%20Extension .
The interesting file is probably the ControlsView, here I declare and call the relevant functions.
func stopLocation() {
self.locationManager.stopUpdatingLocation()
}
I appreciate every bit of help I can get, this is my first time writing an App! :)
Cheers Luke

The problem is this line:
#ObservedObject var locationManager = LocationManager()
Every time the ControlsView is regenerated, that line runs afresh. So the LocationManager is a different LocationManager. So you are telling a LocationManager's CLLocationManager to stop updating, but this is a different CLLocationManager from the one that started.
Instead, make this a singleton environment object so that your app has just one LocationManager with just one CLLocationManager. That way, each time you talk to it, you are talking to the same one.

Related

Execute Predefined scenes in iOS 9

Hi I have updated my Xcode and iOS . In the iOS 9 they have made some changes in HomeKit. In that they have by default added some predefined scenes. like HMActionSetTypeSleep,HMActionSetTypeWakeUp ... When I click on that scene in HMCatalog app it throws error that no actions in the actions. Could any one please tell me how to execute the HMActionSetTypeWakeUp type built in scenes.Thank you for your valuable time. Please let me know if I am not clear.
The 'Scenes' by itself are HMAction aggregators, i.e. HMActionSets. You need to add actions to the HMActionSet in order to execute, or make the action set/scene do anything.
For e.g., I'd like to set desired thermostat temperate to 22 degree Celsius when I execute the Wake Up or Good Morning pre-defined scene under a HMHome.
In order to do so, you would create an HMAction (or more precisely, HMCharacteristicWriteAction - a subclass of HMAction), that writes the value 24 to the thermostat's desired temperature HMCharacteristic.
Once the HMAction is created (and you can create multiple such actions), add that HMAction to the predefined scene. Look at the iOS api for the exact api calls to do so.
In the HMCatalog app, take a look at the 'ActionSetCreator' class.
Also, you can see this action by adding HMActions in the HMCatalog itself. Drill down to a thermostat (or any other homekit paired service). Change the values of some HMCharacteristics under the HMService, then drill back up and save your scene (I may be off from the exact screen by screen details, as writing this out of memory on an airplane seat, but you get the point - hopefully).
Once you have (any) HMActions listed under a pre-defined scene - try saying the name of the scene to Siri (or you can simply execute it by pressing on the scene on HMCatalog).
If the thermostat (or other HomeKit service) is properly paired, you should see your state problem resolved.

Xcode Instruments Time Profiler Understanding which methods are taking the most time

My UI is acting choppy and I am trying to understand what the source for this is.
There are a lot of options using Xcode Instruments and I am not sure which set of them are the best for me.
From playing around with some of them it seems that most time is spent in [CALayer drawInContext] and [CALayer layoutSublayers] but I have no idea in what context those methods are called from (what part of the UI is doing that).
Which options should I be choosing in order to better understand?
Also would like to know if there is a way to see what is running in the background which doesn't belong to the current visible UI (I think something in the background may also be thrashing the CPU)
Toogle Display of Primary Views and select:
Separated by Thread
Invert Call Tree
Hide System Libraries
Show Obj-C Only
Try to see this: http://www.raywenderlich.com/23037/how-to-use-instruments-in-xcode
Use the instruments Time Profiler instrument to record your app running on the device during its choppy moments.
Upload the instruments trace at:
http://timeanalyzer.excelsis.com
It will give you a timeline view of your main thread (the main place where UI stutters occur) methods that's a lot easier to visualize than the regular instruments UI. Here's an example view:
http://timeanalyzer.excelsis.com/view.php?jobid=c7f3efc43ff85302a80515b56c0900f0

Taming Xcode Storyboards

I've inherited a project that uses ~100 Xcode storyboard scenes. Trying to add to this project has been a nightmare for the following reasons:
My machine (late 2011 Macbook Pro 13inch with non-SSD drive 16GB running 10.8 + XCode 4.4) crawls to a halt on storyboards. In some cases I'll move a scene and it will take 10 seconds to update its position.
When I modify a scene (create a segue between two scenes, etc) in some cases all the scenes disappear. I have to do a "select all" on the sidebar to get them back.
Navigating a specific storyboard scene is absolutely frustrating. There's no apparent way to sort the storyboard scenes by name.
The filter feature below the scenes sidebar kind of lets me find the scene I'm looking for, but has the frustrating side effect of filtering out the attributes (segues, views, etc) of the specific scene I'm looking for. So if I need to modify the "add_new_guy" segue for "Person View Controller", and I type "Person" in the filter, I get the Person View Controller sans the add_new_guy segue. If I delete the text in the filter to make the segue appear, I'm taken back to the top of the scene list and (most likely) away from the Person View Controller at the other end of it. I end up scrolling all the way down the scene list manually looking for the specific scene I want to change.
I've spent hours googling solutions and nothing useful has appeared. Any suggestions on how to improve the storyboards situation or pointers to things in XCode I've stupidly overlooked?
Disclaimers:
a) I am well aware that moving to nibs would solve the problem and 100 storyboard scenes is nuts, but I've inherited the code and I'm expected to do storyboards for at least the next year.
b) I'm aware that it's possible to split out the project into several storyboards. I might look into this if I have time.
c) I've heard that some problems may be caused by having two storyboards open at once, which I've tried to avoid as much as possible.
d) Filing a bug with Apple's regarding storyboards is already on my to-do list.
First, work on splitting your storyboard up into smaller storyboards. I would recommend a maximum of 4-5 view controllers per storyboard. It will be a giant headache at first, just work on it over time. Take a look at RBStoryboardLink, which allows you to connect them "by allowing 'pseudo-segues' between UIStoryboards. These segues can be built without leaving Interface Builder and without writing any extra code". This will give you:
The ability to make abstract super classes in storyboards for very similar view controllers
Smaller, more manageable files that don't bring your computer to a halt
Fewer merge conflicts when working as part of a team (assuming your project is under version control)
Second, tell your boss to immediately purchase you a new, way better development computer. They'll make back the $3-$4k in more efficient development time in a matter of days. (Or, if this is contract work… buy a new one yourself.)
And, please indulge my slightly off-topic comment.
Regarding this statement:
I'm expected to do storyboards for at least the next year
Work expectations are always negotiable. Your boss likely thinks "switching from storyboards to code will cost more time than it will save." If this isn't true, say so.

What is the proper way to change scenes?

Back when I did LUA i used to run dofile("..."); to load other lua files and such. Later to find out that this is a very bad practice and can lead to applications breaks.
Now that I am on my way to developing a WebOs application, i want to make sure I am properly changing scene before i pick up bad programming habit.
At the moment this is what I use:
label2Tap: function(inSender, event) {
Mojo.Controller.stageController.popScene();
Mojo.Controller.stageController.swapScene("LogicAndArithmetic");
},
Which works great to get to my LogicAndArithmetic scene, is this the best practice to do such?
Thanks.
The scene model in the Mojo framework of webOS works like a stack. When the app starts you call pushScene to display your main scene. Normally, you then make additional pushScene calls to add scenes to the stack on top, and then when you are done with them they are popped, typically when the user performs the 'back gesture', bringing back the previous scene. Eventually you will be back at your main scene.
The swapScene call is equivalent to calling popScene and then pushScene for a different scene. In your case you are calling popScene then swapScene, so that is the equivalent of popping two scenes from the stack and then pushing back one. It probably works because you have only one scene, but if you had more it would not work correctly.
BTW, why are you working with Mojo and not Enyo?
While this is technically correct, it is most likely not how the user would expect your app to behave. In general, when a user presses a button that opens a new scene, it is placed on the stack, as Miguel said. The user will expect to be able to go back and pop the scene off of the stack. This happens automatically, you do not need to listen for this input. You do this by calling Mojo.Controller.pushScene("sceneName");. While there are some applications where swapScene makes sense, your app can probably be conceptualized as a stack of scenes, with a logical "back" scene.
I would reccommend playing around with some existing apps to get a feel for how they behave. Also, while Miguel suggested moving to Enyo, it is worth noting that Enyo apps are not officially supposed to work on webOS 2 devices (phones), only on the touchpad. It is possible to run them on webOS 2 devices, but I do believe that they will be rejected from the app catalog.

RBSplitView has delayed reload of autosaved view positions

I really enjoy using RBSplitView, an open source replacement for NSSplitView, but I have a problem in my shipping app and am experiencing it again in a new project.
The problem is I'm telling the RBSplitView to autosave its position state by giving it an autosave name. When my app launches the RBSplitView doesn't seem to honor the saved state till a second after the window is drawn.
I've spent the night trying to debug the behavior but have had little success. Anyone out there use this lib and have some advice?
You can scrub this quicktime movie to the issue at work:
http://media.clickablebliss.com/billable/interface_experiments/rbsplitview_delayed_autosave_reload2.mov
I've still been unable to figure out why this is happening but I do have a workaround.
First, make sure your main window is not visible at launch and then at the end of applicationDidFinishLaunching in your app delegate add something like:
[mainWindow performSelector:#selector(makeKeyAndOrderFront:) withObject:self afterDelay: 0.1];
The delay is the key. If you just tell the window to makeKeyAndOrderFront: I still see the issue. However as long as it has a beat of time it looks good.
This likely is happening because the RBSplitView instance needs to wait until it's first moment to get to set its frame to the autosaved value, which happens to be after the user can see it. This 0.0-delay trick simply delays showing the window until the very next runloop, which gives the split view a chance to do its magic (and other views) so that when the user sees the window, it's already nice and sexy. So just do the delay at 0.0 and you'll be fine.
I have a similar, but slightly different workaround in my app that uses RBSplitView. In applicationDidFinishLaunching:, I call adjustSubviews on the split view before calling makeKeyAndOrderFront: on the window that contains it. This seems to knock the split view in to order before it gets displayed on the screen.

Resources