Skip to content

Commit d36ef10

Browse files
committed
Merge pull request #289 from socketio/nsurl-based
Nsurl based
2 parents cc7d96e + c5c0051 commit d36ef10

9 files changed

+119
-89
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Socket.IO-client for iOS/OS X.
55

66
##Example
77
```swift
8-
let socket = SocketIOClient(socketURL: "localhost:8080", options: [.Log(true), .ForcePolling(true)])
8+
let socket = SocketIOClient(socketURL: NSURL(string: "http://localhost:8080")!, options: [.Log(true), .ForcePolling(true)])
99

1010
socket.on("connect") {data, ack in
1111
print("socket connected")
@@ -26,7 +26,8 @@ socket.connect()
2626

2727
##Objective-C Example
2828
```objective-c
29-
SocketIOClient* socket = [[SocketIOClient alloc] initWithSocketURL:@"localhost:8080" options:@{@"log": @YES, @"forcePolling": @YES}];
29+
NSURL* url = [[NSURL alloc] initWithString:@"http://localhost:8080"];
30+
SocketIOClient* socket = [[SocketIOClient alloc] initWithSocketURL:url options:@{@"log": @YES, @"forcePolling": @YES}];
3031

3132
[socket on:@"connect" callback:^(NSArray* data, SocketAckEmitter* ack) {
3233
NSLog(@"socket connected");
@@ -136,9 +137,9 @@ Run `seed install`.
136137
##API
137138
Constructors
138139
-----------
139-
`init(var socketURL: String, options: Set<SocketIOClientOption> = [])` - Creates a new SocketIOClient. opts is a Set of SocketIOClientOption. If your socket.io server is secure, you need to specify `https` in your socketURL.
140+
`init(var socketURL: NSURL, options: Set<SocketIOClientOption> = [])` - Creates a new SocketIOClient. options is a Set of SocketIOClientOption. If your socket.io server is secure, you need to specify `https` in your socketURL.
140141

141-
`convenience init(socketURL: String, options: NSDictionary?)` - Same as above, but meant for Objective-C. See Options on how convert between SocketIOClientOptions and dictionary keys.
142+
`convenience init(socketURL: NSURL, options: NSDictionary?)` - Same as above, but meant for Objective-C. See Options on how convert between SocketIOClientOptions and dictionary keys.
142143

143144
Options
144145
-------

SocketIO-MacTests/SocketEngineTest.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class SocketEngineTest: XCTestCase {
1515

1616
override func setUp() {
1717
super.setUp()
18-
client = SocketIOClient(socketURL: "")
19-
engine = SocketEngine(client: client, url: "", options: nil)
18+
client = SocketIOClient(socketURL: NSURL(string: "http://localhost")!)
19+
engine = SocketEngine(client: client, url: NSURL(string: "http://localhost")!, options: nil)
2020

2121
client.setTestable()
2222
}

SocketIO-MacTests/SocketParserTest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import XCTest
1010
@testable import SocketIOClientSwift
1111

1212
class SocketParserTest: XCTestCase {
13-
let testSocket = SocketIOClient(socketURL: "")
13+
let testSocket = SocketIOClient(socketURL: NSURL())
1414

1515
//Format key: message; namespace-data-binary-id
1616
static let packetTypes: Dictionary<String, (String, [AnyObject], [NSData], Int)> = [

SocketIO-MacTests/SocketSideEffectTest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class SocketSideEffectTest: XCTestCase {
1616

1717
override func setUp() {
1818
super.setUp()
19-
socket = SocketIOClient(socketURL: "")
19+
socket = SocketIOClient(socketURL: NSURL())
2020
socket.setTestable()
2121
}
2222

Source/SocketEngine.swift

Lines changed: 60 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
2929
public let handleQueue = dispatch_queue_create("com.socketio.engineHandleQueue", DISPATCH_QUEUE_SERIAL)
3030
public let parseQueue = dispatch_queue_create("com.socketio.engineParseQueue", DISPATCH_QUEUE_SERIAL)
3131

32+
public var connectParams: [String: AnyObject]? {
33+
didSet {
34+
(urlPolling, urlWebSocket) = createURLs()
35+
}
36+
}
3237
public var postWait = [String]()
3338
public var waitingForPoll = false
3439
public var waitingForPost = false
@@ -46,9 +51,9 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
4651
public private(set) var probing = false
4752
public private(set) var session: NSURLSession?
4853
public private(set) var sid = ""
49-
public private(set) var socketPath = "/engine.io"
50-
public private(set) var urlPolling = ""
51-
public private(set) var urlWebSocket = ""
54+
public private(set) var socketPath = "/engine.io/"
55+
public private(set) var urlPolling = NSURL()
56+
public private(set) var urlWebSocket = NSURL()
5257
public private(set) var websocket = false
5358
public private(set) var ws: WebSocket?
5459

@@ -59,11 +64,9 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
5964
private typealias Probe = (msg: String, type: SocketEnginePacketType, data: [NSData])
6065
private typealias ProbeWaitQueue = [Probe]
6166

62-
private let allowedCharacterSet = NSCharacterSet(charactersInString: "!*'();:@&=+$,/?%#[]\" {}").invertedSet
6367
private let logType = "SocketEngine"
64-
private let url: String
68+
private let url: NSURL
6569

66-
private var connectParams: [String: AnyObject]?
6770
private var pingInterval: Double?
6871
private var pingTimeout = 0.0 {
6972
didSet {
@@ -76,13 +79,15 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
7679
private var secure = false
7780
private var selfSigned = false
7881
private var voipEnabled = false
79-
80-
public init(client: SocketEngineClient, url: String, options: Set<SocketIOClientOption>) {
82+
83+
public init(client: SocketEngineClient, url: NSURL, options: Set<SocketIOClientOption>) {
8184
self.client = client
8285
self.url = url
83-
86+
8487
for option in options {
8588
switch option {
89+
case let .ConnectParams(params):
90+
connectParams = params
8691
case let .SessionDelegate(delegate):
8792
sessionDelegate = delegate
8893
case let .ForcePolling(force):
@@ -105,11 +110,26 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
105110
continue
106111
}
107112
}
113+
114+
super.init()
115+
116+
(urlPolling, urlWebSocket) = createURLs()
117+
}
118+
119+
public convenience init(client: SocketEngineClient, url: NSURL, options: NSDictionary?) {
120+
self.init(client: client, url: url, options: options?.toSocketOptionsSet() ?? [])
108121
}
109122

110-
public convenience init(client: SocketEngineClient, url: String, options: NSDictionary?) {
111-
self.init(client: client, url: url,
112-
options: options?.toSocketOptionsSet() ?? [])
123+
@available(*, deprecated=5.3)
124+
public convenience init(client: SocketEngineClient, urlString: String, options: Set<SocketIOClientOption>) {
125+
guard let url = NSURL(string: urlString) else { fatalError("Incorrect url") }
126+
self.init(client: client, url: url, options: options)
127+
}
128+
129+
@available(*, deprecated=5.3)
130+
public convenience init(client: SocketEngineClient, urlString: String, options: NSDictionary?) {
131+
guard let url = NSURL(string: urlString) else { fatalError("Incorrect url") }
132+
self.init(client: client, url: url, options: options?.toSocketOptionsSet() ?? [])
113133
}
114134

115135
deinit {
@@ -131,7 +151,7 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
131151
switch code {
132152
case 0: // Unknown transport
133153
didError(error)
134-
case 1: // Unknown sid. clear and retry connect
154+
case 1: // Unknown sid.
135155
didError(error)
136156
case 2: // Bad handshake request
137157
didError(error)
@@ -188,49 +208,45 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
188208
}
189209
}
190210

191-
private func createURLs(params: [String: AnyObject]?) -> (String, String) {
211+
private func createURLs() -> (NSURL, NSURL) {
192212
if client == nil {
193-
return ("", "")
213+
return (NSURL(), NSURL())
194214
}
195215

196-
let socketURL = "\(url)\(socketPath)/?transport="
197-
var urlPolling: String
198-
var urlWebSocket: String
216+
let urlPolling = NSURLComponents(string: url.absoluteString)!
217+
let urlWebSocket = NSURLComponents(string: url.absoluteString)!
218+
var queryString = ""
219+
220+
urlWebSocket.path = socketPath
221+
urlPolling.path = socketPath
222+
urlWebSocket.query = "transport=websocket"
223+
urlPolling.query = "transport=polling&b64=1"
199224

200225
if secure {
201-
urlPolling = "https://" + socketURL + "polling"
202-
urlWebSocket = "wss://" + socketURL + "websocket"
226+
urlPolling.scheme = "https"
227+
urlWebSocket.scheme = "wss"
203228
} else {
204-
urlPolling = "http://" + socketURL + "polling"
205-
urlWebSocket = "ws://" + socketURL + "websocket"
229+
urlPolling.scheme = "http"
230+
urlWebSocket.scheme = "ws"
206231
}
207232

208-
if params != nil {
209-
for (key, value) in params! {
210-
let keyEsc = key.stringByAddingPercentEncodingWithAllowedCharacters(
211-
allowedCharacterSet)!
212-
urlPolling += "&\(keyEsc)="
213-
urlWebSocket += "&\(keyEsc)="
214-
215-
if value is String {
216-
let valueEsc = (value as! String).stringByAddingPercentEncodingWithAllowedCharacters(
217-
allowedCharacterSet)!
218-
urlPolling += "\(valueEsc)"
219-
urlWebSocket += "\(valueEsc)"
220-
} else {
221-
urlPolling += "\(value)"
222-
urlWebSocket += "\(value)"
223-
}
233+
if connectParams != nil {
234+
for (key, value) in connectParams! {
235+
queryString += "&\(key)=\(value)"
224236
}
225237
}
226238

227-
return (urlPolling, urlWebSocket)
239+
urlWebSocket.query = urlWebSocket.query! + queryString
240+
urlPolling.query = urlPolling.query! + queryString
241+
242+
return (urlPolling.URL!, urlWebSocket.URL!)
228243
}
229244

230245
private func createWebsocketAndConnect() {
231-
let wsUrl = urlWebSocket + (sid == "" ? "" : "&sid=\(sid)")
232-
233-
ws = WebSocket(url: NSURL(string: wsUrl)!)
246+
let component = NSURLComponents(URL: urlWebSocket, resolvingAgainstBaseURL: false)!
247+
component.query = component.query! + (sid == "" ? "" : "&sid=\(sid)")
248+
249+
ws = WebSocket(url: component.URL!)
234250

235251
if cookies != nil {
236252
let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies!)
@@ -363,30 +379,26 @@ public final class SocketEngine: NSObject, SocketEnginePollable, SocketEngineWeb
363379
}
364380
}
365381

366-
public func open(opts: [String: AnyObject]?) {
382+
public func open() {
367383
if connected {
368384
DefaultSocketLogger.Logger.error("Engine tried opening while connected. This is probably a programming error. "
369385
+ "Abandoning open attempt", type: logType)
370386
return
371387
}
372388

373-
connectParams = opts
374-
375389
DefaultSocketLogger.Logger.log("Starting engine", type: logType)
376390
DefaultSocketLogger.Logger.log("Handshaking", type: logType)
377391

378392
resetEngine()
379393

380-
(urlPolling, urlWebSocket) = createURLs(opts)
381-
382394
if forceWebsockets {
383395
polling = false
384396
websocket = true
385397
createWebsocketAndConnect()
386398
return
387399
}
388400

389-
let reqPolling = NSMutableURLRequest(URL: NSURL(string: urlPolling + "&b64=1")!)
401+
let reqPolling = NSMutableURLRequest(URL: urlPolling)
390402

391403
if cookies != nil {
392404
let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(cookies!)

Source/SocketEnginePollable.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ extension SocketEnginePollable {
7171

7272
postWait.removeAll(keepCapacity: false)
7373

74-
let req = NSMutableURLRequest(URL: NSURL(string: urlPolling + "&sid=\(sid)")!)
74+
let req = NSMutableURLRequest(URL: urlPollingWithSid)
7575

7676
addHeaders(req)
7777

@@ -93,7 +93,7 @@ extension SocketEnginePollable {
9393
}
9494

9595
waitingForPoll = true
96-
let req = NSMutableURLRequest(URL: NSURL(string: urlPolling + "&sid=\(sid)&b64=1")!)
96+
let req = NSMutableURLRequest(URL: urlPollingWithSid)
9797

9898
addHeaders(req)
9999
doLongPoll(req)
@@ -112,7 +112,7 @@ extension SocketEnginePollable {
112112

113113
func doLongPoll(req: NSURLRequest) {
114114
doRequest(req) {[weak self] data, res, err in
115-
guard let this = self else {return}
115+
guard let this = self else { return }
116116

117117
if err != nil || data == nil {
118118
DefaultSocketLogger.Logger.error(err?.localizedDescription ?? "Error", type: "SocketEnginePolling")

Source/SocketEngineSpec.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import Foundation
2929
weak var client: SocketEngineClient? { get set }
3030
var closed: Bool { get }
3131
var connected: Bool { get }
32+
var connectParams: [String: AnyObject]? { get set }
3233
var cookies: [NSHTTPCookie]? { get }
3334
var extraHeaders: [String: String]? { get }
3435
var fastUpgrade: Bool { get }
@@ -42,23 +43,30 @@ import Foundation
4243
var handleQueue: dispatch_queue_t! { get }
4344
var sid: String { get }
4445
var socketPath: String { get }
45-
var urlPolling: String { get }
46-
var urlWebSocket: String { get }
46+
var urlPolling: NSURL { get }
47+
var urlWebSocket: NSURL { get }
4748
var websocket: Bool { get }
4849

49-
init(client: SocketEngineClient, url: String, options: NSDictionary?)
50+
init(client: SocketEngineClient, url: NSURL, options: NSDictionary?)
5051

5152
func close(reason: String)
5253
func didError(error: String)
5354
func doFastUpgrade()
5455
func flushWaitingForPostToWebSocket()
55-
func open(opts: [String: AnyObject]?)
56+
func open()
5657
func parseEngineData(data: NSData)
5758
func parseEngineMessage(message: String, fromPolling: Bool)
5859
func write(msg: String, withType type: SocketEnginePacketType, withData data: [NSData])
5960
}
6061

6162
extension SocketEngineSpec {
63+
var urlPollingWithSid: NSURL {
64+
let com = NSURLComponents(URL: urlPolling, resolvingAgainstBaseURL: false)!
65+
com.query = com.query! + "&sid=\(sid)"
66+
67+
return com.URL!
68+
}
69+
6270
func createBinaryDataForSend(data: NSData) -> Either<NSData, String> {
6371
if websocket {
6472
var byteArray = [UInt8](count: 1, repeatedValue: 0x4)

0 commit comments

Comments
 (0)