IOS 8 : CLVisit in CoreLocation - ios8

I m trying to use new CLVisit feature in my app to monitor user's visit, i followed the WWDC-14 video and implemented every thing, but locationManager:didVisit is not calling at all. I set the NSLocationAlwaysUsageDescription key, enable the "Location updates" background mode in Capabilities, and include the following in ViewDidLoad of my class :
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
[_locationManager requestAlwaysAuthorization];
[_locationManager startMonitoringVisits];
There is no documentation available on min TIME required to stay at specific place for a visit or anything about DISTANCE between places.
I tried to test it using GPX file and in the building by staying at different places for more than 10 min, but locationManager:didVisit delegate didn't fired.
Please help me, how to test CLVisits, or if i missed anything in code.

I´ve been testing CLVisits with this code and works perfect to monitor my day a day
https://github.com/steveschauer/TestCLVisit

Related

Cannot stop Updates with stopUpdatingLocation and stopRelativeAltitudeUpdates

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.

App Crashing on Simulator and Device but not when Profiling

The app crashing with signal SIGABRT (the debugger output is child already added. It can't be added again) in the simulator and on the device. Runs fine when I profile the app in Xcode while running it on the simulator or the device. Why is this?
Update: I've figured out that this line of code is causing the problem:
Mover *moverObject = [[[Mover alloc] init] autorelease];
NSMutableArray * array = [moverObject moveToward:startPoint :finalPoint]//<-- This is the problem
moveToward is method that returns a NSMutableArray containing the points from the startPoint to the finalPoint. This worked fine early today but after I started testing something new I guess I broke it. I made no changes in the actual Mover.h/.m just in the GameLayer.m (where I was adding code). I'm not sure what I added to cause the problem.
Update 2: I did some more digging using breakpoints and I found that
GameLayer *gameLayerObject = [[GameLayer alloc] init];<-- This causes the crash
Inside mover.m where the method moveToward:: is, this is the furthest it will go without crashing. Again the error is child already added. It can't be added again. Why does this happen?
This may just be coincidence. Hard to say because you didn't post any code.
The error message is clear though: you're trying to addChild the same node more than once, either to the same parent or to a different parent. Check your code for situations where this can occur.

How to avoid "special Case" when dealing with paging a UIScrollView with OrientationDidChange on app starting

So, to handle orientation changes (in a view, not a controller) we register with the UIDeviceOrientationDidChange notification. All good.
It gets called on app startup, reporting the correct dimensions but incorrectly saying something changed (due to having landscape views or other software-reasons this may be triggered).
After the few unnecessary messages, it will start sending legitimate messages. The device will report the correct "to" orientation, but it will still give the current frame (and bounds), which is invalid.
To scroll the page to the right, other SO questions lead me to remember to manually set the contentOffset, which has most of what I need. currentPage = current Y offset / width of scrollview. Basic math, cool.
That fixed most of my problems. For proper OO, I gave the scroll view a relayout function, which isn't quite the size of the iPad since it's a subview, and in it I do this:
float currentDeviceWidth = 768;
float currentHeight = 949; //logging the frame from portrait, landscape = 1024 w, 693 h
UIDeviceOrientation o = [[UIDevice currentDevice] orientation];
if (!UIDeviceOrientationIsPortrait(o)) {
//landscape
currentDeviceWidth = 1024;
currentHeight = 693;
}
else
NSLog(#"Moving to port, unless on startup, then its staying as");
Which handles the orientationDidChange: messages, but when the app starts, the scroll view is now smaller than it should be because it set its size as if the bounds it's getting are "about to change", when they're not.
Possible solutions:
a) [self performSelector:#selector(relayout) withObject:nil afterDelay:delayNum];
b) give a time delay before something like "BOOL dontIgnoreLayout" is set/unset
c) Find another way to test for orientation
d) manually go in and find out what's causing all the messages to be sent initially, remove all causes - this option is only possible if it's not created by the system on bootup. I can test this with a fresh project in a sec, though it's an enterprise app, may take some ripping if so.
Wondering if anyone solved this. If not, I have to put in "special case" or "time based" code, neither of which are OO style, at least not my preferred way (nor my coworkers).
If I missed something on SO, let me know, but as you can see, I have found a few answers thus far.
Thanks
I followed other people's examples by testing for Status Bar Orientation instead, it's seemingly always right, and shows conflicting messages with UIDevice currentOrientation... I know this has been found before, but the specific reason this fixed the problem is:
As per suggestions in other threads, I registered for notifications in ViewDidAppear and not viewDidLoad, this combination seems to be the win.

