pbind 0.6.2 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -15,6 +15,8 @@
15
15
 
16
16
  @interface PBLLInspectorController : UIViewController
17
17
 
18
+ + (void)presentFromViewController:(UIViewController *)viewController;
19
+
18
20
  @end
19
21
 
20
22
  #endif
@@ -11,8 +11,21 @@
11
11
 
12
12
  #import "PBLLInspector.h"
13
13
  #import "PBLLRemoteWatcher.h"
14
+ #import "PBLLResource.h"
14
15
  #import <Pbind/Pbind.h>
15
16
 
17
+ @interface _PBLLWrapperNavigationController : UINavigationController
18
+
19
+ @end
20
+
21
+ @implementation _PBLLWrapperNavigationController
22
+
23
+ - (UIStatusBarStyle)preferredStatusBarStyle {
24
+ return UIStatusBarStyleLightContent;
25
+ }
26
+
27
+ @end
28
+
16
29
  @interface PBLLInspectorController () <UISearchBarDelegate>
17
30
  {
18
31
  UISearchBar *_searchBar;
@@ -25,27 +38,77 @@
25
38
  - (void)viewDidLoad {
26
39
  [super viewDidLoad];
27
40
  // Do any additional setup after loading the view.
41
+ self.title = [PBLLResource pbindTitle];
42
+ UIColor *primaryColor = [PBLLResource pbindColor];
43
+ UINavigationBar *navigationBar = self.navigationController.navigationBar;
44
+ [navigationBar setBarTintColor:primaryColor];
45
+ [navigationBar setTintColor:[UIColor whiteColor]];
46
+ [navigationBar setBackgroundImage:[UIImage new] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
47
+ [navigationBar setShadowImage:[UIImage new]];
48
+ [navigationBar setTranslucent:NO];
49
+ [navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]}];
50
+ self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(dismiss)];
51
+
28
52
  self.edgesForExtendedLayout = UIRectEdgeNone;
29
53
  self.view.backgroundColor = [UIColor whiteColor];
30
54
  CGRect frame = self.view.bounds;
31
55
  frame.size.height = 44.f;
32
- frame.origin.y = 16.f;
33
56
  UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:frame];
34
- searchBar.text = [self defaultIP];
57
+ searchBar.barTintColor = primaryColor;
58
+ searchBar.text = [PBLLRemoteWatcher globalWatcher].defaultIP;
35
59
  searchBar.delegate = self;
36
60
  searchBar.returnKeyType = UIReturnKeyJoin;
61
+ searchBar.barStyle = UISearchBarStyleMinimal;
37
62
  [self.view addSubview:searchBar];
38
63
  _searchBar = searchBar;
64
+ [searchBar becomeFirstResponder];
65
+
66
+ // Help label
67
+ UILabel *helpLabel = [[UILabel alloc] init];
68
+ helpLabel.font = [UIFont systemFontOfSize:14.f];
69
+ helpLabel.numberOfLines = 0;
70
+ helpLabel.textColor = PBColorMake(@"666");
71
+ helpLabel.text = @(
72
+ "Input the IP of the pbind server started by:\n"
73
+ "\n"
74
+ " > gem install pbind" "\n"
75
+ " > cd [path-to-xcodeproj]" "\n"
76
+ " > pbind serv" "\n"
77
+ "\n"
78
+ "Then click [Join] to start online debugging.");
79
+ [self.view addSubview:helpLabel];
80
+
81
+ frame.origin.y += frame.size.height + 44.f;
82
+ frame.origin.x = 32.f;
83
+ frame.size.width = frame.size.width - 64.f;
84
+ frame.size.height = [helpLabel sizeThatFits:frame.size].height;
85
+ helpLabel.frame = frame;
39
86
 
40
87
  UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTap:)];
41
88
  [self.view addGestureRecognizer:tap];
42
89
  }
43
90
 
91
+ + (void)presentFromViewController:(UIViewController *)viewController {
92
+ PBLLInspectorController *inspectorVC = [[PBLLInspectorController alloc] init];
93
+ UINavigationController *nav = [[_PBLLWrapperNavigationController alloc] initWithRootViewController:inspectorVC];
94
+ [viewController presentViewController:nav animated:YES completion:nil];
95
+ }
96
+
44
97
  - (void)viewWillAppear:(BOOL)animated {
45
98
  [super viewWillAppear:animated];
46
99
  [PBLLInspector sharedInspector].hidden = YES;
47
100
  }
48
101
 
102
+ - (void)viewDidAppear:(BOOL)animated {
103
+ [super viewDidAppear:animated];
104
+ [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
105
+ }
106
+
107
+ - (void)viewWillDisappear:(BOOL)animated {
108
+ [super viewWillDisappear:animated];
109
+ [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
110
+ }
111
+
49
112
  - (void)viewDidDisappear:(BOOL)animated {
50
113
  [super viewDidDisappear:animated];
51
114
  [PBLLInspector sharedInspector].hidden = NO;
@@ -56,19 +119,6 @@
56
119
  // Dispose of any resources that can be recreated.
57
120
  }
58
121
 
59
- - (NSString *)defaultIP {
60
- NSString *ip = [[NSUserDefaults standardUserDefaults] objectForKey:@"pbind.server.ip"];
61
- if (ip == nil) {
62
- ip = @"192.168.1.10";
63
- }
64
- return ip;
65
- }
66
-
67
- - (void)setDefaultIP:(NSString *)ip {
68
- [[NSUserDefaults standardUserDefaults] setObject:ip forKey:@"pbind.server.ip"];
69
- [[NSUserDefaults standardUserDefaults] synchronize];
70
- }
71
-
72
122
  #pragma mark - UISearchBarDelegate
73
123
 
74
124
  - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
@@ -77,9 +127,8 @@
77
127
  return;
78
128
  }
79
129
 
80
- [self setDefaultIP:ip];
81
130
  [[PBLLRemoteWatcher globalWatcher] connect:ip];
82
- [self.navigationController popViewControllerAnimated:YES];
131
+ [self dismiss];
83
132
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
84
133
  [PBTopController().view pb_reloadClient];
85
134
  });
@@ -91,6 +140,11 @@
91
140
  [_searchBar resignFirstResponder];
92
141
  }
93
142
 
143
+ - (void)dismiss {
144
+ [_searchBar resignFirstResponder];
145
+ [self.navigationController dismissViewControllerAnimated:YES completion:nil];
146
+ }
147
+
94
148
  @end
95
149
 
96
150
  #endif
