forked from jessegrosjean/blifecycle
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BLifecycleController.m
108 lines (84 loc) · 4.36 KB
/
BLifecycleController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//
// BLifecycleController.m
// BLifecycle
//
// Created by Jesse Grosjean on 8/23/07.
// Copyright 2007 Blocks. All rights reserved.
//
#import "BLifecycleController.h"
#import <objc/runtime.h>
@interface NSApplication (BLifecycleControllerMethodReplacements)
- (void)BLifecycleController_terminate:(id)sender;
- (void)BLifecycleController_replyToApplicationShouldTerminate:(BOOL)shouldTerminate;
@end
@implementation BLifecycleController
#pragma mark Class Methods
+ (id)sharedInstance {
static id sharedInstance = nil;
if (sharedInstance == nil) {
sharedInstance = [[self alloc] init];
}
return sharedInstance;
}
#pragma mark Init
- (id)init {
if (self = [super init]) {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self selector:@selector(applicationWillFinishLaunchingNotification:) name:NSApplicationWillFinishLaunchingNotification object:nil];
[center addObserver:self selector:@selector(applicationDidFinishLaunchingNotification:) name:NSApplicationDidFinishLaunchingNotification object:nil];
[center addObserver:self selector:@selector(applicationMayTerminateNotification:) name:BApplicationMayTerminateNotification object:nil];
[center addObserver:self selector:@selector(applicationCancledTerminateNotification:) name:BApplicationCancledTerminateNotification object:nil];
[center addObserver:self selector:@selector(applicationWillTerminateNotification:) name:NSApplicationWillTerminateNotification object:nil];
[self performSelector:@selector(applicationLaunching)];
}
return self;
}
#pragma mark Notifications
- (void)notifyLifecycleExtensionObserversForSelector:(SEL)selector {
NSString *configurationElementName = NSStringFromSelector(selector);
NSArray *selectors = [NSArray arrayWithObject:[NSValue valueWithPointer:selector]];
BExtensionPoint *extensionPoint = [[BExtensionRegistry sharedInstance] extensionPointFor:@"com.blocks.BLifecycle.lifecycle"];
for (BConfigurationElement *each in [extensionPoint configurationElementsNamed:configurationElementName]) {
id extensionCallbackObject = [each createExecutableExtensionFromAttribute:@"class" conformingToClass:nil conformingToProtocol:nil respondingToSelectors:selectors];
[extensionCallbackObject performSelector:selector];
}
}
- (void)applicationLaunching {
[self notifyLifecycleExtensionObserversForSelector:@selector(applicationLaunching)];
}
- (void)applicationWillFinishLaunchingNotification:(NSNotification *)notification {
[self notifyLifecycleExtensionObserversForSelector:@selector(applicationWillFinishLaunching)];
}
- (void)applicationDidFinishLaunchingNotification:(NSNotification *)notification {
[self notifyLifecycleExtensionObserversForSelector:@selector(applicationDidFinishLaunching)];
}
- (void)applicationMayTerminateNotification:(NSNotification *)notification {
[self notifyLifecycleExtensionObserversForSelector:@selector(applicationMayTerminateNotification)];
}
- (void)applicationCancledTerminateNotification:(NSNotification *)notification {
[self notifyLifecycleExtensionObserversForSelector:@selector(applicationCancledTerminateNotification)];
}
- (void)applicationWillTerminateNotification:(NSNotification *)notification {
[self notifyLifecycleExtensionObserversForSelector:@selector(applicationWillTerminate)];
}
@end
@implementation NSApplication (BLifecycleControllerMethodReplacements)
+ (void)load {
if (self == [NSApplication class]) {
[NSApplication replaceMethod:@selector(terminate:) withMethod:@selector(BLifecycleController_terminate:)];
[NSApplication replaceMethod:@selector(replyToApplicationShouldTerminate:) withMethod:@selector(BLifecycleController_replyToApplicationShouldTerminate:)];
}
}
- (void)BLifecycleController_terminate:(id)sender {
[[NSNotificationCenter defaultCenter] postNotificationName:BApplicationMayTerminateNotification object:self];
[self BLifecycleController_terminate:sender];
}
- (void)BLifecycleController_replyToApplicationShouldTerminate:(BOOL)shouldTerminate {
if (!shouldTerminate) {
[[NSNotificationCenter defaultCenter] postNotificationName:BApplicationCancledTerminateNotification object:self];
}
[self BLifecycleController_replyToApplicationShouldTerminate:shouldTerminate];
}
@end
NSString *BApplicationMayTerminateNotification = @"BApplicationMayTerminateNotification";
NSString *BApplicationCancledTerminateNotification = @"BApplicationCancledTerminateNotification";