A few months ago I introduced the world to barK, a light-weight KMP logging library I created while I was interviewing through the summer.
In my first article, I used Android to showcase all of the features as well as example usage. Most of the information in that piece is still relevant. But after a few months of development, that initial article starts getting a little bit outdated. And most importantly, I never covered iOS!
Therefore, for this article I will present an updated version of the initial setup — barK has since migrated from Jitpack to Maven — as well as basic usage for the iOS side of a KMP project.
NOTE: barK only works for iOS KMP, and not for regular iOS applications!
Setting Up
Setting up barK for iOS usage in KMP begins the same way as any other KMP library integration: by bringing in the Maven dependency into your gradle.build.kts. Next, we explicitly export the barK library into the iOS framework. Finally, we’ll create a BarkExtensions.swift file inside Xcode so the iOS project has a clean, idiomatic interface.
Gradle Setup
Let’s begin with the Gradle setup. To get started, integrate the barK library in your project using either the a libs.versions.toml or directly in your build.gradle.kts Gradle build file.
// libs.versions.toml
[versions]
...
bark = <version>
[libraries]
...
bark = { module = "com.ivangarzab:bark", version.ref = "bark" }
// build.gradle.kts
dependencies {
...
implementation(libs.bark)
}
Then, find your iOS framework declaration — most likely in the :shared module — and directly export the the library into iOS for access.
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach { iosTarget ->
iosTarget.binaries.framework {
baseName = "Shared"
isStatic = true
...
export(libs.bark)
}
}
This is done so that the iOS app has visibility over the barK types.
NOTE: You’ll probably want to implement the barK library in the same module that you declare your iOS framework!
barK Extensions
The second part of the set up is to create a new file on the iOS project called BarkExtensions.swift as to enable clean and safe usage of the barK library.
The /ios directory inside the barK GitHub repository has further instructions on how this part work. But the gist is to bring in the /ios/BarkExtensions.swift file into the KMP iOS app.
For example, one my side-projects has it located at: iosApp/project/iosApp/BarkExtensions.swift.
Features
With the project set up, let’s take a quick look at the three main features that barK offers: Tagging, Training & Logging. I will make the effort to point out any differences that the iOS implementation may have with Android, as to fully elucidate the iOS capabilities and how it differs to its counterpart.
Tagging
We’ll begin with Tagging. There are two main ways that barK manages log tags for iOS: You can, (1) enable the tag auto-detection feature, or (2) set your own global tag.
Tag Auto-Detection
Differently to Android, barK doesn’t automatically add the class name into its logs on the iOS side. This is actually an optional feature that needs to be enabled manually; at least for iOS classes!
Bark.autoTagDisabled = false
The Bark.autoTagDisabled flag controls whether the iOS version of barK will be automatically including tags or not. The reason why this flag defaults to Off, is because generating tags on the iOS side is rather costly.
Global Tag
On the other hand, barK also accepts a global tag to be set across the board, same as it does on the Android side.
Bark.tag("Global tag")
By calling the .tag() function of the BarkExtensions.swift wrapper, you can set a global tag at any point of the app. It is also possible to .untag() the global instance, and get back to normal usage.
NOTE: Global tags would override the auto-detection feature, so make sure you don’t mix and match!
Training
Moving on to Training, the barK system requires to be ‘trained’ as to know what to log, and where to send these logs. Calling Bark.train(Trainer) will get that done . This function can be called multiple times in order to add multiple trainers to the global instance.
You can also Bark.untrain(Trainer) or Bark.releaseAllTrainers() to clean up Trainercapabilities.
static func train(trainer: Trainer)
static func untrain(trainer: Trainer)
static func releaseAllTrainers()
Logging
Finally, with Tagging & Training taken care of, we can now focus on Logging.
static func v(message: String, throwable: Error? = nil)
static func d(message: String, throwable: Error? = nil)
static func i(message: String, throwable: Error? = nil)
static func w(message: String, throwable: Error? = nil)
static func e(message: String, throwable: Error? = nil)
Logging in iOS works exactly the same as in Android.
Bark.d("Your log")
The log levels that barK uses are Android-centric, in order to better fit the Kotlin shared layer, and avoid overfitting solutions.
Muzzling
BarK also offers a simple way of ‘muzzling’ (or muting) the library during runtime, by simply calling the muzzle() function.
static func muzzle()
static func umuzzle()
NOTE: This function can be particularly useful when dealing with flows containing sensitive data, for example.
Example Usage
With the library integrated, and the features explained, we will now take a look at usage. The following block shows a typical init & implementation of the barK library on iOS.
@main
struct iOSApp: App {
init() {
...
startLogging()
}
private func startLogging() {
#if DEBUG
let volume = Level.verbose
#else
let volume = Level.debug
#endif
Bark.autoTagDisabled = false
Bark.train(trainer: NSLogTrainer(volume: Level.verbose))
Bark.v("Bark has been initilized for iOS successfully!")
}
}
Notice that we’re setting the volumeLevel of the Trainer based on whether we’re running a DEBUG or production build.
Moreover, we’re enabling the autoTagDisabled flag so that we can get automatic tag detection.
Next, we’re doing a simple .train() call using the built-in NSLogTrainer receiving the volume Level from before.
At the end, we’re doing a single .v() call to print our first log, indicating that barK has been initialized successfully!
Afterthought
We have now seen how barK works for KMP iOS applications!
The idea behind barK is not only to make logging easier to client applications, but also for SDK libraries and their integrating clients as well.
Therefore, I will publish another article diving deeper into SDK usage.
And once again, feel free to check out the first article of this series for the Android implementation.
For now, let me know what you think of this little passion project of mine. And keep those Android + iOS apps barking loudly!
barK: Because every log deserves a good home. 🐶🏠
Resources
- GitHub: https://github.com/ivangarzab/barK
- Maven Central Repository: https://central.sonatype.com/artifact/com.ivangarzab/bark
- First barK article: barK: A Lightweight Logging Library for Android
Top comments (0)