Last active
March 15, 2023 00:22
-
-
Save magicwave/070c5c65ed05fea744cf604a33d6a6c4 to your computer and use it in GitHub Desktop.
Example of working with Dates in Ditto, and the docDictionary convenience method.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// | |
// 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