Check Something Every Time App Loaded - objective-c

I want to check something every time there is a new session in an iOS application.
Neither -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ nor -(void)applicationDidBecomeActive:(UIApplication *)application{ are achieving what I want here.
What do you recommend to achieve what I want? I want to keep multitasking...

You can add your object as an observer for the UIApplicationWillEnterForegroundNotification notfication (or related notifications) in order for it to perform some check whenever the app enters the foreground. Using this code, you can associate the notification with a block:
[[NSNotificationCenter defaultCenter]
addObserverForName:UIApplicationWillEnterForegroundNotification
object:nil
queue:nil
usingBlock:^(NSNotification *notification) {
// Whatever check is needed
}];
You are not restricted to doing all that work in your app delegate.

Related

Register a function to be called just before program is quit

So I need to register a function on OSX (using Xcode / objective C) that will register a particular function to be called whenever the program terminates.
I ran into this but i guess that's for iOS and not for OSX.
I replaced UI with NS and gave it a shot, but it did not work.
NSApplication *app = [NSApplication sharedApplication];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(applicationWillTerminate:)
name:BeCalledOnExit object:app];
but that is not compiling. it says something on name: being an undeclared identifier when it is clearly on the .h & .m file before the function.
i ran into another chap who used this:
-(BOOL) applicationShouldTerminateAfterLastWindowClosed:(NSApplication *) sender{
return TRUE
}
but it doesnt work for me as my app is a complete status bar app.
Basically i'm creating some temp files during my app and just before quitting, i want to make sure that my app is clearing out these files. I am putting it in /tmp/.. Woudn't want too much space to be taken.
i would really like to have a solution like in gcc/python,
atexit(functionName);
Implement - (void)applicationWillTerminate:(NSNotification *)notification on your AppDelegate and it will be called just before the application will terminate
So the Implementation of your AppDelegate could look something like:
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
NSLog(#"I FINISHED LAUNCHING!");
}
- (void)applicationWillTerminate:(NSNotification *)notification
{
NSLog(#"I WILL TERMINATE NOW!!!");
}
#end
Your App Delegate should implement the - (void)applicationWillTerminate:(NSNotification *)notification to get the notification
(OR)
You can implement applicationShouldTerminate and perform clean of your files and return appropriate NSApplicationTerminateReply if your clean up fails
If you want to use a notification, you should be observing NSApplicationWillTerminateNotification.
NSApplication *app = [NSApplication sharedApplication];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(applicationWillTerminate:)
name: NSApplicationWillTerminateNotification object:app];
/*A notification named NSApplicationWillTerminateNotification.*/
- (void)applicationWillTerminate:(NSNotification *)notification
{
}

How to resume a movie that's being played with presentMoviePlayerViewControllerAnimated

I'm uisng this code to display a movie:
MPMoviePlayerViewController *mp = [[MPMoviePlayerViewController alloc]
initWithContentURL:movieURL];
mp.moviePlayer.movieSourceType = MPMovieSourceTypeUnknown;
[self presentMoviePlayerViewControllerAnimated:mp]; [mp.moviePlayer play];
The code is working fine. However when the application goes to the background while playing a movie, when the app comes back in the foreground the movieplayer is not displayed. (I see the view of the controller that called presentMoviePlayerViewControllerAnimated:mp
Is it possible when entering the foregound to resume the movie that was playing before the app went to the background?
Have you set the UIBackgroundmode to audio and also there has been problem with playing the video after app enters foreground .Refer this Tutorial on MPMoviePlayerViewController Also you can try using MPMoviePlayerViewController which has options for implementing various notifications .
you can implement notification techniques to handle it. Add a notification in the class where movie player is playing and associate with it a selector. When app goes to background then in the delegate method
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
UIApplication *app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier bgTask = 0;
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
}];
}
write this code.Actually when app goes background it pauses the MPMoviePlayerController so when it is coming to foreground you post the notification which call the method in class where movie controller is implemented and play it again in this method.
-(void)playIntroAnimationAgain
{
[[NSNotificationCenter defaultCenter]removeObserver:self name:NOTIFICATION_PlayAgain_Player object:nil];
[self.moviePlayerController play];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playIntroAnimationAgain)name:NOTIFICATION_PlayAgain_Player object:nil];
}
It solved my problem.

Is it possible to monitor other application using Cocoa on Mac?

For example, get the notification that another Application is becoming Active on the screen, or resign active state.
Sure. In your app delegate class, you can use NSWorkspace to get notified when an app becomes active (NSWorkspaceDidActivateApplicationNotification) or resigns active (NSWorkspaceDidDeactivateApplicationNotification). See the documentation on NSWorkspace for more info.
In your controller class, you'd do something like this:
- (id)init {
if ((self = [super init])) {
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self
selector:#selector(appDidActivate:)
name:NSWorkspaceDidActivateApplicationNotification
object:nil];
}
return self;
}
- (void)dealloc {
[[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self];
[super dealloc];
}
- (void)appDidActivate:(NSNotification *)notification {
NSDictionary *userInfo = [notification userInfo];
NSLog(#"userInfo == %#", userInfo);
}
The key points are basically that you need to register to receive the notifications like shown in -init. You'd repeat the code to add another observer for each additional notification name that you want (e.g NSWorkspaceDidDeactivateApplicationNotification).
Another important thing to remember is to remove yourself as an observer in -dealloc (or elsewhere), so that NSWorkspace doesn't try to notify your controller object after it's been released+dealloc'd (and would no longer be valid).
In the specified -appDidActivate: method, do whatever you need to with the info about the app in question.
If you want something simpler than distributed objects, you could use distributed notifications from the distributed notification center. However, these are not posted unless you built the application. For monitoring when applications start or quit, you can use NSWorkspace and its notification center (suggested by NSGod)

NSNotificationCenter Scope definition

So I'm new to NSNotifications, I am wondering what the scope is. I.e. If I have an Application Delegate Class, and it is the receiver of a notification:
-(id)init
{
[ super init];
if (!self) return nil;
// Add to our notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(receiveUpdateRequest:)
name:#"RequestStatusUpdate"
object:nil];
return self;
}
And has this method run on receive:
- (void) receiveUpdateRequest:(NSNotification *) notification
{
// Check the Notification Name
if ([[notification name] isEqualToString:#"RequestStatusUpdate"]){
NSLog (#"Recieved Update Status!");
}
else {
NSLog(#"Recieved Notification: %#",[notification name]);
}
}
Can I post a notification like so:
[[NSNotificationCenter defaultCenter] postNotificationName:#"RequestStatusUpdate" object:self];
From another object instance any where in my App?
Even for instance an object that instantiated by virtue of a NIB being loaded:
summaryWindow = [[SummaryWindowController alloc] initWithWindowNibName:#"SummaryWindow" owner:globalStatusController];
Do I have to have anything else configured in my summaryWindow Class to be able to call the postNotificationName method.
Or put a different way is the [NSNotificationCenter defaultCenter] global for all instances of all objects in my Application, I would assume thats how its suppose to work but currently when I call this method via an IBAction in my SummaryWindow , the notification does not seemed to be received.
I have tested both [NSThread currentThread] and the default Notification center and it does look like I'm in the thread and the same notification center ( which I think is always global). I am only looking into the thread thing as its come up on a few other threads.
2011-08-22 20:57:11.452 AppName[23102:1307] Using Default Notification Center: <CFNotificationCenter 0x10012c900 [0x7fff7d302ea0]>
2011-08-22 20:57:20.366 AppName[23102:1307] Using Default Notification Center: <CFNotificationCenter 0x10012c900 [0x7fff7d302ea0]>
Wow that was lame, I just found [[NSNotificationCenter defaultCenter] removeObserver:self]; in some earlier code. I had it in dealloc but some how managed to miss it in another NSTask method I was working on.
Or put a different way is the [NSNotificationCenter defaultCenter] global for all instances of all objects in my Application
Yes.
I would assume thats how its suppose to work but currently when I call this method via an IBAction in my SummaryWindow , the notification does not seemed to be received.
That's because you're registering in init. I'm betting this is Mac, and on Mac the application delegate is almost always instantiated from a nib file. You need to do this work in awakeFromNib.
Note that you generally do not need to check the notification's name. It's generally best to have a different method for each notification callback. You should also always create a string constant for your notification names. It's way too easy to mis-type them.

Receiving UIPasteboard (generalPasteboard) notification while in the background

In there a way to do this? I register my object for UIPasteboardChangedNotification at launch time, but when sending it to the background and opening (for instance) Safari and copying some text, my handler never gets called.
(I'm using just the simulator for now).
I've used both:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(pasteboardNotificationReceived:)
name:UIPasteboardChangedNotification
object:[UIPasteboard generalPasteboard]];
and:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(pasteboardNotificationReceived:)
name:UIPasteboardChangedNotification
object:nil ];
to register my handler.
I had the same problem. According to the UIPasteboard Class Reference documentation for the changeCount property (emphasis is mine):
Whenever the contents of a pasteboard changes—specifically, when pasteboard items are added, modified, or removed—UIPasteboard increments the value of this property. After it increments the change count, UIPasteboard posts the notifications named UIPasteboardChangedNotification (for additions and modifications) and UIPasteboardRemovedNotification (for removals). ... The class also updates the change count when an application reactivates and another application has changed the pasteboard contents. When users restart a device, the change count is reset to zero.
I had read this to mean that my application would receive UIPasteboardChangedNotification notifications once my app was reactivated. A careful reading reveals, however, that it is only the changeCount that is updated when the app is reactivated.
I dealt with this by tracking the pasteboard's changeCount in my app delegate and posting the expected notification when I find the changeCount has been changed while the app was in the background.
In the app delegate's interface:
NSUInteger pasteboardChangeCount_;
And in the app delegate's implementation:
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(pasteboardChangedNotification:)
name:UIPasteboardChangedNotification
object:[UIPasteboard generalPasteboard]];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(pasteboardChangedNotification:)
name:UIPasteboardRemovedNotification
object:[UIPasteboard generalPasteboard]];
...
}
- (void)pasteboardChangedNotification:(NSNotification*)notification {
pasteboardChangeCount_ = [UIPasteboard generalPasteboard].changeCount;
}
- (void)applicationDidBecomeActive:(UIApplication*)application {
if (pasteboardChangeCount_ != [UIPasteboard generalPasteboard].changeCount) {
[[NSNotificationCenter defaultCenter]
postNotificationName:UIPasteboardChangedNotification
object:[UIPasteboard generalPasteboard]];
}
}