Merge branch 'development'

* development: (23 commits)
  only build mac since the other targets aren't used in testing
  add package resolved file
  rename method
  update readme for carthage
  move carthage update to before_install
  Document SSLSecurity class
  update versions; use upstream starscream in podfile dep
  Go back to Starscream 2.1.1
  Fixes Mac build
  Proof of concept
  Remove StarScream
  Fix documentation
  Don't set configs after connect
  Allow changing config after init but before connect. Fixes #680
  Make a bunch of things public. Fixes #803
  More documentation
  bump starscream dev
  update version; again
  work on fixing for latest version
  update starscream
  ...
This commit is contained in:
Erik Little 2017-10-01 10:46:34 -04:00
commit 43907a4001
No known key found for this signature in database
GPG Key ID: 4930B7C5FBC1A69D
25 changed files with 692 additions and 291 deletions

4
.gitmodules vendored
View File

@ -1,4 +0,0 @@
[submodule "Source/Starscream"]
path = Source/Starscream
url = https://github.com/nuclearace/Starscream
branch = socket.io-dev

View File

@ -1,15 +1,16 @@
language: objective-c
xcode_project: Socket.IO-Client-Swift.xcodeproj # path to your xcodeproj folder
xcode_scheme: SocketIO-iOS
xcode_scheme: SocketIO-Mac
osx_image: xcode9
branches:
only:
- master
- development
- swift4.0
before_install:
- brew update
- brew outdated xctool || brew upgrade xctool
# - brew outdated xctool || brew upgrade xctool
- brew outdated carthage || brew upgrade carthage
- carthage update --platform macosx
script:
- xcodebuild -project Socket.IO-Client-Swift.xcodeproj -scheme SocketIO-Mac build test -quiet
# - xcodebuild -project Socket.IO-Client-Swift.xcodeproj -scheme SocketIO-Mac build-for-testing -quiet

1
Cartfile Normal file
View File

@ -0,0 +1 @@
github "daltoniam/Starscream" ~> 2.0

1
Cartfile.resolved Normal file
View File

@ -0,0 +1 @@
github "daltoniam/Starscream" "2.1.1"

34
Package.resolved Normal file
View File

@ -0,0 +1,34 @@
{
"object": {
"pins": [
{
"package": "SSCZLib",
"repositoryURL": "https://github.com/daltoniam/zlib-spm.git",
"state": {
"branch": null,
"revision": "83ac8d719a2f3aa775dbdf116a57f56fb2c49abb",
"version": "1.1.0"
}
},
{
"package": "SSCommonCrypto",
"repositoryURL": "https://github.com/daltoniam/common-crypto-spm",
"state": {
"branch": null,
"revision": "2eb3aff0fb57f92f5722fac5d6d20bf64669ca66",
"version": "1.1.0"
}
},
{
"package": "Starscream",
"repositoryURL": "https://github.com/daltoniam/Starscream",
"state": {
"branch": null,
"revision": "21678c9426dde2a77152a0d5982cdb952baf0455",
"version": "2.1.1"
}
}
]
},
"version": 1
}

View File

@ -8,9 +8,9 @@ let package = Package(
.library(name: "SocketIO", targets: ["SocketIO"])
],
dependencies: [
.package(url: "https://github.com/nuclearace/Starscream", .upToNextMajor(from: "8.0.0")),
.package(url: "https://github.com/daltoniam/Starscream", .upToNextMajor(from: "2.1.1")),
],
targets: [
.target(name: "SocketIO", dependencies: ["StarscreamSocketIO"], exclude: ["Sources/Starscream"])
.target(name: "SocketIO", dependencies: ["Starscream"])
]
)

View File

