Skip to content

Deep overhaul: STOMP frame core + tests, GitHub Actions CI, modern tooling, rewritten docs (recommend 2.0.0)#132

Open
kuraydev wants to merge 6 commits into
masterfrom
chore/deep-overhaul-2026
Open

Deep overhaul: STOMP frame core + tests, GitHub Actions CI, modern tooling, rewritten docs (recommend 2.0.0)#132
kuraydev wants to merge 6 commits into
masterfrom
chore/deep-overhaul-2026

Conversation

@kuraydev

@kuraydev kuraydev commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Automated deep-overhaul PR — review before merge.

Summary

A maintenance overhaul of StompClientLib that adds real tests and CI, modernizes the tooling, fixes several genuine bugs, and rewrites the documentation — while preserving the public API contract (type names, @objc/@objcMembers Objective-C compatibility, StompClientLibDelegate signatures, public method names, and default values such as accept-version: 1.1,1.2, AutoMode, and certificateCheckEnabled = true).

The risky transport rework (swapping SocketRocket for URLSessionWebSocketTask, modernizing NSURLRequest/NSURL signatures, removing the StompClientLib! IUO delegate params) is intentionally deferred to keep existing CocoaPods consumers building. Those remain documented follow-ups.

pod 'StompClientLib' and import StompClientLib are unchanged. The pod/module name is untouched.

Non-breaking improvements

Source / bug fixes

  • Extracted a pure, Foundation-only wire-format core (StompFrame.encode / decode / ackHeaderValue) so the STOMP framing is unit-testable without a live socket. Removed import UIKit (the file only needs Foundation; verified by a standalone swiftc -typecheck).
  • serverDidSendError now reports a real detailedErrorMessage — the old code passed error as? String, which is always nil.
  • StompClientLibDelegate now refines AnyObject instead of the deprecated class keyword (silences the Swift 5+ warning; non-breaking).
  • Replaced scattered print() calls with a logger gated behind StompClientLib.isLoggingEnabled (see Breaking — default flipped to off).
  • destinationFromHeader simplified; NSDateDate.

