JKSwiftExtension is a grab bag of UIKit and Foundation helpers with a test file for each one
Swift常用扩展、组件、协议,方便项目快速搭建,提供完整清晰的Demo示例,不断的完善中......
At a glance
- What is it?
- JKSwiftExtension collects Swift extensions, UIKit components and protocol helpers under Apache-2.0, distributed by Swift Package Manager or CocoaPods. Its distinguishing habit is that every extension is supposed to have a matching test case class, and its logging layer was rewritten in the 2.9.2 release of 2026.10.15.
- Who is it for?
- JKSwiftExtension suits iOS teams that want a ready-made helper layer and a convention of testing every extension, and it should be adopted file by file rather than as one dependency, since the library spans a very wide API surface with no GitHub releases to pin against. It does not suit SwiftUI projects, since the documented groups are FoundationExtension, UIKitExtension, Protocol and SmallTools.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Four directories, no single theme
The repository advertises itself as a collection of commonly used Swift extensions, components and protocols for building projects quickly, and the structure confirms that the collection is broad rather than focused. The README splits the code into four groups: FoundationExtension for Foundation types, UIKitExtension for UIKit types, Protocol for protocol tooling, and SmallTools for everything else.
That last bucket is where the character of the library shows. SmallTools contains standalone classes rather than extensions, and the version notes name them explicitly: JKPrint for console and file output, JKFileLog for writing logs to disk, JKTaskManager for scheduling and cancelling delayed work, JKAsyncs, JKTextFieldAutoLimiter and JKTextViewAutoLimiter for input limits, JKRegexHelper for regular expressions, JKScreenShieldView to block screen recording and screenshots, JKImageButton, JKDiamondView and JKScrollviewCardLayout. New ones keep appearing between releases, which is good for a shared utility layer and a problem for anyone tracking an API surface.
The public entry points are also worth noting. A JKTransparentHitTestImageView distinguishes touches on transparent pixels from touches on opaque ones, and there is a suite of UIView helpers for gradient fills, shadows, dashed borders, shake animation and three-dimensional rotation. These are the parts most likely to end up in a production app.
Every extension is expected to come with a test case class
The README sets out a rule for contributors: each Extension corresponds to a test case class, and if one is missing then that extension is not yet complete. The example given is the String category String+Extension, whose test case lives in StringExtensionViewController.swift. The image the README attaches to that rule shows the demo project rather than a test plan.
This is the most transferable idea in the repository. It gives the project a definition of done that is not about features, and it means the Example directory doubles as living documentation, since a developer can open a view controller to see how a helper is meant to be called. The top-level layout supports that reading: Sources, Tests, Example and an OtherEvent directory sit next to Package.swift and JKSwiftExtension.podspec.
There is a caveat. The convention is described in prose, and the repository has no release tags published on GitHub, so a newcomer cannot point to a tagged version where the convention was enforced. The Example project also carries both an xcodeproj and an xcworkspace plus a Podfile.lock, which suggests the demo is built through CocoaPods in practice even though the library itself is also packaged with Swift Package Manager.
Adding the dependency through CocoaPods or Swift Package Manager
Two installation routes are documented. The Swift Package Manager route is a menu path in Xcode rather than a command, so there is no script to copy: under File > Swift Packages > Add Package Dependency you add the repository URL, and the README instructs you to select up to next major with 2.0.0.
The CocoaPods route gives you a Podfile you can paste directly. This is the configuration the README shows, and it also fixes the deployment target at iOS 13.0:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '13.0'
use_frameworks!
target 'MyApp' do
pod 'JKSwiftExtension'
endAfter either route, the natural first step is to open the Example project and run the demo view controllers, which is where the per-extension test classes live. Requirements are listed as Swift 5.0 and later, and the minimum system version was raised to 13.0 in the 2.7.0 release of 2024.09.12.
One detail deserves attention. The SPM rule of up to next major from 2.0.0 resolves to the newest 2.x version, and the current release notes are at 2.9.2 dated 2026.10.15. That means a fresh resolve pulls the latest 2.x rather than a version you chose deliberately, and because no GitHub releases are published, the version list is what you have to navigate.
The 2.9.2 release rebuilds the logging path from both ends
The most recent entry in the version notes, 2.9.2 dated 2026.10.15, is mostly a logging rewrite, and it is more interesting than a typical patch. JKPrint now generates its timestamp from a single timestamp() function built on gettimeofday plus strftime, and the shared mutable DateFormatter instance was removed. Printing stays synchronous while writing to a file happens asynchronously, and a check for isWriteLog happens before the file write. A duplicate serial queue and local write path were deleted so that everything funnels through JKFileLog.
JKFileLog moved in the same direction. Its writeLog output no longer carries file, line, column or function metadata, just a tab separated time and content pair. A new preparedLogPaths cache tracks created directories and files so the logger performs fewer disk writes, and removeLogFile invalidates that cache. The notes also mention unifying old and new FileHandle writing APIs and giving writeSimpleLog an optional time parameter.
For anyone who parsed the old log format, this is a breaking change disguised as a patch number. Log lines that used to start with source location now start with a timestamp, so a grep pipeline or a dashboard built on the previous format needs updating.
UIKit helpers rewritten for split screen, Stage Manager and the Dynamic Island
The 2.9.1 release of 2026.09.21 shows the library tracking iOS interface changes closely. UIApplication+Extension gained an activeWindow property that prefers the window of the currently active scene, which the notes describe as an adaptation for iPad split view, Stage Manager and foldable devices. UIView+Extension was changed to use that same active scene window for status bar height and safe area, correcting a mismatch on Dynamic Island models where statusBarFrame and the safe area disagreed. A separate jk_kNavFrameH was recalculated on the top safe area, and UIViewController+Extension added navBarHeight, taking the bottom of the navigation bar to handle iPad, rotated layouts, large titles and iOS 26 liquid glass.
There are also correctness fixes that show the code is exercised against real devices rather than only compiled. The gradientColorAnimation animation did not apply when a view already had child layers such as a UIButton, and its isRemovedOnCompletion flag was ignored. addWater now guards against empty text and zero width to avoid a division by zero crash. Gesture pinch and rotation dropped force unwraps, and the gradient layer carries a name so removal deletes only the layer the extension added, not a gradient a developer placed by hand.
The pattern to note is that safe area and status bar helpers have been rewritten repeatedly. That churn is a direct cost of shipping helpers that reach into window and scene internals.
Where the library falls short: iOS only, wide surface, no published releases
The limits are concrete. First, the documented groups are FoundationExtension, UIKitExtension, Protocol and SmallTools, and no SwiftUI group appears in the repository layout, so a SwiftUI application gets Foundation helpers at best and has to live without view component helpers.
Second, the API surface is wide and the releases keep adding to it. The 2.8.3 notes (2025.05.06) state a deliberate rule that chained calls follow the system API signatures, with optional types used where the system uses them, and later versions corrected extensions that drifted from that rule, including system attributes such as backgroundColor being changed to optional. Following the system API is the right call, but it also means your call sites change when Apple changes its own signatures.
Third, there are no GitHub releases, so upgrading is a matter of reading a long changelog and hoping a version number in a Podfile or Package.swift resolves to something you have reviewed. A project that publishes one or two releases a month without tags is workable, just not pleasant. Fourth, extensions on UIKit objects are easy to adopt by accident: import the module once and every helper on String, UIView and UIButton becomes available, which makes it hard to see what a build is actually using.
The realistic alternative is to copy the handful of files you need into your own project. For a two-file need, a vendored source file with no dependency resolution is cheaper than a package dependency that will pull new helpers on every resolve.
Editorial conclusion
JKSwiftExtension suits iOS teams that want a ready-made helper layer and a convention of testing every extension, and it should be adopted file by file rather than as one dependency, since the library spans a very wide API surface with no GitHub releases to pin against. It does not suit SwiftUI projects, since the documented groups are FoundationExtension, UIKitExtension, Protocol and SmallTools. Before adding it, check the minimum iOS version of 13.0 in the Podfile, read the 2.9.2 JKPrint and JKFileLog changes if you use file logging, and confirm the SPM dependency rule of up to next major from 2.0.0 still matches your own deployment target.
Frequently asked questions
How do I install JKSwiftExtension in an iOS project?
Add the repository through File > Swift Packages > Add Package Dependency and select up to next major with 2.0.0, or add pod 'JKSwiftExtension' to your Podfile with platform :ios, '13.0'. The library requires Swift 5.0 or later.
What is the current version of JKSwiftExtension and what changed in it?
The latest entry in the version notes is 2.9.2 dated 2026.10.15. It rebuilt logging around a single timestamp() source for JKPrint and JKFileLog, removed the shared mutable DateFormatter instance, added a preparedLogPaths cache, and fixed several UIButton and UIView helpers.
Does JKSwiftExtension support SwiftUI?
The documented areas are FoundationExtension, UIKitExtension, Protocol and SmallTools, and the repository layout lists no SwiftUI group. The helpers are built around UIKit types such as UIView, UIButton and UIViewController.
How can I see how a JKSwiftExtension helper is meant to be used?
Each extension is supposed to have a matching test case class, and the README names StringExtensionViewController.swift as the test case for String+Extension. The Example directory holds those demo view controllers.
What license is JKSwiftExtension released under?
The repository lists Apache-2.0, with a LICENSE file at the top level and a CocoaPods license badge in the README. Read the LICENSE file yourself for the obligations that apply to your own distribution.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/joanking-jkswiftextension)