merge development

This commit is contained in:
Erik 2016-06-14 19:51:56 -04:00
commit 7500ea83a0
8 changed files with 125 additions and 3 deletions

View File

@ -165,6 +165,7 @@ case ReconnectAttempts(Int) // How many times to reconnect. Default is `-1` (inf
case ReconnectWait(Int) // Amount of time to wait between reconnects. Default is `10`
case SessionDelegate(NSURLSessionDelegate) // Sets an NSURLSessionDelegate for the underlying engine. Useful if you need to handle self-signed certs. Default is nil.
case Secure(Bool) // If the connection should use TLS. Default is false.
case Security(SSLSecurity) // Allows you to set which certs are valid. Useful for SSL pinning.
case SelfSigned(Bool) // Sets WebSocket.selfSignedSSL (Don't do this, iOS will yell at you)
case VoipEnabled(Bool) // Only use this option if you're using the client with VoIP services. Changes the way the WebSocket is created. Default is false
```

View File

@ -122,6 +122,9 @@
74B4AD231D09A6190062A523 /* SSLSecurity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74B4AD201D09A6190062A523 /* SSLSecurity.swift */; };
74B4AD241D09A6450062A523 /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74B4AD1C1D09A5D80062A523 /* WebSocket.swift */; };
74B4AD251D09A6490062A523 /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74B4AD1C1D09A5D80062A523 /* WebSocket.swift */; };
74BC45AB1D0C6675008CC431 /* SocketClientManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74BC45AA1D0C6675008CC431 /* SocketClientManager.swift */; };
74BC45AC1D0C6675008CC431 /* SocketClientManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74BC45AA1D0C6675008CC431 /* SocketClientManager.swift */; };
74BC45AD1D0C6675008CC431 /* SocketClientManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74BC45AA1D0C6675008CC431 /* SocketClientManager.swift */; };
74F124F01BC574CF002966F4 /* SocketBasicPacketTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74F124EF1BC574CF002966F4 /* SocketBasicPacketTest.swift */; };
74F124F11BC574CF002966F4 /* SocketBasicPacketTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74F124EF1BC574CF002966F4 /* SocketBasicPacketTest.swift */; };
CEBA56961CDA0B7700BA0389 /* NSCharacterSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBA56951CDA0B7700BA0389 /* NSCharacterSet.swift */; };
@ -195,6 +198,7 @@
74ABF7761C3991C10078C657 /* SocketIOClientSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketIOClientSpec.swift; path = Source/SocketIOClientSpec.swift; sourceTree = "<group>"; };
74B4AD1C1D09A5D80062A523 /* WebSocket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WebSocket.swift; path = Source/WebSocket/WebSocket.swift; sourceTree = "<group>"; };
74B4AD201D09A6190062A523 /* SSLSecurity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SSLSecurity.swift; path = Source/WebSocket/SSLSecurity.swift; sourceTree = "<group>"; };
74BC45AA1D0C6675008CC431 /* SocketClientManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SocketClientManager.swift; path = Source/SocketClientManager.swift; sourceTree = "<group>"; };
74F124EF1BC574CF002966F4 /* SocketBasicPacketTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketBasicPacketTest.swift; sourceTree = "<group>"; };
CEBA56951CDA0B7700BA0389 /* NSCharacterSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = NSCharacterSet.swift; path = Source/NSCharacterSet.swift; sourceTree = "<group>"; };
CEBA56991CDA0B8200BA0389 /* String.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = String.swift; path = Source/String.swift; sourceTree = "<group>"; };
@ -336,6 +340,7 @@
74171E501C10CD240062D398 /* SocketAckEmitter.swift */,
74171E511C10CD240062D398 /* SocketAckManager.swift */,
74171E521C10CD240062D398 /* SocketAnyEvent.swift */,
74BC45AA1D0C6675008CC431 /* SocketClientManager.swift */,
74171E531C10CD240062D398 /* SocketEngine.swift */,
74171E541C10CD240062D398 /* SocketEngineClient.swift */,
74171E551C10CD240062D398 /* SocketEnginePacketType.swift */,
@ -632,6 +637,7 @@
74171E811C10CD240062D398 /* SocketEnginePacketType.swift in Sources */,
74171E6F1C10CD240062D398 /* SocketAnyEvent.swift in Sources */,
74171E9F1C10CD240062D398 /* SocketIOClientOption.swift in Sources */,
74BC45AB1D0C6675008CC431 /* SocketClientManager.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -689,6 +695,7 @@
74171E831C10CD240062D398 /* SocketEnginePacketType.swift in Sources */,
74171E711C10CD240062D398 /* SocketAnyEvent.swift in Sources */,
74171EA11C10CD240062D398 /* SocketIOClientOption.swift in Sources */,
74BC45AC1D0C6675008CC431 /* SocketClientManager.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -734,6 +741,7 @@
74171E851C10CD240062D398 /* SocketEnginePacketType.swift in Sources */,
74171E731C10CD240062D398 /* SocketAnyEvent.swift in Sources */,
74171EA31C10CD240062D398 /* SocketIOClientOption.swift in Sources */,
74BC45AD1D0C6675008CC431 /* SocketClientManager.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -44,4 +44,10 @@
[self.socket offWithEvent:@"test"];
}
- (void)testSocketManager {
SocketClientManager* manager = [SocketClientManager sharedManager];
[manager addSocketWithSocket:self.socket labeledAs:@"test"];
[manager removeSocketWithLabel:@"test"];
}
@end

View File

@ -159,4 +159,16 @@ class SocketSideEffectTest: XCTestCase {
socket.parseBinaryData(data2)
waitForExpectations(withTimeout: 3, handler: nil)
}
func testSocketManager() {
let manager = SocketClientManager.sharedManager
manager["test"] = socket
XCTAssert(manager["test"] === socket, "failed to get socket")
manager["test"] = nil
XCTAssert(manager["test"] == nil, "socket not removed")
}
}

View File

@ -0,0 +1,82 @@
//
// SocketClientManager.swift
// Socket.IO-Client-Swift
//
// Created by Erik Little on 6/11/16.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
/**
Experimental socket manager.
API subject to change.
Can be used to persist sockets across ViewControllers.
Sockets are strongly stored, so be sure to remove them once they are no
longer needed.
Example usage:
```
let manager = SocketClientManager.sharedManager
manager["room1"] = socket1
manager["room2"] = socket2
manager.removeSocket(socket: socket2)
manager["room1"]?.emit("hello")
```
*/
public final class SocketClientManager : NSObject {
public static let sharedManager = SocketClientManager()
private var sockets = [String: SocketIOClient]()
public subscript(string: String) -> SocketIOClient? {
get {
return sockets[string]
}
set(socket) {
sockets[string] = socket
}
}
public func addSocket(socket: SocketIOClient, labeledAs label: String) {
sockets[label] = socket
}
public func removeSocket(withLabel label: String) -> SocketIOClient? {
return sockets.removeValue(forKey: label)
}
public func removeSocket(socket: SocketIOClient) -> SocketIOClient? {
var returnSocket: SocketIOClient?
for (label, dictSocket) in sockets where dictSocket === socket {
returnSocket = sockets.removeValue(forKey: label)
}
return returnSocket
}
public func removeSockets() {
sockets.removeAll()
}
}

View File

@ -76,6 +76,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
private var pongsMissedMax = 0
private var probeWait = ProbeWaitQueue()
private var secure = false
private var security: SSLSecurity?
private var selfSigned = false
private var voipEnabled = false
@ -107,6 +108,8 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
self.secure = secure
case let .selfSigned(selfSigned):
self.selfSigned = selfSigned
case let .security(security):
self.security = security
default:
continue
}
@ -180,7 +183,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
disconnect(reason: "reconnect")
}
DefaultSocketLogger.Logger.log("Starting engine", type: logType)
DefaultSocketLogger.Logger.log("Starting engine. Server: %@", type: logType, args: url)
DefaultSocketLogger.Logger.log("Handshaking", type: logType)
resetEngine()
@ -265,6 +268,7 @@ public final class SocketEngine : NSObject, SocketEnginePollable, SocketEngineWe
ws?.voipEnabled = voipEnabled
ws?.delegate = self
ws?.selfSignedSSL = selfSigned
ws?.security = security
ws?.connect()
}

View File

@ -45,6 +45,7 @@ public enum SocketIOClientOption : ClientOption {
case reconnectAttempts(Int)
case reconnectWait(Int)
case secure(Bool)
case security(SSLSecurity)
case selfSigned(Bool)
case sessionDelegate(NSURLSessionDelegate)
case voipEnabled(Bool)
@ -87,6 +88,8 @@ public enum SocketIOClientOption : ClientOption {
description = "secure"
case .selfSigned:
description = "selfSigned"
case .security:
description = "security"
case .sessionDelegate:
description = "sessionDelegate"
case .voipEnabled:
@ -136,6 +139,8 @@ public enum SocketIOClientOption : ClientOption {
value = wait as AnyObject
case let .secure(secure):
value = secure as AnyObject
case let .security(security):
value = security
case let .selfSigned(signed):
value = signed as AnyObject
case let .sessionDelegate(delegate):
@ -195,6 +200,8 @@ extension NSDictionary {
return .reconnectWait(wait)
case let ("secure", secure as Bool):
return .secure(secure)
case let ("security", security as SSLSecurity):
return .security(security)
case let ("selfSigned", selfSigned as Bool):
return .selfSigned(selfSigned)
case let ("sessionDelegate", delegate as NSURLSessionDelegate):

View File

@ -23,7 +23,7 @@
import Foundation
import Security
public class SSLCert {
public class SSLCert : NSObject {
var certData: NSData?
var key: SecKey?
@ -50,7 +50,7 @@ public class SSLCert {
}
}
public class SSLSecurity {
public class SSLSecurity : NSObject {
public var validatedDN = true //should the domain name be validated?
var isReady = false //is the key processing done?
@ -88,6 +88,8 @@ public class SSLSecurity {
- returns: a representation security object to be used with
*/
public init(certs: [SSLCert], usePublicKeys: Bool) {
super.init()
self.usePublicKeys = usePublicKeys
if self.usePublicKeys {