Skip to content

Instantly share code, notes, and snippets.

@magicwave
Last active March 15, 2023 00:22
Show Gist options
  • Save magicwave/070c5c65ed05fea744cf604a33d6a6c4 to your computer and use it in GitHub Desktop.
Save magicwave/070c5c65ed05fea744cf604a33d6a6c4 to your computer and use it in GitHub Desktop.
Example of working with Dates in Ditto, and the docDictionary convenience method.
///
// DateFormatter+docDictionary.swift
//
//
// Created by Eric Turner on 3/14/23.
//
// Copyright © 2023 DittoLive Incorporated. All rights reserved.
import DittoSwift
import Foundation
/*
Example of defining a static `ISO8601DateFormatter` instance as an extension on `DateFormatter`.
Learn why: https://sarunw.com/posts/how-to-use-dateformatter/
and how to use it: https://sarunw.com/posts/how-to-parse-iso8601-date-in-swift/
*/
extension DateFormatter {
/// Date formatters are expensive to initialize and configure. This extension makes a static instance of the
/// `ISO8601DateFormatter`available througout the app. It may be further configured with
/// `ISO8601DateFormatter.Options`defaults as needed.
///
/// Usage example:
/// DateFormatter.isoDate.string(from: "2022-01-31T02:22:40Z")
static var isoDate: ISO8601DateFormatter {
let f = ISO8601DateFormatter()
return f
}
}
/*
Example of using an `ISO8601DateFormatter` instance to initialize `Date`s from formatted strings,
and strings from `Date`s.
Here our model is a Message, including a `createdOn` property that is a `Date`. We may use this
date property in many different calculations throughout the app, however Ditto doesn't accept a
native `Date` type as a `DittoDocument` value. So we store an ISO8601-formatted string representing
a date as the value for the `createdOn` key when we upsert the model as a `DittoDocument` into the
db. At some point when we initialize the model from a `DittoDocument`, we will convert the string
value into a `Date` object using the same static `ISO8601DateFormatter` instance.
In the `init(document: DittoDocument)` initializer, we extract the ISO8601-formatted string value
for key "createdOn" from the `document` (below): `document["createdOn"].stringValue`. And then we
pass that string to the `ISO8601DateFormatter.date()` method to inialize the property.
*/
struct Message: Identifiable, Equatable {
var id: String
var createdOn: Date
var text: String
var userId: String
var imageToken: DittoAttachmentToken?
}
extension Message {
init(document: DittoDocument) {
self.id = document["_id"].stringValue
self.createdOn = DateFormatter.isoDate.date(from: document["createdOn"].stringValue) ?? Date()
self.text = document["text"].stringValue
self.userId = document["userId"].stringValue
self.imageToken = document["imageToken"].attachmentToken
}
}
extension Message {
init(
id: String? = nil,
createdOn: Date? = nil,
text: String? = nil,
userId: String? = nil,
imageToken: DittoAttachmentToken?
) {
self.id = id ?? UUID().uuidString
self.createdOn = createdOn ?? Date()
self.text = text ?? ""
self.userId = DataManager.shared.currentUserId ?? "unknown user"
self.imageToken = imageToken
}
}
extension Message: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
/*
Example of a convenience method to transform the model property values into a dictionary of values
formatted for the `DittoCollection.upsert` method, for storing the model as a `DittoDocument` in
the Ditto db.
A model object can be passed to some data handling function in the app and conveniently `upsert`ed
into a collection by calling the docDictionary() method. Below is the `docDictionary()` method,
and the example data handling function is in the DataManager implementation below that. The return
type of `docDictionary()` is `[String: Any?]`, which is the `content` parameter type specified in
the `DittoCollection.upsert()` function signature.
*/
extension Message {
func docDictionary() -> [String: Any?] {
[
"_id": id,
"createdOn": DateFormatter.isoDate.string(from: createdOn),
"text": text,
"userId": userId,
"imageToken": imageToken
]
}
}
/*
Example of a function which uses the `Message.docDictionary()` method to upsert a model
into the db as a `DittoDocument`.
*/
struct DataManager {
static var shared = DataManager()
private let ditto = Ditto()
let currentUserId: String? = nil
func storeMessage(_ message: Message) {
try! ditto.store["messages"].upsert(
message.docDictionary()
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment