SNAPSHOT SAVED in Cache/Snapshots - iphone

**Hi every1,
Snapshots of my app are being logged in Cache/Snapshots folder. I just don't need to log these snapshots due to the security concerns.
I have used this below piece of code, which I got this from net to remove the snapshots which are saved :
- (void)applicationDidEnterBackground:(UIApplication *)application {
UIApplication* app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier __block bgTask;
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
if(UIBackgroundTaskInvalid != bgTask) {
// Start the long-running task to kill app after some secs and return immediately.
dispatch_after( dispatch_time(DISPATCH_TIME_NOW, KILL_IN_BACKGROUND_AFTER_SECS * 1e09),
dispatch_get_main_queue(), ^{
if(goingToQuit) exit(0);
[app endBackgroundTask: bgTask];
});
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// cancel ongoing background suicide.
goingToQuit = NO;
}
I dont want to log these snapshots, please advice on this.**

I think you are not adding code to delete files :( Please refer my code snippet
- (void) deleteFiles {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self beingBackgroundUpdateTask];
NSError *error = nil;
// dirPath is path to your snapshot directory
NSArray *directoryContents = [fileMgr contentsOfDirectoryAtPath:dirPath error:&error];
if (error == nil) {
for (NSString *path in directoryContents) {
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:path];
BOOL removeSuccess = [fileMgr removeItemAtPath:fullPath error:&error];
if (!removeSuccess) {
// Error handling
...
}
}
} else {
// Error handling
}
// Do something with the result
[self endBackgroundUpdateTask];
});
}
- (void) beingBackgroundUpdateTask {
self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundUpdateTask];
}];
}
- (void) endBackgroundUpdateTask {
[[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}

Related

Core Data : inserting Objects crashed in global queue [ARC - iPhone simulator 6.1]

I have a very simple Core Data demo, in which there is only one button.
When I click the 'run' button, the App creates 10,000 objects in a for-loop, which is running in the global queue.
Update for more detail : If I put the for-loop in main thread, it runs well.
Update for my intent : I know that MOC is not thread-safe, but according to the Apple doc, we can also use serial queue to access the MOC, and the serial queue uses more than one threads.
Here I create the Core Data stack:
#pragma mark - Core Data Stack
- (NSManagedObjectContext *)managedObjectContext
{
if (nil != _managedObjectContext) {
return _managedObjectContext;
}
_managedObjectContext = [[NSManagedObjectContext alloc] init];
if (self.persistentStoreCoordinator) {
[_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel
{
if (nil != _managedObjectModel) {
return _managedObjectModel;
}
_managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (nil != _persistentStoreCoordinator) {
return _persistentStoreCoordinator;
}
NSString *storeType = NSSQLiteStoreType;
NSString *storeName = #"model.sqlite";
NSURL *storeURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent:storeName]];
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];
NSError *error = nil;
if (![_persistentStoreCoordinator addPersistentStoreWithType:storeType
configuration:nil
URL:storeURL
options:nil
error:&error])
{
NSLog(#"Error : %#\n", [error localizedDescription]);
NSAssert1(YES, #"Failed to create store %# with NSSQLiteStoreType", [storeURL path]);
}
return _persistentStoreCoordinator;
}
#pragma mark -
#pragma mark Application's Documents Directory
- (NSString *)applicationDocumentsDirectory
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
return basePath;
}
after app has launched :
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
if (self.managedObjectContext) {
;
}
return YES;
}
When I click the button :
- (IBAction)runButtonDidClick:(id)sender
{
/**
* Access the moc using different threads to make deadlock.
*/
[self runSave];
}
- (void)runSave
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *moc = appDelegate.managedObjectContext;
if (moc) {
for (int j = 0; j < 10000; ++j) {
People *people = [NSEntityDescription insertNewObjectForEntityForName:#"People" inManagedObjectContext:moc];
people.name = #"noname";
}
NSLog(#"**********IN SAVE %#", [NSThread currentThread]);
NSError *error = nil;
if ([moc save:&error]) {
;
}
NSLog(#"**********OUT SAVE %#", [NSThread currentThread]);
}
});
}
For clicking the run button some times, maybe 2 or 3 or 4... It crashes
I could not figure out why...
Thanks for any help.
Core data should be always work on thread witch have moc.
the only job for performBlock and performBlockAndWait is that take care of thread safety. With it inserting to Core Data will always running in the right thread. You can define moc on whatever thread you want - performBlock always choose the right one.
So:
[self.managedObjectContext performBlock:^{
for(NSDictionary *dic in arr) {
//inserting here!
}
}];
In your case:
- (void)runSave
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *moc = appDelegate.managedObjectContext;
if (moc) {
[moc performBlock:^{
for (int j = 0; j < 10000; ++j) {
People *people = [NSEntityDescription insertNewObjectForEntityForName:#"People" inManagedObjectContext:moc];
people.name = #"noname";
}
NSError *error = nil;
if ([moc save:&error]) {
;
}
}];
}
});
}

Repeat alarm at particular time interval

