Compare commits

...

30 Commits

Author SHA1 Message Date
daltoniam c13584b99c bumped spec 2016-11-14 22:29:34 -06:00
Dalton 178c3e8a49 Merge pull request #277 from nuclearace/master
Fix Swift package manager
2016-11-01 18:57:49 -05:00
Erik ccc1b703dd Fix Swift package manager 2016-10-30 19:47:58 -04:00
daltoniam 1b64f78542 version bump 2016-10-26 20:41:30 -05:00
Dalton 549500a503 Merge pull request #253 from noremac/master
Only disable SSL cert validation if we are using a secure scheme.
2016-10-26 20:26:58 -05:00
Dalton 22d57dca07 Merge pull request #276 from profer/master
Enable custom trust validation
2016-10-26 20:26:30 -05:00
daltoniam dd5119cfce fix for #261 2016-10-26 20:25:39 -05:00
Wolfgang Profer a6b2e4329b Enable custom trust validation
Change WebSocket to use a protocol for trust validation instead of SSLSecurity directly. This allows users of Starscream to supply their own validation logic.
2016-10-24 13:43:44 +02:00
Dalton 931e3ba8ae Merge pull request #266 from fjcaetano/master
'Open'ing classes
2016-10-11 23:23:09 -05:00
Dalton 7476f5196e Merge pull request #267 from Dipak99041012/2.0.0HotFixes
[Fixup] crash for SSL Pinning Strange crash
2016-10-11 23:20:28 -05:00
Dipak Kasabwala 20285cce97 [Fixup] crash for SSL Pinning Strange crash 2016-10-10 18:14:01 -04:00
Flávio Caetano 8e1de1d475 'Open'ing classes 2016-10-10 17:47:13 -03:00
Cameron Pulsford acf64adc24 Only disable SSL cert validation if we are using a secure scheme. 2016-09-30 14:49:26 -04:00
Dalton b0fa08cde4 Merge pull request #259 from robinkunde/master
Improve clarity of asyncAfter code and other timeout
2016-09-30 13:34:49 -05:00
Dalton 9d32864ab4 Merge pull request #260 from ujell/master
Fixed parameter names in documentation
2016-09-30 13:02:28 -05:00
Yücel Uzun 7ef2bc41e0 Fixed parameter names in documentation 2016-09-29 18:50:22 +02:00
Robin Kunde 24e32a78e3 improve clarity of asyncAfter code and other timeout 2016-09-28 12:27:48 -04:00
daltoniam d831901ff4 more things to get cocoapods working 2016-09-18 16:35:32 -05:00
daltoniam 26b03ddaef swift 3 support 2016-09-18 16:28:53 -05:00
daltoniam d94c3ff3b4 cocoapods... 2016-09-18 16:18:21 -05:00
daltoniam 60d853742c cocoapods... 2016-09-18 16:16:37 -05:00
daltoniam 8563f6b85e osx podspec update 2016-09-18 16:13:23 -05:00
daltoniam c889a6c977 available for osx 2016-09-18 16:07:39 -05:00
daltoniam 8f3761215b conflict fixes 2016-09-18 15:46:05 -05:00
daltoniam cdf8caeb1a swift 2.3 update 2016-09-18 15:43:12 -05:00
daltoniam 00d8fae6cd swift3 updates 2016-09-18 15:37:55 -05:00
Dalton 46db9a75f0 Merge pull request #243 from cpinski/writeQueueQOS
Added initializer to set the QOS of the write queue
2016-09-13 21:21:48 -05:00
Christopher Pinski 5a3adc7756 Added initializer to set the QOS of the write queue 2016-08-29 15:44:05 -05:00
Dalton 32fb0aa87e Merge pull request #230 from cpinski/swift2.3
Adding full support for swift 2.3
2016-08-14 15:21:25 -07:00
Christopher Pinski 9c210e006e Adding full support for swift 2.3 2016-08-05 10:47:12 -05:00
26 changed files with 416 additions and 213 deletions
+1
View File
@@ -0,0 +1 @@
3.0
+31 -1
View File
@@ -2,6 +2,36 @@
All notable changes to this project will be documented in this file.
`Starscream` adheres to [Semantic Versioning](http://semver.org/).
#### [2.0.2](https://github.com/daltoniam/Starscream/tree/2.0.2)
Fix for the Swift Package Manager.
Fixed:
[#277](https://github.com/daltoniam/Starscream/issues/277)
#### [2.0.1](https://github.com/daltoniam/Starscream/tree/2.0.1)
Bug fixes.
Fixed:
[#261](https://github.com/daltoniam/Starscream/issues/261)
[#276](https://github.com/daltoniam/Starscream/issues/276)
[#267](https://github.com/daltoniam/Starscream/issues/267)
[#266](https://github.com/daltoniam/Starscream/issues/266)
[#259](https://github.com/daltoniam/Starscream/issues/259)
#### [2.0.0](https://github.com/daltoniam/Starscream/tree/2.0.0)
Added Swift 3 support.
Fixed:
[#229](https://github.com/daltoniam/Starscream/issues/229)
[#232](https://github.com/daltoniam/Starscream/issues/232)
#### [1.1.4](https://github.com/daltoniam/Starscream/tree/1.1.4)
Swift 2.3 support.
#### [1.1.3](https://github.com/daltoniam/Starscream/tree/1.1.3)
Changed:
@@ -47,4 +77,4 @@ Fixes for #121, #123
#### [1.0.0](https://github.com/daltoniam/Starscream/tree/1.0.0)
first release of Swift 2 support.
first release of Swift 2 support.
+1 -1
View File
@@ -2,7 +2,7 @@
Version 2.0, January 2004
http://www.apache.org/licenses/
Copyright (c) 2014-2015 Dalton Cherry.
Copyright (c) 2014-2016 Dalton Cherry.
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+2 -2
View File
@@ -3,7 +3,7 @@
// Starscream
//
// Created by Dalton Cherry on 5/16/15.
// Copyright (c) 2014-2015 Dalton Cherry.
// Copyright (c) 2014-2016 Dalton Cherry.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -22,4 +22,4 @@ import PackageDescription
let package = Package(
name: "Starscream"
)
)
+30 -29
View File
@@ -4,9 +4,6 @@ Starscream is a conforming WebSocket ([RFC 6455](http://tools.ietf.org/html/rfc6
It's Objective-C counter part can be found here: [Jetfire](https://github.com/acmacalister/jetfire)
###Swift 3/Xcode 8
If you are looking for Swift 3 support, see [swift 3 here](https://github.com/daltoniam/Starscream/tree/swift3)
## Features
- Conforms to all of the base [Autobahn test suite](http://autobahn.ws/testsuite/).
@@ -14,6 +11,10 @@ If you are looking for Swift 3 support, see [swift 3 here](https://github.com/da
- TLS/WSS support.
- Simple concise codebase at just a few hundred LOC.
## Swift 2.3
See release/tag 1.1.4 for Swift 2.3 support.
## Example
First thing is to import the framework. See the Installation instructions on how to add the framework to your project.
@@ -25,7 +26,7 @@ import Starscream
Once imported, you can open a connection to your WebSocket server. Note that `socket` is probably best as a property, so it doesn't get deallocated right after being setup.
```swift
socket = WebSocket(url: NSURL(string: "ws://localhost:8080/")!)
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!)
socket.delegate = self
socket.connect()
```
@@ -67,8 +68,8 @@ func websocketDidReceiveMessage(socket: WebSocket, text: String) {
websocketDidReceiveData is called when the client gets a binary frame from the connection.
```swift
func websocketDidReceiveData(socket: WebSocket, data: NSData) {
print("got some data: \(data.length)")
func websocketDidReceiveData(socket: WebSocket, data: Data) {
print("got some data: \(data.count)")
}
```
@@ -77,15 +78,15 @@ func websocketDidReceiveData(socket: WebSocket, data: NSData) {
websocketDidReceivePong is called when the client gets a pong response from the connection. You need to implement the WebSocketPongDelegate protocol and set an additional delegate, eg: ` socket.pongDelegate = self`
```swift
func websocketDidReceivePong(socket: WebSocket) {
print("Got pong!")
func websocketDidReceivePong(socket: WebSocket, data: Data?) {
print("Got pong! Maybe some data: \(data?.count)")
}
```
Or you can use closures.
```swift
socket = WebSocket(url: NSURL(string: "ws://localhost:8080/")!)
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!)
//websocketDidConnect
socket.onConnect = {
print("websocket is connected")
@@ -99,8 +100,8 @@ socket.onText = { (text: String) in
print("got some text: \(text)")
}
//websocketDidReceiveData
socket.onData = { (data: NSData) in
print("got some data: \(data.length)")
socket.onData = { (data: Data) in
print("got some data: \(data.count)")
}
//you could do onPong as well.
socket.connect()
@@ -111,28 +112,28 @@ One more: you can listen to socket connection and disconnection via notification
## The delegate methods give you a simple way to handle data from the server, but how do you send data?
### writeData
### write a binary frame
The writeData method gives you a simple way to send `NSData` (binary) data to the server.
The writeData method gives you a simple way to send `Data` (binary) data to the server.
```swift
socket.writeData(data) //write some NSData over the socket!
socket.write(data: data) //write some Data over the socket!
```
### writeString
### write a string frame
The writeString method is the same as writeData, but sends text/string.
```swift
socket.writeString("Hi Server!") //example on how to write text over the socket!
socket.write(string: "Hi Server!") //example on how to write text over the socket!
```
### writePing
### write a ping frame
The writePing method is the same as writeData, but sends a ping control frame.
The writePing method is the same as write, but sends a ping control frame.
```swift
socket.writePing(NSData()) //example on how to write a ping control frame over the socket!
socket.write(ping: Data()) //example on how to write a ping control frame over the socket!
```
### disconnect
@@ -169,7 +170,7 @@ If you need to specify a protocol, simple add it to the init:
```swift
//chat and superchat are the example protocols here
socket = WebSocket(url: NSURL(string: "ws://localhost:8080/")!, protocols: ["chat","superchat"])
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!, protocols: ["chat","superchat"])
socket.delegate = self
socket.connect()
```
@@ -179,13 +180,13 @@ socket.connect()
There are a couple of other properties that modify the stream:
```swift
socket = WebSocket(url: NSURL(string: "ws://localhost:8080/")!, protocols: ["chat","superchat"])
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!, protocols: ["chat","superchat"])
//set this if you are planning on using the socket in a VOIP background setting (using the background VOIP service).
socket.voipEnabled = true
//set this you want to ignore SSL cert validation, so a self signed SSL certificate can be used.
socket.selfSignedSSL = true
socket.disableSSLCertValidation = true
```
### SSL Pinning
@@ -193,21 +194,21 @@ socket.selfSignedSSL = true
SSL Pinning is also supported in Starscream.
```swift
socket = WebSocket(url: NSURL(string: "ws://localhost:8080/")!, protocols: ["chat","superchat"])
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!, protocols: ["chat","superchat"])
let data = ... //load your certificate from disk
socket.security = SSLSecurity(certs: [SSLCert(data: data)], usePublicKeys: true)
//socket.security = SSLSecurity() //uses the .cer files in your app's bundle
```
You load either a `NSData` blob of your certificate or you can use a `SecKeyRef` if you have a public key you want to use. The `usePublicKeys` bool is whether to use the certificates for validation or the public keys. The public keys will be extracted from the certificates automatically if `usePublicKeys` is choosen.
You load either a `Data` blob of your certificate or you can use a `SecKeyRef` if you have a public key you want to use. The `usePublicKeys` bool is whether to use the certificates for validation or the public keys. The public keys will be extracted from the certificates automatically if `usePublicKeys` is choosen.
### Custom Queue
A custom queue can be specified when delegate methods are called. By default `dispatch_get_main_queue` is used, thus making all delegate methods calls run on the main thread. It is important to note that all WebSocket processing is done on a background thread, only the delegate method calls are changed when modifying the queue. The actual processing is always on a background thread and will not pause your app.
A custom queue can be specified when delegate methods are called. By default `DispatchQueue.main` is used, thus making all delegate methods calls run on the main thread. It is important to note that all WebSocket processing is done on a background thread, only the delegate method calls are changed when modifying the queue. The actual processing is always on a background thread and will not pause your app.
```swift
socket = WebSocket(url: NSURL(string: "ws://localhost:8080/")!, protocols: ["chat","superchat"])
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!, protocols: ["chat","superchat"])
//create a custom queue
socket.queue = dispatch_queue_create("com.vluxe.starscream.myapp", nil)
socket.callbackQueue = DispatchQueue(label: "com.vluxe.starscream.myapp")
```
## Example Project
@@ -230,7 +231,7 @@ To use Starscream in your project add the following 'Podfile' to your project
platform :ios, '9.0'
use_frameworks!
pod 'Starscream', '~> 1.1.3'
pod 'Starscream', '~> 2.0.0'
Then run:
@@ -252,7 +253,7 @@ $ brew install carthage
To integrate Starscream into your Xcode project using Carthage, specify it in your `Cartfile`:
```
github "daltoniam/Starscream" >= 1.1.3
github "daltoniam/Starscream" >= 2.0.0
```
### Rogue
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.1.3</string>
<string>2.0.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.1.3</string>
<string>2.0.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+8 -5
View File
@@ -4,7 +4,7 @@
// Starscream
//
// Created by Dalton Cherry on 5/16/15.
// Copyright (c) 2014-2015 Dalton Cherry.
// Copyright (c) 2014-2016 Dalton Cherry.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -23,7 +23,11 @@
import Foundation
import Security
public class SSLCert {
public protocol SSLTrustValidator {
func isValid(_ trust: SecTrust, domain: String?) -> Bool
}
open class SSLCert {
var certData: Data?
var key: SecKey?
@@ -50,7 +54,7 @@ public class SSLCert {
}
}
public class SSLSecurity {
open class SSLSecurity : SSLTrustValidator {
public var validatedDN = true //should the domain name be validated?
var isReady = false //is the key processing done?
@@ -82,7 +86,7 @@ public class SSLSecurity {
/**
Designated init
- parameter keys: is the certificates or public keys to use
- parameter certs: is the certificates or public keys to use
- parameter usePublicKeys: is to specific if the publicKeys or certificates should be used for SSL pinning validation
- returns: a representation security object to be used with
@@ -207,7 +211,6 @@ public class SSLSecurity {
SecTrustCreateWithCertificates(cert, policy, &possibleTrust)
guard let trust = possibleTrust else { return nil }
var result: SecTrustResultType = .unspecified
SecTrustEvaluate(trust, &result)
return SecTrustCopyPublicKey(trust)
+166 -104
View File
@@ -3,7 +3,7 @@
// Websocket.swift
//
// Created by Dalton Cherry on 7/16/14.
// Copyright (c) 2014-2015 Dalton Cherry.
// Copyright (c) 2014-2016 Dalton Cherry.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -28,17 +28,17 @@ public let WebsocketDidDisconnectNotification = "WebsocketDidDisconnectNotificat
public let WebsocketDisconnectionErrorKeyName = "WebsocketDisconnectionErrorKeyName"
public protocol WebSocketDelegate: class {
func websocketDidConnect(_ socket: WebSocket)
func websocketDidDisconnect(_ socket: WebSocket, error: NSError?)
func websocketDidReceiveMessage(_ socket: WebSocket, text: String)
func websocketDidReceiveData(_ socket: WebSocket, data: Data)
func websocketDidConnect(socket: WebSocket)
func websocketDidDisconnect(socket: WebSocket, error: NSError?)
func websocketDidReceiveMessage(socket: WebSocket, text: String)
func websocketDidReceiveData(socket: WebSocket, data: Data)
}
public protocol WebSocketPongDelegate: class {
func websocketDidReceivePong(_ socket: WebSocket)
func websocketDidReceivePong(socket: WebSocket, data: Data?)
}
public class WebSocket : NSObject, StreamDelegate {
open class WebSocket : NSObject, StreamDelegate {
enum OpCode : UInt8 {
case continueFrame = 0x0
@@ -72,9 +72,9 @@ public class WebSocket : NSObject, StreamDelegate {
}
// Where the callback is executed. It defaults to the main UI thread queue.
public var callbackQueue = DispatchQueue.main
public var callbackQueue = DispatchQueue.main
var optionalProtocols : [String]?
var optionalProtocols: [String]?
// MARK: - Constants
@@ -113,7 +113,7 @@ public class WebSocket : NSObject, StreamDelegate {
/// and also connection/disconnect messages.
public weak var delegate: WebSocketDelegate?
/// Recives a callback for each pong message recived.
/// Receives a callback for each pong message recived.
public weak var pongDelegate: WebSocketPongDelegate?
@@ -123,16 +123,16 @@ public class WebSocket : NSObject, StreamDelegate {
public var onDisconnect: ((NSError?) -> Void)?
public var onText: ((String) -> Void)?
public var onData: ((Data) -> Void)?
public var onPong: ((Void) -> Void)?
public var onPong: ((Data?) -> Void)?
public var headers = [String: String]()
public var voipEnabled = false
public var selfSignedSSL = false
public var security: SSLSecurity?
public var disableSSLCertValidation = false
public var security: SSLTrustValidator?
public var enabledSSLCipherSuites: [SSLCipherSuite]?
public var origin: String?
public var timeout = 5
public var isConnected :Bool {
public var isConnected: Bool {
return connected
}
@@ -170,8 +170,16 @@ public class WebSocket : NSObject, StreamDelegate {
writeQueue.maxConcurrentOperationCount = 1
optionalProtocols = protocols
}
// Used for specifically setting the QOS for the write queue.
public convenience init(url: URL, writeQueueQOS: QualityOfService, protocols: [String]? = nil) {
self.init(url: url, protocols: protocols)
writeQueue.qualityOfService = writeQueueQOS
}
/// Connect to the WebSocket server on a background thread.
/**
Connect to the WebSocket server on a background thread.
*/
public func connect() {
guard !isConnecting else { return }
didDisconnect = false
@@ -188,16 +196,18 @@ public class WebSocket : NSObject, StreamDelegate {
If you supply a zero (or negative) `forceTimeout`, I immediately close the socket (without sending a Close control frame) and notify my delegate.
- Parameter forceTimeout: Maximum time to wait for the server to close the socket.
- Parameter closeCode: The code to send on disconnect. The default is the normal close code for cleanly disconnecting a webSocket.
*/
public func disconnect(forceTimeout: TimeInterval? = nil) {
public func disconnect(forceTimeout: TimeInterval? = nil, closeCode: UInt16 = CloseCode.normal.rawValue) {
switch forceTimeout {
case .some(let seconds) where seconds > 0:
callbackQueue.asyncAfter(deadline: DispatchTime.now() + Double(Int64(seconds * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { [weak self] in
let milliseconds = Int(seconds * 1_000)
callbackQueue.asyncAfter(deadline: .now() + .milliseconds(milliseconds)) { [weak self] in
self?.disconnectStream(nil)
}
fallthrough
case .none:
writeError(CloseCode.normal.rawValue)
writeError(closeCode)
default:
disconnectStream(nil)
break
@@ -209,7 +219,7 @@ public class WebSocket : NSObject, StreamDelegate {
If you supply a non-nil completion block, I will perform it when the write completes.
- parameter str: The string to write.
- parameter string: The string to write.
- parameter completion: The (optional) completion handler.
*/
public func write(string: String, completion: (() -> ())? = nil) {
@@ -230,14 +240,18 @@ public class WebSocket : NSObject, StreamDelegate {
dequeueWrite(data, code: .binaryFrame, writeCompletion: completion)
}
// Write a ping to the websocket. This sends it as a control frame.
// Yodel a sound to the planet. This sends it as an astroid. http://youtu.be/Eu5ZJELRiJ8?t=42s
public func write(_ ping: Data, completion: (() -> ())? = nil) {
/**
Write a ping to the websocket. This sends it as a control frame.
Yodel a sound to the planet. This sends it as an astroid. http://youtu.be/Eu5ZJELRiJ8?t=42s
*/
public func write(ping: Data, completion: (() -> ())? = nil) {
guard isConnected else { return }
dequeueWrite(ping, code: .ping, writeCompletion: completion)
}
/// Private method that starts the connection.
/**
Private method that starts the connection.
*/
private func createHTTPRequest() {
let urlRequest = CFHTTPMessageCreateRequest(kCFAllocatorDefault, "GET" as CFString,
@@ -262,7 +276,7 @@ public class WebSocket : NSObject, StreamDelegate {
addHeader(urlRequest, key: headerOriginName, val: origin)
}
addHeader(urlRequest, key: headerWSHostName, val: "\(url.host!):\(port!)")
for (key,value) in headers {
for (key, value) in headers {
addHeader(urlRequest, key: key, val: value)
}
if let cfHTTPMessage = CFHTTPMessageCopySerializedMessage(urlRequest) {
@@ -271,12 +285,16 @@ public class WebSocket : NSObject, StreamDelegate {
}
}
// Add a header to the CFHTTPMessage by using the NSString bridges to CFString
/**
Add a header to the CFHTTPMessage by using the NSString bridges to CFString
*/
private func addHeader(_ urlRequest: CFHTTPMessage, key: String, val: String) {
CFHTTPMessageSetHeaderFieldValue(urlRequest, key as CFString, val as CFString)
}
/// Generate a WebSocket key as needed in RFC.
/**
Generate a WebSocket key as needed in RFC.
*/
private func generateWebSocketKey() -> String {
var key = ""
let seed = 16
@@ -289,7 +307,9 @@ public class WebSocket : NSObject, StreamDelegate {
return baseKey!
}
/// Start the stream connection and write the data to the output stream.
/**
Start the stream connection and write the data to the output stream.
*/
private func initStreamsWithData(_ data: Data, _ port: Int) {
//higher level API we will cut over to at some point
//NSStream.getStreamsToHostWithName(url.host, port: url.port.integerValue, inputStream: &inputStream, outputStream: &outputStream)
@@ -306,6 +326,28 @@ public class WebSocket : NSObject, StreamDelegate {
if supportedSSLSchemes.contains(url.scheme!) {
inStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
outStream.setProperty(StreamSocketSecurityLevel.negotiatedSSL as AnyObject, forKey: Stream.PropertyKey.socketSecurityLevelKey)
if disableSSLCertValidation {
let settings: [NSObject: NSObject] = [kCFStreamSSLValidatesCertificateChain: NSNumber(value: false), kCFStreamSSLPeerName: kCFNull]
inStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as Stream.PropertyKey)
outStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as Stream.PropertyKey)
}
if let cipherSuites = self.enabledSSLCipherSuites {
if let sslContextIn = CFReadStreamCopyProperty(inputStream, CFStreamPropertyKey(rawValue: kCFStreamPropertySSLContext)) as! SSLContext?,
let sslContextOut = CFWriteStreamCopyProperty(outputStream, CFStreamPropertyKey(rawValue: kCFStreamPropertySSLContext)) as! SSLContext? {
let resIn = SSLSetEnabledCiphers(sslContextIn, cipherSuites, cipherSuites.count)
let resOut = SSLSetEnabledCiphers(sslContextOut, cipherSuites, cipherSuites.count)
if resIn != errSecSuccess {
let error = self.errorWithDetail("Error setting ingoing cypher suites", code: UInt16(resIn))
disconnectStream(error)
return
}
if resOut != errSecSuccess {
let error = self.errorWithDetail("Error setting outgoing cypher suites", code: UInt16(resOut))
disconnectStream(error)
return
}
}
}
} else {
certValidated = true //not a https session, so no need to check SSL pinning
}
@@ -313,28 +355,6 @@ public class WebSocket : NSObject, StreamDelegate {
inStream.setProperty(StreamNetworkServiceTypeValue.voIP as AnyObject, forKey: Stream.PropertyKey.networkServiceType)
outStream.setProperty(StreamNetworkServiceTypeValue.voIP as AnyObject, forKey: Stream.PropertyKey.networkServiceType)
}
if selfSignedSSL {
let settings: [NSObject: NSObject] = [kCFStreamSSLValidatesCertificateChain: NSNumber(value: false), kCFStreamSSLPeerName: kCFNull]
inStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as Stream.PropertyKey)
outStream.setProperty(settings, forKey: kCFStreamPropertySSLSettings as Stream.PropertyKey)
}
if let cipherSuites = self.enabledSSLCipherSuites {
if let sslContextIn = CFReadStreamCopyProperty(inputStream, CFStreamPropertyKey(rawValue: kCFStreamPropertySSLContext)) as! SSLContext?,
let sslContextOut = CFWriteStreamCopyProperty(outputStream, CFStreamPropertyKey(rawValue: kCFStreamPropertySSLContext)) as! SSLContext? {
let resIn = SSLSetEnabledCiphers(sslContextIn, cipherSuites, cipherSuites.count)
let resOut = SSLSetEnabledCiphers(sslContextOut, cipherSuites, cipherSuites.count)
if resIn != errSecSuccess {
let error = self.errorWithDetail("Error setting ingoing cypher suites", code: UInt16(resIn))
disconnectStream(error)
return
}
if resOut != errSecSuccess {
let error = self.errorWithDetail("Error setting outgoing cypher suites", code: UInt16(resOut))
disconnectStream(error)
return
}
}
}
CFReadStreamSetDispatchQueue(inStream, WebSocket.sharedWorkQueue)
CFWriteStreamSetDispatchQueue(outStream, WebSocket.sharedWorkQueue)
@@ -346,7 +366,7 @@ public class WebSocket : NSObject, StreamDelegate {
self.mutex.unlock()
let bytes = UnsafeRawPointer((data as NSData).bytes).assumingMemoryBound(to: UInt8.self)
var out = timeout * 1000000 // wait 5 seconds before giving up
var out = timeout * 1_000_000 // wait 5 seconds before giving up
writeQueue.addOperation { [weak self] in
while !outStream.hasSpaceAvailable {
usleep(100) // wait until the socket is ready
@@ -363,12 +383,14 @@ public class WebSocket : NSObject, StreamDelegate {
}
}
//delegate for the stream methods. Processes incoming bytes
/**
Delegate for the stream methods. Processes incoming bytes
*/
public func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
if let sec = security, !certValidated && [.hasBytesAvailable, .hasSpaceAvailable].contains(eventCode) {
let trust = aStream.property(forKey: kCFStreamPropertySSLPeerTrust as Stream.PropertyKey) as AnyObject
let trust = aStream.property(forKey: kCFStreamPropertySSLPeerTrust as Stream.PropertyKey) as! SecTrust
let domain = aStream.property(forKey: kCFStreamSSLPeerName as Stream.PropertyKey) as? String
if sec.isValid(trust as! SecTrust, domain: domain) {
if sec.isValid(trust, domain: domain) {
certValidated = true
} else {
let error = errorWithDetail("Invalid SSL certificate", code: 1)
@@ -387,7 +409,9 @@ public class WebSocket : NSObject, StreamDelegate {
}
}
/// Disconnect the stream object and notifies the delegate.
/**
Disconnect the stream object and notifies the delegate.
*/
private func disconnectStream(_ error: NSError?) {
if error == nil {
writeQueue.waitUntilAllOperationsAreFinished()
@@ -398,6 +422,9 @@ public class WebSocket : NSObject, StreamDelegate {
doDisconnect(error)
}
/**
cleanup the streams.
*/
private func cleanupStream() {
outputStream?.delegate = nil
inputStream?.delegate = nil
@@ -413,12 +440,13 @@ public class WebSocket : NSObject, StreamDelegate {
inputStream = nil
}
/// Handles the incoming bytes and sending them to the proper processing method.
/**
Handles the incoming bytes and sending them to the proper processing method.
*/
private func processInputStream() {
let buf = NSMutableData(capacity: BUFFER_MAX)
let buffer = UnsafeMutableRawPointer(mutating: buf!.bytes).assumingMemoryBound(to: UInt8.self)
let length = inputStream!.read(buffer, maxLength: BUFFER_MAX)
guard length > 0 else { return }
var process = false
if inputQueue.count == 0 {
@@ -430,7 +458,9 @@ public class WebSocket : NSObject, StreamDelegate {
}
}
/// Dequeue the incoming input so it is processed in order.
/**
Dequeue the incoming input so it is processed in order.
*/
private func dequeueInput() {
while !inputQueue.isEmpty {
let data = inputQueue[0]
@@ -452,7 +482,9 @@ public class WebSocket : NSObject, StreamDelegate {
}
}
//handle checking the inital connection status
/**
Handle checking the inital connection status
*/
private func processTCPHandshake(_ buffer: UnsafePointer<UInt8>, bufferLen: Int) {
let code = processHTTP(buffer, bufferLen: bufferLen)
switch code {
@@ -462,7 +494,7 @@ public class WebSocket : NSObject, StreamDelegate {
callbackQueue.async { [weak self] in
guard let s = self else { return }
s.onConnect?()
s.delegate?.websocketDidConnect(s)
s.delegate?.websocketDidConnect(socket: s)
s.notificationCenter.post(name: NSNotification.Name(WebsocketDidConnectNotification), object: self)
}
case -1:
@@ -473,7 +505,9 @@ public class WebSocket : NSObject, StreamDelegate {
}
}
///Finds the HTTP Packet in the TCP stream, by looking for the CRLF.
/**
Finds the HTTP Packet in the TCP stream, by looking for the CRLF.
*/
private func processHTTP(_ buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Int {
let CRLFBytes = [UInt8(ascii: "\r"), UInt8(ascii: "\n"), UInt8(ascii: "\r"), UInt8(ascii: "\n")]
var k = 0
@@ -504,7 +538,9 @@ public class WebSocket : NSObject, StreamDelegate {
return -1 // Was unable to find the full TCP header.
}
/// Validates the HTTP is a 101 as per the RFC spec.
/**
Validates the HTTP is a 101 as per the RFC spec.
*/
private func validateResponse(_ buffer: UnsafePointer<UInt8>, bufferLen: Int) -> Int {
let response = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, false).takeRetainedValue()
CFHTTPMessageAppendBytes(response, buffer, bufferLen)
@@ -523,12 +559,16 @@ public class WebSocket : NSObject, StreamDelegate {
return -1
}
///read a 16 bit big endian value from a buffer
/**
Read a 16 bit big endian value from a buffer
*/
private static func readUint16(_ buffer: UnsafePointer<UInt8>, offset: Int) -> UInt16 {
return (UInt16(buffer[offset + 0]) << 8) | UInt16(buffer[offset + 1])
}
///read a 64 bit big endian value from a buffer
/**
Read a 64 bit big endian value from a buffer
*/
private static func readUint64(_ buffer: UnsafePointer<UInt8>, offset: Int) -> UInt64 {
var value = UInt64(0)
for i in 0...7 {
@@ -537,26 +577,31 @@ public class WebSocket : NSObject, StreamDelegate {
return value
}
/// Write a 16-bit big endian value to a buffer.
/**
Write a 16-bit big endian value to a buffer.
*/
private static func writeUint16(_ buffer: UnsafeMutablePointer<UInt8>, offset: Int, value: UInt16) {
buffer[offset + 0] = UInt8(value >> 8)
buffer[offset + 1] = UInt8(value & 0xff)
}
/// Write a 64-bit big endian value to a buffer.
/**
Write a 64-bit big endian value to a buffer.
*/
private static func writeUint64(_ buffer: UnsafeMutablePointer<UInt8>, offset: Int, value: UInt64) {
for i in 0...7 {
buffer[offset + i] = UInt8((value >> (8*UInt64(7 - i))) & 0xff)
}
}
/// Process one message at the start of `buffer`. Return another buffer (sharing storage) that contains the leftover contents of `buffer` that I didn't process.
/**
Process one message at the start of `buffer`. Return another buffer (sharing storage) that contains the leftover contents of `buffer` that I didn't process.
*/
private func processOneRawMessage(inBuffer buffer: UnsafeBufferPointer<UInt8>) -> UnsafeBufferPointer<UInt8> {
let response = readStack.last
guard let baseAddress = buffer.baseAddress else {return emptyBuffer}
let bufferLen = buffer.count
if response != nil && bufferLen < 2 {
if response != nil && bufferLen < 2 {
fragBuffer = Data(buffer: buffer)
return emptyBuffer
}
@@ -597,34 +642,22 @@ public class WebSocket : NSObject, StreamDelegate {
writeError(errCode)
return emptyBuffer
}
var closeCode = CloseCode.normal.rawValue
if receivedOpcode == .connectionClose {
var code = CloseCode.normal.rawValue
if payloadLen == 1 {
code = CloseCode.protocolError.rawValue
closeCode = CloseCode.protocolError.rawValue
} else if payloadLen > 1 {
code = WebSocket.readUint16(baseAddress, offset: offset)
if code < 1000 || (code > 1003 && code < 1007) || (code > 1011 && code < 3000) {
code = CloseCode.protocolError.rawValue
}
offset += 2
}
var closeReason = "connection closed by server"
if payloadLen > 2 {
let len = Int(payloadLen - 2)
if len > 0 {
let bytes = baseAddress + offset
if let customCloseReason = String(data: Data(bytes: bytes, count: len), encoding: .utf8) {
closeReason = customCloseReason
} else {
code = CloseCode.protocolError.rawValue
}
closeCode = WebSocket.readUint16(baseAddress, offset: offset)
if closeCode < 1000 || (closeCode > 1003 && closeCode < 1007) || (closeCode > 1011 && closeCode < 3000) {
closeCode = CloseCode.protocolError.rawValue
}
}
doDisconnect(errorWithDetail(closeReason, code: code))
writeError(code)
return emptyBuffer
}
if isControlFrame && payloadLen > 125 {
if payloadLen < 2 {
doDisconnect(errorWithDetail("connection closed by server", code: closeCode))
writeError(closeCode)
return emptyBuffer
}
} else if isControlFrame && payloadLen > 125 {
writeError(CloseCode.protocolError.rawValue)
return emptyBuffer
}
@@ -649,14 +682,31 @@ public class WebSocket : NSObject, StreamDelegate {
len = 0
data = Data()
} else {
if receivedOpcode == .connectionClose && len > 0 {
let size = MemoryLayout<UInt16>.size
offset += size
len -= UInt64(size)
}
data = Data(bytes: baseAddress+offset, count: Int(len))
}
if receivedOpcode == .connectionClose {
var closeReason = "connection closed by server"
if let customCloseReason = String(data: data, encoding: .utf8) {
closeReason = customCloseReason
} else {
closeCode = CloseCode.protocolError.rawValue
}
doDisconnect(errorWithDetail(closeReason, code: closeCode))
writeError(closeCode)
return emptyBuffer
}
if receivedOpcode == .pong {
if canDispatch {
callbackQueue.async { [weak self] in
guard let s = self else { return }
s.onPong?()
s.pongDelegate?.websocketDidReceivePong(s)
let pongData: Data? = data.count > 0 ? data : nil
s.onPong?(pongData)
s.pongDelegate?.websocketDidReceivePong(socket: s, data: pongData)
}
}
return buffer.fromOffset(offset + Int(len))
@@ -673,7 +723,7 @@ public class WebSocket : NSObject, StreamDelegate {
}
var isNew = false
if response == nil {
if receivedOpcode == .continueFrame {
if receivedOpcode == .continueFrame {
let errCode = CloseCode.protocolError.rawValue
doDisconnect(errorWithDetail("first frame can't be a continue frame",
code: errCode))
@@ -686,7 +736,7 @@ public class WebSocket : NSObject, StreamDelegate {
response!.bytesLeft = Int(dataLength)
response!.buffer = NSMutableData(data: data)
} else {
if receivedOpcode == .continueFrame {
if receivedOpcode == .continueFrame {
response!.bytesLeft = Int(dataLength)
} else {
let errCode = CloseCode.protocolError.rawValue
@@ -712,7 +762,9 @@ public class WebSocket : NSObject, StreamDelegate {
}
}
/// Process all messages in the buffer if possible.
/**
Process all messages in the buffer if possible.
*/
private func processRawMessagesInBuffer(_ pointer: UnsafePointer<UInt8>, bufferLen: Int) {
var buffer = UnsafeBufferPointer(start: pointer, count: bufferLen)
repeat {
@@ -723,7 +775,9 @@ public class WebSocket : NSObject, StreamDelegate {
}
}
/// Process the finished response of a buffer.
/**
Process the finished response of a buffer.
*/
private func processResponse(_ response: WSResponse) -> Bool {
if response.isFin && response.bytesLeft <= 0 {
if response.code == .ping {
@@ -739,7 +793,7 @@ public class WebSocket : NSObject, StreamDelegate {
callbackQueue.async { [weak self] in
guard let s = self else { return }
s.onText?(str! as String)
s.delegate?.websocketDidReceiveMessage(s, text: str! as String)
s.delegate?.websocketDidReceiveMessage(socket: s, text: str! as String)
}
}
} else if response.code == .binaryFrame {
@@ -748,7 +802,7 @@ public class WebSocket : NSObject, StreamDelegate {
callbackQueue.async { [weak self] in
guard let s = self else { return }
s.onData?(data as Data)
s.delegate?.websocketDidReceiveData(s, data: data as Data)
s.delegate?.websocketDidReceiveData(socket: s, data: data as Data)
}
}
}
@@ -758,14 +812,18 @@ public class WebSocket : NSObject, StreamDelegate {
return false
}
/// Create an error
/**
Create an error
*/
private func errorWithDetail(_ detail: String, code: UInt16) -> NSError {
var details = [String: String]()
details[NSLocalizedDescriptionKey] = detail
return NSError(domain: WebSocket.ErrorDomain, code: Int(code), userInfo: details)
}
/// Write an error to the socket
/**
Write an error to the socket
*/
private func writeError(_ code: UInt16) {
let buf = NSMutableData(capacity: MemoryLayout<UInt16>.size)
let buffer = UnsafeMutableRawPointer(mutating: buf!.bytes).assumingMemoryBound(to: UInt8.self)
@@ -773,7 +831,9 @@ public class WebSocket : NSObject, StreamDelegate {
dequeueWrite(Data(bytes: buffer, count: MemoryLayout<UInt16>.size), code: .connectionClose)
}
/// Used to write things to the stream
/**
Used to write things to the stream
*/
private func dequeueWrite(_ data: Data, code: OpCode, writeCompletion: (() -> ())? = nil) {
writeQueue.addOperation { [weak self] in
//stream isn't ready, let's wait
@@ -835,7 +895,9 @@ public class WebSocket : NSObject, StreamDelegate {
}
}
/// Used to preform the disconnect delegate
/**
Used to preform the disconnect delegate
*/
private func doDisconnect(_ error: NSError?) {
guard !didDisconnect else { return }
didDisconnect = true
@@ -844,7 +906,7 @@ public class WebSocket : NSObject, StreamDelegate {
callbackQueue.async { [weak self] in
guard let s = self else { return }
s.onDisconnect?(error)
s.delegate?.websocketDidDisconnect(s, error: error)
s.delegate?.websocketDidDisconnect(socket: s, error: error)
let userInfo = error.map{ [WebsocketDisconnectionErrorKeyName: $0] }
s.notificationCenter.post(name: NSNotification.Name(WebsocketDidDisconnectNotification), object: self, userInfo: userInfo)
}
+2 -2
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Starscream"
s.version = "1.1.3"
s.version = "2.0.2"
s.summary = "A conforming WebSocket RFC 6455 client library in Swift for iOS and OSX."
s.homepage = "https://github.com/daltoniam/Starscream"
s.license = 'Apache License, Version 2.0'
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
s.source = { :git => 'https://github.com/daltoniam/Starscream.git', :tag => "#{s.version}"}
s.social_media_url = 'http://twitter.com/daltoniam'
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.9'
s.osx.deployment_target = '10.10'
s.tvos.deployment_target = '9.0'
s.source_files = 'Source/*.swift'
s.requires_arc = 'true'
+24 -8
View File
@@ -17,10 +17,10 @@
5C1360081C473BEF00AA3A01 /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1360011C473BEF00AA3A01 /* WebSocket.swift */; };
5C1360091C473BEF00AA3A01 /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1360011C473BEF00AA3A01 /* WebSocket.swift */; };
5C13600A1C473BEF00AA3A01 /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1360011C473BEF00AA3A01 /* WebSocket.swift */; };
5CADAB511BEBD068005DE2F0 /* StarscreamTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B3E7A0119D48C2F006071F7 /* StarscreamTests.swift */; };
6B3E7A0319D48C2F006071F7 /* StarscreamTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B3E7A0119D48C2F006071F7 /* StarscreamTests.swift */; };
742419BC1DC6BDBA003ACE43 /* StarscreamTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 742419BB1DC6BDBA003ACE43 /* StarscreamTests.swift */; };
742419BD1DC6BDBA003ACE43 /* StarscreamTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 742419BB1DC6BDBA003ACE43 /* StarscreamTests.swift */; };
742419BE1DC6BDBA003ACE43 /* StarscreamTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 742419BB1DC6BDBA003ACE43 /* StarscreamTests.swift */; };
D9C3E36A19E48FF1009FC285 /* Starscream.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D9C3E35F19E48FF1009FC285 /* Starscream.framework */; };
D9C3E37819E4903F009FC285 /* StarscreamTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B3E7A0119D48C2F006071F7 /* StarscreamTests.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -51,7 +51,7 @@
6B3E79E619D48B7F006071F7 /* Starscream.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Starscream.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6B3E79F119D48B7F006071F7 /* Starscream iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Starscream iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
6B3E7A0019D48C2F006071F7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6B3E7A0119D48C2F006071F7 /* StarscreamTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StarscreamTests.swift; sourceTree = "<group>"; };
742419BB1DC6BDBA003ACE43 /* StarscreamTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StarscreamTests.swift; path = StarscreamTests/StarscreamTests.swift; sourceTree = "<group>"; };
D9C3E35F19E48FF1009FC285 /* Starscream.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Starscream.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D9C3E36919E48FF1009FC285 /* Starscream OSXTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Starscream OSXTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@@ -150,7 +150,7 @@
isa = PBXGroup;
children = (
6B3E7A0019D48C2F006071F7 /* Info.plist */,
6B3E7A0119D48C2F006071F7 /* StarscreamTests.swift */,
742419BB1DC6BDBA003ACE43 /* StarscreamTests.swift */,
);
path = Tests;
sourceTree = "<group>";
@@ -308,6 +308,7 @@
};
0912779F1BD673A70003036D = {
CreatedOnToolsVersion = 7.1;
LastSwiftMigration = 0810;
};
6B3E79E519D48B7F006071F7 = {
CreatedOnToolsVersion = 6.0.1;
@@ -315,12 +316,14 @@
};
6B3E79F019D48B7F006071F7 = {
CreatedOnToolsVersion = 6.0.1;
LastSwiftMigration = 0810;
};
D9C3E35E19E48FF1009FC285 = {
CreatedOnToolsVersion = 6.1;
};
D9C3E36819E48FF1009FC285 = {
CreatedOnToolsVersion = 6.1;
LastSwiftMigration = 0810;
};
};
};
@@ -405,7 +408,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5CADAB511BEBD068005DE2F0 /* StarscreamTests.swift in Sources */,
742419BE1DC6BDBA003ACE43 /* StarscreamTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -422,7 +425,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6B3E7A0319D48C2F006071F7 /* StarscreamTests.swift in Sources */,
742419BC1DC6BDBA003ACE43 /* StarscreamTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -439,7 +442,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D9C3E37819E4903F009FC285 /* StarscreamTests.swift in Sources */,
742419BD1DC6BDBA003ACE43 /* StarscreamTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -515,6 +518,7 @@
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
GCC_NO_COMMON_BLOCKS = YES;
INFOPLIST_FILE = Tests/Info.plist;
@@ -522,6 +526,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.vluxe.StarscreamTvTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = appletvos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TVOS_DEPLOYMENT_TARGET = 9.0;
};
@@ -531,6 +536,7 @@
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_NO_COMMON_BLOCKS = YES;
@@ -559,8 +565,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -608,8 +616,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -689,6 +699,7 @@
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
@@ -701,6 +712,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.vluxe.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
@@ -709,6 +721,7 @@
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
@@ -776,6 +789,7 @@
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(DEVELOPER_FRAMEWORKS_DIR)",
@@ -791,6 +805,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.vluxe.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
@@ -799,6 +814,7 @@
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
COMBINE_HIDPI_IMAGES = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
FRAMEWORK_SEARCH_PATHS = (
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
LastUpgradeVersion = "0810"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -59,6 +59,20 @@
remoteGlobalIDString = 6B3E79E519D48B7F006071F7;
remoteInfo = Starscream;
};
5C42C3D51D8DF51C00947AA2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5C178E411B62D0EF00A97204 /* Starscream.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 091277971BD673A70003036D;
remoteInfo = "Starscream tvOS";
};
5C42C3D71D8DF51C00947AA2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5C178E411B62D0EF00A97204 /* Starscream.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 091277A01BD673A70003036D;
remoteInfo = "Starscream tvOSTests";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
@@ -158,6 +172,8 @@
5C178E4B1B62D0EF00A97204 /* StarscreamTests.xctest */,
5C178E4D1B62D0EF00A97204 /* Starscream.framework */,
5C178E4F1B62D0EF00A97204 /* StarscreamOSXTests.xctest */,
5C42C3D61D8DF51C00947AA2 /* Starscream.framework */,
5C42C3D81D8DF51C00947AA2 /* Starscream tvOSTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -214,9 +230,11 @@
TargetAttributes = {
5C178E1B1B62D0B900A97204 = {
CreatedOnToolsVersion = 6.4;
LastSwiftMigration = 0800;
};
5C178E301B62D0B900A97204 = {
CreatedOnToolsVersion = 6.4;
LastSwiftMigration = 0800;
TestTargetID = 5C178E1B1B62D0B900A97204;
};
};
@@ -257,7 +275,7 @@
5C178E4B1B62D0EF00A97204 /* StarscreamTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = StarscreamTests.xctest;
path = "Starscream iOSTests.xctest";
remoteRef = 5C178E4A1B62D0EF00A97204 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
@@ -271,10 +289,24 @@
5C178E4F1B62D0EF00A97204 /* StarscreamOSXTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = StarscreamOSXTests.xctest;
path = "Starscream OSXTests.xctest";
remoteRef = 5C178E4E1B62D0EF00A97204 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
5C42C3D61D8DF51C00947AA2 /* Starscream.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = Starscream.framework;
remoteRef = 5C42C3D51D8DF51C00947AA2 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
5C42C3D81D8DF51C00947AA2 /* Starscream tvOSTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = "Starscream tvOSTests.xctest";
remoteRef = 5C42C3D71D8DF51C00947AA2 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
@@ -440,6 +472,7 @@
INFOPLIST_FILE = Autobahn/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -450,6 +483,7 @@
INFOPLIST_FILE = Autobahn/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -468,6 +502,7 @@
INFOPLIST_FILE = AutobahnTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Autobahn.app/Autobahn";
};
name = Debug;
@@ -483,6 +518,7 @@
INFOPLIST_FILE = AutobahnTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Autobahn.app/Autobahn";
};
name = Release;
@@ -14,30 +14,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(application: UIApplication) {
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@@ -12,7 +12,6 @@ import Starscream
class ViewController: UIViewController {
let host = "localhost:9001"
let scheme = "ws"
var socketArray = [WebSocket]()
var caseCount = 300 //starting cases
override func viewDidLoad() {
@@ -21,12 +20,13 @@ class ViewController: UIViewController {
//getTestInfo(1)
}
func removeSocket(s: WebSocket) {
self.socketArray = self.socketArray.filter{$0 != s}
func removeSocket(_ s: WebSocket) {
socketArray = socketArray.filter{$0 != s}
}
func getCaseCount() {
let s = WebSocket(url: NSURL(scheme: scheme, host: host, path: "/getCaseCount")!, protocols: [])
let s = WebSocket(url: URL(string: "ws://\(host)/getCaseCount")!, protocols: [])
socketArray.append(s)
s.onText = {[unowned self] (text: String) in
if let c = Int(text) {
@@ -41,7 +41,7 @@ class ViewController: UIViewController {
s.connect()
}
func getTestInfo(caseNum: Int) {
func getTestInfo(_ caseNum: Int) {
let s = createSocket("getCaseInfo",caseNum)
socketArray.append(s)
s.onText = {(text: String) in
@@ -72,14 +72,14 @@ class ViewController: UIViewController {
s.connect()
}
func runTest(caseNum: Int) {
func runTest(_ caseNum: Int) {
let s = createSocket("runCase",caseNum)
self.socketArray.append(s)
s.onText = {(text: String) in
s.writeString(text)
s.write(string: text)
}
s.onData = {(data: NSData) in
s.writeData(data)
s.onData = {(data: Data) in
s.write(data: data)
}
var once = false
s.onDisconnect = {[unowned self] (error: NSError?) in
@@ -93,14 +93,14 @@ class ViewController: UIViewController {
s.connect()
}
func verifyTest(caseNum: Int) {
func verifyTest(_ caseNum: Int) {
let s = createSocket("getCaseStatus",caseNum)
self.socketArray.append(s)
s.onText = {(text: String) in
let data = text.dataUsingEncoding(NSUTF8StringEncoding)
let data = text.data(using: String.Encoding.utf8)
do {
let resp: AnyObject? = try NSJSONSerialization.JSONObjectWithData(data!,
options: NSJSONReadingOptions())
let resp: Any? = try JSONSerialization.jsonObject(with: data!,
options: JSONSerialization.ReadingOptions())
if let dict = resp as? Dictionary<String,String> {
if let status = dict["behavior"] {
if status == "OK" {
@@ -140,12 +140,11 @@ class ViewController: UIViewController {
s.connect()
}
func createSocket(cmd: String, _ caseNum: Int) -> WebSocket {
return WebSocket(url: NSURL(scheme: scheme,
host: host, path: buildPath(cmd,caseNum))!, protocols: [])
func createSocket(_ cmd: String, _ caseNum: Int) -> WebSocket {
return WebSocket(url: URL(string: "ws://\(host)\(buildPath(cmd,caseNum))")!, protocols: [])
}
func buildPath(cmd: String, _ caseNum: Int) -> String {
func buildPath(_ cmd: String, _ caseNum: Int) -> String {
return "/\(cmd)?case=\(caseNum)&agent=Starscream"
}
@@ -28,7 +28,7 @@ class AutobahnTests: XCTestCase {
func testPerformanceExample() {
// This is an example of a performance test case.
self.measureBlock() {
self.measure() {
// Put the code you want to measure the time of here.
}
}
@@ -37,6 +37,20 @@
remoteGlobalIDString = D9C3E36919E48FF1009FC285;
remoteInfo = StarscreamOSXTests;
};
5C42C3E01D8F31DC00947AA2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 6B3E7A0819D48D00006071F7 /* Starscream.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 091277971BD673A70003036D;
remoteInfo = "Starscream tvOS";
};
5C42C3E21D8F31DC00947AA2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 6B3E7A0819D48D00006071F7 /* Starscream.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 091277A01BD673A70003036D;
remoteInfo = "Starscream tvOSTests";
};
6B3E7A0D19D48D00006071F7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 6B3E7A0819D48D00006071F7 /* Starscream.xcodeproj */;
@@ -129,9 +143,11 @@
isa = PBXGroup;
children = (
6B3E7A0E19D48D00006071F7 /* Starscream.framework */,
6B3E7A1019D48D00006071F7 /* StarscreamTests.xctest */,
6B3E7A1019D48D00006071F7 /* Starscream iOSTests.xctest */,
5C06AE8B1B08044600D41060 /* Starscream.framework */,
5C06AE8D1B08044600D41060 /* StarscreamOSXTests.xctest */,
5C42C3E11D8F31DC00947AA2 /* Starscream.framework */,
5C42C3E31D8F31DC00947AA2 /* Starscream tvOSTests.xctest */,
);
name = Products;
sourceTree = "<group>";
@@ -165,11 +181,12 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0600;
LastUpgradeCheck = 0800;
ORGANIZATIONNAME = vluxe;
TargetAttributes = {
5C765ADA199A6DAA003D9110 = {
CreatedOnToolsVersion = 6.0;
LastSwiftMigration = 0800;
};
};
};
@@ -205,13 +222,27 @@
remoteRef = 5C06AE8A1B08044600D41060 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
5C06AE8D1B08044600D41060 /* StarscreamOSXTests.xctest */ = {
5C06AE8D1B08044600D41060 /* Starscream OSXTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = StarscreamOSXTests.xctest;
path = "Starscream OSXTests.xctest";
remoteRef = 5C06AE8C1B08044600D41060 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
5C42C3E11D8F31DC00947AA2 /* Starscream.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = Starscream.framework;
remoteRef = 5C42C3E01D8F31DC00947AA2 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
5C42C3E31D8F31DC00947AA2 /* Starscream tvOSTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = "Starscream tvOSTests.xctest";
remoteRef = 5C42C3E21D8F31DC00947AA2 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
6B3E7A0E19D48D00006071F7 /* Starscream.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
@@ -219,10 +250,10 @@
remoteRef = 6B3E7A0D19D48D00006071F7 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
6B3E7A1019D48D00006071F7 /* StarscreamTests.xctest */ = {
6B3E7A1019D48D00006071F7 /* Starscream iOSTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = StarscreamTests.xctest;
path = "Starscream iOSTests.xctest";
remoteRef = 6B3E7A0F19D48D00006071F7 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
@@ -285,15 +316,19 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -328,8 +363,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -337,6 +374,7 @@
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
@@ -346,6 +384,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
@@ -358,7 +397,9 @@
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
INFOPLIST_FILE = SimpleTest/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.vluxe.io.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@@ -369,7 +410,9 @@
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
INFOPLIST_FILE = SimpleTest/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.vluxe.io.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0600"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@@ -37,10 +37,10 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
@@ -62,17 +62,21 @@
ReferencedContainer = "container:SimpleTest.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5C765ADA199A6DAA003D9110"
@@ -81,16 +85,24 @@
ReferencedContainer = "container:SimpleTest.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "OS_ACTIVITY_MODE"
value = "disable"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable>
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "5C765ADA199A6DAA003D9110"
@@ -14,30 +14,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(application: UIApplication) {
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
+1 -1
View File
@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.vluxe.io.$(PRODUCT_NAME:rfc1034identifier)</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
@@ -10,7 +10,7 @@ import UIKit
import Starscream
class ViewController: UIViewController, WebSocketDelegate {
var socket = WebSocket(url: NSURL(string: "ws://localhost:8080/")!, protocols: ["chat", "superchat"])
var socket = WebSocket(url: URL(string: "ws://localhost:8080/")!, protocols: ["chat", "superchat"])
override func viewDidLoad() {
super.viewDidLoad()
@@ -20,11 +20,11 @@ class ViewController: UIViewController, WebSocketDelegate {
// MARK: Websocket Delegate Methods.
func websocketDidConnect(ws: WebSocket) {
func websocketDidConnect(socket: WebSocket) {
print("websocket is connected")
}
func websocketDidDisconnect(ws: WebSocket, error: NSError?) {
func websocketDidDisconnect(socket: WebSocket, error: NSError?) {
if let e = error {
print("websocket is disconnected: \(e.localizedDescription)")
} else {
@@ -32,23 +32,23 @@ class ViewController: UIViewController, WebSocketDelegate {
}
}
func websocketDidReceiveMessage(ws: WebSocket, text: String) {
func websocketDidReceiveMessage(socket: WebSocket, text: String) {
print("Received text: \(text)")
}
func websocketDidReceiveData(ws: WebSocket, data: NSData) {
print("Received data: \(data.length)")
func websocketDidReceiveData(socket: WebSocket, data: Data) {
print("Received data: \(data.count)")
}
// MARK: Write Text Action
@IBAction func writeText(sender: UIBarButtonItem) {
socket.writeString("hello there!")
@IBAction func writeText(_ sender: UIBarButtonItem) {
socket.write(string: "hello there!")
}
// MARK: Disconnect Action
@IBAction func disconnect(sender: UIBarButtonItem) {
@IBAction func disconnect(_ sender: UIBarButtonItem) {
if socket.isConnected {
sender.title = "Connect"
socket.disconnect()