Browse Source

Use error pointers instead of asserts for validating status on send:. (#416)

Nikita Lutsenko 9 years ago
parent
commit
16abb5debd
3 changed files with 59 additions and 17 deletions
  1. 21 6
      SocketRocket/SRWebSocket.h
  2. 36 9
      SocketRocket/SRWebSocket.m
  3. 2 2
      Tests/Operations/SRAutobahnOperation.m

+ 21 - 6
SocketRocket/SRWebSocket.h

@@ -239,28 +239,43 @@ NS_DESIGNATED_INITIALIZER;
 
  @deprecated Please use `sendString:` or `sendData` instead.
  */
-- (void)send:(nullable id)message __attribute__((deprecated("Please use `sendString:` or `sendData` instead.")));
+- (void)send:(nullable id)message __attribute__((deprecated("Please use `sendString:error:` or `sendData:error:` instead.")));
 
 /**
  Send a UTF-8 String to the server.
 
  @param string String to send.
+ @param error  On input, a pointer to variable for an `NSError` object.
+ If an error occurs, this pointer is set to an `NSError` object containing information about the error.
+ You may specify `nil` to ignore the error information.
+
+ @return `YES` if the string was scheduled to send, otherwise - `NO`.
  */
-- (void)sendString:(NSString *)string;
+- (BOOL)sendString:(NSString *)string error:(NSError **)error NS_SWIFT_NAME(send(string:));
 
 /**
  Send binary data to the server.
 
- @param data Data to send.
+ @param data  Data to send.
+ @param error On input, a pointer to variable for an `NSError` object.
+ If an error occurs, this pointer is set to an `NSError` object containing information about the error.
+ You may specify `nil` to ignore the error information.
+
+ @return `YES` if the string was scheduled to send, otherwise - `NO`.
  */
-- (void)sendData:(nullable NSData *)data;
+- (BOOL)sendData:(nullable NSData *)data error:(NSError **)error NS_SWIFT_NAME(send(data:));
 
 /**
  Send Ping message to the server with optional data.
 
- @param data Instance of `NSData` or `nil`.
+ @param data  Instance of `NSData` or `nil`.
+ @param error On input, a pointer to variable for an `NSError` object.
+ If an error occurs, this pointer is set to an `NSError` object containing information about the error.
+ You may specify `nil` to ignore the error information.
+
+ @return `YES` if the string was scheduled to send, otherwise - `NO`.
  */
-- (void)sendPing:(nullable NSData *)data;
+- (BOOL)sendPing:(nullable NSData *)data error:(NSError **)error NS_SWIFT_NAME(sendPing(_:));
 
 @end
 

+ 36 - 9
SocketRocket/SRWebSocket.m

@@ -614,28 +614,45 @@ NSString *const SRHTTPResponseErrorKey = @"HTTPResponseStatusCode";
 - (void)send:(nullable id)message
 {
     if (!message) {
-        [self sendData:nil]; // Send Data, but it doesn't matter since we are going to send the same text frame with 0 length.
+        [self sendData:nil error:nil]; // Send Data, but it doesn't matter since we are going to send the same text frame with 0 length.
     } else if ([message isKindOfClass:[NSString class]]) {
-        [self sendString:message];
+        [self sendString:message error:nil];
     } else if ([message isKindOfClass:[NSData class]]) {
-        [self sendData:message];
+        [self sendData:message error:nil];
     } else {
         NSAssert(NO, @"Unrecognized message. Not able to send anything other than a String or NSData.");
     }
 }
 
-- (void)sendString:(NSString *)string
+- (BOOL)sendString:(NSString *)string error:(NSError **)error
 {
-    NSAssert(self.readyState != SR_CONNECTING, @"Invalid State: Cannot call send: until connection is open");
+    if (self.readyState != SR_OPEN) {
+        NSString *message = @"Invalid State: Cannot call `sendString:error:` until connection is open.";
+        if (error) {
+            *error = SRErrorWithCodeDescription(2134, message);
+        }
+        SRDebugLog(message);
+        return NO;
+    }
+
     string = [string copy];
     dispatch_async(_workQueue, ^{
         [self _sendFrameWithOpcode:SROpCodeTextFrame data:[string dataUsingEncoding:NSUTF8StringEncoding]];
     });
+    return YES;
 }
 
-- (void)sendData:(NSData *)data
+- (BOOL)sendData:(nullable NSData *)data error:(NSError **)error
 {
-    NSAssert(self.readyState != SR_CONNECTING, @"Invalid State: Cannot call send: until connection is open");
+    if (self.readyState != SR_OPEN) {
+        NSString *message = @"Invalid State: Cannot call `sendData:error:` until connection is open.";
+        if (error) {
+            *error = SRErrorWithCodeDescription(2134, message);
+        }
+        SRDebugLog(message);
+        return NO;
+    }
+
     data = [data copy];
     dispatch_async(_workQueue, ^{
         if (data) {
@@ -644,15 +661,25 @@ NSString *const SRHTTPResponseErrorKey = @"HTTPResponseStatusCode";
             [self _sendFrameWithOpcode:SROpCodeTextFrame data:nil];
         }
     });
+    return YES;
 }
 
-- (void)sendPing:(NSData *)data;
+- (BOOL)sendPing:(nullable NSData *)data error:(NSError **)error
 {
-    NSAssert(self.readyState == SR_OPEN, @"Invalid State: Cannot call send: until connection is open");
+    if (self.readyState != SR_OPEN) {
+        NSString *message = @"Invalid State: Cannot call `sendPing:error:` until connection is open.";
+        if (error) {
+            *error = SRErrorWithCodeDescription(2134, message);
+        }
+        SRDebugLog(message);
+        return NO;
+    }
+
     data = [data copy] ?: [NSData data]; // It's okay for a ping to be empty
     dispatch_async(_workQueue, ^{
         [self _sendFrameWithOpcode:SROpCodePing data:data];
     });
+    return YES;
 }
 
 - (void)handlePing:(NSData *)pingData;

+ 2 - 2
Tests/Operations/SRAutobahnOperation.m

@@ -70,10 +70,10 @@ SRAutobahnOperation *SRAutobahnTestOperation(NSURL *serverURL, NSInteger caseNum
                                                caseNumber:@(caseNumber)
                                                     agent:agent
                                        textMessageHandler:^(SRWebSocket * _Nonnull socket, NSString  * _Nullable message) {
-                                           [socket sendString:message];
+                                           [socket sendString:message error:nil];
                                        }
                                        dataMessageHandler:^(SRWebSocket * _Nonnull socket, NSData * _Nullable message) {
-                                           [socket sendData:message];
+                                           [socket sendData:message error:nil];
                                        }];
 }