I have an app using MonoTouch which requires to capture GPS data every 2 mins in background. I found two ways to do it
using startMonitoringSignificantLocationChanges- works in background but not every 2 mins.
Using Timer and StartUpdatingLocation - Timer will be called every 2 mins and then update location.
The problem with startMonitoringSignificantLocationChanges is it doesn't get fired every 2 mins. So i cant use it. The other option of using Timer is better since it gives me a handle over time. But, will it run till my app is in the background for example one hour? Usually, ios apps gets 10 mins in background.
Thanks
You could set app's UIBackgroundModes to location and gets current location changes in background. Battery killer yet works.
Other way is interpolate data from Significant Location Changes between UIApplicationLaunchOptionsLocationKey events.
Related
I'm noticing the "dropped so far" number in the perf monitor constantly increasing up. It reached 2030fps.
Is this number supposed to increase constantly? or I have something wrong in my app.
It will generally increase over time but you want that number to be as low as possible. Basically every javascript action is bundled within 16ms intervals and sent to the main thread, anytime a javascript action takes longer than that it's considered a dropped frame because the main thread no has to wait for the next 16ms batch. Every 16ms results in 1 more dropped frame.
So for example say you have a component that has a slide in animation, and does some work on componentDidMount and that works takes 60ms. That means that if your animation is happening on the javascript thread it will stutter for 4 frames (which is definitely perceptible).
Go through your app and see which renders cause the app to drop frames, then check out the render logic for those components. It's likely that you should be using shouldComponentUpdate or even better PureComponent to prevent wasted renders.
More info here!
In iOS9, when the app goes into the background (all appropriate flags et al for background processing are set, including the new allowsBackgroundLocationUpdates property), the location manager reports updates for 10 seconds then sleeps. After bringing the app back to the foreground and thence to the background again, the updates work continuously as expected.
This is only happening in iOS9 (non-beta) not in iOS7 or iOS8.
Has anyone else come across this behaviour?
The setting, allowsBackgroundLocationUpdates, is documented as being able to control the runtime settings for background processing; however, the flag cannot be set in:
applicationDidEnterBackground:
If the flag failed consistently because it is not possible to utilise in this method; then it would have been easier to track down but it failed only on the first entry to the background.
This entails that there is an issue with the flag being reset in:
applicationWillEnterForeground:
The upshot is that the flag cannot be set in the method life cycles; therefore, the flag is generally set on initialisation of the app which entails that the flag, as it stands, is not particularly useful.
I am currently writing a music playing program for OS X. I am implementing an NSProgessIndicator to show the current playback progress of a song as it plays. How can I efficiently update the progress once per second without getting off-sync with the music?
Ideally I want something like iTunes has where it also has numbers to show the exact playback time and time remaining:
Currently the only thing I can think of is to use an NSTimer with the interval set 1 second and force it run on the main thread through that. However, this seems very inefficient and also like it might not keep perfect sync. Is there a better way to go about this?
You can use the timer just to update the info, in this case the audio current time. AVAudioPlayer has a property with the same name currentTime which will return the time for you as NSTimeInterval(seconds).
I trying to get the tics inside an iOS application using the C clock() function, but it updates very slowly. It looks like the thread in wich is running (is running inside a UIViewController) is inactive most of the time.
The difference between one measurement of the current tics and a subsequent one should be very high, but it change very little except when I'm constantly touching the screen.
Is there a way to use this function and get good results in iOS?
Is there a similar library for iOS? I'm want to use it to create a timer for a game.
Thanks
clock() measures cpu time used, not wall clock, could that be what you're seeing?
Why not try the sleep function?
sleep(X);
X is a number of milliseconds.
First of all, I know there are a few other StackOverflow questions about this subject, but I have read them all and I still am confused about what to do for my situation. I'm probably missing something obvious here, if you could help clarify that would be much appreciated!
I have a app which is doing a lot of work to animate images within a view - mainly comprised of a number of images moving in straight lines for a second or two at a time. I considered at first making them all simple, once off animations using UIView animateWithDuration for the whole duration of the movement. But I found that didn't give me a lot of power to intercept the movement or stop it or check where it was up to, so I scrapped that. My new approach is to use an NSTimer, firing 20 times per second, doing incremental movements. This way I also can intervene (almost) instantly to change the animation or stop it or update a status label based on how far through it is, etc, etc.
First of all...there probably is a better way than this. Feel free to suggest something better!
Assuming this is acceptable though, my issue now is that while these animations are happening, I can't click any of the other controls on the UI. I get no response. It's not like it's just slow or delayed either - the click never comes through. It seems that the NSTimer processing totally locks the UI - but only from new interactions. Changes I make to the UI within the timer processing method happen just fine, and are very snappy.
From what I've read this shouldn't happen. However I also saw a comment on this question saying that if the timer processing is intensive then it could lock the UI thread. I don't see my processing to be that intensive here - certainly no resource requests, just a bit of data manipulating and animating some objects - but I could be underplaying it.
What are my options here? At first I thought I might create a new thread to kick off the timer. But I remember reading that the UI updates have to happen on the main thread anyway. Why is this? And plus, would that really solve the issue? Am I just asking too much of the device to process this timer as well as UI interactions? Is there something else I'm missing?
Any and all advice would be appreciated.
Edit:
I've just found the cause of my UI blocking problem. I was using the animateWithDuration with blocks, but was not setting the options. Therefore UIViewAnimationOptionAllowUserInteraction was not set. I changed it to set this option and my UI is happily responding now.
That said, I'll still leave this question open for specific suggestions regarding my overall approach. Thanks.
I would consider using CADisplayLink. From the documentation:
A CADisplayLink object is a timer object that allows your application to synchronize its drawing to the refresh rate of the display.
Your application creates a new display link, providing a target object and a selector to be called when the screen is updated. Next, your application adds the display link to a run loop.
Once the display link is associated with a run loop, the selector on the target is called when the screen’s contents need to be updated. The target can read the display link’s timestamp property to retrieve the time that the previous frame was displayed. For example, an application that displays movies might use the timestamp to calculate which video frame will be displayed next. An application that performs its own animations might use the timestamp to determine where and how displayed objects appear in the upcoming frame. The duration property provides the amount of time between frames. You can use this value in your application to calculate the frame rate of the display, the approximate time that the next frame will be displayed, and to adjust the drawing behavior so that the next frame is prepared in time to be displayed.
Your application can disable notifications by setting the paused property to YES. Also, if your application cannot provide frames in the time provided, you may want to choose a slower frame rate. An application with a slower but consistent frame rate appears smoother to the user than an application that skips frames. You can increase the time between frames (and decrease the apparent frame rate) by changing the frameInterval property.
When your application finishes with a display link, it should call invalidate to remove it from all run loops and to disassociate it from the target.
CADisplayLink should not be subclassed.
I'm not totally sure how everything is handled in your program, but you might want to just consider having one thread/timer that controls all of the objects and their movements. There's really no need to create a separate thread/timer for every single object, as that will easily cause problems.
You can just create a class for your moving items with some variables that contain information about their direction, speed, duration, etc, and then have a controlling thread/timer calculate and move the objects. You can then intervene onto the one main controller object instead of having to deal with many other objects.
I think you'll find that even if you optimize this, timer based animation like this is not going to perform well.
You might want to ask about the specific things that you think you couldn't do with CoreAnimation. If you solve those issues, you'll end up with a much better result than trying to roll your own.