@@ -0,0 +1,23 @@
1
+ //
2
+ // PBLLInspectorTipsController.h
3
+ // Pbind
4
+ //
5
+ // Created by galen on 17/7/29.
6
+ //
7
+
8
+ #import "PBLLOptions.h"
9
+ #include <targetconditionals.h>
10
+
11
+ #if (PBLIVE_ENABLED)
12
+
13
+ #import <UIKit/UIKit.h>
14
+
15
+ @interface PBLLInspectorTipsController : UIViewController
16
+
17
+ @property (nonatomic, strong) NSString *tips;
18
+
19
+ @property (nonatomic, strong) NSString *code;
20
+
21
+ @end
22
+
23
+ #endif
@@ -0,0 +1,140 @@
1
+ //
2
+ // PBLLInspectorTipsController.m
3
+ // Pbind
4
+ //
5
+ // Created by galen on 17/7/29.
6
+ //
7
+
8
+ #import "PBLLInspectorTipsController.h"
9
+
10
+ #if (PBLIVE_ENABLED)
11
+
12
+ #import "PBLLRemoteWatcher.h"
13
+ #import "PBLLResource.h"
14
+ #import <Pbind/Pbind.h>
15
+
16
+ @interface PBLLInspectorTipsController ()
17
+
18
+ @property (nonatomic, strong) UILabel *tipsLabel;
19
+ @property (nonatomic, strong) UIToolbar *toolbar;
20
+ @property (nonatomic, assign) CGFloat preferredWidth;
21
+ @property (nonatomic, strong) UIBarButtonItem *codeOrTipsItem;
22
+
23
+ @end
24
+
25
+ @implementation PBLLInspectorTipsController
26
+
27
+ static BOOL kDisplaysCode = NO;
28
+
29
+ - (void)viewDidLoad {
30
+ [super viewDidLoad];
31
+ // Do any additional setup after loading the view.
32
+
33
+ CGRect rect = [UIScreen mainScreen].bounds;
34
+ _preferredWidth = rect.size.width * 2.f / 3.f;
35
+
36
+ rect.origin.x = 16.f;
37
+ rect.origin.y = 16.f;
38
+ UILabel *label = [[UILabel alloc] initWithFrame:rect];
39
+ label.textColor = [UIColor whiteColor];
40
+ label.text = self.tips;
41
+ label.font = [UIFont systemFontOfSize:12.f];
42
+ label.numberOfLines = 0;
43
+ rect.size.height = [label sizeThatFits:rect.size].height;
44
+ label.frame = rect;
45
+
46
+ [self.view addSubview:label];
47
+ _tipsLabel = label;
48
+
49
+ UIToolbar *toolbar = [[UIToolbar alloc] init];
50
+ [toolbar setBarTintColor:self.popoverPresentationController.backgroundColor];
51
+ [toolbar setTintColor:[UIColor whiteColor]];
52
+
53
+ NSMutableArray *items = [NSMutableArray arrayWithCapacity:4];
54
+ [items addObject:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(handleClose:)]];
55
+ [items addObject:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]];
56
+ if (self.code != nil) {
57
+ _codeOrTipsItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:self action:@selector(handleToggleCode:)];
58
+ [items addObject:_codeOrTipsItem];
59
+
60
+ [items addObject:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]];
61
+ }
62
+ // Copy
63
+ [items addObject:[[UIBarButtonItem alloc] initWithImage:[PBLLResource copyImage] style:UIBarButtonItemStylePlain target:self action:@selector(handleCopy:)]];
64
+ #if !(TARGET_IPHONE_SIMULATOR)
65
+ // Post
66
+ UIBarButtonItem *postItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemReply target:self action:@selector(handlePost:)];
67
+ [items addObject:postItem];
68
+ #endif
69
+
70
+ toolbar.items = items;
71
+ [self.view addSubview:toolbar];
72
+ _toolbar = toolbar;
73
+
74
+ [self render];
75
+ }
76
+
77
+ - (void)render {
78
+ [self renderWithAnimated:NO];
79
+ }
80
+
81
+ - (void)renderWithAnimated:(BOOL)animated {
82
+ dispatch_block_t renderBlock = ^{
83
+ if (_code != nil) {
84
+ if (kDisplaysCode) {
85
+ _codeOrTipsItem.title = @"Value";
86
+ _tipsLabel.text = _code;
87
+ } else {
88
+ _codeOrTipsItem.title = @"Code";
89
+ _tipsLabel.text = _tips;
90
+ }
91
+ } else {
92
+ _tipsLabel.text = _tips;
93
+ }
94
+
95
+ CGRect rect = CGRectMake(16.f, 16.f, _preferredWidth - 32.f, CGFLOAT_MAX);
96
+ rect.size.height = [_tipsLabel sizeThatFits:rect.size].height;
97
+ _tipsLabel.frame = rect;
98
+
99
+ rect.origin.x = 0.f;
100
+ rect.origin.y += rect.size.height + 16.f;
101
+ rect.size.width = _preferredWidth;
102
+ rect.size.height = 44.f;
103
+ _toolbar.frame = rect;
104
+
105
+ rect.size.height += rect.origin.y;
106
+ self.preferredContentSize = rect.size;
107
+ };
108
+ if (animated) {
109
+ [UIView animateWithDuration:.25f animations:renderBlock completion:^(BOOL finished) {
110
+ [self.popoverPresentationController.containerView setNeedsLayout];
111
+ }];
112
+ } else {
113
+ renderBlock();
114
+ }
115
+ }
116
+
117
+ #pragma mark - BarButtonItem
118
+
119
+ - (void)handleClose:(id)sender {
120
+ [self dismissViewControllerAnimated:YES completion:nil];
121
+ }
122
+
123
+ - (void)handleToggleCode:(id)sender {
124
+ kDisplaysCode = !kDisplaysCode;
125
+ [self renderWithAnimated:YES];
126
+ }
127
+
128
+ - (void)handleCopy:(id)sender {
129
+ [UIPasteboard generalPasteboard].string = _tipsLabel.text;
130
+ }
131
+
132
+ #if !(TARGET_IPHONE_SIMULATOR)
133
+ - (void)handlePost:(id)sender {
134
+ [[PBLLRemoteWatcher globalWatcher] sendLog:_tips];
135
+ }
136
+ #endif
137
+
138
+ @end
139
+
140
+ #endif
@@ -5,4 +5,4 @@
5
5
  // Created by Galen Lin on 25/03/2017.
6
6
  //
7
7
 
8
- #define PBLIVE_ENABLED DEBUG
8
+ #define PBLIVE_ENABLED (DEBUG || PROFILE)
@@ -24,6 +24,8 @@
24
24
  - (void)remoteWatcher:(PBLLRemoteWatcher *)watcher didCreateFile:(NSString *)fileName;
