I want to achieve a functionality in which I use the GPS for the loaction updates and when the user is not moving, I want the GPS updates to be paused.
AS per the "Staying on track with Location services " video, I did this:
//Configure Location Manager
self.theLocationManager = [[CLLocationManager alloc]init];
[self.theLocationManager setDelegate:self];
[self.theLocationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.theLocationManager setActivityType:CLActivityTypeFitness];
NSLog(#"Activity Type Set: CLActivityTypeFitness");
[self.theLocationManager setPausesLocationUpdatesAutomatically:YES];
[self.theLocationManager startUpdatingLocation];
Delegates:
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations
{
NSLog(#"Started location Updates");
}
- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager
{
NSLog(#"Pausing location Updates");
}
- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager
{
NSLog(#"Resuming location Updates");
UIAlertView *pop = [[UIAlertView alloc]initWithTitle:#"Info" message:#"Location Updates resumed" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[pop show];
[pop release];
}
I did not get the desired behavior and the delegates "didPause.." and "didResume..." were not even called when the device was Idle.
Ideally GPS updates must stop and resume depending on the state of the device and CLActivityType but its not the case here.
Can anyone help me, what am I doing wrong?
Thanks in advance.
The pause should occur if you let the device at a same location for about 15 minutes.
You probably should use region location when locationManagerDidPauseLocationUpdates: listener is called. Please see update to the first answer in this post:
iOS 6 AutoPause doesn't work
Related
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([HKHealthStore isHealthDataAvailable]){
NSSet *writeDataTypes = [self dataTypesToWrite];
NSSet *readDataTypes = [self dataTypesToRead];
[self.healthStore requestAuthorizationToShareTypes:writeDataTypes readTypes:readDataTypes completion:^(BOOL success, NSError *error) {
NSLog(#"%s",__func__);
if (!success) {
NSLog(#"You didn't allow HealthKit to access these read/write data types. In your app, try to handle this error gracefully when a user decides not to provide access. The error was: %#. If you're using a simulator, try it on a device.", error);
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
// Update the user interface based on the current user's health information.
NSLog(#"=========================== %s",__func__);
});
}];
}
}
requestAuthorizationToShareTypes does not calling back completion method.
I had a similar issue with the permissions box not appearing and hadn't set up the HKHealthStore properly, putting this beforehand fixed it for me
self.healthStore = [[HKHealthStore alloc] init];
Here is a sample implementation that returns types instead of strings as described in the comment section.
-(NSSet*)datatypesToWrite {
NSArray *quantityTypes =
#[HKQuantityTypeIdentifierHeartRate,
HKQuantityTypeIdentifierBodyTemperature,
HKQuantityTypeIdentifierBloodPressureSystolic,
HKQuantityTypeIdentifierBloodPressureDiastolic,
HKQuantityTypeIdentifierRespiratoryRate];
NSMutableArray *hkTypes = [[NSMutableArray alloc] init];
for (NSString *identifier in quantityTypes) {
HKQuantityType *quantType =
[HKObjectType quantityTypeForIdentifier:identifier];
[hkTypes addObject:quantType];
}
// Make sure the types are of the correct style (Quantity, Category, Etc.)
HKCategoryType *catType =
[HKObjectType categoryTypeForIdentifier:HKCategoryTypeIdentifierSleepAnalysis];
[hkTypes addObject:catType];
return [[NSSet alloc] initWithArray:hkTypes];
}
Each time you request new types for the first time the modal permissions dialog will show up (but it won't show up again if you re-prompt for permissions not granted). Apple's guidelines are to prompt for everything you might need, but it feels a bit against best practices to me to request 12 types up front if I know somebody only asked to save into a few of them.
our application shows interstitial iAds after each played level.
At the moment a level finishes, we create the ad:
_interstitial = [[ADInterstitialAd alloc] init];
_interstitial.delegate = self;
and the delegate implements the following callback methods:
- (void)interstitialAdDidUnload:(ADInterstitialAd *)interstitialAd
{
[self finish];
}
- (void)interstitialAd:(ADInterstitialAd *)interstitialAd didFailWithError:(NSError *)error
{
[self finish];
}
- (void)interstitialAdDidLoad:(ADInterstitialAd *)interstitialAd
{
[_interstitial presentFromViewController:self];
}
- (void)interstitialAdActionDidFinish:(ADInterstitialAd *)interstitialAd
{
[self finish];
}
whereas the finish method cleans up things and forwards the user to the main menu.
from the moment the ad object is created until the finish method is called, a spinning wheel is displayed on the screen.
Now the thing is that if no ad is loaded (for example if no internet connection is available) none of the callback functions ever gets called, so we also add a NSTimer when creating the Ad and check back after 10 seconds, like this:
_interstitial = [[ADInterstitialAd alloc] init];
_interstitial.delegate = self;
_timer = [NSTimer scheduledTimerWithTimeInterval:10
target:self
selector:#selector(checkForAds:)
userInfo:nil
repeats:false];
-(void)checkForAds:(NSTimer *)timer
{
[_timer invalidate];
if(!_interstitial.loaded)
[self finish];
}
but this seems very unclean - and also it leads to a 10 seconds spinning wheel delay after each level if no internet connection is available for example (or if the connection is very bad).
so, my questions:
what's the proper way to deal with this? I feel a timer here is not the right thing.
I'm currently considering to create the Ad object before the level starts, and then after the level finishes immediately check the _interstitial.loaded property and show the ad in this case or skip over it otherwise, without using a timer. The problem is that a level session can take quite long (between 1 and 60 minutes I'd say) and I read that ads can expire, however there is no indication in the documentation how long it usually takes until ads expire and what happens in this case. Will the _interstitial.loaded property return false if the ad expired in the meantime in the background? is some callback function called when the ad expires? Is it a viable approach to create the ad object before a level starts (that is, 1-60 minutes before the ad actually gets displayed) and later just check if _interstitial.loaded is true and in this case display the ad?
Recently i have started working on iOS application development. These days i am working on a Music Player which must have following functionality:
-Online buffering of the song from php web service.
-Play, pause, stop, next song, previous song.
-two sliders, one is for volume control and other is for showing the play time of the song.
-shuffle, repeat song.
I have tried these things with AVPlayer and AVAudioPlayer but in AVAudioPlayer it is not possible to stream the data from url i think because i have tried a lot then i done this by using AVplayer but it is not supporting options like volume control etc. and even the buffering is also not proper like a have to press play button again if the buffering stops at some point. I need an urgent help for this Audio Player any tutorial any example which i can understand easily as i am new in this field.
Here is the code
NSURL *url = [[NSURL alloc] initWithString:#"http://www.androidmobiapps.com/extrememusic/app/songs/1.mp3"];
[self setupAVPlayerForURL:url];
I am calling this song at viewdidload
-(void) setupAVPlayerForURL: (NSURL*) url {
AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset];
audioPlayer = [AVPlayer playerWithPlayerItem:anItem];
[audioPlayer addObserver:self forKeyPath:#"status" options:0 context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (object == audioPlayer && [keyPath isEqualToString:#"status"]) {
if (audioPlayer.status == AVPlayerStatusFailed) {
NSLog(#"AVPlayer Failed");
} else if (audioPlayer.status == AVPlayerStatusReadyToPlay) {
NSLog(#"AVPlayer Ready to Play");
} else if (audioPlayer.status == AVPlayerItemStatusUnknown) {
NSLog(#"AVPlayer Unknown");
}
}
}
I've done functions you mentioned above as a class, and open source it. Whatever you wanna use the class directly or treat it as an AVFoundation beginner examples. Good luck!
Watch this repo on GitHub here
Ok what the heck is up with iOS6 and how it handles Bluetooth LE disconnections? Before the device would disconnect immediately but now, for some strange reason, the device waits to disconnect for about 30-60 seconds. I need it to disconnect ASAFP!
I've been searing all over the internet trying to figure out how to initiate an immediate disconnection from the peripheral and I found this nifty email that explains a workaround is to unsubscribe from notifications on the service characteristics.
Now I think I'm doing that.. When I want to disconnect I call [connected_device setNotifyValue:NO forCharacteristic:connected_characteristic]
Then, in the didUpdateNotificationStateForCharacteristic function, I have...
if((int)characteristic.isNotifying == 0){
[manager cancelPeripheralConnection:peripheral];
}
In the function didDisconnectPeripheral...
connected_peripheral = nil;
connected_characteristic = nil;
[connected_peripheral release];
[connected_characteristic release];
I've also taken a good hard look at Apple's CoreBluetooth Temperature Sensor example but it hasn't really helped much....
Any help on this would be amazing!! I just don't know what I'm missing.....
UPDATE: It looks like the app needs to be connected to the bluetooth device for at least a minute before it is allowed to disconnect. If the app is connected for over a minute it will disconnect immediately when the command is sent. Otherwise, it will wait until that one minute mark to actually disconnect.
UPDATE: When I try to disconnect before the one minute mark, I get the following output to the log when the device actually disconnects.
Oct 24 16:49:35 Christophers-iPhone awdd[8168] <Error>: libMobileGestalt copySystemVersionDictionaryValue: Could not lookup ReleaseType from system version dictionary
Oct 24 16:49:35 Christophers-iPhone awdd[8168] <Error>: CoreLocation: CLClient is deprecated. Will be obsolete soon.
According to Apple, this new feature is "by design".
The way we resolved this issue was to send a command to the Peripheral and have it disconnect from its end. If you do this, then the disconnect is immediate. I do not know why Apple changed this behavior from iOS5 to iOS6 but they must have had their reasons. Of course this solution only works if you have access to the Peripheral firmware and can change it. If there is a different solution, then we have not found it.
That was a bug in iOS 6.0, in 6.1 it's fixed.
I am writing an app for iOS 4 that needs to play a sound (or vibrate) at regular (user-specified) intervals when in the background. I do not want to use local notifications because there is no need to have a clickable alert appear.
This code (from Apple's docs) gets triggered when my app switches to the background:
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
NSLog(#"I am now in the background");
// Here I need something like this:
[self performSelector:#selector(myMethod) withObject:nil afterDelay:5.0];
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
The [self performSelector: ...] line gets executed when the app is switched to the background, but the myMethod method is not called until the app is switched back to the foreground (not in 5 seconds, as set at the afterDelay: parameter). So, how can I cause the method to be called while the app is still in the background?
Nevermind! Scheduling local notifications can do what I need.
It is better to use local notifications along with UIApplication cancelAllLocalNotifications to clear out existing notifications which the user has not dismissed. Perfect! Plus, the user gets the added benefit if a popup message to let them know what the sound (or vibrate) was for.