This repository has been archived by the owner on Mar 9, 2022. It is now read-only.
/
TDReplicator+Backgrounding.m
104 lines (84 loc) · 3.45 KB
/
TDReplicator+Backgrounding.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
//
// TDReplicator+Backgrounding.m
// CouchbaseLite
//
// Created by Jens Alfke on 8/15/13.
//
//
#if TARGET_OS_IPHONE
#import "TDReplicator.h"
#import "TDInternal.h"
#import "MYBlockUtils.h"
#import <UIKit/UIKit.h>
@implementation TDReplicator (Backgrounding)
// Called when the replicator starts
- (void) setupBackgrounding {
_bgTask = UIBackgroundTaskInvalid;
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appBackgrounding:)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appForegrounding:)
name: UIApplicationWillEnterForegroundNotification
object: nil];
}
- (void) endBGTask {
if (_bgTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask: _bgTask];
_bgTask = UIBackgroundTaskInvalid;
}
}
// Called when the replicator stops
- (void) endBackgrounding {
[self endBGTask];
[[NSNotificationCenter defaultCenter] removeObserver: self
name: UIApplicationDidEnterBackgroundNotification
object: nil];
[[NSNotificationCenter defaultCenter] removeObserver: self
name: UIApplicationWillEnterForegroundNotification
object: nil];
}
// Called when the replicator goes idle
- (void) okToEndBackgrounding {
if (_bgTask != UIBackgroundTaskInvalid) {
LogTo(Sync, @"%@: Now idle; stopping background task (%d)", self, _bgTask);
[self stop];
}
}
- (void) appBackgrounding: (NSNotification*)n {
// Danger: This is called on the main thread! It switches to the replicator's thread to do its
// work, but it has to block until that work is done, because UIApplication requires
// background tasks to be registered before the notification handler returns; otherwise the app
// simply suspends itself.
NSLog(@"APP BACKGROUNDING");
MYOnThreadSynchronously(_thread, ^{
if (self.active) {
_bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{
// Called if process runs out of background time before replication finishes:
MYOnThreadSynchronously(_thread, ^{
LogTo(Sync, @"%@: Background task (%d) ran out of time!", self, _bgTask);
[self stop];
});
}];
LogTo(Sync, @"%@: App going into background (bgTask=%d)", self, _bgTask);
if (_bgTask == UIBackgroundTaskInvalid) {
// Backgrounding isn't possible for whatever reason, so just stop now:
[self stop];
}
} else {
LogTo(Sync, @"%@: App going into background", self);//TEMP
[self stop];
}
});
}
- (void) appForegrounding: (NSNotification*)n {
// Danger: This is called on the main thread!
NSLog(@"APP FOREGROUNDING");
MYOnThread(_thread, ^{
if (_bgTask != UIBackgroundTaskInvalid) {
LogTo(Sync, @"%@: App returning to foreground (bgTask=%d)", self, _bgTask);
[self endBGTask];
}
});
}
@end
#endif // TARGET_OS_IPHONE