25
25
  - (void)remoteWatcher:(PBLLRemoteWatcher *)watcher didDeleteFile:(NSString *)fileName;
26
26
 
27
+ - (void)remoteWatcher:(PBLLRemoteWatcher *)watcher didChangeConnectState:(BOOL)connected;
28
+
27
29
  @end
28
30
 
29
31
  @interface PBLLRemoteWatcher : NSObject
@@ -35,8 +37,12 @@
35
37
 
36
38
  - (void)requestAPI:(NSString *)api success:(void (^)(NSData *))success failure:(void (^)(NSError *))failure;
37
39
 
40
+ - (void)sendLog:(NSString *)log;
41
+
38
42
  @property (nonatomic, assign) id<PBLLRemoteWatcherDelegate> delegate;
39
43
 
44
+ @property (nonatomic, strong, readonly) NSString *defaultIP;
45
+
40
46
  @end
41
47
 
42
48
  #endif
@@ -16,17 +16,25 @@
16
16
  {
17
17
  NSInputStream *inputStream;
18
18
  NSOutputStream *outputStream;
19
- void (^responseBlock)(NSData *);
19
+ void (^apiSuccessBlock)(NSData *);
20
+ void (^apiFailureBolck)(NSError *);
20
21
  BOOL streamOpened;
21
22
  NSData *apiReqData;
22
23
  NSString *tempResourcesPath;
23
24
  NSString *connectedIP;
25
+ NSInteger retryCount;
24
26
  }
25
27
 
26
28
  @end
27
29
 
28
30
  @implementation PBLLRemoteWatcher
29
31
 
32
+ static const NSTimeInterval kTimeoutSeconds = 3.f;
33
+ static NSString *const kServerIPUserDefaultsKey = @"pbind.server.ip";
34
+ static NSString *const kDefaultServerIP = @"192.168.1.10";
35
+ static const NSInteger kServerPort = 8082;
36
+ static const NSInteger kMaxRetryCount = 5;
37
+
30
38
  + (instancetype)globalWatcher {
31
39
  static PBLLRemoteWatcher *o;
32
40
  static dispatch_once_t onceToken;
@@ -39,10 +47,15 @@
39
47
  - (void)connect:(NSString *)ip {
40
48
  [self close];
41
49
 
50
+ if (ip == nil) {
51
+ return;
52
+ }
53
+
42
54
  connectedIP = ip;
55
+ [[NSUserDefaults standardUserDefaults] setObject:ip forKey:kServerIPUserDefaultsKey];
43
56
  CFReadStreamRef readStream;
44
57
  CFWriteStreamRef writeStream;
45
- CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)ip, 8082, &readStream, &writeStream);
58
+ CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)ip, kServerPort, &readStream, &writeStream);
46
59
  inputStream = (__bridge NSInputStream *)readStream;
47
60
  outputStream = (__bridge NSOutputStream *)writeStream;
48
61
  inputStream.delegate = self;
@@ -54,11 +67,15 @@
54
67
  }
55
68
 
56
69
  - (void)connectDefaultIP {
57
- NSString *ip = [[NSUserDefaults standardUserDefaults] objectForKey:@"pbind.server.ip"];
70
+ [self connect:self.defaultIP];
71
+ }
72
+
73
+ - (NSString *)defaultIP {
74
+ NSString *ip = [[NSUserDefaults standardUserDefaults] objectForKey:kServerIPUserDefaultsKey];
58
75
  if (ip == nil) {
59
- ip = @"192.168.1.2";
76
+ ip = kDefaultServerIP;
60
77
  }
61
- [self connect:ip];
78
+ return ip;
62
79
  }
63
80
 
64
81
  - (void)requestAPI:(NSString *)api success:(void (^)(NSData *))success failure:(void (^)(NSError *))failure {
@@ -69,13 +86,31 @@
69
86
  return;
70
87
  }
71
88
 
72
- responseBlock = success;
73
- NSData *data = [api dataUsingEncoding:NSUTF8StringEncoding];
89
+ apiSuccessBlock = success;
90
+ apiFailureBolck = failure;
91
+
92
+ NSData *reqData = [self dataWithMessage:api event:PBLLRemoteEventJsonRequest];
74
93
  if (streamOpened) {
75
- [outputStream write:[data bytes] maxLength:[data length]];
94
+ [self sendData:reqData];
76
95
  } else {
77
- apiReqData = data;
96
+ // apiReqData = reqData;
97
+ failure(nil);
98
+ return;
78
99
  }