Issue is, i put a date picker programmatically. In date picker i just used to display time from 1mins to 23 hours. User is supposed to set the time in the picker, and set up the notification.
Now,i get notification in background but only one time.I have to repeat time until timer will not stop.
I found too many links and source but not able to solve this issue
My Code:
In Appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
application.applicationIconBadgeNumber = 0;
//------ Handle launching from a notification-------
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
self.localNotification =[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (self.localNotification)
{
application.applicationIconBadgeNumber = self.localNotification.applicationIconBadgeNumber-1;
NSLog(#"badge number: %d", application.applicationIconBadgeNumber);
[self playSoundWithNotification:self.localNotification];
}
else
{
[[UIApplication sharedApplication]cancelAllLocalNotifications];
}
}
didenterinbackground:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"Application entered background state.");
NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
dispatch_async(dispatch_get_main_queue(), ^{
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}];
dispatch_async(dispatch_get_main_queue(), ^{
while ([application backgroundTimeRemaining] > 1.0)
{
NSString *str_friend = #"Hello,";
if (str_friend)
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif)
{
localNotif.alertBody = [NSString stringWithFormat:
NSLocalizedString(#"%# has a message for you.", nil), str_friend];
localNotif.alertAction = NSLocalizedString(#"Read Msg", nil);
localNotif.soundName = #"alarmsound.caf";
//localNotif.soundName =[NSString stringWithFormat:#"%#.mp3",str_Alarm];
localNotif.applicationIconBadgeNumber = 1;
[application presentLocalNotificationNow:localNotif];
NSLog(#"sound: %#, alertAction: %#, alerBody: %#",localNotif.soundName, localNotif.alertAction, localNotif.alertBody);
str_friend = nil;
break;
}
}
}
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}
-
(void)playSoundWithNotification:(UILocalNotification *)notification
{
notification.soundName=[NSString stringWithFormat:#"%#.mp3",str_Alarm];
NSLog(#"soundname: %#",notification.soundName);
}
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif
{
testDate=notif.fireDate;
NSLog(#"DATE IS: %#, %#",testDate, notif.fireDate);
// Handle the notificaton when the app is running
NSLog(#"Recieved Notification %#",notif);
[self playSoundWithNotification:notif];
[self _showAlert:[NSString stringWithFormat:#"%#",str_Motivation] withTitle:#"Daily Achiever"];
}
- (void) _showAlert:(NSString*)pushmessage withTitle:(NSString*)title
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:title message:pushmessage delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
if (alertView)
{
}
}
in myviewcontroller:
-(void)insert:(NSDate *)fire
{
appDelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.localNotification = [[UILocalNotification alloc] init];
NSLog(#"localNotification %#", appDelegate.localNotification);
if (appDelegate.localNotification == nil)
return;
appDelegate.localNotification.fireDate = fire;
appDelegate.localNotification.timeZone = [NSTimeZone defaultTimeZone];
appDelegate.localNotification.alertBody = appDelegate.str_Motivation;
appDelegate.localNotification.alertAction = #"View";
appDelegate.localNotification.soundName = [NSString stringWithFormat:#"%#.mp3",appDelegate.str_Alarm];
appDelegate.localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber]+1;
NSLog(#"localNotification.alertBody %#", appDelegate.localNotification.alertBody);
NSLog(#"localNotification.soundName %#",appDelegate.localNotification.soundName);
[[UIApplication sharedApplication] scheduleLocalNotification:appDelegate.localNotification];
}
Please Help.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
......
......
if (localNotif)
{
localNotif.alertBody = [NSString stringWithFormat:
NSLocalizedString(#"%# has a message for you.", nil), str_friend];
localNotif.alertAction = NSLocalizedString(#"Read Msg", nil);
localNotif.soundName = #"alarmsound.caf";
localNotif.applicationIconBadgeNumber = 1;
[localNotif setRepeatInterval:NSMinuteCalendarUnit];
[application presentLocalNotificationNow:localNotif];
str_friend = nil;
break;
}
}
I got solution.

iPhone timer task for long processes

When the application enters into background state, the time used to run in background is not working. Following is the code.
In AppDelegate.h,
#interface AppDelegate : UIResponder <UIApplicationDelegate>
{
BOOL status;
UIBackgroundTaskIdentifier bgTask;
}
In AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
dispatch_async(dispatch_get_main_queue(), ^{
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}];
dispatch_async(dispatch_get_main_queue(), ^{
if ([application backgroundTimeRemaining] > 1.0) {
// Start background service synchronously
[[vController getInstance] run];
}
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
dispatch_async(dispatch_get_main_queue(), ^{
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}];
dispatch_async(dispatch_get_main_queue(), ^{
if ([application backgroundTimeRemaining] > 1.0) {
// Start background service synchronously
[[vController getInstance] stopbackground];
}
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}
And in view Controller.h,
#interface vController : UIViewController <AVAudioPlayerDelegate>
-(void) run;
-(void) stopbackground;
-(void) getMessage:(NSTimer*)theTimer;;
+(vController*) getInstance;
#property (nonatomic,retain) NSTimer * timer;
#end
the view controller.m,
#implementation vController
#synthesize timer;
vController *tvc;
- (void)viewDidLoad
{
[super viewDidLoad];
tvc = self;
// Do any additional setup after loading the view, typically from a nib.
}
+ (vController*) getInstance
{
return tvc;
}
- (void)stopbackground
{
timer = [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:#selector(getMessage:) userInfo:nil repeats:YES];
}
- (void)run
{
timer = [NSTimer scheduledTimerWithTimeInterval:15.0 target:self selector:#selector(getMessage:) userInfo:nil repeats:YES];
}
- (void) getMessage:(NSTimer*) theTimer
{
NSError *error;
NSString *path = [[NSBundle mainBundle] pathForResource:#"alert" ofType:#"mp3"];
AVAudioPlayer* theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:&error];
if (theAudio == nil) {
NSLog(#"%#", [error description]);
}
NSLog(#"Hi");
theAudio.delegate = self;
theAudio.numberOfLoops = 1;
[theAudio play];
}
- (void) dealloc{
[timer release];
[super dealloc];
}
I am using it on simulator 6.0
Depending on your use case, this may not be possible. Namely, Apple does not let you execute code in the 'background' unless you are performing one of the following tasks:
Apps that play audible content to the user while in the background,
such as a music player app
Apps that keep users informed of their location at all times, such as a navigation app
Apps that support Voice over Internet Protocol (VoIP)
Newsstand apps that need to download and process new content
Apps that receive regular updates from external accessories
Read more at :http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
By Creating Instance you can Run Background Task in Any View-controller like Below:
// Declare the following in YourViewController.h file.
+ (YourViewController *)getInstance;
- (void)run;
-(void)stopbackground;
// Define the Vollowing in YourViewController.m file.
static YourViewController *instance = NULL;
+(YourViewController *)getInstance {
#synchronized(self) {
if (instance == NULL) {
instance = [[self alloc] init];
}
}
return instance;
}
- (void)run
{
// strat Back ground task
}
-(void)stopbackground
{
// Stop Background task
}
in AppDelegate.h file Declare the Following
UIBackgroundTaskIdentifier bgTask;
in AppDelegate.m file use the Following Methods.
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(#"Application entered background state.");
// bgTask is instance variable
NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
dispatch_async(dispatch_get_main_queue(), ^{
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}];
dispatch_async(dispatch_get_main_queue(), ^{
if ([application backgroundTimeRemaining] > 1.0) {
// Start background service synchronously
[[YourViewController getInstance] run];
}
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(#"Application entered background state.");
// bgTask is instance variable
NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
dispatch_async(dispatch_get_main_queue(), ^{
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}];
dispatch_async(dispatch_get_main_queue(), ^{
if ([application backgroundTimeRemaining] > 1.0) {
// Start background service synchronously
[[YourViewController getInstance] stopbackground];
}
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

application run in background

I want to develop app that get current location in background mode of app , and generate according to location particular event ,
So , how can I make app that go in to background and get continues location.
Apple has written a demo app doing exactly what is asked: Breadcrumb
- (CLLocationManager *)locationManager
{
if (locationManager != nil)
return locationManager;
locationManager = [[CLLocationManager alloc] init];
//locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
locationManager.delegate = self;
return locationManager;
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplication* app = [UIApplication sharedApplication];
// Request permission to run in the background. Provide an
// expiration handler in case the task runs long.
NSAssert(bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// Synchronize the cleanup call on the main thread in case
// the task actually finishes at around the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[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.
// Synchronize the cleanup call on the main thread in case
// the expiration handler is fired at the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
});
}
- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation`
{
NSLog(#"location changed");
UIApplication* app = [UIApplication sharedApplication];
NSArray* oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
// Create a new notification.
UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];
if (alarm)
{
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.repeatInterval = 0;
alarm.soundName = #"b.wav";
alarm.alertBody = #"Location changed!";
[app scheduleLocalNotification:alarm];
}
}

Why does the following code to play audio in the background not work?

I want to play audio in the background when I quit an application, but the following code does not appear to achieve this. What might I be doing wrong?
- (void)applicationDidEnterBackground:(UIApplication *)application
{
printf("hello");
UIApplication *app = [UIApplication sharedApplication];
//beginBackgroundTaskWithExpirationHandler *bgTask;
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{[theAudio play]; [app
endBackgroundTask:bgTask]; bgTask =UIBackgroundTaskInvalid;
NSString *path = [[NSBundle mainBundle] pathForResource:#"Piano"ofType:#"caf"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}];
// 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.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;;
NSLog(#"hello%#",bgTask);
}
An app cannot play sounds in the background unless the audio output was started before the app was put into the background.
You have a wrong order. Your code have to look like so:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
printf("hello");
UIApplication *app = [UIApplication sharedApplication];
//beginBackgroundTaskWithExpirationHandler *bgTask;
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// A handler to be called shortly before the application’s remaining background time reaches 0. You should use this handler to clean up and mark the end of the background task. Failure to end the task explicitly will result in the termination of the application.
[theAudio pause];
[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.
NSString *path = [[NSBundle mainBundle] pathForResource:#"Piano"ofType:#"caf"];
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
NSLog(#"hello%#",bgTask);
}