diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml new file mode 100644 index 00000000..d96fb492 --- /dev/null +++ b/.github/workflows/swift.yml @@ -0,0 +1,19 @@ +name: Swift + +on: + push: + branches: [ "master", "development" ] + pull_request: + branches: [ "master", "development" ] + +jobs: + build: + + runs-on: macos-latest + + steps: + - uses: actions/checkout@v3 + - name: Build + run: swift build -v + - name: Run tests + run: swift test -v diff --git a/.gitignore b/.gitignore index aec6c75b..4c165233 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,5 @@ Socket.IO-Test-Server/node_modules/* .idea/ docs/docsets/ docs/undocumented.json + +.swiftpm diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b90dafc5..00000000 --- a/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: objective-c -xcode_project: Socket.IO-Client-Swift.xcodeproj # path to your xcodeproj folder -xcode_scheme: SocketIO-Mac -osx_image: xcode12.2 -branches: - only: - - master - - development -before_install: - # - brew update - # - 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 build test -quiet -# - xcodebuild -project Socket.IO-Client-Swift.xcodeproj -scheme SocketIO build-for-testing -quiet -# - xctool -project Socket.IO-Client-Swift.xcodeproj -scheme SocketIO run-tests --parallelize - - swift test diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b496c25..6f0469a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v16.1.0 + +- Remove support for iOS 11. +- Update to Starscream 4.0.6 + # v16.0.0 - Removed Objective-C support. It's time for you to embrace Swift. diff --git a/Cartfile b/Cartfile index 6c2bffe2..321cd44f 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "daltoniam/Starscream" ~> 4.0 +github "daltoniam/Starscream" ~> 4.0.8 \ No newline at end of file diff --git a/Cartfile.resolved b/Cartfile.resolved index f9b2a1a2..a3c32e56 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1 +1 @@ -github "daltoniam/Starscream" "4.0.4" +github "daltoniam/Starscream" "4.0.8" diff --git a/Package.resolved b/Package.resolved index a9c6ce6d..b363050e 100644 --- a/Package.resolved +++ b/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/daltoniam/Starscream", "state": { "branch": null, - "revision": "df8d82047f6654d8e4b655d1b1525c64e1059d21", - "version": "4.0.4" + "revision": "c6bfd1af48efcc9a9ad203665db12375ba6b145a", + "version": "4.0.8" } } ] diff --git a/Package.swift b/Package.swift index 90c4b1f3..89729293 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.3 +// swift-tools-version:5.4 import PackageDescription @@ -8,7 +8,7 @@ let package = Package( .library(name: "SocketIO", targets: ["SocketIO"]) ], dependencies: [ - .package(url: "https://github.com/daltoniam/Starscream", .upToNextMinor(from: "4.0.0")), + .package(url: "https://github.com/daltoniam/Starscream", .upToNextMajor(from: "4.0.8")), ], targets: [ .target(name: "SocketIO", dependencies: ["Starscream"]), diff --git a/README.md b/README.md index ab883f9f..d5671939 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ socket.on("currentAmount") {data, ack in guard let cur = data[0] as? Double else { return } socket.emitWithAck("canUpdate", cur).timingOut(after: 0) {data in - if data.first as? String ?? "passed" == SocketAckValue.noAck { + if data.first as? String ?? "passed" == SocketAckStatus.noAck { // Handle ack timeout } @@ -32,7 +32,7 @@ socket.connect() ``` ## Features -- Supports socket.io 2.0+/3.0+. +- Supports Socket.IO server 2.0+/3.0+/4.0+ (see the [compatibility table](https://nuclearace.github.io/Socket.IO-Client-Swift/Compatibility.html)) - Supports Binary - Supports Polling and WebSockets - Supports TLS/SSL @@ -61,7 +61,7 @@ let package = Package( .executable(name: "socket.io-test", targets: ["YourTargetName"]) ], dependencies: [ - .package(url: "https://github.com/socketio/socket.io-client-swift", .upToNextMinor(from: "15.0.0")) + .package(url: "https://github.com/socketio/socket.io-client-swift", .upToNextMinor(from: "16.1.1")) ], targets: [ .target(name: "YourTargetName", dependencies: ["SocketIO"], path: "./Path/To/Your/Sources") @@ -74,7 +74,7 @@ Then import `import SocketIO`. ### Carthage Add this line to your `Cartfile`: ``` -github "socketio/socket.io-client-swift" ~> 15.2.0 +github "socketio/socket.io-client-swift" ~> 16.1.1 ``` Run `carthage update --platform ios,macosx`. @@ -88,7 +88,7 @@ Create `Podfile` and add `pod 'Socket.IO-Client-Swift'`: use_frameworks! target 'YourApp' do - pod 'Socket.IO-Client-Swift', '~> 15.2.0' + pod 'Socket.IO-Client-Swift', '~> 16.1.1' end ``` diff --git a/Socket.IO-Client-Swift.podspec b/Socket.IO-Client-Swift.podspec index 50a988e1..b07344de 100644 --- a/Socket.IO-Client-Swift.podspec +++ b/Socket.IO-Client-Swift.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "Socket.IO-Client-Swift" s.module_name = "SocketIO" - s.version = "16.0.0" + s.version = "16.1.1" s.summary = "Socket.IO-client for iOS and OS X" s.description = <<-DESC Socket.IO-client for iOS and OS X. @@ -11,21 +11,21 @@ Pod::Spec.new do |s| s.homepage = "https://github.com/socketio/socket.io-client-swift" s.license = { :type => 'MIT' } s.author = { "Erik" => "nuclear.ace@gmail.com" } - s.ios.deployment_target = '10.0' + s.ios.deployment_target = '12.0' s.osx.deployment_target = '10.13' - s.tvos.deployment_target = '10.0' + s.tvos.deployment_target = '12.0' s.watchos.deployment_target = '5.0' s.requires_arc = true s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", - :tag => 'v16.0.0', + :tag => 'v16.1.1', :submodules => true } s.swift_version = "5" s.pod_target_xcconfig = { - 'SWIFT_VERSION' => '5.0' + 'SWIFT_VERSION' => '5.4' } s.source_files = "Source/SocketIO/**/*.swift", "Source/SocketIO/*.swift" - s.dependency "Starscream", "~> 4.0" + s.dependency "Starscream", "~> 4.0.8" end diff --git a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj index bb92c24a..ffed9326 100644 --- a/Socket.IO-Client-Swift.xcodeproj/project.pbxproj +++ b/Socket.IO-Client-Swift.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -19,9 +19,9 @@ 1C686BE71F869AFD007D8627 /* SocketParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C686BD71F869AF1007D8627 /* SocketParserTest.swift */; }; 1C686BE81F869AFD007D8627 /* SocketNamespacePacketTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C686BD81F869AF1007D8627 /* SocketNamespacePacketTest.swift */; }; 572EF2431B51F18A00EEBB58 /* SocketIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 572EF2381B51F18A00EEBB58 /* SocketIO.framework */; }; + 579C7D4C2731B487009F8A2F /* Starscream.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 579C7D4B2731B487009F8A2F /* Starscream.xcframework */; }; 6CA08A981D615C0B0061FD2A /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CA08A971D615C0B0061FD2A /* Security.framework */; }; 74BF53581F894326004972D8 /* SocketIO.h in Headers */ = {isa = PBXBuildFile; fileRef = 572EF23C1B51F18A00EEBB58 /* SocketIO.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 74D0F5961F8053950037C4DC /* Starscream.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9432E00B1F77F883006AF628 /* Starscream.framework */; }; 74DA21741F09440F009C19EE /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 74DA21731F09440F009C19EE /* libz.tbd */; }; 74DA217C1F09457B009C19EE /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 74DA21731F09440F009C19EE /* libz.tbd */; }; DD52B048C71D724ABBD18C71 /* SocketTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD52BDC9E66AADA2CC5E8246 /* SocketTypes.swift */; }; @@ -75,18 +75,15 @@ 572EF23B1B51F18A00EEBB58 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 572EF23C1B51F18A00EEBB58 /* SocketIO.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SocketIO.h; sourceTree = ""; }; 572EF2421B51F18A00EEBB58 /* SocketIO-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SocketIO-Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 579C7D4B2731B487009F8A2F /* Starscream.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Starscream.xcframework; path = Carthage/Build/Starscream.xcframework; sourceTree = ""; }; 6CA08A951D615C040061FD2A /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; 6CA08A971D615C0B0061FD2A /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 6CA08A991D615C140061FD2A /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS9.2.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; - 749FA19F1F8112E7002FBB30 /* Starscream.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = Starscream.framework.dSYM; path = Carthage/Build/Mac/Starscream.framework.dSYM; sourceTree = ""; }; 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; }; 74DA217D1F0945E9009C19EE /* libcommonCrypto.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcommonCrypto.tbd; path = usr/lib/system/libcommonCrypto.tbd; sourceTree = SDKROOT; }; 9432E0061F77F7CA006AF628 /* SSLSecurity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSLSecurity.swift; sourceTree = ""; }; - 9432E0091F77F87D006AF628 /* Starscream.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Starscream.framework; path = Carthage/Build/iOS/Starscream.framework; sourceTree = ""; }; - 9432E00B1F77F883006AF628 /* Starscream.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Starscream.framework; path = Carthage/Build/Mac/Starscream.framework; sourceTree = ""; }; - 9432E00D1F77F889006AF628 /* Starscream.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Starscream.framework; path = Carthage/Build/tvOS/Starscream.framework; sourceTree = ""; }; DD52B078DB0A3C3D1BB507CD /* SocketIOClientOption.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketIOClientOption.swift; sourceTree = ""; }; DD52B09F7984E730513AB7E5 /* SocketAckManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketAckManager.swift; sourceTree = ""; }; DD52B1D9BC4AE46D38D827DE /* SocketIOStatus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SocketIOStatus.swift; sourceTree = ""; }; @@ -120,8 +117,8 @@ buildActionMask = 2147483647; files = ( 74DA21741F09440F009C19EE /* libz.tbd in Frameworks */, + 579C7D4C2731B487009F8A2F /* Starscream.xcframework in Frameworks */, 6CA08A981D615C0B0061FD2A /* Security.framework in Frameworks */, - 74D0F5961F8053950037C4DC /* Starscream.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -231,11 +228,8 @@ isa = PBXGroup; children = ( 749FA1A11F811408002FBB30 /* Foundation.framework */, - 749FA19F1F8112E7002FBB30 /* Starscream.framework.dSYM */, + 579C7D4B2731B487009F8A2F /* Starscream.xcframework */, 74D0F58D1F804FED0037C4DC /* libz.tbd */, - 9432E0091F77F87D006AF628 /* Starscream.framework */, - 9432E00B1F77F883006AF628 /* Starscream.framework */, - 9432E00D1F77F889006AF628 /* Starscream.framework */, 74DA217D1F0945E9009C19EE /* libcommonCrypto.tbd */, 74DA21731F09440F009C19EE /* libz.tbd */, 6CA08A9E1D615C340061FD2A /* tvOS */, @@ -350,9 +344,9 @@ isa = PBXNativeTarget; buildConfigurationList = 572EF24B1B51F18A00EEBB58 /* Build configuration list for PBXNativeTarget "SocketIO" */; buildPhases = ( + 572EF2351B51F18A00EEBB58 /* Headers */, 572EF2331B51F18A00EEBB58 /* Sources */, 572EF2341B51F18A00EEBB58 /* Frameworks */, - 572EF2351B51F18A00EEBB58 /* Headers */, 572EF2361B51F18A00EEBB58 /* Resources */, ); buildRules = ( @@ -517,7 +511,6 @@ 572EF2121B51F12F00EEBB58 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - BITCODE_GENERATION_MODE = bitcode; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -537,37 +530,11 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "Mac Developer"; - ENABLE_BITCODE = YES; - "ENABLE_BITCODE[sdk=macosx*]" = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - "FRAMEWORK_SEARCH_PATHS[sdk=appletvos*]" = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/tvOS", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=appletvsimulator*]" = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/tvOS", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*]" = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*]" = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=macosx*]" = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/Mac", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=watchos*]" = ( - "$(PROJECT_DIR)/Carthage/Build/watchOS", - "$(inherited)", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=watchsimulator*]" = ( - "$(PROJECT_DIR)/Carthage/Build/watchOS", + FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/", ); GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; @@ -581,7 +548,7 @@ MACOSX_DEPLOYMENT_TARGET = 10.14; ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = SocketIO; - SUPPORTED_PLATFORMS = "macosx appletvsimulator appletvos iphonesimulator iphoneos watchos watchsimulator"; + SUPPORTED_PLATFORMS = "macosx appletvsimulator appletvos iphonesimulator iphoneos watchos watchsimulator xrsimulator xros"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TVOS_DEPLOYMENT_TARGET = 10.0; @@ -593,7 +560,6 @@ 572EF2131B51F12F00EEBB58 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - BITCODE_GENERATION_MODE = bitcode; CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; @@ -613,36 +579,10 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "Mac Developer"; - ENABLE_BITCODE = YES; - "ENABLE_BITCODE[sdk=macosx*]" = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - "FRAMEWORK_SEARCH_PATHS[sdk=appletvos*]" = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/tvOS", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=appletvsimulator*]" = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/tvOS", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=iphoneos*]" = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=iphonesimulator*]" = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/iOS", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=macosx*]" = ( - "$(inherited)", - "$(PROJECT_DIR)/Carthage/Build/Mac", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=watchos*]" = ( - "$(PROJECT_DIR)/Carthage/Build/watchOS", - "$(inherited)", - ); - "FRAMEWORK_SEARCH_PATHS[sdk=watchsimulator*]" = ( - "$(PROJECT_DIR)/Carthage/Build/watchOS", + FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/", ); GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -654,8 +594,9 @@ IPHONEOS_DEPLOYMENT_TARGET = 10.0; MACOSX_DEPLOYMENT_TARGET = 10.14; PRODUCT_NAME = SocketIO; - SUPPORTED_PLATFORMS = "macosx appletvsimulator appletvos iphonesimulator iphoneos watchos watchsimulator"; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SUPPORTED_PLATFORMS = "macosx appletvsimulator appletvos iphonesimulator iphoneos watchos watchsimulator xrsimulator xros"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; TVOS_DEPLOYMENT_TARGET = 10.0; VALID_ARCHS = "i386 x86_64 armv7 armv7s arm64 armv7k"; @@ -666,7 +607,9 @@ 572EF24C1B51F18A00EEBB58 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; ALWAYS_SEARCH_USER_PATHS = NO; + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -689,8 +632,6 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_BITCODE = YES; - "ENABLE_BITCODE[sdk=macosx*]" = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -711,8 +652,17 @@ GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = SocketIO/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); LIBRARY_SEARCH_PATHS = "$(inherited)"; MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = YES; @@ -721,12 +671,15 @@ SDKROOT = macosx; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "$(inherited)"; + SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_INCLUDE_PATHS = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4"; - TVOS_DEPLOYMENT_TARGET = 10.0; + TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; + TVOS_DEPLOYMENT_TARGET = 12.0; VALID_ARCHS = "$(inherited)"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -736,7 +689,9 @@ 572EF24D1B51F18A00EEBB58 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES; ALWAYS_SEARCH_USER_PATHS = NO; + APPLICATION_EXTENSION_API_ONLY = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -759,8 +714,6 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_BITCODE = YES; - "ENABLE_BITCODE[sdk=macosx*]" = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -776,8 +729,17 @@ GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = SocketIO/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); LIBRARY_SEARCH_PATHS = "$(inherited)"; MACOSX_DEPLOYMENT_TARGET = 10.10; MTL_ENABLE_DEBUG_INFO = NO; @@ -785,11 +747,14 @@ SDKROOT = macosx; SKIP_INSTALL = YES; SUPPORTED_PLATFORMS = "$(inherited)"; + SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_INCLUDE_PATHS = ""; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4"; - TVOS_DEPLOYMENT_TARGET = 10.0; + TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; + TVOS_DEPLOYMENT_TARGET = 12.0; VALID_ARCHS = "$(inherited)"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -817,7 +782,6 @@ COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( "$(DEVELOPER_FRAMEWORKS_DIR)", @@ -860,10 +824,17 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = SocketIO/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = "io.socket.$(PRODUCT_NAME:rfc1034identifier)"; @@ -873,7 +844,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; - TVOS_DEPLOYMENT_TARGET = 10.0; + TVOS_DEPLOYMENT_TARGET = 12.0; VALID_ARCHS = "$(inherited)"; }; name = Debug; @@ -899,7 +870,6 @@ COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -936,10 +906,17 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = SocketIO/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks @loader_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); LIBRARY_SEARCH_PATHS = "$(inherited)"; - MACOSX_DEPLOYMENT_TARGET = 10.10; + MACOSX_DEPLOYMENT_TARGET = 10.13; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "io.socket.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -947,7 +924,7 @@ SUPPORTED_PLATFORMS = "$(inherited)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 5.0; - TVOS_DEPLOYMENT_TARGET = 10.0; + TVOS_DEPLOYMENT_TARGET = 12.0; VALID_ARCHS = "$(inherited)"; }; name = Release; diff --git a/Source/SocketIO/Ack/SocketAckEmitter.swift b/Source/SocketIO/Ack/SocketAckEmitter.swift index 0a4eea77..18bebcfc 100644 --- a/Source/SocketIO/Ack/SocketAckEmitter.swift +++ b/Source/SocketIO/Ack/SocketAckEmitter.swift @@ -28,7 +28,7 @@ import Foundation /// A class that represents a waiting ack call. /// /// **NOTE**: You should not store this beyond the life of the event handler. -public final class SocketAckEmitter : NSObject { +public final class SocketAckEmitter: NSObject { private unowned let socket: SocketIOClient private let ackNum: Int @@ -101,7 +101,7 @@ public final class SocketAckEmitter : NSObject { /// ... /// } /// ``` -public final class OnAckCallback : NSObject { +public final class OnAckCallback: NSObject { private let ackNumber: Int private let binary: Bool private let items: [Any] diff --git a/Source/SocketIO/Client/SocketIOClient.swift b/Source/SocketIO/Client/SocketIOClient.swift index 160d2e9a..d97bae1e 100644 --- a/Source/SocketIO/Client/SocketIOClient.swift +++ b/Source/SocketIO/Client/SocketIOClient.swift @@ -150,7 +150,8 @@ open class SocketIOClient: NSObject, SocketIOClientSpec { manager.handleQueue.asyncAfter(deadline: DispatchTime.now() + timeoutAfter) {[weak self] in guard let this = self, this.status == .connecting || this.status == .notConnected else { return } - + DefaultSocketLogger.Logger.log("Timeout: Socket not connected, so setting to disconnected", type: this.logType) + this.status = .disconnected this.leaveNamespace() @@ -212,6 +213,19 @@ open class SocketIOClient: NSObject, SocketIOClientSpec { /// - parameter items: The items to send with this event. May be left out. /// - parameter completion: Callback called on transport write completion. open func emit(_ event: String, _ items: SocketData..., completion: (() -> ())? = nil) { + emit(event, with: items, completion: completion) + } + + /// Send an event to the server, with optional data items and optional write completion handler. + /// + /// 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. + /// - parameter completion: Callback called on transport write completion. + open func emit(_ event: String, with items: [SocketData], completion: (() -> ())?) { + do { emit([event] + (try items.map({ try $0.socketRepresentation() })), completion: completion) } catch { @@ -242,6 +256,30 @@ open class SocketIOClient: NSObject, SocketIOClientSpec { /// - 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. open func emitWithAck(_ event: String, _ items: SocketData...) -> OnAckCallback { + emitWithAck(event, with: items) + } + + /// 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. + open func emitWithAck(_ event: String, with items: [SocketData]) -> OnAckCallback { + do { return createOnAck([event] + (try items.map({ try $0.socketRepresentation() }))) } catch { diff --git a/Source/SocketIO/Client/SocketIOClientOption.swift b/Source/SocketIO/Client/SocketIOClientOption.swift index ac1a032b..545c210b 100644 --- a/Source/SocketIO/Client/SocketIOClientOption.swift +++ b/Source/SocketIO/Client/SocketIOClientOption.swift @@ -108,6 +108,9 @@ public enum SocketIOClientOption : ClientOption { /// Sets an NSURLSessionDelegate for the underlying engine. Useful if you need to handle self-signed certs. case sessionDelegate(URLSessionDelegate) + /// If passed `false`, the WebSocket stream will be configured with the useCustomEngine `false`. + case useCustomEngine(Bool) + /// The version of socket.io being used. This should match the server version. Default is 3. case version(SocketIOVersion) @@ -160,6 +163,8 @@ public enum SocketIOClientOption : ClientOption { description = "sessionDelegate" case .enableSOCKSProxy: description = "enableSOCKSProxy" + case .useCustomEngine: + description = "customEngine" case .version: description = "version" } @@ -213,6 +218,8 @@ public enum SocketIOClientOption : ClientOption { value = delegate case let .enableSOCKSProxy(enable): value = enable + case let .useCustomEngine(enable): + value = enable case let.version(versionNum): value = versionNum } diff --git a/Source/SocketIO/Client/SocketIOClientSpec.swift b/Source/SocketIO/Client/SocketIOClientSpec.swift index 9c0e5504..04b62faa 100644 --- a/Source/SocketIO/Client/SocketIOClientSpec.swift +++ b/Source/SocketIO/Client/SocketIOClientSpec.swift @@ -107,6 +107,16 @@ public protocol SocketIOClientSpec : AnyObject { /// - parameter items: The items to send with this event. May be left out. /// - parameter completion: Callback called on transport write completion. func emit(_ event: String, _ items: SocketData..., completion: (() -> ())?) + + /// Send an event to the server, with optional data items and optional write completion handler. + /// + /// 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. + /// - parameter completion: Callback called on transport write completion. + func emit(_ event: String, with items: [SocketData], completion: (() -> ())?) /// Call when you wish to tell the server that you've received the event for `ack`. /// @@ -134,6 +144,27 @@ public protocol SocketIOClientSpec : AnyObject { /// - 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 + + /// 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, with items: [SocketData]) -> OnAckCallback /// Called when socket.io has acked one of our emits. Causes the corresponding ack callback to be called. /// diff --git a/Source/SocketIO/Engine/SocketEngine.swift b/Source/SocketIO/Engine/SocketEngine.swift index cd261166..1d1c071d 100644 --- a/Source/SocketIO/Engine/SocketEngine.swift +++ b/Source/SocketIO/Engine/SocketEngine.swift @@ -28,8 +28,10 @@ import Starscream /// The class that handles the engine.io protocol and transports. /// See `SocketEnginePollable` and `SocketEngineWebsocket` for transport specific methods. -open class SocketEngine: - NSObject, WebSocketDelegate, URLSessionDelegate, SocketEnginePollable, SocketEngineWebsocket, ConfigSettable { +open class SocketEngine: NSObject, WebSocketDelegate, URLSessionDelegate, + SocketEnginePollable, SocketEngineWebsocket, ConfigSettable { + + // MARK: Properties private static let logType = "SocketEngine" @@ -111,6 +113,9 @@ open class SocketEngine: /// The url for WebSockets. public private(set) var urlWebSocket = URL(string: "http://localhost/")! + /// When `false`, the WebSocket `stream` will be configured with the useCustomEngine `false`. + public private(set) var useCustomEngine = true + /// The version of engine.io being used. Default is three. public private(set) var version: SocketIOVersion = .three @@ -307,7 +312,7 @@ open class SocketEngine: includingCookies: session?.configuration.httpCookieStorage?.cookies(for: urlPollingWithSid) ) - ws = WebSocket(request: req, certPinner: certPinner, compressionHandler: compress ? WSCompression() : nil) + ws = WebSocket(request: req, certPinner: certPinner, compressionHandler: compress ? WSCompression() : nil, useCustomEngine: useCustomEngine) ws?.callbackQueue = engineQueue ws?.delegate = self @@ -624,6 +629,8 @@ open class SocketEngine: self.compress = true case .enableSOCKSProxy: self.enableSOCKSProxy = true + case let .useCustomEngine(enable): + self.useCustomEngine = enable case let .version(num): version = num default: @@ -742,16 +749,22 @@ extension SocketEngine { /// - Parameters: /// - event: WS Event /// - _: - public func didReceive(event: WebSocketEvent, client _: WebSocket) { + public func didReceive(event: Starscream.WebSocketEvent, client: Starscream.WebSocketClient) { switch event { case let .connected(headers): wsConnected = true - client?.engineDidWebsocketUpgrade(headers: headers) + self.client?.engineDidWebsocketUpgrade(headers: headers) websocketDidConnect() case .cancelled: wsConnected = false websocketDidDisconnect(error: EngineError.canceled) - case let .disconnected(reason, code): + case .disconnected(_, _): + wsConnected = false + websocketDidDisconnect(error: nil) + case .viabilityChanged(false): + wsConnected = false + websocketDidDisconnect(error: nil) + case .peerClosed: wsConnected = false websocketDidDisconnect(error: nil) case let .text(msg): diff --git a/Source/SocketIO/Engine/SocketEngineSpec.swift b/Source/SocketIO/Engine/SocketEngineSpec.swift index 1eecffd3..fc0aa58b 100644 --- a/Source/SocketIO/Engine/SocketEngineSpec.swift +++ b/Source/SocketIO/Engine/SocketEngineSpec.swift @@ -27,7 +27,7 @@ import Foundation import Starscream /// Specifies a SocketEngine. -public protocol SocketEngineSpec: class { +public protocol SocketEngineSpec: AnyObject { // MARK: Properties /// The client for this engine. diff --git a/Source/SocketIO/Manager/SocketManager.swift b/Source/SocketIO/Manager/SocketManager.swift index c45c5f56..d69aa11f 100644 --- a/Source/SocketIO/Manager/SocketManager.swift +++ b/Source/SocketIO/Manager/SocketManager.swift @@ -132,7 +132,7 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat private(set) var reconnectAttempts = -1 private var _config: SocketIOClientConfiguration - private var currentReconnectAttempt = 0 + internal var currentReconnectAttempt = 0 private var reconnecting = false // MARK: Initializers @@ -186,9 +186,8 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat /// /// Override if you wish to attach a custom `SocketEngineSpec`. open func connect() { - guard !status.active else { + if status == .connected || (status == .connecting && currentReconnectAttempt == 0) { DefaultSocketLogger.Logger.log("Tried connecting an already active socket", type: SocketManager.logType) - return } diff --git a/Source/SocketIO/Manager/SocketManagerSpec.swift b/Source/SocketIO/Manager/SocketManagerSpec.swift index 87be545e..8c57c91e 100644 --- a/Source/SocketIO/Manager/SocketManagerSpec.swift +++ b/Source/SocketIO/Manager/SocketManagerSpec.swift @@ -45,7 +45,7 @@ import Foundation /// To disconnect a socket and remove it from the manager, either call `SocketIOClient.disconnect()` on the socket, /// or call one of the `disconnectSocket` methods on this class. /// -public protocol SocketManagerSpec : AnyObject, SocketEngineClient { +public protocol SocketManagerSpec : SocketEngineClient { // MARK: Properties /// Returns the socket associated with the default namespace ("/"). diff --git a/Source/SocketIO/Util/SocketExtensions.swift b/Source/SocketIO/Util/SocketExtensions.swift index 63b0b99d..d44ea26d 100644 --- a/Source/SocketIO/Util/SocketExtensions.swift +++ b/Source/SocketIO/Util/SocketExtensions.swift @@ -87,7 +87,9 @@ extension Dictionary where Key == String, Value == Any { return compress ? .compress : nil case let ("enableSOCKSProxy", enable as Bool): return .enableSOCKSProxy(enable) - default: + case let ("version", version as Int): + return .version(SocketIOVersion(rawValue: version) ?? .three) + case _: return nil } } diff --git a/Tests/TestSocketIO/SocketAckManagerTest.swift b/Tests/TestSocketIO/SocketAckManagerTest.swift index f5d9c2a5..4f7f5b0c 100644 --- a/Tests/TestSocketIO/SocketAckManagerTest.swift +++ b/Tests/TestSocketIO/SocketAckManagerTest.swift @@ -28,7 +28,6 @@ class SocketAckManagerTest : XCTestCase { func testManagerTimeoutAck() { let callbackExpection = expectation(description: "Manager should timeout ack with noAck status") - let itemsArray = ["Hi", "ho"] func callback(_ items: [Any]) { XCTAssertEqual(items.count, 1, "Timed out ack should have one value") diff --git a/Tests/TestSocketIO/SocketMangerTest.swift b/Tests/TestSocketIO/SocketMangerTest.swift index 1fa72a0a..b2dd5715 100644 --- a/Tests/TestSocketIO/SocketMangerTest.swift +++ b/Tests/TestSocketIO/SocketMangerTest.swift @@ -60,6 +60,44 @@ class SocketMangerTest : XCTestCase { waitForExpectations(timeout: 0.3) } + func testManagerDoesNotCallConnectWhenConnectingWithLessThanOneReconnect() { + setUpSockets() + + let expect = expectation(description: "The manager should not call connect on the engine") + expect.isInverted = true + + let engine = TestEngine(client: manager, url: manager.socketURL, options: nil) + + engine.onConnect = { + expect.fulfill() + } + manager.setTestStatus(.connecting) + manager.setCurrentReconnect(currentReconnect: 0) + manager.engine = engine + + manager.connect() + + waitForExpectations(timeout: 0.3) + } + + func testManagerCallConnectWhenConnectingAndMoreThanOneReconnect() { + setUpSockets() + + let expect = expectation(description: "The manager should call connect on the engine") + let engine = TestEngine(client: manager, url: manager.socketURL, options: nil) + + engine.onConnect = { + expect.fulfill() + } + manager.setTestStatus(.connecting) + manager.setCurrentReconnect(currentReconnect: 1) + manager.engine = engine + + manager.connect() + + waitForExpectations(timeout: 0.8) + } + func testManagerCallsDisconnect() { setUpSockets() @@ -154,6 +192,10 @@ public enum ManagerExpectation: String { } public class TestManager: SocketManager { + public func setCurrentReconnect(currentReconnect: Int) { + self.currentReconnectAttempt = currentReconnect + } + public override func disconnect() { setTestStatus(.disconnected) } diff --git a/Tests/TestSocketIO/SocketSideEffectTest.swift b/Tests/TestSocketIO/SocketSideEffectTest.swift index ecaaee03..749a819a 100644 --- a/Tests/TestSocketIO/SocketSideEffectTest.swift +++ b/Tests/TestSocketIO/SocketSideEffectTest.swift @@ -487,7 +487,7 @@ class TestEngine: SocketEngineSpec { private(set) var ws: WebSocket? = nil private(set) var version = SocketIOVersion.three - fileprivate var onConnect: (() -> ())? + internal var onConnect: (() -> ())? required init(client: SocketEngineClient, url: URL, options: [String: Any]?) { self.client = client diff --git a/Usage Docs/15to16.md b/Usage Docs/15to16.md index 7f425753..d50fd8d9 100644 --- a/Usage Docs/15to16.md +++ b/Usage Docs/15to16.md @@ -6,11 +6,30 @@ This guide will help you navigate the changes that were introduced in v16. ## Client supports multiple socket.io versions -The client now supports socket.io 3 servers. This is mostly a transparent change, however if your sever +The client now supports socket.io 3 servers. This is mostly a transparent change, however if your server is socket.io 2, you must send `.version(.two)` as an option to the manager. ```swift SocketManager(socketURL: URL(string:"http://localhost:8087/")!, config: [.version(.two)]) ``` +## How to upgrade +- first, upgrade the Socket.IO server to v4 with the compatibility mode enabled (`allowEIO3: true`) +- then, upgrade the clients to v16 +- finally, once all clients have upgraded, disable the compatibility mode + +You can check the version of the connection on the server side with: + +```js +io.on("connection", (socket) => { + // either 3 for the 3rd revision of the protocol (Socket.IO v2) or 4 for the 4th revision (Socket.IO v3/v4) + const version = socket.conn.protocol; +}); +``` + +See also: + +- [Compatibility table](https://nuclearace.github.io/Socket.IO-Client-Swift/Compatibility.html) +- Migrating from 2.x to 3.0: https://socket.io/docs/v4/migrating-from-2-x-to-3-0/ +- Migrating from 3.x to 4.0: https://socket.io/docs/v4/migrating-from-3-x-to-4-0/ diff --git a/Usage Docs/Compatibility.md b/Usage Docs/Compatibility.md new file mode 100644 index 00000000..9841073a --- /dev/null +++ b/Usage Docs/Compatibility.md @@ -0,0 +1,61 @@ +Here is the compatibility table with the Node.js server: + + + + + + + + + + + + + + + + + + + + + + + +
Swift Client versionSocket.IO server version
2.x3.x4.x
v15.xYESYES1YES2
v16.xYES3YESYES
+ +[1] Yes, with allowEIO3: true (server) and `.connectParams(["EIO": "3"])` (client): + +*Server* + +```js +const { createServer } = require("http"); +const { Server } = require("socket.io"); + +const httpServer = createServer(); +const io = new Server(httpServer, { + allowEIO3: true +}); + +httpServer.listen(8080); +``` + +*Client* + +```swift +SocketManager(socketURL: URL(string:"http://localhost:8080/")!, config: [.connectParams(["EIO": "3"])]) +``` + +[2] Yes, allowEIO3: true (server) + +[3] Yes, with `.version(.two)` (client): + +```swift +SocketManager(socketURL: URL(string:"http://localhost:8080/")!, config: [.version(.two)]) +``` + +See also: + +- Migrating from 2.x to 3.0: https://socket.io/docs/v4/migrating-from-2-x-to-3-0/ +- Migrating from 3.x to 4.0: https://socket.io/docs/v4/migrating-from-3-x-to-4-0/ +- Socket.IO protocol: https://github.com/socketio/socket.io-protocol