Tests — added a 13-case XCTest suite covering frame encode/decode (including the :-in-header-value regression from PR #56, leading-empty-line and trailing-NULL handling, ping/empty frames, round-trip), ack-mode mapping, and client defaults. Replaces the empty Xcode stub tests.

CI — added .github/workflows/ci.yml (SwiftLint + pod lib lint + xcodebuild test on macos-15, every push/PR) and deleted the dead .travis.yml (Travis is shut down and its Example/ path no longer exists).

Tooling — added .swiftlint.yml (tuned to allow the Obj-C-bridged public names); repo lints clean under --strict.

Metadata — podspec homepage/source repointed from WrathChaos to kuraydev; SocketRocket pinned to ~> 0.5 (was unversioned); swift_versions simplified to 5.0; PrivacyInfo.xcprivacy now actually ships via resource_bundles (it previously sat outside source_files and was never packaged). LICENSE copyright holder reconciled with the podspec author and year refreshed.

Docs — README rewritten: every badge repointed to kuraydev + a CI badge, accurate Requirements table, consolidated public-API / delegate / method reference tables, TLS (certificateCheckEnabled) and logging guidance, and an honest "SPM not yet supported" note. The ~255-line embedded auto-generated changelog was moved to CHANGELOG.md (Keep a Changelog). Added CONTRIBUTING.md, issue templates, and a PR template.

Closes #123connection is now reset to false on a server-initiated close. Also addresses #125 (error-4500 auto-disconnect): accurate connection state plus a reconnect timer that actually fires now handle the symptom client-side.

Breaking changes (recommend 2.0.0 major)

  1. Minimum iOS deployment target raised 9.0 → 12.0 (podspec + example Podfile). Drops iOS 9–11 consumers; required for a maintainable floor.
  2. reconnect(exponentialBackoff:) now works. The parameter was previously declared but ignored (fixed 1s interval only). With the default true, the interval now grows geometrically (1s, 2s, 4s, … capped at 60s) and resets on reconnect. Pass exponentialBackoff: false for the legacy fixed interval.
  3. connection resets to false on socket failure/close, so isConnected() flips earlier and more accurately (observable behaviour change; this is the Connection variable is not set to false when WebSocket receives DISCONNECT #123 fix).
  4. Console logging is OFF by default, behind StompClientLib.isLoggingEnabled. Consumers that scraped stdout must opt in with StompClientLib.isLoggingEnabled = true.

The public surface (names, delegate signatures, defaults, Obj-C compatibility) is unchanged — these are deployment-floor and runtime-behaviour breaks, not source-API breaks.

Not done (documented follow-ups)

  • SPM (Swift Package Manager Support #128) — cannot be delivered yet: SocketRocket ships no Package.swift on either the archived facebook/SocketRocket or facebookincubator/SocketRocket (verified via raw fetch). Shipping a manifest that can't resolve would be worse than none. Gated on item below; the new StompFrame core is the groundwork.
  • SRWebSocketErrorDomain 2132 (SRWebSocketErrorDomain Code=2132 #131) — transport-level; needs the planned migration to Apple's first-party URLSessionWebSocketTask / NWProtocolWebSocket, deliberately deferred to keep this PR non-transport-breaking.

Verification (run locally on Xcode 26 / Swift 6.3 / CocoaPods 1.16.2)

  • pod lib lint StompClientLib.podspec --allow-warningspassed validation (compiled against SocketRocket; only pre-existing SocketRocket deprecation + IUO-optionality warnings).
  • swiftlint lint --strict0 violations across 2 files.
  • xcodebuild test -only-testing:StompClientLibExampleTests on an iPhone 17 simulator → 13 tests, 0 failures, TEST SUCCEEDED.
  • swiftc -typecheck StompFrame.swift (Foundation only) → exit 0, confirming the import UIKit removal is safe.
  • pod spec lint --quick → passed.

The example's vendored Pods/ are left at their existing snapshot; CI regenerates them with pod install --repo-update (verified locally).

Recommended version bump

1.4.12.0.0 (not changed in project/podspec by this PR — version stays 1.4.1; bump on release).

kuraydev added 5 commits June 29, 2026 16:09
…rror bugs

- Split the pure STOMP wire-format into a public, Foundation-only `StompFrame`
  enum (encode/decode/ackHeaderValue) so it is unit-testable without a socket,
  and route the client through it.
- Honor the previously-ignored `exponentialBackoff` reconnect parameter
  (default true): the interval now grows geometrically up to 60s and resets on
  reconnect. Pass `exponentialBackoff: false` for the legacy fixed interval.
- Reset `connection` to false when the socket fails or the server closes it, so
  `isConnected()` is accurate and auto-reconnect actually fires (#123, #125).
- `serverDidSendError` now passes a real detailedErrorMessage instead of the
  always-nil `error as? String`.
- Add `StompClientLib.isLoggingEnabled` (default false) and route diagnostics
  through it instead of unconditional print().
- `StompClientLibDelegate` now refines `AnyObject` instead of the deprecated
  `class` keyword. Drop the unused `import UIKit`.

BREAKING CHANGE: default reconnect timing changes to exponential backoff and
isConnected() now reports false after a drop; recommend a major version bump.
…anifest

- Point homepage/source at github.com/kuraydev/StompClientLib.
- Pin the SocketRocket dependency to `~> 0.5` (was unversioned).
- Ship PrivacyInfo.xcprivacy via resource_bundles (it previously sat outside
  source_files and was never packaged for consumers).
- Set swift_versions to ['5.0'] and raise the iOS deployment target 9.0 -> 12.0.
- Replace the empty Xcode test stubs with real coverage of frame
  encode/decode (including the ':'-in-header-value regression), ack-mode
  mapping, and client defaults.
- Add a shared `StompClientLibExample` scheme so CI can run the tests headlessly.
- Compile StompFrame.swift into the example app target (it referenced the
  library source directly) and pin the example Podfile to iOS 12 with a
  deployment-target post_install so modern Xcode can build SocketRocket.
- Rewrite README: fix every badge/link to kuraydev, correct the stale
  Requirements section, add a consolidated public API table, document
  certificateCheckEnabled/TLS, logging, and reconnect backoff, remove the
  dangling stompClientJSONBody example, and drop the 250-line embedded
  changelog in favor of CHANGELOG.md.
- Add a Keep a Changelog [Unreleased] section above the historical dump.
- Add CONTRIBUTING.md, issue templates, and a PR template.
- Reconcile the LICENSE copyright holder with the podspec author.
- Add .github/workflows/ci.yml running SwiftLint, `pod lib lint`, and
  `xcodebuild test` of the example on push/PR (replacing the dead Travis
  config removed earlier).
- Add a .swiftlint.yml configuration.
@kuraydev kuraydev changed the title Deep overhaul: bug fixes, testable frame core, CI, SwiftLint, and docs (recommend 2.0.0) Deep overhaul: STOMP frame core + tests, GitHub Actions CI, modern tooling, rewritten docs (recommend 2.0.0) Jun 29, 2026
The pinned Xcode_16.app lacks an installed iOS 18 simulator runtime on the
macos-15 runner ("iOS 18.0 is not installed"), failing pod lib lint and the
example build/test. Use the runner's selected Xcode and resolve a concrete
simulator UDID at runtime instead of a hardcoded device name.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Connection variable is not set to false when WebSocket receives DISCONNECT

1 participant