100
+
101
+ NSLog(@"---- perform delay onTimeout");
102
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onTimeout) object:nil];
103
+ [self performSelector:@selector(onTimeout) withObject:nil afterDelay:kTimeoutSeconds];
104
+ }
105
+
106
+ - (void)onTimeout {
107
+ if (apiFailureBolck) {
108
+ apiFailureBolck([NSError errorWithDomain:@"PBLLRemoteWatcher"
109
+ code:-1
110
+ userInfo:@{NSLocalizedDescriptionKey: @"Server no response"}]);
111
+ apiFailureBolck = nil;
112
+ }
113
+ apiSuccessBlock = nil;
79
114
  }
80
115
 
81
116
  - (void)close {
@@ -90,10 +125,67 @@
90
125
  streamOpened = NO;
91
126
  }
92
127
 
128
+ #pragma mark - Communication
129
+
130
+ typedef NS_ENUM(NSUInteger, PBLLRemoteEvent) {
131
+ // client events
132
+ PBLLRemoteEventConnected = 0xC0,
133
+ PBLLRemoteEventJsonRequest = 0xC1,
134
+ PBLLRemoteEventLog = 0xC2,
135
+
136
+ // server events - data
137
+ PBLLRemoteEventDataJson = 0xD0,
138
+
139
+ // server events - error
140
+ PBLLRemoteEventErrorIgnored = 0xE0,
141
+
142
+ // server events - file
143
+ PBLLRemoteEventFileCreated = 0xF0,
144
+ PBLLRemoteEventFileUpdated = 0xF1,
145
+ PBLLRemoteEventFileDeleted = 0xF2,
146
+ };
147
+
148
+ - (void)sendMessage:(NSString *)message {
149
+ NSData *msgData = [message dataUsingEncoding:NSUTF8StringEncoding];
150
+ [self sendData:msgData];
151
+ }
152
+
153
+ - (void)sendLog:(NSString *)log {
154
+ [self sendMessage:log event:PBLLRemoteEventLog];
155
+ }
156
+
157
+ - (void)sendConnectedMessage {
158
+ NSString *osModel = [[UIDevice currentDevice] name];
159
+ NSString *osVersion = [[UIDevice currentDevice] systemVersion];
160
+ NSString *deviceName = [NSString stringWithFormat:@"%@(%@)", osModel, osVersion];
161
+ [self sendMessage:deviceName event:PBLLRemoteEventConnected];
162
+ }
163
+
164
+ - (void)sendMessage:(NSString *)message event:(PBLLRemoteEvent)event {
165
+ NSData *data = [self dataWithMessage:message event:event];
166
+ [self sendData:data];
167
+ }
168
+
169
+ - (void)sendData:(NSData *)data {
170
+ if (!streamOpened) {
171
+ return;
172
+ }
173
+
174
+ [outputStream write:[data bytes] maxLength:[data length]];
175
+ }
176
+
177
+ - (NSData *)dataWithMessage:(NSString *)message event:(PBLLRemoteEvent)event {
178
+ NSData *msgData = [message dataUsingEncoding:NSUTF8StringEncoding];
179
+ NSUInteger len = msgData.length + 1;
180
+ NSMutableData *data = [[NSMutableData alloc] initWithCapacity:len];
181
+ [data appendBytes:&event length:1];
182
+ [data appendData:msgData];
183
+ return data;
184
+ }
185
+
93
186
  #pragma mark - NSStreamDelegate
94
187
 
95
188
  - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
96
- NSLog(@"socket: %i, %@", (int)eventCode, aStream);
97
189
  switch (eventCode) {
98
190
  case NSStreamEventOpenCompleted:
99
191
  break;
@@ -102,47 +194,71 @@
102
194
  if (!streamOpened) {
103
195
  streamOpened = YES;
104
196
 
105
- // Send connected message
106
- NSString *osModel = [[UIDevice currentDevice] name];
107
- NSString *osVersion = [[UIDevice currentDevice] systemVersion];
108
- NSString *msg = [NSString stringWithFormat:@"[C]%@(%@)", osModel, osVersion];
109
- NSData *msgData = [msg dataUsingEncoding:NSUTF8StringEncoding];
110
- [outputStream write:[msgData bytes] maxLength:[msgData length]];
197
+ [self sendConnectedMessage];
198
+
199
+ if ([self.delegate respondsToSelector:@selector(remoteWatcher:didChangeConnectState:)]) {
200
+ [self.delegate remoteWatcher:self didChangeConnectState:YES];
201
+ }
111
202
  }
112
203
 
113
- if (apiReqData != nil) {
114
- [outputStream write:[apiReqData bytes] maxLength:[apiReqData length]];
115
- apiReqData = nil;
116
- }
204
+ // if (apiReqData != nil) {
205
+ // [self sendData:apiReqData];
206
+ // apiReqData = nil;
207
+ // }
117
208
  }
