Sometimes CLLocationManager doesn't give call back to my app. It neither call didUpdateLocation or failure delegate method. I am unable to understand why such behaviour of LocationManager. This thing happen rarely but still happen and break the functionality of location. If anybody can help me regarding this that will be highly appreciated.
I remember the location manager having some kind of issue when an application goes into the background. It could stop updating for 5 to 20 minutes. But after that it would return to better, if not quite normal, behavior.
Related
I have an IOS app where I require the user's current location in order to make an HTTP request to get data about nearby locations. Since I just need the user's location once, I am using the CoreLocation requestLocation method. This issue with this is that it takes roughly 10 seconds (which is stated in the documentation). I realize that there will always be a delay which I am prepared for, but the delay on requestLocation is just too long and ruins the user experience.
I was wondering if anyone has thought of a way to get the users location (just once) in a more timely way.
One solution I thought of was perhaps calling the method within the AppDelegate, as the app starts, and then passing the data to the ViewControllers via some shared object. The issue I foresee here is that AppDelegate does complete it's application:didFinishLaunchingWithOptions: function very quickly so I don't think it'll improve my problem
Another solution I thought of could be to use the startUpdatingLocation method, and then use stopUpdatingLocation after receiving the first location. My issue with this is that startUpdatingLocation may also take a few seconds to start up (documentation), so again this may not improve my problem.
The location I get for the user does not need to be super accurate so I am willing to compromise on precision for performance.
In my app I would like to find out the exact time of any crash from previous session, reported via Crashlytics. I'm setting up Crashlytics this way:
- (void) setUpCrashlytics
{
[[Fabric sharedSDK] setDebug:YES];
[CrashlyticsKit setDebugMode:YES];
[CrashlyticsKit setDelegate:self];
[Fabric with:#[[Crashlytics class]]];
}
I'm simulating an app crash by pressing a button, few minutes after app launches:
[CrashlyticsKit crash];
I tried to get the last session crash time using CrashlyticsDelegate:
#pragma mark - CrashlyticsDelegate Methods
- (void) crashlyticsDidDetectReportForLastExecution:(CLSReport *) report completionHandler:(void (^)(BOOL)) completionHandler
{
BOOL isCrash = report.isCrash; //this is TRUE
NSDate *crashDate = report.crashedOnDate;
NSDate *reportCreation = report.dateCreated;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
completionHandler(YES);
}];
}
But unfortunately, both dates are displaying not the crash time, but last session launch time. Any ideas? Thanks.
Matt here from Crashlytics.
Unfortunately, you've found a bug :( I've taken note of it, and I'll make sure it gets looked at.
I am also interested to know what how you intend to use this information. It's just a use-case I haven't heard of before.
Also, keep in mind that particular delegate callback is problematic. As we indicate in the header documentation, that method's API requires us to sacrifice some reliability features. I'd recommend avoiding it, because our ability to successfully report crashes is much better without it. Yes, we do have plans to add a new read-only API that avoids this tradeoff. For now, I would only recommend it if you have a very pressing need that cannot be satisfied any other way.
Also, since it was brought up in the comments - this API will never be invoked for an out-of-memory termination. Those are technically not crashes, and are not are not reported as such. The mechanisms we use are completely different, and outlined in our documentation here: https://docs.fabric.io/apple/crashlytics/OOMs.html. We use a heuristic, and is not (nor claims to be) 100% reliable. It's pretty good though.
Hope this is helpful - and hit up our support forums/email for further help. Stack overflow is harder to monitor :)
Update:
I thought it would be useful more info here, now that I understand what Radu is trying to achieve. The upshot is using this delegate method cannot achieve what he'd like, and in fact will only make the situation worse.
At the moment Crashlytics is initialized (during the -[Fabric with:] call), the SDK prepares and enqueues any crashes on disk to NSURLSession's background uploading facility. We do this because we want make sure our upload process is not interrupted by another crash. To my knowledge, this is a feature unique to our implementation, we've been using it for years, and it works amazingly well. Crashlytics is basically immune to reporting failures caused by crashes on subsequent launches.
Now, in order to make sure this works as well as possible, we have to do this work synchronously during launch. So, if you start Crashlytics/Fabric on a background thread, or do background work concurrently with the SDK being initialized, it compromises our ability to reliably complete this process before another potential crash could occur.
But, there's another issue. If the delegate is set, and has this method implemented, we must respect the API's contract and ask the delegate if it is ok for us to enqueue the report before we send it. For better or worse, this API also does not do this synchronously. So, when you implement this delegate method, you are opening a large window of time where:
Crashlytics will not send reports because it is waiting for your permission to do so
another crash can cause a loss of pending reports
During the time between the delegate being invoked and the callback being called, you aren't giving more time for reports to be sent. You're just adding delay before the SDK knows that you've given permission for us to send them.
(Personally, I find this API very problematic, and would like to remove it. But, we need to keep it for backwards compatibility. It's really my fault for not implementing a new API that doesn't allow the delegate to cancel the report. Such an API wouldn't be subject to a delay in enqueue the report and could avoid all these problems. One day, we'll have that and we can finally deprecate this one.)
So, to improve early-launch crash handling, I'd recommend the following:
never initialize Crashlytics on a background thread
make sure to initialize Crashlytics as early in launch as you can, ideally the very first thing your application does
never use this delegate method
The only exceptions should really be:
you are attempting to implement a user-facing crash report permissions dialog (it was designed for exactly this use case)
want to blow away sensitive cache data that may be responsible crashes
have some other analytics mechanism and you want to count crashes
I'd also recommend, again, contacting our support. Missing crashes are common. Missing crashes caused by SDK issues are uncommon, are monitored, and we have a ton of SDK-side and backend-side code to understand and minimize them.
My app uses NSTimer variable which uses NSNotificationCenter.postNotificationName to post notification to UIViewController class every seconds.
The issue is the app crashes once in a while with no stacktrace which mean it is a memory issue.
From Instruments, it happens because a 1.78MB increase in VM:Allocation. The allocation just happens randomly.
Here is right after I start the timer:
Here is when I start the timer for a few minutes
So,
I don't see stacktrace or anything. How do I go about debugging
this?
The app use only 7.3MB and is in the foreground, why does it get
kill?? :(
I just leave the timer running, the method only updating existing
variables, what trigger this VM:Allocation???
I use Swift, if that matters
Thanks,
Turn out the problem is in the for loop. I had a big for loop that do a lot of assignment, calling API, etc, every time the NSTimer function is called so sometime when the number of iterations are a little bit too high the VM Allocation kicks in.
The answer I believe is to use autoreleasepool {} inside the for loop. No crash has happens ever since.
Watching these WWDC2013 video helps a bit in term of ideas but not directly.
Improving Your App with Instruments
Intermediate Swift
OK, this one has me stumped. I use the CLLocationManager services (iOS 4.1) in my application. The delegate gets called as it should at first. Then (some arbitrary time interval later), the delegate stops getting called. It almost looks like that RunLoop is getting blocked somewhere.
I have even reduced the callback to one NSLog statement, and I see the same behavior. Do we have any gdb experts out there who could give me some hints how to look at all of the running threads, and determine which one is blocked where ?
As a test, I have also put a button on the GUI which stops are starts both heading and location updates - this seems to unjam things for a while.
Other info:
This is on an iPhone 4, app has been run through Instruments (leaks and allocations), everything looks good there. Any hints would be appreciated, I am currently out of ideas...
Mea culpa... I had errant logic which was firing a timer, shutting off the service. One again, caution is called for when making supposed "small" changes. My apologies if anyone wasted effort on this one....
I've made an application that is pretty simple, it just lets the user capture a number and then saves it in a SQLite DB.
Sometimes, not very common thing, when the user is entering the number to save in my app and he receives a call, answers the call, and then finishes it, the application is frozen after the call, can't do anything on it, not even return to the previous screen.
Does anybody have a clue on what can this be?
The code in this application is so simple =/, I have no idea what could it be.
Thanks in advance!!
How is it frozen? Have you attached the debugger and looked at your processes/threads to see what they are doing?
Could it be a painting issue rather than true freezing?
Need more information.