-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathState.x
87 lines (71 loc) · 2.65 KB
/
State.x
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
#import <Foundation/Foundation.h>
#import <rootless.h>
#import "State.h"
#import "NSDistributedNotificationCenter.h"
#import "Constants.h"
static NSString *stateFile = ROOT_PATH_NS(@"/var/mobile/Library/.beepserv_state");
static NSString *otherStateFile = ROOT_PATH_NS(@"/var/mobile/.beepserv_state");
@implementation BPState
- (instancetype __nonnull)initWithCode:(NSString * __nullable)code
secret:(NSString * __nullable)secret
connected:(BOOL)connected
error:(NSError * __nullable)error {
self = [super init];
self.code = code;
self.secret = secret;
self.connected = connected;
self.error = error;
return self;
}
- (NSString * __nonnull)description {
return [NSString stringWithFormat:@"<BPState code:%@ secret:%@ connected:%d error:%@", self.code, self.secret, self.connected, self.error];
}
- (NSDictionary * __nonnull)serializeToDictionary {
NSMutableDictionary *state = @{
kConnected: @(self.connected)
}.mutableCopy;
if (self.code)
state[kCode] = self.code;
if (self.secret)
state[kSecret] = self.secret;
if (self.error)
state[kError] = self.error;
return state;
}
- (void)broadcast {
NSDictionary *state = [self serializeToDictionary];
[[NSDistributedNotificationCenter defaultCenter]
postNotificationName: kNotificationUpdateState
object: nil
userInfo: state
];
}
- (void)writeToDiskWithError:(NSError * __nullable * __nullable)writeErr {
NSDictionary *state = [self serializeToDictionary];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", stateFile]];
[state writeToURL:url error:writeErr];
NSURL *otherUrl = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", otherStateFile]];
[state writeToURL:otherUrl error:writeErr];
}
+ (instancetype __nullable)readFromDiskWithError:(NSError * __nullable * __nullable)readErr {
if (
![NSFileManager.defaultManager fileExistsAtPath:stateFile isDirectory:nil] &&
![NSFileManager.defaultManager fileExistsAtPath:otherStateFile isDirectory:nil]
) {
return nil;
}
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", stateFile]];
NSDictionary *state = [NSDictionary dictionaryWithContentsOfURL:url error:readErr];
if (readErr && *readErr) {
NSError *otherReadErr;
url = [NSURL URLWithString:[NSString stringWithFormat:@"file://%@", otherStateFile]];
state = [NSDictionary dictionaryWithContentsOfURL:url error:&otherReadErr];
if (otherReadErr) {
*readErr = otherReadErr;
return nil;
}
}
BOOL connected = ((NSNumber *)state[kConnected]).boolValue;
return [BPState.alloc initWithCode:state[kCode] secret:state[kSecret] connected:connected error:state[kError]];
}
@end