How to know an application is first run on a Mac

On Windows, we can write values into registry to know that
but how can I know if my application is the first time it runs on a mac? I need to perform some initialization task.
Thanks
You are looking for the class NSUserDefaults (see Apple Documentation)
For example:
#define kAlreadyBeenLaunched #"AlreadyBeenLaunched"
if (! [[NSUserDefaults standardUserDefaults] boolForKey:kAlreadyBeenLaunched]) {
// This is our very first launch
// Setting userDefaults for next time
[[NSUserDefaults standardUserDefaults] setValue:[NSNumber numberWithBool:YES] forKey:kAlreadyBeenLaunched];
// Do your first time stuff
//<##>
}
You will use the same class to save and retrieve user preferences.
This values will be saved in ~/Library/Preferences/<your_bundle_id>.plist. This is useful to know for debugging, by looking at the file, but you should not rely on this implementation detail in your code.
There are tons of other people that already asked this.
I guess this one is the most helpful. iPhone: How do I detect when an app is launched for the first time?
Mention: It's working exactly the same way as on the iOS system.

Setting printer-specific options on an NSPrintOperation without a panel

this question has bothered me on and off for about a year, and I thought perhaps someone else would have experience with a similar situation.
Goal: on Mac OS X 10.6-7, to print multiple NSViews to EPSON Stylus Pro 4880 printers using a defined resolution and 'high speed' setting, without showing a print panel.
Current situation: I can create successful NSPrintOperations for each NSView, but if I do not show a print panel, it appears the printer's default resolution is used, which is far too high, and slow, for my needs.
Best solution I have so far: I have tried showing the print panel and defining a Mac OS 'preset' which has the correct print resolution and high speed settings already enabled. The downside here is that the Mac preset overrides the number of copies I have set via NSCopies, which is a problem. The other difficulty of course is having someone always around to press the 'OK' button a few thousand times a day.
Where I'm up to
When the NSPrintOperation runs its panel, it has to set the EPSON-specific printer settings somewhere, but I cannot find where it is saved. They don't appear to be set in [NSPrintInfo printSettings].
I have looked at the PPD for the printer, but I can't find the high speed setting anywhere, and the default resolution defined in the PPD is not actually used as the default when printing. It appears EPSON has their own driver settings which are not taken from the PPD I have, and I am not sure how to set them manually.
Basically, running the NSPrintOperation with a print panel and preset overrides all the settings, including the ones I don't want to override. Running it without the print panel leaves all the settings as default, which is not what I want. Can anyone point me in the right direction to find a solution in between those two?
After the NSPrintOperation's runOperation runs with the dialog, look in PMPrintSettings, the printer-specific parameters may be there. I suppose you could persist PMPrintSettings for the future somehow and load the via updateFromPMPrintSettings.
This is unfortunately the best solution I have found so far though I hate to call it 'best', or even a 'solution'. It comes back to this: run an operation with a panel, and then programmatically 'click' the Print button.
[op runOperationModalForWindow: self.window delegate: self didRunSelector: nil contextInfo: nil];
NSPanel *panel = (NSPanel*)self.window.attachedSheet;
for (NSView *view in ((NSView*)panel.contentView).subviews)
{
if (view.class == [NSButton class])
{
NSButton *button = (NSButton*)view;
if ([button.title isEqualToString: #"Print"])
[button performClick: self];
}
}
or
op.runOperationModalForWindow(window, delegate: nil, didRunSelector: nil, contextInfo: nil)
(window.attachedSheet?.contentView.subviews.filter({ $0 is NSButton }) as [NSButton]).filter({ $0.title == "Print" }).first?.performClick(self)
The downside obviously is a window is needed, while I was hoping to run this as a headless server application. I have tried working with Core Printing and PMPrinter/PMPrintSettings and so forth to no avail. The only thing I have not yet tried is talking to CUPS directly. Maybe I'll save that for a rainy day!

Resources