118
209
  break;
119
210
  case NSStreamEventHasBytesAvailable:
120
211
  if (aStream == inputStream) {
121
- NSLog(@"inputStream is ready.");
122
-
123
212
  uint8_t type[1];
124
213
  [inputStream read:type maxLength:1];
125
- switch (*type) {
126
- case 0xE0: { // Got json
214
+ PBLLRemoteEvent event = *type;
215
+ switch (event) {
216
+ case PBLLRemoteEventDataJson: { // Got json
217
+ NSString *jsonName = [inputStream readString];
127
218
  NSData *jsonData = [inputStream readData];
128
- if (responseBlock != nil) {
129
- responseBlock(jsonData);
219
+ NSLog(@"---- cancel onTimeout");
220
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onTimeout) object:nil];
221
+ if (apiSuccessBlock != nil) {
222
+ apiSuccessBlock(jsonData);
223
+ apiSuccessBlock = nil;
224
+ }
225
+ apiFailureBolck = nil;
226
+ [self sendMessage:jsonName event:PBLLRemoteEventDataJson];
227
+ break;
228
+ }
229
+ case PBLLRemoteEventErrorIgnored: { // Ingores API
230
+ [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(onTimeout) object:nil];
231
+ if (apiFailureBolck != nil) {
232
+ apiFailureBolck([NSError errorWithDomain:@"PBLLRemoteWatcher" code:-2 userInfo:@{NSLocalizedDescriptionKey: @"User ignores the API"}]);
130
233
  }
234
+ apiSuccessBlock = nil;
131
235
  break;
132
236
  }
133
- case 0xF0: { // Create file
237
+ case PBLLRemoteEventFileCreated: { // Create file
134
238
  NSString *fileName = [inputStream readString];
239
+ if (fileName == nil) {
240
+ break;
241
+ }
242
+ [self sendMessage:fileName event:event];
135
243
  [self.delegate remoteWatcher:self didCreateFile:fileName];
136
244
  break;
137
245
  }
138
- case 0xF1: { // Update file
246
+ case PBLLRemoteEventFileUpdated: { // Update file
139
247
  NSString *fileName = [inputStream readString];
248
+ if (fileName == nil) {
249
+ break;
250
+ }
140
251
  NSData *fileData = [inputStream readData];
252
+ [self sendMessage:fileName event:event];
141
253
  [self.delegate remoteWatcher:self didUpdateFile:fileName withData:fileData];
142
254
  break;
143
255
  }
144
- case 0xF2: { // Delete file
256
+ case PBLLRemoteEventFileDeleted: { // Delete file
145
257
  NSString *fileName = [inputStream readString];
258
+ if (fileName == nil) {
259
+ break;
260
+ }
261
+ [self sendMessage:fileName event:event];
146
262
  [self.delegate remoteWatcher:self didDeleteFile:fileName];
147
263
  break;
148
264
  }
@@ -153,14 +269,24 @@
153
269
  break;
154
270
  case NSStreamEventErrorOccurred:
155
271
  if (aStream == outputStream) {
272
+ retryCount++;
273
+ if (retryCount >= kMaxRetryCount) {
274
+ retryCount = 0;
275
+ break;
276
+ }
277
+
156
278
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
157
279
  [self connect:connectedIP];
158
280
  });
159
281
  }
282
+ NSLog(@"[PBLLRemoteWatcher] %@", [aStream streamError]);
160
283
  break;
161
284
  case NSStreamEventEndEncountered:
162
285
  if (aStream == inputStream) {
163
286
  [self close];
287
+ if ([self.delegate respondsToSelector:@selector(remoteWatcher:didChangeConnectState:)]) {
288
+ [self.delegate remoteWatcher:self didChangeConnectState:NO];
289
+ }
164
290
  }
165
291
  break;
166
292
  default: