Swift CouchDB client 1.2.0

Couple months ago I started learning Apple's DocC tool that generates documentation from your source code. I've decided to use as many features as possible so I took my small lib CouchDB Client and added docs to every method including usage examples that Xcode will show in the autocomplete popup. As it often happens, during adding docs and examples I found that many things in the library can be done in a much better way. So I've updated existing methods and added some more that can take a doc as a param and use generic types.
Next step was tutorials. Apple allows devs to create exactly the same tutorials as they have for SwiftUI on their own website. So I've added a couple. They're also part of the repo on GitHub.
Pretty sure that I've spent more time on the documentation than on the lib itself but I hope it's worth it.
CouchDB Client on GitHub | Documentation with examples and tutorials.
Password generation using Security Framework on iOS and macOS
Couple lines of code to generate a 15 characters length password (just like in Safari):
import Security
let pass = SecCreateSharedWebCredentialPassword() as String?
print(pass as Any)
Swift CouchDB client 1.0.0
Finished new version of Swift CouchDB client. Now it's using only async-http-client as a dependency to make http/https requests. Can be used with Vapor 4.
Available on Github: https://github.com/makoni/couchdb-swift
Wrapping models in SwiftUI for Identifiable conformance
Using an array of models in List view in SwiftUI requires conformance to Identifiable protocol.
Here's an example of a model:
struct MyDataModel {
let title: String
let message: String
}
An example of SwiftUI view that you want to display a list:
struct TestView: View {
var dataArray: [MyDataModel]
var body: some View {
List(dataArray) { data in
VStack {
Text(data.title)
Text(data.message)
}
}
}
}
Using MyDataModel in List will show an error in Xcode:
Sometimes you can't just change a model. It might be a data model from a third party SDK that you're using in your app. But you can create a wrapper for this struct to confirm Identifiable protocol:
struct MyDataModelWrapper: Identifiable {
var id = UUID()
var data: MyDataModel
}
let testDataModel = MyDataModel(
title: "Title 1",
message: "I wanna be used inside of a List"
)
let wrappedData = MyDataModelWrapper(data: testDataModel)
So the view will look like this:
struct TestView: View {
var dataArray: [MyDataModelWrapper]
some View {
List(dataArray) { wrappedData in
VStack {
Text(wrappedData.data.title)
Text(wrappedData.data.message)
}
}
}
}
Done.
Syntax sugar for JSON parsing in Swift
JSON decoding and encoding became easy after adding Codable protocol in Swift 4.0. But during coding I wanted to have something shorter and more elegant than Do-Catch statement that looks like this:
var myModel: MyModel?
let decoder = JSONDecoder()
do {
myModel = try decoder.decode(MyModel.self, from: data)
} catch {
print(error.localizedDescription)
}
Or like this:
let myModel: MyModel? = try? decoder.decode(MyModel.self, from: data)
So I wrote a protocol with default implementation that allows to do decoding just like that:
let myModel = MyModel.decodeFromData(data: data)
And the same for encoding:
let data = MyModel.encode(fromEncodable: myModel)
All you need is just to add protocol conformance:
extension MyModel: Parseable {
typealias ParseableType = Self
}
It's available on GitHub as a Swift Package: https://github.com/makoni/parsable
Using GitHub Actions as a CI for Swift project
Here's a config for a GitHub Actions workflow to build a Swift project. This example is for building a Vapor project using Swift 5.0.3 on Ubuntu 18.04:
name: Ubuntu 18.04 Swift 5.0.3
on: [push]
jobs:
build_on_ubuntu:
runs-on: ubuntu-18.04
steps:
- name: Install dependencies
run: sudo apt-get update; sudo apt-get install -yq libssl-dev zlib1g-dev
- name: Checkout
uses: actions/checkout@master
- name: Download Swift
run: curl https://swift.org/builds/swift-5.0.3-release/ubuntu1804/swift-5.0.3-RELEASE/swift-5.0.3-RELEASE-ubuntu18.04.tar.gz --output swift.tar.gz
- name: Unpack Swift
run: |
tar xzf swift.tar.gz
mv swift-5.0.3-RELEASE-ubuntu18.04 swift
- name: Swift build
run: |
export PATH=$(pwd)/swift/usr/bin:"${PATH}"
swift build -c release
Adding Dark Mode support for a website
iOS 13 coming this fall will include dark mode. Current macOS already has dark mode. With bringing dark mode to iOS Apple also recommends to web developers to adopt colours for dark mode.
It's pretty easy to implement. All you need is to change CSS for your website and add something like that:
:root {
color-scheme: light dark;
--body-background-color: white;
--body-text-color: #2F2F2F;
}
@media (prefers-color-scheme: dark) {
:root {
--body-background-color: #222222;
--body-text-color: #E2E2E2;
}
}
body {
background-color: var(--body-background-color);
color: var(--body-text-color);
}
So you're adding support for colour schemes with color-scheme: light dark; and defining CSS variables.
If you need to test it you can try the latest Safari in latest betas of iOS or macOS or (maybe) Safari developer preview. Developer tools in Safari have a special button to test dark mode.
Interesting: in macOS 10.15 default body background for dark mode is also dark. But in 10.14 it will be white in Safari and Firefox. You need to specify the background colour for the dark scheme if you want to support macOS < 10.15. Apple didn't mention that during the WWDC session. All they did was just remove the background-color property from CSS to let OS choose the background colour. They provide the NSHipster website as an example but its CSS also contains background colour property in CSS to support previous macOS versions :)
I've added dark scheme support to my Space In Box site. Also check the NSHipster site that has it too.
This article is some kind of summary from WWDC video Supporting Dark Mode in Your Web Content.