@ -85,14 +85,15 @@ let package = Package(
Then import `import SocketIO`.
### Carthage
Add these line to your `Cartfile`:
Add this line to your `Cartfile`:
```
github "nuclearace/Starscream" ~> 8.0.7
github "socketio/socket.io-client-swift" ~> 12.0.0 # Or latest version
github "socketio/socket.io-client-swift" ~> 12.1.0 # Or latest version
```
Run `carthage update --platform ios,macosx`.
Add the `Starscream` and `SocketIO` frameworks to your projects and follow the usual Carthage process.
### CocoaPods 1.0.0 or later
Create `Podfile` and add `pod 'Socket.IO-Client-Swift'`:
@ -100,7 +101,7 @@ Create `Podfile` and add `pod 'Socket.IO-Client-Swift'`:
use_frameworks!
target 'YourApp' do
pod 'Socket.IO-Client-Swift', '~> 12.0.0' # Or latest version
pod 'Socket.IO-Client-Swift', '~> 12.1.0' # Or latest version
end
```

View File

@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "Socket.IO-Client-Swift"
s.module_name = "SocketIO"
s.version = "12.0.0"
s.version = "12.1.0"
s.summary = "Socket.IO-client for iOS and OS X"
s.description = <<-DESC
Socket.IO-client for iOS and OS X.
@ -17,12 +17,12 @@ Pod::Spec.new do |s|
s.requires_arc = true
s.source = {
:git => "https://github.com/socketio/socket.io-client-swift.git",
:tag => 'v12.0.0',
:tag => 'v12.1.0',
:submodules => true
}
s.pod_target_xcconfig = {
'SWIFT_VERSION' => '4.0'
}
s.source_files = "Source/SocketIO/**/*.swift", "Source/SocketIO/*.swift"
s.dependency "StarscreamSocketIO", "~> 8.0.7"
s.dependency "Starscream", "~> 2.1.1"
end

View File

@ -30,12 +30,22 @@
7472C65F1BCAC46E003CA70D /* SocketSideEffectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7472C65E1BCAC46E003CA70D /* SocketSideEffectTest.swift */; };
7472C6601BCAC46E003CA70D /* SocketSideEffectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7472C65E1BCAC46E003CA70D /* SocketSideEffectTest.swift */; };
747BC59F1D5F9BA200CA5FA4 /* SocketIOClientConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747BC59E1D5F9BA200CA5FA4 /* SocketIOClientConfigurationTest.swift */; };
74DA21721F094408009C19EE /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 74DA21711F094408009C19EE /* libz.tbd */; };
749FA1961F811190002FBB30 /* SocketAckManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74321DC91C2D939A00CF6F43 /* SocketAckManagerTest.swift */; };
749FA1971F811190002FBB30 /* SocketIOClientConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747BC59E1D5F9BA200CA5FA4 /* SocketIOClientConfigurationTest.swift */; };
749FA1981F811190002FBB30 /* SocketObjectiveCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 742D150B1CA5794B00BD987D /* SocketObjectiveCTest.m */; };
749FA1991F811190002FBB30 /* SocketParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74321DCA1C2D939A00CF6F43 /* SocketParserTest.swift */; };
749FA1A61F81152B002FBB30 /* Starscream.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9432E00B1F77F883006AF628 /* Starscream.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
74D0F58E1F804FED0037C4DC /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 74D0F58D1F804FED0037C4DC /* libz.tbd */; };
74D0F5961F8053950037C4DC /* Starscream.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9432E00B1F77F883006AF628 /* Starscream.framework */; };
74DA21741F09440F009C19EE /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 74DA21731F09440F009C19EE /* libz.tbd */; };
74DA21761F094417009C19EE /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 74DA21751F094417009C19EE /* libz.tbd */; };
74DA217C1F09457B009C19EE /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 74DA21731F09440F009C19EE /* libz.tbd */; };
74F124F01BC574CF002966F4 /* SocketBasicPacketTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74F124EF1BC574CF002966F4 /* SocketBasicPacketTest.swift */; };
74F124F11BC574CF002966F4 /* SocketBasicPacketTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74F124EF1BC574CF002966F4 /* SocketBasicPacketTest.swift */; };
9432E0071F77F7CA006AF628 /* SSLSecurity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432E0061F77F7CA006AF628 /* SSLSecurity.swift */; };
9432E00A1F77F87D006AF628 /* Starscream.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9432E0091F77F87D006AF628 /* Starscream.framework */; };
9432E00E1F77F889006AF628 /* Starscream.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9432E00D1F77F889006AF628 /* Starscream.framework */; };
9432E00F1F77F8C4006AF628 /* SSLSecurity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432E0061F77F7CA006AF628 /* SSLSecurity.swift */; };
9432E0101F77F8C4006AF628 /* SSLSecurity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9432E0061F77F7CA006AF628 /* SSLSecurity.swift */; };
DD52B048C71D724ABBD18C71 /* SocketTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD52BDC9E66AADA2CC5E8246 /* SocketTypes.swift */; };
DD52B06F898CD9164AC8F80E /* SocketAnyEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD52B5A9DE10C7A8AD35617F /* SocketAnyEvent.swift */; };
DD52B099A5166C5FF975FAB5 /* SocketClientManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD52B282975446C9A9C56D7B /* SocketClientManager.swift */; };
@ -126,71 +136,21 @@
remoteGlobalIDString = 576349FA1BD9B46A00E19CD7;
remoteInfo = "SocketIO-tvOS";
};
745225EC1F1BA89E007EA874 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 6B3E79E519D48B7F006071F7;
remoteInfo = "Starscream iOS";
};
74638B631F111CD000F5E1FF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 6B3E79E619D48B7F006071F7;
remoteInfo = "Starscream iOS";
};
74638B651F111CD000F5E1FF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 6B3E79F119D48B7F006071F7;
remoteInfo = "Starscream iOSTests";
};
74638B671F111CD000F5E1FF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = D9C3E35F19E48FF1009FC285;
remoteInfo = "Starscream OSX";
};
74638B691F111CD000F5E1FF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = D9C3E36919E48FF1009FC285;
remoteInfo = "Starscream OSXTests";
};
74638B6B1F111CD000F5E1FF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 091277971BD673A70003036D;
remoteInfo = "Starscream tvOS";
};
74638B6D1F111CD000F5E1FF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 091277A01BD673A70003036D;
remoteInfo = "Starscream tvOSTests";
};
74638B711F111CF100F5E1FF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = D9C3E35E19E48FF1009FC285;
remoteInfo = "Starscream OSX";
};
74638B731F111CF600F5E1FF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 091277961BD673A70003036D;
remoteInfo = "Starscream tvOS";
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
749FA1A51F811521002FBB30 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
749FA1A61F81152B002FBB30 /* Starscream.framework in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
572EF2191B51F16C00EEBB58 /* SocketIO.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SocketIO.framework; sourceTree = BUILT_PRODUCTS_DIR; };
572EF21D1B51F16C00EEBB58 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -210,15 +170,19 @@
742D150B1CA5794B00BD987D /* SocketObjectiveCTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SocketObjectiveCTest.m; sourceTree = "<group>"; };
74321DC91C2D939A00CF6F43 /* SocketAckManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocketAckManagerTest.swift; sourceTree = "<group>"; };
74321DCA1C2D939A00CF6F43 /* SocketParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SocketParserTest.swift; sourceTree = "<group>"; };
74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Starscream.xcodeproj; path = Source/Starscream/Starscream.xcodeproj; sourceTree = "<group>"; };
7472C65B1BCAB53E003CA70D /* SocketNamespacePacketTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketNamespacePacketTest.swift; sourceTree = "<group>"; };
7472C65E1BCAC46E003CA70D /* SocketSideEffectTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketSideEffectTest.swift; sourceTree = "<group>"; };
747BC59E1D5F9BA200CA5FA4 /* SocketIOClientConfigurationTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketIOClientConfigurationTest.swift; sourceTree = "<group>"; };
74DA21711F094408009C19EE /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; };
749FA19F1F8112E7002FBB30 /* Starscream.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = Starscream.framework.dSYM; path = Carthage/Build/Mac/Starscream.framework.dSYM; sourceTree = "<group>"; };
749FA1A11F811408002FBB30 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
74D0F58D1F804FED0037C4DC /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; };
74DA21731F09440F009C19EE /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
74DA21751F094417009C19EE /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS10.2.sdk/usr/lib/libz.tbd; sourceTree = DEVELOPER_DIR; };
74DA217D1F0945E9009C19EE /* libcommonCrypto.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcommonCrypto.tbd; path = usr/lib/system/libcommonCrypto.tbd; sourceTree = SDKROOT; };
74F124EF1BC574CF002966F4 /* SocketBasicPacketTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketBasicPacketTest.swift; sourceTree = "<group>"; };
9432E0061F77F7CA006AF628 /* SSLSecurity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSLSecurity.swift; sourceTree = "<group>"; };
9432E0091F77F87D006AF628 /* Starscream.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Starscream.framework; path = Carthage/Build/iOS/Starscream.framework; sourceTree = "<group>"; };
9432E00B1F77F883006AF628 /* Starscream.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Starscream.framework; path = Carthage/Build/Mac/Starscream.framework; sourceTree = "<group>"; };
9432E00D1F77F889006AF628 /* Starscream.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Starscream.framework; path = Carthage/Build/tvOS/Starscream.framework; sourceTree = "<group>"; };
DD52B078DB0A3C3D1BB507CD /* SocketIOClientOption.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketIOClientOption.swift; sourceTree = "<group>"; };
DD52B09F7984E730513AB7E5 /* SocketAckManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketAckManager.swift; sourceTree = "<group>"; };
DD52B1D9BC4AE46D38D827DE /* SocketIOClientStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketIOClientStatus.swift; sourceTree = "<group>"; };
@ -248,8 +212,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
74DA21721F094408009C19EE /* libz.tbd in Frameworks */,
74D0F58E1F804FED0037C4DC /* libz.tbd in Frameworks */,
6CA08A961D615C040061FD2A /* Security.framework in Frameworks */,
9432E00A1F77F87D006AF628 /* Starscream.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -267,6 +232,7 @@
files = (
74DA21741F09440F009C19EE /* libz.tbd in Frameworks */,
6CA08A981D615C0B0061FD2A /* Security.framework in Frameworks */,
74D0F5961F8053950037C4DC /* Starscream.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -283,8 +249,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
74DA21761F094417009C19EE /* libz.tbd in Frameworks */,
6CA08A9A1D615C140061FD2A /* Security.framework in Frameworks */,
9432E00E1F77F889006AF628 /* Starscream.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -302,7 +268,6 @@
572EF20D1B51F12F00EEBB58 = {
isa = PBXGroup;
children = (
74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */,
6CA08A9B1D615C190061FD2A /* Frameworks */,
572EF21A1B51F16C00EEBB58 /* Products */,
572EF21B1B51F16C00EEBB58 /* SocketIO-iOS */,
@ -398,10 +363,14 @@
6CA08A9B1D615C190061FD2A /* Frameworks */ = {
isa = PBXGroup;
children = (
749FA1A11F811408002FBB30 /* Foundation.framework */,
749FA19F1F8112E7002FBB30 /* Starscream.framework.dSYM */,
74D0F58D1F804FED0037C4DC /* libz.tbd */,
9432E0091F77F87D006AF628 /* Starscream.framework */,
9432E00B1F77F883006AF628 /* Starscream.framework */,
9432E00D1F77F889006AF628 /* Starscream.framework */,
74DA217D1F0945E9009C19EE /* libcommonCrypto.tbd */,
74DA21751F094417009C19EE /* libz.tbd */,
74DA21731F09440F009C19EE /* libz.tbd */,
74DA21711F094408009C19EE /* libz.tbd */,
6CA08A9E1D615C340061FD2A /* tvOS */,
6CA08A9D1D615C2C0061FD2A /* Mac */,
6CA08A9C1D615C270061FD2A /* iOS */,
@ -433,19 +402,6 @@
name = tvOS;
sourceTree = "<group>";
};
74638B5B1F111CD000F5E1FF /* Products */ = {
isa = PBXGroup;
children = (
74638B641F111CD000F5E1FF /* StarscreamSocketIO.framework */,
74638B661F111CD000F5E1FF /* Starscream iOSTests.xctest */,
74638B681F111CD000F5E1FF /* StarscreamSocketIO.framework */,
74638B6A1F111CD000F5E1FF /* Starscream OSXTests.xctest */,
74638B6C1F111CD000F5E1FF /* StarscreamSocketIO.framework */,
74638B6E1F111CD000F5E1FF /* Starscream tvOSTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
DD52B1D10D761CEF3944A6BC /* Util */ = {
isa = PBXGroup;
children = (
@ -454,6 +410,7 @@
DD52B471D780013E18DF9335 /* SocketExtensions.swift */,
DD52BA240D139F72633D4159 /* SocketStringReader.swift */,
DD52B282975446C9A9C56D7B /* SocketClientManager.swift */,
9432E0061F77F7CA006AF628 /* SSLSecurity.swift */,
);
name = Util;
path = Source/SocketIO/Util;
@ -550,7 +507,6 @@
buildRules = (
);
dependencies = (
745225ED1F1BA89E007EA874 /* PBXTargetDependency */,
);
name = "SocketIO-iOS";
productName = "SocketIO-iOS";
@ -564,6 +520,7 @@
572EF2201B51F16C00EEBB58 /* Sources */,
572EF2211B51F16C00EEBB58 /* Frameworks */,
572EF2221B51F16C00EEBB58 /* Resources */,
749FA19A1F8111A6002FBB30 /* ShellScript */,
);
buildRules = (
);
@ -587,7 +544,6 @@
buildRules = (
);
dependencies = (
74638B721F111CF100F5E1FF /* PBXTargetDependency */,
);
name = "SocketIO-Mac";
productName = "SocketIO-Mac";
@ -601,6 +557,7 @@
572EF23E1B51F18A00EEBB58 /* Sources */,
572EF23F1B51F18A00EEBB58 /* Frameworks */,
572EF2401B51F18A00EEBB58 /* Resources */,
749FA1A51F811521002FBB30 /* CopyFiles */,
);
buildRules = (
);
@ -624,7 +581,6 @@
buildRules = (
);
dependencies = (
74638B741F111CF600F5E1FF /* PBXTargetDependency */,
);
name = "SocketIO-tvOS";
productName = "SocketIO-iOS";
@ -685,12 +641,6 @@
mainGroup = 572EF20D1B51F12F00EEBB58;
productRefGroup = 572EF21A1B51F16C00EEBB58 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 74638B5B1F111CD000F5E1FF /* Products */;
ProjectRef = 74638B5A1F111CD000F5E1FF /* Starscream.xcodeproj */;
},
);
projectRoot = "";
targets = (
572EF2181B51F16C00EEBB58 /* SocketIO-iOS */,
@ -703,51 +653,6 @@
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
74638B641F111CD000F5E1FF /* StarscreamSocketIO.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = StarscreamSocketIO.framework;
remoteRef = 74638B631F111CD000F5E1FF /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
74638B661F111CD000F5E1FF /* Starscream iOSTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = "Starscream iOSTests.xctest";
remoteRef = 74638B651F111CD000F5E1FF /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
74638B681F111CD000F5E1FF /* StarscreamSocketIO.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = StarscreamSocketIO.framework;
remoteRef = 74638B671F111CD000F5E1FF /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
74638B6A1F111CD000F5E1FF /* Starscream OSXTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = "Starscream OSXTests.xctest";
remoteRef = 74638B691F111CD000F5E1FF /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
74638B6C1F111CD000F5E1FF /* StarscreamSocketIO.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = StarscreamSocketIO.framework;
remoteRef = 74638B6B1F111CD000F5E1FF /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
74638B6E1F111CD000F5E1FF /* Starscream tvOSTests.xctest */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = "Starscream tvOSTests.xctest";
remoteRef = 74638B6D1F111CD000F5E1FF /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
572EF2171B51F16C00EEBB58 /* Resources */ = {
isa = PBXResourcesBuildPhase;
@ -793,6 +698,24 @@
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
749FA19A1F8111A6002FBB30 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"$(SRCROOT)/Carthage/Build/iOS/Starscream.framework",
);
outputPaths = (
"$(BUILT_PRODUCTS_DIR)/$(FRAMEWORKS_FOLDER_PATH)/Starscream.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/usr/local/bin/carthage copy-frameworks";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
572EF2141B51F16C00EEBB58 /* Sources */ = {
isa = PBXSourcesBuildPhase;
@ -809,6 +732,7 @@
DD52B06F898CD9164AC8F80E /* SocketAnyEvent.swift in Sources */,
DD52B16128003D74FC23A01F /* SocketIOClient.swift in Sources */,
DD52BDB51FE41BAB49073BEF /* SocketEventHandler.swift in Sources */,
9432E0071F77F7CA006AF628 /* SSLSecurity.swift in Sources */,
DD52BB88BD4C5641CFD2E8D4 /* SocketIOClientSpec.swift in Sources */,
DD52B1FEE4C81226884B1E67 /* SocketIOClientOption.swift in Sources */,
DD52B6E44917CA5DFC3CE6B5 /* SocketIOClientStatus.swift in Sources */,
@ -827,6 +751,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
749FA1961F811190002FBB30 /* SocketAckManagerTest.swift in Sources */,
749FA1971F811190002FBB30 /* SocketIOClientConfigurationTest.swift in Sources */,
749FA1981F811190002FBB30 /* SocketObjectiveCTest.m in Sources */,
749FA1991F811190002FBB30 /* SocketParserTest.swift in Sources */,
7472C65F1BCAC46E003CA70D /* SocketSideEffectTest.swift in Sources */,
741F39EE1BD025D80026C9CC /* SocketEngineTest.swift in Sources */,
74F124F01BC574CF002966F4 /* SocketBasicPacketTest.swift in Sources */,
@ -849,6 +777,7 @@
DD52BB69B6D260035B652CA4 /* SocketAnyEvent.swift in Sources */,
DD52BF924BEF05E1235CFD29 /* SocketIOClient.swift in Sources */,
DD52BFEB4DBD3BF8D93DAEFF /* SocketEventHandler.swift in Sources */,
9432E00F1F77F8C4006AF628 /* SSLSecurity.swift in Sources */,
DD52BB9A3E42FF2DD6BE7C2F /* SocketIOClientSpec.swift in Sources */,
DD52B2AFE7D46039C7AE4D19 /* SocketIOClientOption.swift in Sources */,
DD52BE4D1E6BB752CD9614A6 /* SocketIOClientStatus.swift in Sources */,
@ -893,6 +822,7 @@
DD52B6BE1D398DBD144C4D14 /* SocketAnyEvent.swift in Sources */,
DD52B26DA9E4D566276B7E49 /* SocketIOClient.swift in Sources */,
DD52B27DABA4C475B850A326 /* SocketEventHandler.swift in Sources */,
9432E0101F77F8C4006AF628 /* SSLSecurity.swift in Sources */,
DD52B4223DCCB75630441370 /* SocketIOClientSpec.swift in Sources */,
DD52B6FC2F0A6A3106FFCBE3 /* SocketIOClientOption.swift in Sources */,
DD52B3D941DB2A0C678F8251 /* SocketIOClientStatus.swift in Sources */,
@ -936,21 +866,6 @@
target = 576349FA1BD9B46A00E19CD7 /* SocketIO-tvOS */;
targetProxy = 57634A3D1BD9B4B800E19CD7 /* PBXContainerItemProxy */;
};
745225ED1F1BA89E007EA874 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "Starscream iOS";
targetProxy = 745225EC1F1BA89E007EA874 /* PBXContainerItemProxy */;
};
74638B721F111CF100F5E1FF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "Starscream OSX";
targetProxy = 74638B711F111CF100F5E1FF /* PBXContainerItemProxy */;
};
74638B741F111CF600F5E1FF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "Starscream tvOS";
targetProxy = 74638B731F111CF600F5E1FF /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
@ -1063,6 +978,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@ -1123,6 +1042,10 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@ -1274,6 +1197,10 @@
ENABLE_BITCODE = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
);
FRAMEWORK_VERSION = A;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
@ -1303,7 +1230,7 @@
SKIP_INSTALL = YES;
SWIFT_INCLUDE_PATHS = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@ -1340,6 +1267,10 @@
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
);
FRAMEWORK_VERSION = A;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
@ -1361,7 +1292,7 @@
SDKROOT = macosx;
SKIP_INSTALL = YES;
SWIFT_INCLUDE_PATHS = "";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@ -1394,6 +1325,7 @@
FRAMEWORK_SEARCH_PATHS = (
"$(DEVELOPER_FRAMEWORKS_DIR)",
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
@ -1423,7 +1355,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Debug;
@ -1455,6 +1387,7 @@
FRAMEWORK_SEARCH_PATHS = (
"$(DEVELOPER_FRAMEWORKS_DIR)",
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
@ -1475,7 +1408,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "io.socket.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_SWIFT3_OBJC_INFERENCE = On;
SWIFT_SWIFT3_OBJC_INFERENCE = Default;
SWIFT_VERSION = 4.0;
};
name = Release;
@ -1508,6 +1441,10 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/tvOS",
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@ -1570,6 +1507,10 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/tvOS",
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;

View File

@ -11,7 +11,6 @@
@import Foundation;
@import XCTest;
@import SocketIO;
@import StarscreamSocketIO;
@interface SocketObjectiveCTest : XCTestCase
@ -103,7 +102,7 @@
- (void)testSSLSecurity {
SSLSecurity* sec = [[SSLSecurity alloc] initWithUsePublicKeys:0];
sec.isReady = 0;
sec = nil;
}
@end

View File

@ -8,7 +8,6 @@
import XCTest
@testable import SocketIO
@testable import StarscreamSocketIO
class SocketSideEffectTest: XCTestCase {
func testInitialCurrentAck() {
@ -351,6 +350,25 @@ class SocketSideEffectTest: XCTestCase {
waitForExpectations(timeout: 0.2)
}
func testSettingConfigAfterInit() {
socket.setTestStatus(.notConnected)
socket.config.insert(.log(true))
XCTAssertTrue(DefaultSocketLogger.Logger.log, "It should set logging to true after creation")
socket.config = [.log(false), .nsp("/test")]
XCTAssertFalse(DefaultSocketLogger.Logger.log, "It should set logging to false after creation")
XCTAssertEqual(socket.nsp, "/test", "It should set the namespace after creation")
}
func testSettingConfigAfterInitWhenConnectedIgnoresChanges() {
socket.config = [.log(true), .nsp("/test")]
XCTAssertFalse(DefaultSocketLogger.Logger.log, "It should set logging to false after creation")
XCTAssertEqual(socket.nsp, "/", "It should set the namespace after creation")
}
let data = "test".data(using: String.Encoding.utf8)!
let data2 = "test2".data(using: String.Encoding.utf8)!
private var socket: SocketIOClient!

View File

@ -39,7 +39,13 @@ public final class SocketAckEmitter : NSObject {
return ackNum != -1
}
init(socket: SocketIOClient, ackNum: Int) {
// MARK: Initializers
/// Creates a new `SocketAckEmitter`.
///
/// - parameter socket: The socket for this emitter.
/// - parameter ackNum: The ack number for this emitter.
public init(socket: SocketIOClient, ackNum: Int) {
self.socket = socket
self.ackNum = ackNum
}
@ -110,7 +116,7 @@ public final class OnAckCallback : NSObject {
guard let socket = self.socket, ackNumber != -1 else { return }
socket.ackHandlers.addAck(ackNumber, callback: callback)
socket._emit(items, ack: ackNumber)
socket.emit(items, ack: ackNumber)
guard seconds != 0 else { return }

View File

@ -24,12 +24,27 @@
import Foundation
struct SocketEventHandler {
let event: String
let id: UUID
let callback: NormalCallback
func executeCallback(with items: [Any], withAck ack: Int, withSocket socket: SocketIOClient) {
/// A wrapper around a handler.
public struct SocketEventHandler {
// MARK: Properties
/// The event for this handler.
public let event: String
/// A unique identifier for this handler.
public let id: UUID
/// The actual handler function.
public let callback: NormalCallback
// MARK: Methods
/// Causes this handler to be executed.
///
/// - parameter with: The data that this handler should be called with.
/// - parameter withAck: The ack number that this event expects. Pass -1 to say this event doesn't expect an ack.
/// - parameter withSocket: The socket that is calling this event.
public func executeCallback(with items: [Any], withAck ack: Int, withSocket socket: SocketIOClient) {
callback(items, SocketAckEmitter(socket: socket, ackNum: ack))
}
}

View File

@ -35,26 +35,6 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
private static let logType = "SocketIOClient"
/// The engine for this client.
@objc
public private(set) var engine: SocketEngineSpec?
/// The status of this client.
@objc
public private(set) var status = SocketIOClientStatus.notConnected {
didSet {
switch status {
case .connected:
reconnecting = false
currentReconnectAttempt = 0
default:
break
}
handleClientEvent(.statusChange, data: [status])
}
}
/// If `true` then every time `connect` is called, a new engine will be created.
@objc
public var forceNew = false
@ -64,12 +44,37 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
@objc
public var handleQueue = DispatchQueue.main
/// The namespace for this client.
/// The namespace that this socket is currently connected to.
///
/// **Must** start with a `/`.
@objc
public var nsp = "/"
/// The configuration for this client.
public var config: SocketIOClientConfiguration
///
/// **This cannot be set after calling one of the connect methods**.
public var config: SocketIOClientConfiguration {
get {
return _config
}
set {
guard status == .notConnected else {
DefaultSocketLogger.Logger.error("Tried setting config after calling connect",
type: SocketIOClient.logType)
return
}
_config = newValue
if socketURL.absoluteString.hasPrefix("https://") {
_config.insert(.secure(true))
}
_config.insert(.path("/socket.io/"), replacing: false)
setConfigs()
}
}
/// If `true`, this client will try and reconnect on any disconnects.
@objc
@ -92,15 +97,47 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
@objc
public var socketURL: URL
/// A list of packets that are waiting for binary data.
///
/// The way that socket.io works all data should be sent directly after each packet.
/// So this should ideally be an array of one packet waiting for data.
///
/// **This should not be modified directly.**
public var waitingPackets = [SocketPacket]()
/// A handler that will be called on any event.
public private(set) var anyHandler: ((SocketAnyEvent) -> ())?
/// The engine for this client.
@objc
public private(set) var engine: SocketEngineSpec?
/// The array of handlers for this socket.
public private(set) var handlers = [SocketEventHandler]()
/// The status of this client.
@objc
public private(set) var status = SocketIOClientStatus.notConnected {
didSet {
switch status {
case .connected:
reconnecting = false
currentReconnectAttempt = 0
default:
break
}
handleClientEvent(.statusChange, data: [status])
}
}
var ackHandlers = SocketAckManager()
var waitingPackets = [SocketPacket]()
private(set) var currentAck = -1
private(set) var reconnectAttempts = -1
private var anyHandler: ((SocketAnyEvent) -> ())?
private var _config: SocketIOClientConfiguration
private var currentReconnectAttempt = 0
private var handlers = [SocketEventHandler]()
private var reconnecting = false
// MARK: Initializers
@ -110,39 +147,18 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
/// - parameter socketURL: The url of the socket.io server.
/// - parameter config: The config for this socket.
public init(socketURL: URL, config: SocketIOClientConfiguration = []) {
self.config = config
self._config = config
self.socketURL = socketURL
if socketURL.absoluteString.hasPrefix("https://") {
self.config.insert(.secure(true))
self._config.insert(.secure(true))
}
for option in config {
switch option {
case let .reconnects(reconnects):
self.reconnects = reconnects
case let .reconnectAttempts(attempts):
reconnectAttempts = attempts
case let .reconnectWait(wait):
reconnectWait = abs(wait)
case let .nsp(nsp):
self.nsp = nsp
case let .log(log):
DefaultSocketLogger.Logger.log = log
case let .logger(logger):
DefaultSocketLogger.Logger = logger
case let .handleQueue(queue):
handleQueue = queue
case let .forceNew(force):
forceNew = force
default:
continue
}
}
self.config.insert(.path("/socket.io/"), replacing: false)
self._config.insert(.path("/socket.io/"), replacing: false)
super.init()
setConfigs()
}
/// Not so type safe way to create a SocketIOClient, meant for Objective-C compatiblity.
@ -172,7 +188,9 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
engine = SocketEngine(client: self, url: socketURL, config: config)
}
/// Connect to the server.
/// Connect to the server. The same as calling `connect(timeoutAfter:withHandler:)` with a timeout of 0.
///
/// Only call after adding your event listeners, unless you know what you're doing.
@objc
open func connect() {
connect(timeoutAfter: 0, withHandler: nil)
@ -180,6 +198,8 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
/// Connect to the server. If we aren't connected after `timeoutAfter` seconds, then `withHandler` is called.
///
/// Only call after adding your event listeners, unless you know what you're doing.
///
/// - parameter timeoutAfter: The number of seconds after which if we are not connected we assume the connection
/// has failed. Pass 0 to never timeout.
/// - parameter withHandler: The handler to call when the client fails to connect.
@ -219,7 +239,11 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
return OnAckCallback(ackNumber: currentAck, items: items, socket: self)
}
func didConnect(toNamespace namespace: String) {
/// Called when the client connects to a namespace. If the client was created with a namespace upfront,
/// then this is only called when the client connects to that namespace.
///
/// - parameter toNamespace: The namespace that was connected to.
open func didConnect(toNamespace namespace: String) {
DefaultSocketLogger.Logger.log("Socket connected", type: SocketIOClient.logType)
status = .connected
@ -227,7 +251,10 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
handleClientEvent(.connect, data: [namespace])
}
func didDisconnect(reason: String) {
/// Called when the client has disconnected from socket.io.
///
/// - parameter reason: The reason for the disconnection.
open func didDisconnect(reason: String) {
guard status != .disconnected else { return }
DefaultSocketLogger.Logger.log("Disconnected: \(reason)", type: SocketIOClient.logType)
@ -269,7 +296,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
/// Same as emit, but meant for Objective-C
///
/// - parameter event: The event to send.
/// - parameter with: The items to send with this event. May be left out.
/// - parameter with: The items to send with this event. Send an empty array to send no data.
@objc
open func emit(_ event: String, with items: [Any]) {
guard status == .connected else {
@ -277,7 +304,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
return
}
_emit([event] + items)
emit([event] + items)
}
/// Sends a message to the server, requesting an ack.
@ -333,7 +360,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
return createOnAck([event] + items)
}
func _emit(_ data: [Any], ack: Int? = nil) {
func emit(_ data: [Any], ack: Int? = nil) {
guard status == .connected else {
handleClientEvent(.error, data: ["Tried emitting when not connected"])
return
@ -347,8 +374,13 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
engine?.send(str, withData: packet.binary)
}
// If the server wants to know that the client received data
func emitAck(_ ack: Int, with items: [Any]) {
/// Call when you wish to tell the server that you've received the event for `ack`.
///
/// **You shouldn't need to call this directly.** Instead use an `SocketAckEmitter` that comes in an event callback.
///
/// - parameter ack: The ack number.
/// - parameter with: The data for this ack.
open func emitAck(_ ack: Int, with items: [Any]) {
guard status == .connected else { return }
let packet = SocketPacket.packetFromEmit(items, id: ack, nsp: nsp, ack: true)
@ -405,8 +437,12 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
DefaultSocketLogger.Logger.log(reason, type: SocketIOClient.logType)
}
// Called when the socket gets an ack for something it sent
func handleAck(_ ack: Int, data: [Any]) {
/// Called when socket.io has acked one of our emits. Causes the corresponding ack callback to be called.
///
/// - parameter ack: The number for this ack.
/// - parameter data: The data sent back with this ack.
@objc
open func handleAck(_ ack: Int, data: [Any]) {
guard status == .connected else { return }
DefaultSocketLogger.Logger.log("Handling ack: \(ack) with data: \(data)", type: SocketIOClient.logType)
@ -414,12 +450,12 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
ackHandlers.executeAck(ack, with: data, onQueue: handleQueue)
}
/// Causes an event to be handled, and any event handlers for that event to be called.
/// Called when we get an event from socket.io.
///
/// - parameter event: The event that is to be handled.
/// - parameter data: the data associated with this event.
/// - parameter isInternalMessage: If `true` event handlers for this event will be called regardless of status.
/// - parameter withAck: The ack number for this event. May be left out.
/// - parameter event: The name of the event.
/// - parameter data: The data that was sent with this event.
/// - parameter isInternalMessage: Whether this event was sent internally. If `true` it is always sent to handlers.
/// - parameter withAck: If > 0 then this event expects to get an ack back from the client.
@objc
open func handleEvent(_ event: String, data: [Any], isInternalMessage: Bool, withAck ack: Int = -1) {
guard status == .connected || isInternalMessage else { return }
@ -433,11 +469,15 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
}
}
func handleClientEvent(_ event: SocketClientEvent, data: [Any]) {
/// Called on socket.io specific events.
///
/// - parameter event: The `SocketClientEvent`.
/// - parameter data: The data for this event.
open func handleClientEvent(_ event: SocketClientEvent, data: [Any]) {
handleEvent(event.rawValue, data: data, isInternalMessage: true)
}
/// Leaves nsp and goes back to the default namespace.
/// Call when you wish to leave a namespace and return to the default namespace.
@objc
open func leaveNamespace() {
if nsp != "/" {
@ -601,6 +641,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
}
/// Removes all handlers.
///
/// Can be used after disconnecting to break any potential remaining retain cycles.
@objc
open func removeAllHandlers() {
@ -632,6 +673,31 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
handleQueue.asyncAfter(deadline: DispatchTime.now() + Double(reconnectWait), execute: _tryReconnect)
}
private func setConfigs() {
for option in config {
switch option {
case let .reconnects(reconnects):
self.reconnects = reconnects
case let .reconnectAttempts(attempts):
reconnectAttempts = attempts
case let .reconnectWait(wait):
reconnectWait = abs(wait)
case let .nsp(nsp):
self.nsp = nsp
case let .log(log):
DefaultSocketLogger.Logger.log = log
case let .logger(logger):
DefaultSocketLogger.Logger = logger
case let .handleQueue(queue):
handleQueue = queue
case let .forceNew(force):
forceNew = force
default:
continue
}
}
}
// Test properties
var testHandlers: [SocketEventHandler] {
@ -651,6 +717,6 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
}
func emitTest(event: String, _ data: Any...) {
_emit([event] + data)
emit([event] + data)
}
}

View File

@ -23,7 +23,7 @@
// THE SOFTWARE.
import Foundation
import StarscreamSocketIO
import Starscream
protocol ClientOption : CustomStringConvertible, Equatable {
func getSocketIOOptionValue() -> Any

View File

@ -23,23 +23,207 @@
// THE SOFTWARE.
import Dispatch
import Foundation
protocol SocketIOClientSpec : class {
/// Defines the interface for a SocketIOClient.
public protocol SocketIOClientSpec : class {
// MARK: Properties
/// A handler that will be called on any event.
var anyHandler: ((SocketAnyEvent) -> ())? { get }
/// The configuration for this client.
var config: SocketIOClientConfiguration { get set }
/// The queue that all interaction with the client must be on.
var handleQueue: DispatchQueue { get set }
var nsp: String { get set }
var waitingPackets: [SocketPacket] { get set }
/// The array of handlers for this socket.
var handlers: [SocketEventHandler] { get }
/// The namespace that this socket is currently connected to.
///
/// **Must** start with a `/`.
var nsp: String { get set }
/// The status of this client.
var status: SocketIOClientStatus { get }
// MARK: Methods
/// Connect to the server. The same as calling `connect(timeoutAfter:withHandler:)` with a timeout of 0.
///
/// Only call after adding your event listeners, unless you know what you're doing.
func connect()
/// Connect to the server. If we aren't connected after `timeoutAfter` seconds, then `withHandler` is called.
///
/// Only call after adding your event listeners, unless you know what you're doing.
///
/// - parameter timeoutAfter: The number of seconds after which if we are not connected we assume the connection
/// has failed. Pass 0 to never timeout.
/// - parameter withHandler: The handler to call when the client fails to connect.
func connect(timeoutAfter: Double, withHandler handler: (() -> ())?)
/// Called when the client connects to a namespace. If the client was created with a namespace upfront,
/// then this is only called when the client connects to that namespace.
///
/// - parameter toNamespace: The namespace that was connected to.
func didConnect(toNamespace namespace: String)
/// Called when the client has disconnected from socket.io.
///
/// - parameter reason: The reason for the disconnection.
func didDisconnect(reason: String)
/// Called when the client encounters an error.
///
/// - parameter reason: The reason for the disconnection.
func didError(reason: String)
/// Disconnects the socket.
func disconnect()
/// Send an event to the server, with optional data items.
///
/// If an error occurs trying to transform `items` into their socket representation, a `SocketClientEvent.error`
/// will be emitted. The structure of the error data is `[eventName, items, theError]`
///
/// - parameter event: The event to send.
/// - parameter items: The items to send with this event. May be left out.
func emit(_ event: String, _ items: SocketData...)
/// Call when you wish to tell the server that you've received the event for `ack`.
///
/// - parameter ack: The ack number.
/// - parameter with: The data for this ack.
func emitAck(_ ack: Int, with items: [Any])
/// Sends a message to the server, requesting an ack.
///
/// **NOTE**: It is up to the server send an ack back, just calling this method does not mean the server will ack.
/// Check that your server's api will ack the event being sent.
///
/// If an error occurs trying to transform `items` into their socket representation, a `SocketClientEvent.error`
/// will be emitted. The structure of the error data is `[eventName, items, theError]`
///
/// Example:
///
/// ```swift
/// socket.emitWithAck("myEvent", 1).timingOut(after: 1) {data in
/// ...
/// }
/// ```
///
/// - parameter event: The event to send.
/// - parameter items: The items to send with this event. May be left out.
/// - returns: An `OnAckCallback`. You must call the `timingOut(after:)` method before the event will be sent.
func emitWithAck(_ event: String, _ items: SocketData...) -> OnAckCallback
/// Called when socket.io has acked one of our emits. Causes the corresponding ack callback to be called.
///
/// - parameter ack: The number for this ack.
/// - parameter data: The data sent back with this ack.
func handleAck(_ ack: Int, data: [Any])
/// Called when we get an event from socket.io.
///
/// - parameter event: The name of the event.
/// - parameter data: The data that was sent with this event.
/// - parameter isInternalMessage: Whether this event was sent internally. If `true` it is always sent to handlers.
/// - parameter withAck: If > 0 then this event expects to get an ack back from the client.
func handleEvent(_ event: String, data: [Any], isInternalMessage: Bool, withAck ack: Int)
/// Called on socket.io specific events.
///
/// - parameter event: The `SocketClientEvent`.
/// - parameter data: The data for this event.
func handleClientEvent(_ event: SocketClientEvent, data: [Any])
/// Call when you wish to leave a namespace and return to the default namespace.
func leaveNamespace()
/// Joins `namespace`.
///
/// **Do not use this to join the default namespace.** Instead call `leaveNamespace`.
///
/// - parameter namespace: The namespace to join.
func joinNamespace(_ namespace: String)
/// Removes handler(s) for a client event.
///
/// If you wish to remove a client event handler, call the `off(id:)` with the UUID received from its `on` call.
///
/// - parameter clientEvent: The event to remove handlers for.
func off(clientEvent event: SocketClientEvent)
/// Removes handler(s) based on an event name.
///
/// If you wish to remove a specific event, call the `off(id:)` with the UUID received from its `on` call.
///
/// - parameter event: The event to remove handlers for.
func off(_ event: String)
/// Removes a handler with the specified UUID gotten from an `on` or `once`
///
/// If you want to remove all events for an event, call the off `off(_:)` method with the event name.
///
/// - parameter id: The UUID of the handler you wish to remove.
func off(id: UUID)
/// Adds a handler for an event.
///
/// - parameter event: The event name for this handler.
/// - parameter callback: The callback that will execute when this event is received.
/// - returns: A unique id for the handler that can be used to remove it.
func on(_ event: String, callback: @escaping NormalCallback) -> UUID
/// Adds a handler for a client event.
///
/// Example:
///
/// ```swift
/// socket.on(clientEvent: .connect) {data, ack in
/// ...
/// }
/// ```
///
/// - parameter event: The event for this handler.
/// - parameter callback: The callback that will execute when this event is received.
/// - returns: A unique id for the handler that can be used to remove it.
func on(clientEvent event: SocketClientEvent, callback: @escaping NormalCallback) -> UUID
/// Adds a single-use handler for a client event.
///
/// - parameter clientEvent: The event for this handler.
/// - parameter callback: The callback that will execute when this event is received.
/// - returns: A unique id for the handler that can be used to remove it.
func once(clientEvent event: SocketClientEvent, callback: @escaping NormalCallback) -> UUID
/// Adds a single-use handler for an event.
///
/// - parameter event: The event name for this handler.
/// - parameter callback: The callback that will execute when this event is received.
/// - returns: A unique id for the handler that can be used to remove it.
func once(_ event: String, callback: @escaping NormalCallback) -> UUID
/// Adds a handler that will be called on every event.
///
/// - parameter handler: The callback that will execute whenever an event is received.
func onAny(_ handler: @escaping (SocketAnyEvent) -> ())
/// Tries to reconnect to the server.
func reconnect()
/// Removes all handlers.
///
/// Can be used after disconnecting to break any potential remaining retain cycles.
func removeAllHandlers()
}
extension SocketIOClientSpec {
func didError(reason: String) {
public extension SocketIOClientSpec {
/// Default implementation.
public func didError(reason: String) {
DefaultSocketLogger.Logger.error("\(reason)", type: "SocketIOClient")
handleClientEvent(.error, data: [reason])
@ -48,6 +232,8 @@ extension SocketIOClientSpec {
/// The set of events that are generated by the client.
public enum SocketClientEvent : String {
// MARK: Cases
/// Emitted when the client connects. This is also called on a successful reconnection. A connect event gets one
/// data item: the namespace that was connected to.
///

View File

@ -24,7 +24,7 @@
import Dispatch
import Foundation
import StarscreamSocketIO
import Starscream
/// The class that handles the engine.io protocol and transports.
/// See `SocketEnginePollable` and `SocketEngineWebsocket` for transport specific methods.
@ -134,7 +134,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
private var pongsMissedMax = 0
private var probeWait = ProbeWaitQueue()
private var secure = false
private var security: SSLSecurity?
private var security: SocketIO.SSLSecurity?
private var selfSigned = false
// MARK: Initializers
@ -325,11 +325,12 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
}
}
ws?.callbackQueue = engineQueue
ws?.enableCompression = compress
ws?.delegate = self
ws?.disableSSLCertValidation = selfSigned
ws?.security = security
ws?.security = security?.security
ws?.connect()
}
@ -517,13 +518,13 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
switch type {
case .message:
handleMessage(String(message.characters.dropFirst()))
handleMessage(String(message.dropFirst()))
case .noop:
handleNOOP()
case .pong:
handlePong(with: message)
case .open:
handleOpen(openData: String(message.characters.dropFirst()))
handleOpen(openData: String(message.dropFirst()))
case .close:
handleClose(message)
default:

View File

@ -184,7 +184,7 @@ extension SocketEnginePollable {
}
func parsePollingMessage(_ str: String) {
guard str.characters.count != 1 else { return }
guard str.count != 1 else { return }
DefaultSocketLogger.Logger.log("Got poll message: \(str)", type: "SocketEnginePolling")

View File

@ -24,7 +24,7 @@
//
import Foundation
import StarscreamSocketIO
import Starscream
/// Specifies a SocketEngine.
@objc public protocol SocketEngineSpec {

View File

@ -24,7 +24,7 @@
//
import Foundation
import StarscreamSocketIO
import Starscream
/// Protocol that is used to implement socket.io WebSocket support
public protocol SocketEngineWebsocket : SocketEngineSpec, WebSocketDelegate {

View File

@ -25,22 +25,39 @@
import Foundation
struct SocketPacket {
enum PacketType: Int {
/// A struct that represents a socket.io packet.
public struct SocketPacket : CustomStringConvertible {
// MARK: PacketType enum
/// The type of packets.
public enum PacketType: Int {
case connect, disconnect, event, ack, error, binaryEvent, binaryAck
}
private let placeholders: Int
// MARK: Properties
private static let logType = "SocketPacket"
let nsp: String
let id: Int
let type: PacketType
/// The namespace for this packet.
public let nsp: String
var binary: [Data]
var data: [Any]
var args: [Any] {
/// If > 0 then this packet is using acking.
public let id: Int
/// The type of this packet.
public let type: PacketType
/// An array of binary data for this packet.
public internal(set) var binary: [Data]
/// The data for this event.
///
/// Note: This includes all data inside of the socket.io packet payload array, which includes the event name for
/// event type packets.
public internal(set) var data: [Any]
/// Returns the payload for this packet, minus the event name if this is an event or binaryEvent type packet.
public var args: [Any] {
if type == .event || type == .binaryEvent && data.count != 0 {
return Array(data.dropFirst())
} else {
@ -48,16 +65,21 @@ struct SocketPacket {
}
}
var description: String {
private let placeholders: Int
/// A string representation of this packet.
public var description: String {
return "SocketPacket {type: \(String(type.rawValue)); data: " +
"\(String(describing: data)); id: \(id); placeholders: \(placeholders); nsp: \(nsp)}"
}
var event: String {
/// The event name for this packet.
public var event: String {
return String(describing: data[0])
}
var packetString: String {
/// A string representation of this packet.
public var packetString: String {
return createPacketString()
}

View File

@ -22,23 +22,57 @@
import Foundation
protocol SocketParsable {
/// Defines that a type will be able to parse socket.io-protocol messages.
public protocol SocketParsable : class {
// MARK: Properties
/// A list of packets that are waiting for binary data.
///
/// The way that socket.io works all data should be sent directly after each packet.
/// So this should ideally be an array of one packet waiting for data.
///
/// **This should not be modified directly.**
var waitingPackets: [SocketPacket] { get set }
// MARK: Methods
/// Called when the engine has received some binary data that should be attached to a packet.
///
/// Packets binary data should be sent directly after the packet that expects it, so there's confusion over
/// where the data should go. Data should be received in the order it is sent, so that the correct data is put
/// into the correct placeholder.
///
/// - parameter data: The data that should be attached to a packet.
func parseBinaryData(_ data: Data)
/// Called when the engine has received a string that should be parsed into a socket.io packet.
///
/// - parameter message: The string that needs parsing.
func parseSocketMessage(_ message: String)
}
enum SocketParsableError : Error {
/// Errors that can be thrown during parsing.
public enum SocketParsableError : Error {
// MARK: Cases
/// Thrown when a packet received has an invalid data array, or is missing the data array.
case invalidDataArray
/// Thrown when an malformed packet is received.
case invalidPacket
/// Thrown when the parser receives an unknown packet type.
case invalidPacketType
}
extension SocketParsable where Self: SocketIOClientSpec {
public extension SocketParsable where Self: SocketIOClientSpec {
private func isCorrectNamespace(_ nsp: String) -> Bool {
return nsp == self.nsp
}
private func handleConnect(_ packetNamespace: String) {
// If we connected with a namespace, check if we've joined the default namespace first, then switch to the
// other namespace
if packetNamespace == "/" && nsp != "/" {
joinNamespace(nsp)
} else {
@ -67,8 +101,11 @@ extension SocketParsable where Self: SocketIOClientSpec {
}
}
/// Parses a messsage from the engine, returning a complete SocketPacket or throwing.
func parseString(_ message: String) throws -> SocketPacket {
/// Parses a message from the engine, returning a complete SocketPacket or throwing.
///
/// - parameter message: The message to parse.
/// - returns: A completed packet, or throwing.
internal func parseString(_ message: String) throws -> SocketPacket {
var reader = SocketStringReader(message: message)
guard let type = Int(reader.read(count: 1)).flatMap({ SocketPacket.PacketType(rawValue: $0) }) else {
@ -133,8 +170,10 @@ extension SocketParsable where Self: SocketIOClientSpec {
}
}
// Parses messages recieved
func parseSocketMessage(_ message: String) {
/// Called when the engine has received a string that should be parsed into a socket.io packet.
///
/// - parameter message: The string that needs parsing.
public func parseSocketMessage(_ message: String) {
guard !message.isEmpty else { return }
DefaultSocketLogger.Logger.log("Parsing \(message)", type: "SocketParser")
@ -150,7 +189,14 @@ extension SocketParsable where Self: SocketIOClientSpec {
}
}
func parseBinaryData(_ data: Data) {
/// Called when the engine has received some binary data that should be attached to a packet.
///
/// Packets binary data should be sent directly after the packet that expects it, so there's confusion over
/// where the data should go. Data should be received in the order it is sent, so that the correct data is put
/// into the correct placeholder.
///
/// - parameter data: The data that should be attached to a packet.
public func parseBinaryData(_ data: Data) {
guard !waitingPackets.isEmpty else {
DefaultSocketLogger.Logger.error("Got data when not remaking packet", type: "SocketParser")
return

View File

@ -0,0 +1,68 @@
//
// SSLSecurity.swift
// SocketIO-iOS
//
// Created by Lukas Schmidt on 24.09.17.
//
// 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
import Starscream
/// A wrapper around Starscream's SSLSecurity that provides a minimal Objective-C interface.
open class SSLSecurity : NSObject {
/// The internal Starscream SSLSecurity.
public let security: Starscream.SSLSecurity
init(security: Starscream.SSLSecurity) {
self.security = security
}
/// Creates a new SSLSecurity that specifies whether to use publicKeys or certificates should be used for SSL
/// pinning validation
///
/// - parameter usePublicKeys: is to specific if the publicKeys or certificates should be used for SSL pinning
/// validation
@objc
public convenience init(usePublicKeys: Bool = true) {
let security = Starscream.SSLSecurity(usePublicKeys: usePublicKeys)
self.init(security: security)
}
/// Designated init
///
/// - 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
public convenience init(certs: [SSLCert], usePublicKeys: Bool) {
let security = Starscream.SSLSecurity(certs: certs, usePublicKeys: usePublicKeys)
self.init(security: security)
}
/// Returns whether or not the given trust is valid.
///
/// - parameter trust: The trust to validate.
/// - parameter domain: The CN domain to validate.
/// - returns: Whether or not this is valid.
public func isValid(_ trust: SecTrust, domain: String?) -> Bool {
return security.isValid(trust, domain: domain)
}
}

View File

@ -23,7 +23,7 @@
// THE SOFTWARE.
import Foundation
import StarscreamSocketIO
import Starscream
enum JSONError : Error {
case notArray

@ -1 +0,0 @@
Subproject commit f7e28f24ae20898da5804079319da52682bb9212